[SCM] faust/master: Imported Upstream version 0.9.73~repack1

umlaeute at users.alioth.debian.org umlaeute at users.alioth.debian.org
Tue May 17 21:42:44 UTC 2016


The following commit has been merged in the master branch:
commit 9cad20a7b7e3af8047f682c986086b191159296a
Author: IOhannes m zmölnig <zmoelnig at umlautQ.umlaeute.mur.at>
Date:   Tue May 17 23:41:19 2016 +0200

    Imported Upstream version 0.9.73~repack1

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6cd377c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.aux
+*.log
+*.out
+*.rai
+*.rao
+*.toc
+*.o
+*.mxo
+*.bak
+*.app
+.DS_Store
+*tmp*
+*dir*
+
+
diff --git a/Makefile b/Makefile
index c3b2aaf..929286e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-version := 0.9.46
+version := 0.9.73
 
 DESTDIR ?= 
 PREFIX ?= /usr/local
@@ -6,33 +6,69 @@ CROSS=i586-mingw32msvc-
 
 MAKEFILE := Makefile.unix
 
+system	?= $(shell uname -s)
+
+ifeq ($(system), Darwin)
+LIB_EXT = dylib
+else
+ifneq ($(findstring MINGW32, $(system)),)
+LIB_EXT = dll
+EXE = .exe
+else
+LIB_EXT = so
+endif
+endif
+
 prefix := $(DESTDIR)$(PREFIX)
 arch   := $(wildcard architecture/*.*)
 mfiles := $(wildcard examples/Makefile.*)
 vname := faust-$(version)-$(shell date +%y%m%d.%H%M%S)
 zname := faust-$(version)
 
+.PHONY: all world dynamic httpd win32 sound2faust
+
 all :
 	$(MAKE) -C compiler -f $(MAKEFILE) prefix=$(prefix)
 	$(MAKE) -C architecture/osclib
 
+# make world: This builds all the common targets for a fairly complete Faust
+# installation: Faust compiler, sound2faust utility, OSC and HTTPD libraries
+# (both static and dynamic). Most of the extra targets require additional
+# dependencies and hence aren't built by default; please check the Faust
+# README for details. This target may be built in parallel (make -j).
+world : all sound2faust httpd dynamic
+
+dynamic : all httpd
+	$(MAKE) -C architecture/httpdlib/src dynamic PREFIX=$(PREFIX)
+	$(MAKE) -C architecture/osclib dynamic PREFIX=$(PREFIX)
+
+httpd :
+	$(MAKE) -C architecture/httpdlib/src
+
 win32 :
 	$(MAKE) -C compiler -f $(MAKEFILE) prefix=$(prefix) CXX=$(CROSS)g++
 	$(MAKE) -C architecture/osclib CXX=$(CROSS)g++ system=Win32
 
+sound2faust: 
+
+	$(MAKE) -C tools/sound2faust
 
 .PHONY: clean depend install ininstall dist parser help
 
 help :
-	@echo "make or make all : compiler the faust compiler"
+	@echo "Usage : 'make; sudo make install'"
+	@echo "For http support : 'make httpd; make; sudo make install' (requires GNU libmicrohttpd)"
+	@echo "make or make all : compile the Faust compiler and osc support library"
+	@echo "make httpd : compile httpdlib (requires GNU libmicrohttpd)"
+	@echo "make dynamic : compile httpd & osc supports as dynamic libraries"
+	@echo "make sound2faust : compile sound to DSP file converter"
 	@echo "make parser : generate the parser from the lex and yacc files"
 	@echo "make clean : remove all object files"
 	@echo "make doc : generate the documentation using doxygen"
-	@echo "make install : install the compiler and the architecture files in $(prefix)/bin $(prefix)/lib/faust"
+	@echo "make install : install the compiler, tools and the architecture files in $(prefix)/bin $(prefix)/lib/faust $(prefix)/include/faust"
 	@echo "make uninstall : undo what install did"
-	@echo "make dist : make a tar.gz file ready for distribution"
+	@echo "make dist : make a Faust distribution as a .zip file"
 	@echo "make log : make a changelog file"
-	@echo "make zip : make a windows binary distribution"
 
 parser :
 	$(MAKE) -C compiler -f $(MAKEFILE) parser
@@ -41,10 +77,13 @@ clean :
 	$(MAKE) -C compiler -f $(MAKEFILE) clean
 	$(MAKE) -C examples clean
 	$(MAKE) -C architecture/osclib clean
+	$(MAKE) -C architecture/httpdlib/src clean
+	$(MAKE) -C tools/sound2faust clean
 
 depend :
 	$(MAKE) -C compiler -f $(MAKEFILE) depend
 	$(MAKE) -C architecture/osclib depend
+	$(MAKE) -C architecture/httpdlib/src depend
 
 
 doc :
@@ -52,90 +91,146 @@ doc :
 
 
 install :
-	mkdir -p $(prefix)/lib/faust/osclib
+	# install faust itself
 	mkdir -p $(prefix)/bin/
+	mkdir -p $(prefix)/include/
+	mkdir -p $(prefix)/include/faust/
+	mkdir -p $(prefix)/include/faust/osc/
 	install compiler/faust $(prefix)/bin/
-	install -m 0644 $(arch) $(prefix)/lib/faust/
-	rm -rf $(prefix)/lib/faust/VST
-	cp -r architecture/VST $(prefix)/lib/faust/
-	rm -rf $(prefix)/lib/faust/iPhone
-	cp -r architecture/iPhone $(prefix)/lib/faust/
-	cp -r architecture/audio $(prefix)/lib/faust/
-	cp -r architecture/gui $(prefix)/lib/faust/
-	cp architecture/osclib/lib*.a $(prefix)/lib/faust/osclib
-	cp architecture/osclib/faust/include/*.h $(prefix)/lib/faust/osclib
-	find $(prefix)/lib/faust/ -name CVS | xargs rm -rf
-	install -m 0644 $(mfiles) $(prefix)/lib/faust/
+	# install architecture and faust library files
+	mkdir -p $(prefix)/lib/faust
+	cp architecture/*.cpp $(prefix)/lib/faust/
+	cp architecture/*.lib $(prefix)/lib/faust/
+	# install iOS
+	rm -rf $(prefix)/lib/faust/iOS
+	cp -r architecture/iOS $(prefix)/lib/faust/
+	rm -rf $(prefix)/lib/faust/iOS/DerivedData/
+	# install AU
+	rm -rf $(prefix)/lib/faust/AU/
+	cp -r architecture/AU $(prefix)/lib/faust/
+	cp -r architecture/android $(prefix)/lib/faust/
+	cp -r architecture/max-msp $(prefix)/lib/faust/
+
+	# install math documentation files
+	cp architecture/mathdoctexts-*.txt $(prefix)/lib/faust/
+	cp architecture/latexheader.tex $(prefix)/lib/faust/
+	# install additional binary libraries (osc, http,...)
+	([ -e architecture/httpdlib/libHTTPDFaust.a ] && cp architecture/httpdlib/libHTTPDFaust.a $(prefix)/lib/) || echo libHTTPDFaust.a not available
+	([ -e architecture/httpdlib/libHTTPDFaust.$(LIB_EXT) ] && cp architecture/httpdlib/libHTTPDFaust.$(LIB_EXT) $(prefix)/lib/) || echo libHTTPDFaust.$(LIB_EXT) not available
+		
+	([ -e architecture/osclib/libOSCFaust.a ] && cp architecture/osclib/libOSCFaust.a $(prefix)/lib/) || echo libOSCFaust.a not available
+	([ -e architecture/osclib/libOSCFaust.$(LIB_EXT) ] && cp -a architecture/osclib/libOSCFaust*.$(LIB_EXT)* $(prefix)/lib/) || echo libOSCFaust.$(LIB_EXT) not available
+	
+	cp -r architecture/httpdlib/html/js $(prefix)/lib/faust/js
+	([ -e architecture/httpdlib/src/hexa/stylesheet ] && cp architecture/httpdlib/src/hexa/stylesheet $(prefix)/lib/faust/js/stylesheet.js) || echo stylesheet not available
+	([ -e architecture/httpdlib/src/hexa/jsscripts ] && cp architecture/httpdlib/src/hexa/jsscripts $(prefix)/lib/faust/js/jsscripts.js) || echo jsscripts not available
+	# install includes files for architectures
+	cp -r architecture/faust $(prefix)/include/
+	# install additional includes files for binary libraries  (osc, http,...)
+	cp architecture/osclib/faust/faust/OSCControler.h $(prefix)/include/faust/gui/
+	cp architecture/osclib/faust/faust/osc/*.h $(prefix)/include/faust/osc/
+	cp architecture/httpdlib/src/include/*.h $(prefix)/include/faust/gui/
+	# install faust2xxx tools
 	make -C tools/faust2appls install
+	# install sound2faust converter
+	[ -e tools/sound2faust/sound2faust ] && make -C tools/sound2faust install || echo sound2faust not compiled
+	# install webaudio
+	cp -r architecture/webaudio $(prefix)/lib/faust/
+	# install Max/MSP
+	cp -r architecture/max-msp $(prefix)/lib/faust/
+        
 
 
 uninstall :
+	rm -f $(addprefix $(prefix)/lib/, libHTTPDFaust.a libHTTPDFaust.$(LIB_EXT) libOSCFaust.a libOSCFaust*.$(LIB_EXT)*)
 	rm -rf $(prefix)/lib/faust/
-	rm -f $(prefix)/bin/faust
+	rm -rf $(prefix)/include/faust/
+	rm -f $(prefix)/bin/faust$(EXE)
+	make -C tools/faust2appls uninstall
+	rm -f $(prefix)/bin/sound2faust$(EXE)
 
+# make a faust distribution .zip file
 dist :
-	$(MAKE) -C compiler -f $(MAKEFILE) clean
-	$(MAKE) -C examples clean
-	mkdir -p faust-$(version)
-	cp README WHATSNEW COPYING Makefile faust-$(version)
-	cp -r architecture faust-$(version)
-	cp -r benchmark faust-$(version)
-	cp -r compiler faust-$(version)
-	cp -r documentation faust-$(version)
-	cp -r examples faust-$(version)
-	cp -r syntax-highlighting faust-$(version)
-	cp -r tools faust-$(version)
-	cp -r windows faust-$(version)
-	find faust-$(version) -name CVS | xargs rm -rf
-	find faust-$(version) -name "*~" | xargs rm -rf
-	find faust-$(version) -name ".#*" | xargs rm -rf
-	find faust-$(version) -name "*.o" | xargs rm -rf
-	rm -f faust-$(version).tar.gz
-	tar czfv faust-$(version).tar.gz faust-$(version)
-	rm -rf faust-$(version)
-
-# make a faust distribution by cloning the git repository
-clonedist :
-	git clone git://faudiostream.git.sourceforge.net/gitroot/faudiostream/faudiostream faust-$(version)
-	rm -rf faust-$(version)/.git
-	rm -f faust-$(version).tar.gz
-	tar czfv faust-$(version).tar.gz faust-$(version)
-	rm -rf faust-$(version)
-
-archive :
-	$(MAKE) -C compiler -f $(MAKEFILE) clean
-	$(MAKE) -C examples clean
-	mkdir -p $(vname)
-	cp README COPYING Makefile $(vname)
-	cp -r architecture $(vname)
-	cp -r benchmark $(vname)
-	cp -r compiler $(vname)
-	cp -r documentation $(vname)
-	cp -r examples $(vname)
-	cp -r syntax-highlighting $(vname)
-	cp -r tools $(vname)
-	cp -r windows $(vname)
-	find $(vname) -name "*~" | xargs rm -rf
-	tar czfv $(vname).tar.gz $(vname)
-	rm -rf $(vname)
-
-zip :
-	mkdir -p $(zname)
-	cp README COPYING Makefile $(zname)
-	cp -r architecture $(zname)
-	cp -r benchmark $(zname)
-	cp    compiler/faust.exe $(zname)
-	cp -r examples $(zname)
-	cp -r documentation $(zname)
-	cp -r syntax-highlighting $(zname)
-	cp -r tools $(zname)
-	cp -r windows $(zname)
-	find $(zname) -name "*~" | xargs rm -rf
-	find $(zname) -name CVS | xargs rm -rf
-	find $(zname) -name ".#*" | xargs rm -rf
-	zip -r $(zname).zip $(zname)
-	rm -rf $(zname)
+	git archive --format=tar.gz -o faust-$(version).tgz --prefix=faust-$(version)/ HEAD
+
 
 log :
-	cvs2cl --fsf
+	git log --oneline --date-order --reverse --after={2014-05-19} master >log-$(version)
+
+# Make Debian packages. This builds a package from the current HEAD in a
+# subdirectory named $(debdist). It also creates the source archive that goes
+# along with it. All files will be created in the toplevel Faust source
+# directory.
+
+# To make this work, you need to have the Debian package toolchain (debuild
+# and friends) installed. Also make sure you have your DEBEMAIL and
+# DEBFULLNAME environment variables set up as explained in the debchange(1)
+# manual page. These are needed to create changelog entries and in order to
+# sign the Debian packages created with 'make deb' and 'make debsrc'.
+
+# The typical workflow is as follows:
+
+# 1. Run 'make debchange' once to create a new debian/changelog entry. You
+# *must* do this once so that debuild knows about the proper version number of
+# the package.
+
+# 2. Run 'make deb' to build a signed binary package. Or 'make deb-us' for an
+# unsigned one.
+
+# If you only need the binary package for local deployment then you're done.
+# Otherwise proceed to step 3.
+
+# 3. Run 'make debsrc' to create a signed Debian source package which can be
+# uploaded, e.g, to Launchpad using 'dput'. Or 'make debsrc-us' for an
+# unsigned package.
+
+# 4. Run 'make debclean' to get rid of any files that were created in steps 2
+# and 3.
+
+# The Debian version gets derived from the package version $(version) as well
+# as the date and serial number of the last commit.
+debversion = $(version)+git$(shell git log -1 --format=%cd --date=short | sed -e 's/-//g')+$(shell git rev-list --count HEAD)
+# Debian revision number of the package.
+debrevision = 1
+# Source tarball and folder.
+debsrc = faust_$(debversion).orig.tar.gz
+debdist = faust-$(debversion)
+
+# This is used for automatically generated debian/changelog entries (cf. 'make
+# debchange'). Adjust as needed.
+debmsg = "Build from latest upstream source."
+debprio = "low"
+
+.PHONY: debversion debchange debclean deb debsrc deb-us debsrc-us
+
+debversion:
+	@echo $(debversion)
+
+debchange:
+	dch -u $(debprio) -v $(debversion)-$(debrevision) $(debmsg) && dch -r ""
+
+debclean: $(debsrc)
+	rm -rf $(debdist)
+	rm -f faust_$(version)+git*
+
+deb: $(debsrc)
+	rm -rf $(debdist)
+	tar xfz $(debsrc)
+# Here we just copy debian/ from the working copy since it might have changes
+# that haven't been committed yet.
+	cd $(debdist) && cp -R ../debian . && debuild $(DEBUILD_FLAGS)
+	rm -rf $(debdist)
+
+debsrc:
+	$(MAKE) deb DEBUILD_FLAGS=-S
+
+deb-us:
+	$(MAKE) deb DEBUILD_FLAGS="-us -uc"
+
+debsrc-us:
+	$(MAKE) deb DEBUILD_FLAGS="-S -us -uc"
+
+$(debsrc) :
+	git archive --format=tar.gz -o $(debsrc) --prefix=$(debdist)/ HEAD
+
 # DO NOT DELETE
diff --git a/README b/README
index 2b90efc..a77fd96 100644
--- a/README
+++ b/README
@@ -5,7 +5,6 @@
 	 			 http://www.grame.fr
 
 
-
 1/ Introduction
 ----------------
 FAUST (Functional Audio Stream) is a functional programming
@@ -22,25 +21,20 @@ JACK or ALSA applications, as well as CSOUND, LADSPA, MAX/MSP, PD,
 Q, SC and VST plugins. 
 
 
-2/ Organisation of the distribution
+2/ Organization of the distribution
 -----------------------------------
 The Faust distribution can be downloaded at:
 	http://sourceforge.net/projects/faudiostream
 
-It's organisation is the following :
+It's organization is the following :
 
-	architecture/		: the architecture files and libraries 
-						  currently supported
-	benchmark/			: tools to measure the impact of various 
-                          compiler options
-	compiler/			: sources of the Faust compiler
-	documentation /		: Faust developer's documentation
-	examples/			: examples of Faust programs with makefiles
-						  for various audio targets
-	syntax-highlighting/: support for syntax highlighting for 
-						  several editors
-	tools/				: Additional easy-to-use scripts to 
-						  produce binaries and plugins
+	architecture/          : the architecture files and libraries currently supported
+	benchmark/             : tools to measure the impact of various compiler options
+	compiler/              : sources of the Faust compiler
+	documentation/         : Faust developer's documentation
+	examples/              : examples of Faust programs with makefiles for various audio targets
+	syntax-highlighting/   : support for syntax highlighting for several editors
+	tools/                 : Additional easy-to-use scripts to produce binaries and plugins
 
 
 3/ Compilation and installation
@@ -89,7 +83,7 @@ To list for possible audio targets :
 
 	make help
 
-About 20 different audio plateforms are supported : 
+About 20 different audio platforms are supported : 
 
 - Action Script
 - Alsa
@@ -144,8 +138,5 @@ contribute to the project, two mailing lists are available:
 https://lists.sourceforge.net/lists/listinfo/faudiostream-devel
 https://lists.sourceforge.net/lists/listinfo/faudiostream-users
 
-
-
-
 Yann Orlarey
 
diff --git a/WHATSNEW b/WHATSNEW
index 74d870f..650bf8b 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1,111 +1,715 @@
-
 							================
-							| FAUST 0.9.46 |
+							| FAUST 0.9.73 |
 							================
 
-GRAME - Centre National de Creation Musicale - is happy to announce the release
-of FAUST 0.9.46. This new release provides several fixes, additions and
-improvements in particular in the examples, libraries and architecture files.
+GRAME - Centre National de Creation Musicale - is happy to announce
+the release of FAUST 0.9.73. 
+
+This release provides many bug fixes and improvements in several architectures 
+(in particular Android) and libraries, as well as a new ROS (Robotic Operating System)
+architecture. 
+ 
 
 -------------
 About FAUST :
 -------------
 
 FAUST (Functional Audio Stream) is a functional programming language
-specifically designed for real-time signal processing and synthesis. A
-distinctive characteristic of FAUST is to be fully compiled. The FAUST compiler
-translates DSP specifications into very efficient C++ code that works at sample
-level. It targets high-performance signal processing applications, libraries and
-audio plug-ins for a variety of audio platforms and standards. A same FAUST
-specification can be used to easily generate native JACK or ALSA applications,
-as well as CSOUND, LADSPA, MAX/MSP, PD, Q, SC and VST plugins.  
-
-The Faust distribution can be downloaded at:
+specifically designed for real-time signal processing and synthesis. 
+
+A distinctive characteristic of FAUST is to be fully compiled. The FAUST compiler
+translates DSP specifications into very efficient C++ code that works at sample 
+level. The generated code is self contained and doesn't depend on any library or 
+runtime.
+
+Moreover a same FAUST specification can be used to generate native implementations 
+for most OS (Linux, OSX, Android, iOS) or platforms (LV2, Ladspa, VST, PD, Csound, SC,..)
+
+
+Faust distribution can be downloaded at:
 http://sourceforge.net/projects/faudiostream
 
 The GIT repository can be cloned with the following command :
-git clone git://faudiostream.git.sourceforge.net/gitroot/faudiostream/faudiostream faust
+git clone git://git.code.sf.net/p/faudiostream/code faust
+
+To compile faust :
+make httpd (skip this step if you don't have GNU libmicrohttpd installed)
+make
+sudo make install
+
 
 Two mailing lists are available:
 https://lists.sourceforge.net/lists/listinfo/faudiostream-devel
 https://lists.sourceforge.net/lists/listinfo/faudiostream-users
 
 In order to test FAUST without installing it, please refer to the
-Online Faust Compiler (requires firefox): 
+Online Faust Compiler : 
 http://faust.grame.fr
 
 
-======================== WHAT'S NEW ==============================
+======================== Change log since 0.9.67 ==============================
 
 
----------------
-Architectures :
----------------
-- supercollider : 
-	- revised search-order for SuperCollider headers in Linux, 
-	- enhancements to SuperCollider class and control name generation in faust2sc and supercollider.cpp, 
-	- Faust prefix added to SuperCollider module name to conform with faust2supercollider script, 
-	- default SynthDef with metadata support added to faust2supercollider and faust2sc
-	- -DNO_LIBSNDFILE and -DNDEBUG added to Makefile.sccompile for conformity with faust2supercollider (Darwin)
-- matlabplot : new -s <nnnnn> (skip) option allowing to skip <nnnnn> samples before printing
-- netjack : IP and port paramaters added in netjack-dsp architecture, NetJack client now restart.
-- iPhone : architecture files updated
-- pure : bug fixes, realtime-friendly voice allocation fixes, support for metadata.
-- puredata : on Darwin both 32 and 64-bits intel code are now generated
 
+93afbeb Fixes horizontal bargraph display.
+0f50a61 Changes makefiles to search for HTTP library independently of Faust library. This way, if it is in a different place, utilization is still possible.
+e0b5e14 Removes titling capabilities from jquery.svg.js.
+c8b2f02 Correct JSONUI: generated 'meta' only if needed.
+aa347f9 faust2asm : -comb now allows to combine several .dsp files in a unique comb.js output.
+cdb47b3 faust2webaudioasm, faust2asm : correct JS page generation.
+edc0cfd Correct faust2asm.
+fb06328 Correct httpd Makefile.
+327b4f5 Correct Makefile.
+e88cadd Documantation for 'sound2faust' tool.
+ba3cc41 New poly-dsp file, update webaudio-asm-poly.cpp to use it.
+eba3563 Add -i parameter in sound2faust tool.
+6caf48e cached() method made private in source reader
+14e1cc4 faust2webaudioasm : add 'controls' function in the DSP API to get the list of all input controls path.
+904ed50 vsti-poly.cpp renamed vst.cpp. Other vat architecture files removed. faust2vst and faust2vsti updated to use vat.cpp
+d3c196a Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+fbb8481 faust2ebaudioasm : complete MIDI implementation.
+51ffc41 Correct 'make dist'.
+9169c87 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+f95a57d Implements the possibility to create multiple UIs on a single webpage.
+dcd250f Cleanup.
+2b146ec Implements dynamic callback creation for UIs.
+8c1f0bc Allows for multiple UIs to be in one web page.
+53aa462 in case slider step is zero don't get blocked in QT optimalTick()
+b18206a Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+4021488 faust2webaudiosm : correct getJSON.
+1ef28de faust2webaudiosm : correct getJSON for poly.
+a4cc38f VSTi: Set parameter min, max and step properties
+21ddf22 flatten mode in JSONUI.
+2bd5ce9 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+203d6c6 Correct JSONUI.h.
+ae63e3d Installing Event Filter on GroupBox QT to enable Drag and Drop
+fa954e3 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+bd6f7ab Correct faust2webaudioasm JS wrappers.
+440e0f2 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+11c3a20 Add FTZ in math.lib.
+de7a364 New « …[style:numerical]… » option added to barographs. It allows values to be displayed as numbers instead of bars.
+056292b Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+145120f fix closing braquet
+d2da626 Allows for UI-specific callbacks in web UI
+645cc8c faust2webaudioasm : remove handler parameter in DSP contructor.
+933b48e Correct  _f4u.main.
+2156a4d Makes the delayed tooltip list local to SVG objects instead of global.
+975db32 Fix for iRig in coreaudio-ios-dsp.h.
+396bbc7 fix default value and range limits in second eq section in zita-rev1; flag controls which should be logarithmic
+29e3e92 Sound2faust now generates a rtable for each channel.
+5b477ce Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+df59beb Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+8540cba When generating UI, empty labels are converted in '0xABCD' locking ones.
+1fe5f1f Adapt GTK and QT UI for '0xABCD' kind of labels.
+aa12bc2 new [scale:log] metadata. Currently only available in the QT version. [scale:log] added in relevant places to effect.lib
+c5daf59 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+1c8dad1 Correct coreaudio-dsp.h to allow several application to access audio input in 'aggregate device' mode.
+a0ec043 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+d31480f incorporate nice new [scale:log] metadata field for Qt sliders
+d0cbf47 faustqt.h initialization of const parameter N modified
+76282ff Added linear, log and exp ValueConverters.
+d3bfac7 Added inline option -i when compiling with Faust like in faust2msp
+22a0082 New interface elements (only for qt right now) : radio button groups and pop-up menus. These elements are accessible using two new radio and menu styles : ...[style:radio{'foo':0.54;'faa':-10.8;...'fuu':3.14}]... and ...[style:menu{'foo':0.54;'faa':-10.8;...'fuu':3.14}]... . The file examples/tester2.dsp demonstrates these new styles
+a8098c1 Small modification in QT architecture to keep QT4.8 compatibility
+c4ccfff Smooth transitions added to tester2.dsp
+e6290f6 Added freeverb and vocoder to effect.lib
+8632a4f included missing string.h header
+e046176 const declarations getDesAddress renamed getDestAddress
+e2d2b20 first received packet from another host sets the destination address to this host (unless this address is already not localhost)
+d534d45 Correct sound2faust Makefile.
+d910a60 Commented out some unused trace code to avoid warnings
+126e265 Removed fPort field from HTTPDServer
+d83b3b5 Declared OSCUI first parameter as a const char*
+95bfb4c Accessors added to OSCUI interface
+392df28 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+b1e06de fix type warning : arity() returns an int
+5a57aa3 removed useless variable
+65501d6 Paul Batchelor update for csound6.
+7fd39d2 DSP without enclosing group are now labelled with an 'empty' (= 0xABCD) label.
+206bd7c version number changed + change log
+258d860 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+f3d128a Correct faust2csound for Linux.
+23aae1f Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+c03b694 StyleSheet for QT architecture in separate resource file
+b0dea65 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+9741dfc Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+cb5ce64 Some unused code commented out from list.cpp
+e4f84dd Added two new functions stereoize(p) and recursivize(p,q) :
+653c79f Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+88fea20 Correct group naming in case of no explicit global name.
+2107cff Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+bc4d1ff Correct checkNullLabel for UI generation.
+81bf55f QTGUI derived from QWidget instead of QObject
+0395188 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+f148c5e add event filter on each box opened in QTGUI
+98c90ff Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+b0e7f69 Update MapUI.
+ac6a46f Fixed some unused variable warning for 'err'
+b8c881d Fixed some warnings when compiling the parser.
+12155af Fixed voice_node struct definition to cross-compile with i686-w64-mingw32 on linux
+2395417 Added faust2w32vst script to cross-compile 32-bits windows vst plug-ins from Linux
+0a73502 Correct minimal.cpp.
+78f375c Oli Larkin patch for faust2vst and hslider step parameter.
+c792641 Correct use of getcwd.
+70e6a68 Add disconnect in JS code.
+cdb383d Default Group border style
+6508405 Correct webaudioasm architecture files.
+cea5b67 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+82326b6 Correct FICocoaUI.h (memory management).
+371512a Correct preferences management for iOS target.
+879a043 Establishes infrastructure for abstracting out SVG drawing backend. Adds new file faust_jquery_svg_backend.js. This will allow an eventual migration to other SVG drawing libraries.
+0447e1c Abstracts out svg.text to _f4u.make_text
+d7578bc Abstracts out svg.circle to _f4u.make_circle
+ed70128 Abstracts out svg.group to _f4u.make_g
+33dae37 Abstracts out svg.path to _f4u.make_path
+7c21201 Abstracts out svg.line to _f4u.make_line
+f2769c1 Moves button event callbacks to group creation in SVG display
+a04a0cb Abstracts out svg.configure to _f4u.configure_svg
+4855ba7 Abstracts out svg.defs to _f4u.get_svg_defs
+3ffe636 Migrates svg gradient code to backend
+12b5063 Removes misleading comment from faust_ui_builder
+14bddc2 Moves svg removal code to backend
+db1484e Moves svg creation in div to backend
+f9a7c0c Improvements to backend separation for SVG UI
+30d7598 Fixes case in SVG UI where multiple elements could get the same id.
+21df603 Fix dssi.cpp bug due to an inappropriate usage of string::c_str() result.
+2e8c7bc Fix a compilation warning in dssi architecture
+f3202d4 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+c5c5812 Styles a little more coherent for FaustLive uses
+e4ef75a Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+d0a31b2 extractMetadata modified to replace control characters by white spaces
+4c75673 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+32d2daa Revert "extractMetadata modified to replace control characters by white spaces"
+9f19220 remove control characters before creating string symbols
+7ce573d Version number set to 0.9.68
+5dd9439 Fix missing stdio.h include
+5d3bba6 Added script to cross-compile puredata externals for windows
+3a386d5 Use environment variable MINGWPREFIX to specify mingw prefix. Add --enable-auto-import linker option.
+bf7aa43 Improved faust2w32msp and faust2w32vst, use of MINGWPREFIX
+6874cfe Blue Stylesheet revised
+c09d147 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+5257135 Pull changes to build system from faust2 (make dynamic httpd sound2faust)
+a6a11ac Correct faust2netjackconsole.
+dd7f85c Correct SVGDev and PSDev contructor.
+060c5be Correct header declaration.
+c0232b1 Fix up empty group labels in puredata architecture.
+2281095 Bugfixes.
+1a4336a Update faust2pd
+9b8ab69 add ifdef HTTPCTRL for windows compatibility
+1ae5820 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+a26b21f Bugfixes.
+24c03b4 Sync pure.cpp with Pure repository
+5a07925 Correct warning.
+353d502 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+4a7742d Add JSON generation in max/msp wrapper files.
+65c5c54 dynamic target added to compile a shared library
+c01733d Style improvment
+03eb431 correct libOSCFaust symbolic link
+7481bcb soversion changed
+a8fb6fd Fix xml generation to replace empty labels "" with "0x00" in order to be consistent with the code generation.
+5061d26 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+982d138 Correct buffer size management in coreaudio-dsp.h.
+d330007 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+008cfe7 Faust2pd updated to version 2.9
+4b82b83 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+b9d0c5a faust2pd: Remove generated files from repo.
+1f70c55 Option -poly added to faust2puredata. It calls faust2pd with options -n 8 to create an 8-voices polyphonic synth.
+aaa99d0 add init zone flag to OSCUI
+b52fa76 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+2f77fb1 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+588d77e init flag added to httpdUI
+96cbfb0 Make 'make dynamic' work for osclib on Linux.
+2806c7c Add proper soname (-Wl,-soname) for osclib on Linux.
+5dae5d3 Albert patch for 'make dynamic' on OSX.
+a9e6828 Remove warning.
+48a440d Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+ad30480 Naming coherency.
+addd9e0 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+56dc9fa SVG UI rendeder now ignore 0x prefixed labels.
+5bfe7bd osclib: Set proper install_name and library version on OS X.
+7910758 OS X: Fix up install_name of libHTTPDFaust.dylib.
+88000b6 Windows compatibility fixes (mingw 4.4+ and msvc 2012).
+926dfb0 Regenerate lexer.
+abd70fd Ros Files
+a3a346e msg file updated
+f471efe Correct tools Makefile.
+2d5c596 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+4e91808 Correct JS string memory allocation scheme.
+305566d Correct JS string memory allocation scheme(2).
+c1b94c3 RosUI.h updated to handle spaces in labels
+93b8191 Mingw32 fixes. Make the httpd and dynamic targets work on Windows. Fix some Windows-specific glitches in the Makefiles.
+6c3e6c7 Makefile fixes (Ryan Schmidt).
+c112ae3 Add 'make world' target.
+c07701d Automatic UI generation in Max/MSP architecture files.
+cb75225 Avoid having to install liboscpack by statically linking it into libOSCFaust. Install OSC and HTTP libraries into standard ../lib path instead of ../lib/faust
+70d92c4 Faust version number set to 0.9.70
+f81b817 uses also pkg-config when building libHTTPDFaust for Linux
+4b49c76 faust2jack and faust2alsa scripts adapted (liboscpack and special path removed)
+a1dd5c7 Renaming.
+6096827 correct possible division by zero in expandBoxesContent of iOS interface
+d6aabf5 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+964dc18 More scripts adapted (liboscpack and special path removed)
+19d4d3a Script added to test the various faust2xxx scripts.
+9f7ca4b Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+ac6acc2 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+64cca72 Add possibly missing include for Max6.
+52f08a8 Add possibly missing include for Max5.
+47ab25c Avoid having to install liboscpack by statically linking it into libOSCFaust, 2nd attempt.
+e185a81 ranlib needed on OSX
+b749b31 Add Debian packaging.
+9b84354 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+3d7e792 make uninstall: added libHTTPDFaust, libOSCFaust, sound2faust.
+076b25d Revert rev. e185a813.
+55cc37f Fix typo in FICocoaUI.h.
+c911c5a Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+a756a68 In Max6, automatic creation of UI in a generated .maxpat file.
+5e41d00 Update Debian changelog.
+185aca2 Debian revision number should be 1, not 0.
+e92e4be Make linking libOSCFaust.a+liboscpack.a work on OS X with fat binaries.
+493b62a Update usage in comments
+62d6b96 correct QRCode message & implement stop function in faustqt
+f765564 MainWindow not deleted in QTGUI otherwise it loops in QTGUI destructor
+20167ce Update for ROS files : - RosUI.H includes now a string process function to handle labels - jack-ros.cpp & jack-gtk-ros.cpp are commented - faust2ros & faust2rosgtk handle 2 options : -install and -o     - install : create packages in the specified workspace     - o : rename the package
+111873c add scrollbar to QT application
+c52aca9 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+d897598 Pull faustqt.h over from the faust2 branch.
+eb547b7 add scrollbar to faustqt independent applications
+6d34cfd qmake project updated
+52e416a Fix QF bug in isBoxNumeric (must not try a2sb on abstractions).
+1f75a60 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+deaf694 Renaming.
+4a2c01c Documentation to explain how to use Faust with ROS. Feel free to tell me how to improve it !
+1253a66 Fix zero delayed expression bug. No vector name to expect in this case.
+77305b4 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+ee674a3 propagate faust2asmjs renaming into faust2appls makefile.
+7500ed2 Fix zero delayed expression bug also in vector mode
+a6185cf ROS files updated to fit to the ROS C++ Guide In RosUI.h : strProcess function modified to have more explicit ASCII characters (constants used)
+599d8d2 Add missing Max/MSP files.
+7136ba4 Correct Windows Max/MSP script.
+913576f add Scrollbar style
+bef80f6 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+d633a28 faust2ros and faust2rosgtk updated ; documentation updated
+b24fda8 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+06236cf Missing support to -poly option added to faust2w32puredata
+5d9b1ec Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+c922968 ROS documentation file updated
+1a95ef8 Add -json parameter (in progress).
+6d75538 Add metadata generation in -json mode.
+2f3adaa Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+81bbfa6 add oscpack and libOSCFaust VS projects
+529a08a Correct JSON generation.
+191e7b6 Add inputs/outputs in httpd JSON generated file.
+5cbcd4c Correct faust2max6 to produce universal 32/64 bits binary.
+e8c4a61 Use 'anything' method in faust2msp.
+6b688b6 Use 'anything' method in faust2max6.
+dbb2e1a Correct handling of parameter list in Max/MSP.
+bb3a34f Correct handling of parameter list in Max/MSP(2).
+4fc44a9 Correct 'meta' handling in httpUI and JSONUI.
+2f89aee Correct jsongroup::print.
+978f75d Remove unneeded TMetas typedef.
+3cd96a5 change some headers for OSC and HTTP compilation on windows visual studio
+fa52e2f solve previous bad commit from windows
+0f08857 go back to right format Unix LF
+9b4259f Fix wrong file permissions.
+a6d0659 Removing deprecated Makefiles of the faust-stk directory.
+979db07 Correct Symbol::get.
+db9714a Adding pitch-bend to poly-dsp.h
+b9bc4c0 Allowing float MIDI notes in poly-dsp.h
+ecf6267 ROS files modified : RosUI.h now includes topic hierarchy faust2ros(gtk) now allows to overwrite packages, and have been modified so that there isn't anymore the faust_msgs type of messages.
+fb4604a ROS files updated : - faust2ros(gtk) updated so that the zip file is located in the current directory - ROS documentation source files added to documentation folder - ROS documentation updated to fit recent changes (any comment will be welcome)
+8811f79 faust2ros(gtk) updated to test workspaces existence in a better way (checked with Lucie R.)
+cc3f9b7 modify Jack architecture files to replace stack allocations by alloca keyword
+bfbe4d3 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+63c2556 Adding voice selection for setValue in poly-dsp.h
+2963b01 Missing /op/local/include path added. It is needed when using macport.
+1093af8 jack shutdown --> client becomes NULL. Protects use of client once it's corrupted
+7110967 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+00e9d25 Adding the new version of faust2android
+7b47eeb Normalizing the Android native API. Adding ios-coreaudio-api.cpp, the equivalent to android.cpp for iOS. Adding faust2api.
+55275fd Modification of ‘environment’ syntax to allow any statements not only definitions
+767456f Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+d66d9bc Memory management corrections for faust2api + adding faust2api to the faust2appls Makefile
+16e839d Correct iOS project search paths.
+e5dc3b4 Correct sound2faust : now refuses soundfiles with a digit as first character.
+3f66807 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+07f7ba4 Correct poly-dsp.h to detect 'freq', 'gate', 'gain' labels.
+f85922b Add OSC support for ios target.
+ed17959 Add missing compiled libraries for OSS in iOS.
+5917bc4 ROS FILES including metadata handling
+83d354d remove an old doc file
+eb1c2d6 Protects bash variable CONVERT with quotes
+9b55aef Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+dbafcd3 New -inj <file> option added. It simply injects code into the architecture file instead of really compiling a dsp file.
+60149be Always restore initial directory after trying to open an architecture file
+466cc09 minor modification
+89ec4d3 Voice dealocation in poly-dsp.h
+c095589 Fixing poly-dsp.h previous commit issue.
+f4f72bf implement fix for gate_gain_mono suggested by Jonatan Liljedahl <lijon at kymatica.com>, plus one other fix, plus some rewriting for clarity
+70ff4c8 Merge branch 'master' into injection
+a42adfa Missing ends_with() function added
+fb7fc3a Merge branch 'master' into injection
+dd5f53b Don’t generate xml description anymore.  Differences between the number of physical vs logical audio channels are handled dynamically at execution time.
+2d4203d Merge branch 'androidNoXML' into injection
+682bf11 Migrating faust2android to Android Studio.
+47209b4 Cleanup poly-dsp.h.
+3c5d198 opencv files for jack gtk
+8f22259 Correct poly-dsp.h.
+18c90e2 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+4db76fd Small bug correction in the faust2android compilation script
+23ad52a OpenCV UI file modified with pthread_exit() and pthread_join()
+c3c7a58 Updating faust2api to be compatible with Android Studio
+f7a6b17 Android Accelerometers are set in m/s^2 between -100 and 100.
+1a817fe android, computed height for checkbox
+5a29981 add guitarix in examples
+a34afa8 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+7570656 Merge android accelerometers range between -100 and 100 m/s2
+10e6ba6 ROS Files updated with metadata improvement. You can now add some max and min values in ros metadata
+a6e6446 New approach to deal with the number input and output channels when different from 0 or 1 input and 1 or 2 outputs.
+3fe646b Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+b6fcec3 Correctly restore current directory in enrobage.cpp when searching for files.
+b9a419a fix conflicts in android.cpp coments
+b66f838 ROS Documentation updated
+7ae20fe ROS bash files updated to add a readme.txt in the generated directory
+7c71ab6 faust2jack file updated to add the -ocv option
+9dd73aa Faust version set to 0.9.71
+2cce2e7 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+15a7079 Partial fix of count’s bug in vector and openMP mode. Bug in shed mode not fixed yet
+8536453 Fix of count’s bug in scheduler mode.
+0e7569b ROS Callbacks Interface file updated (bugs rectified)
+8689cb1 Add iOS8 compatability in iOS target.
+96a61cc Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+24ba37a ROS files updated
+f38f178 faust2ros and faust2rosgtk modified to add some help messages
+fb0cd77 RosCI.h modified to use ints and floats in ROS metadata
+41d394f Correct webaudio-asm-poly MIDI input device handling.
+8d9f1c7 quad definition only added when needed
+88bdff3 Renaming.
+22c2476 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+86c6e66 Contributions by Jonatan Liljedahl at http://kymatica.com added to effect.lib
+a273613 add toString() before split function to avoid warnings
+bd3d972 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+2369da8 /jonatan contribution refinement
+fe6d223 ROS documentation updated with cheatsheet and tutorials
+125a312 Improve faust2webaudioasm.
+4cb7973 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+9a81e92 install Jonatan Liljedahl refinement of amp_follower in effect.lib
+3a889da Cleanup.
+4b0fce0 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+45728f4 Cleanup string handling code.
+800a091 Correct directory mangement functions.
+5065081 Cleanup asm.js wrapper code.
+205f247 Correct memory management code in asm.js wrapping code.
+8e5dbc2 Added faust2w32max6 (not tested yet)
+97b784f Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+3d847d4 OCVUI.h documented
+acbac21 Fix script for Csound6 64bits
+19258c3 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+b2ac78a Make faust2webaudioasm works again with 'emcc'.
+7aafbb7 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+f3da43a Make faust2webaudioasm works again with 'emcc'(2).
+a00e9df Correct faust2asmjs.
+b9950f6 Correct webaudio-asm-footer.js.
+b56c10c Correct asm.js wrapper files.
+a48a931 Correct poly_dsp.h.
+897f2e1 Correct asm.js wrapping code.
+dc3daa9 Correct asm.js wrapping code(2).
+8de9d84 midiToFreq now uses 'double' to avoid an issue with latest emcc compiler.
+b428a62 Rework poly-dsp mixing code.
+0c879a0 Documentation of WebAudio related tools.
+584328c Simplify webaudio related scripts.
+c332952 Correct poly-dsp mixing normalization code.
+dc9e654 Small fixes in faust2api for iOS
+606a6f7 add xmitfilter message to filter parameters at emission
+d9143e5 add -xmitfilter at initialisation
+ce3dd46 Remove duplicated generated lines.
+2ce2892 Correct Symbol::get to remove string size limit.
+2bebfaa Correct Symbol::get to remove string size limit.
+60fd404 Cleanup android and iOS API architecture files.
+f0cc37c Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+db52d3b Make mydsp_poly a subclass of dsp.
+d94dfa3 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+a36a395 Missing changes afer previous commits.
+22932b3 Add jack-poly-qt.cpp file.
+8112673 New libOSCFaust.a version for iOS.
+d5409ef Correct poly-dsp.h and android.cpp : add setVoiceGain.
+9a71526 Correct function declaration.
+73a961c Remove warning.
+91b1b83 Correct iOS project for 'storyboard' strange issue.
+d4dcd63 Add allNotesOff method in poly-dsp.h.
+3ba1857 Major cleanup of JS webaudio wrapping code.
+ffa8eec Major cleanup of JS webaudio wrapping code(2).
+9d32626 Typos.
+c566beb Add compute callback in the WebAudio wrapping code.
+db852d7 Add missing pitchBend function in emcc wrapping code.
+eaba2d8 improve Moog VCF demo; improve comments; fix off-by-one in filter.lib/ff_*comb, restore missing allpass_fcomb; add allpass_fcomb5
+6ddf62d add parenthesis as recoded characters in OSCUI
+bfff90b Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+1a041c4 New libOSCFaust.a for iOS.
+f0dd27d Add public getProcessor in WebAudio asm wrapper code.
+d610c96 Typos.
+a76d93b accept more than 2 parameters for xMitfilter requests
+f48ad01 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+a38f6f9 New iOS ibOSCFaust.a version.
+f99d5ba Correct asm.js wrapping code.
+e0b202a Typos in JS code.
+4676619 Add 'use strict' in JS code.
+b3fdd24 modify split uses for firefox portability
+de0fb2b Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+84793eb Correct setHandler in asm.js wrapper.
+1a036b4 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+de16274 Fix import(« .. ») in environments by using gReader.expandlist
+55b71d4 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+76180ab add sampling-rate option to matlabplot.cpp
+d258b4c Remove unused variable.
+bf2bcb8 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+51de88d Correct connect/disconnect JS functions.
+058e6c9 Cleanup asm.js wrappers.
+8a2844b Fixed setting Audio Unit Instrument frequency slider
+615333b Add dynamic version in poly-dsp.h
+53d6d63 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+ce768d0 Make poly-dsp.h more flexible.
+27d3b64 Make poly-dsp.h more flexible(2).
+02c06fb Correct faust2asmjs.
+699c79d Cleanup.
+9a550fd Use FAUSTFLOAT when needed in poly-dsp.h.
+c0608e2 Correct 'metadata' use in poly-dsp.h.
+56a8479 Use MIX_BUFFER_SIZE so that 'mydsp_poly' object really behaves as a 'dsp'.
+678174d Cleanup.
+6fa34ef Add -h in faust2jaqt.
+a5cd669 Correct CoreAudio devices aggregation code.
+62ee3a5 Export service in HTML pages.
+fc6b2c8 Restore contructor in mydsp_poly for comptability.
+f14073c Correct faust2webaudioasm.
+f42849a Correct faust2webaudioasm(2).
+2596b58 modify export-wrapper to embbed images as svg
+4ef2bb5 add gif loader while waiting for qrcode
+ff53665 New implementation and several new value converters added, including value converters for accelerometers.
+e6e9a26 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+3cea2a2 modify DSP dynamic modification
+0b7a59d Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+4d92c18 Add audio on iOS activation in WebAudio HTML wrappers.
+1aa6306 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+34c755d event error correctected for firefox
+e090d43 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+e6cb2b9 change source location for export
+9d02850 Better handling of degenerated interpolations
+9cce732 More code comments
+7622044 More code comments
+73e5df7 Correct WebAudio HTML wrapper.
+2fdbb10 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+b651968 Correct WebAudio HTML wrapper(2).
+1fbfdf3 Number of outputs for VST reduced to 2
+341fecf VST/i-s are compiled for both i386 and x86_64 architectures on Darwin and combined using lipo
+948a985 Add 'poly' mode in faust2caqt, improve faust2jaqt.
+b43c7b8 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+ad0178b MIDI control in progress.
+157d626 Add midi.h generic file, correct midi-io.h.
+66799c1 Add MIDI in faust2caqt.
+485490b Correct faust2jaqt and faust2caqt for MIDI on OSX.
+f25fb7a New MidiUI.h file.
+5b0a494 Add dynamic -poly parameter.
+f1095ea Correct MidiUI.h.
+83aa776 Add MIDI control (in progress).
+8d22c7c Cleanup.
+d54f369 Add MIDI out control (in progress).
+afa244e Add MIDI out message generation.
+b7dd929 Naming.
+08ce72f Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+8ec3758 MIDI in progress.
+98cf9a1 MIDI out now working.
+3bf809b MIDI: correct 'poly' mode.
+410b03d More combinable 'midi' and 'poly' modes.
+aed611d Cleanup.
+ffcb7f5 Cleanup.
+e3fbfa7 Cleanup.
+2a2a687 Cleanup.
+10304c8 Cleanup.
+eea74a1 Better fmod interval computation
+c97ee32 Correct MIDI output.
+ee5da2b Add licences.
+f8de41b Better separation of 'poly' and 'midi' modes.
+51fb0eb Renaming.
+1ab37ad Correct mydsp_poly.
+a86430f File reorganization.
+e7e8488 Correct use of mydsp_poly.
+89c0429 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+627d3aa Improved fdelay via Lagrange interpolation in filter.lib to use the faster (complexity of order N) Candan 2007 method, and generalized to all N>0
+94e47ad added fdelayltv to filter.lib for robust time-varying Lagrange interpolation
+0af22fb added protection against floating-point exception in fdelayltv in filter.lib
+7626b09 Fix warning : abs replaced by labs
+88f140b Warning messages in case of potential division by 0 or food by 0
+0bbe67e Fix up Debian packaging rules, update Debian changelog for latest git revision.
+9478fa0 Comment Klass::printMetadata function.
+756eebd lseek defined for windows (change was already in faust2)
+d5cbc29 increment OSC version and add xmitfilter to documentation
+6544457 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+ec370d9 Cleanup README.
+cabd94a Add -lpthread to OSCDEFS.
+d59542b Division by zero warnings deactivated (more precise intervals required)
+d9ee3e4 allow gate in effect.lib to have faster release than attack
+9140064 Change amp_follower_ud to amp_follower_ar internally in effect.lib to allow faster release than attack in gate, compressor, and vocoder; clarify comments
+d1eb0b1 revise relation between input level calculation and attack/release times in gate in effect.lib
+4cac36e Add conditional NAN definition for Windows.
+dde1005 Correct faust2jaqt and faust2caqt.
+c5a1d84 New RtAudio based architecture file.
+d9c7298 Update ValueConverter.h.
+53961cb Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+52ca0db Version set to 0.9.72
+b84465b Revert to use ARCHFLAGS
+3d48094 Fix missing install of max-map architecture subfolder
+65a08e7 add triangle-wave LFO to oscillator.lib
+7bf6bb5 Typos in faust2raqt.
+6c8e6c1 New Android architecture
+9429153 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+3c29cf5 Fix a compile warning
+92a1ffd Add get_num_inputs/get_num_outputs methods in audio class.
+18a1264 Correct jack-dsp.h.
+58cc86b Correct jack-dsp.h(2).
+2d9ef51 Extend jack-dsp API.
+0a8d065 Extend jack-dsp API(2).
+5e4078b New architecture file for OWL provided by  Martin Klang and the OWL team. This version is both backwards and forward compatible with the next version of the OWL firmware.
+7e22e89 Cleanup.
+a6e8181 Cleanup.
+9f4c40a Correct netjack-dsp.h.
+5ad5847 convert UTF-8 emdash to plain ASCII dashes
+b394414 Rework coreaudio-dsp.h.
+ac513cd Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+bbd5adb Use kAudioSessionProperty_OverrideCategoryDefaultToSpeaker in iOS architecture file.
+9d71a82 Use kAudioSessionProperty_OverrideCategoryDefaultToSpeaker in iOS architecture file(2).
+bb51b9d Correct SVG UI css.
+3215fa4 Correct rt-midi.h.
+54ecf3b Correct MIDI headers.
+ff5036c Add naming in MIDI handling.
+34bd248 Fix end of line, from windows to unix.
+5b58bb5 Cleanup coreaudio-ios-dsp.h.
+e737272 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+879f2e9 Disable AGC in coreaudio-ios-dsp.h.
+e80c704 Disable AGC in coreaudio-ios-dsp.h(2).
+16f1965 Rework MidiUI.
+2f668fd AGC disabled by default in coreaudio-ios-dsp.h.
+17daac5 Add -noagc in faust2ios.
+45bc4bc Add platform conditional compilation in RtMidi.h.
+8092923 Correct rtmidi destructor.
+ed3a6b0 Correct fasut2android to correcty take optional parameters in account.
+498bf55 Added -reuse option to faust2android. This option speedup the compilation by reusing the previous build directory.
+a0a4b3a Correct sound2faust.
+c13b167 Correct SourceReader::parse.
+846897d Added static libraries needed when cross-compiling for Windows
+6a9f75f Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+2d45e5c Added Faust syntax highlighting support for Atom editor
+1d8c52c Added faust2md a simple documentation system for Faust. faust2md creates a markdown file by extracting the comments from a Faust source file.
+fd88efc Added 'doc' snippet to Atom's syntax highlighting package
+b8dc608 Add a new line before starting a new #xxx section in faust2md
+ed26b8f New documentation comments of math.lib (in progress)
+df94194 more documentation comments in math.lib
+67692f7 Cleanup OSC code.
+5b21f4c Correct OSC documentation.
+772aa32 add cos and arbitrary-phase sinusoidal wavetable oscillators to music.lib; use music.lib and filter.lib privately instead of globally within oscillator.lib; rewrite x^2 as x*x to further minimize powf() usage
+9c68528 Optimize android_AudioOut.
+b92363b New Android audio architecture.
+0c08a2d Correct androidaudio::stop method.
+ea5403a Cleanup.
+fd35f04 Cleanup.
+fd76d4b Separated APIUI.h file.
+2fc2832 Correct APIUI.h.
+6962a52 Correct APIUI.h(2).
+f95d0ec Correct APIUI.h(3).
+e005b30 Improve Android code: audio backend and interaction with Java code.
+cd87f45 Android: correct sliders setValue method.
+7aa63d4 Android: cleanup Java code.
+8450b59 Android: OSC somewhat working.
+fb9a04d Android: use the new APIUI class in C side.
+299c217 Correct APIUI memory management.
+2797e7f Android: add propagateAccX, propagateAccY, propagateAccY API.
+4520f27 Android: add missing curve in editor.
+2de8bd9 New setAccConverter/getAccConverter in APIUI, cleanup.
+bcc61ab Android: cleanup Java acceleroleter code (in progress).
+f606ef8 Android: add a version number in parameters file.
+a9d4d88 Android: accelerometer mapping edition somewhat working.
+4d135f4 Android: accelerometer mapping edition somewhat working(2).
+357f00f Cleanup.
+b5a5692 Android: correct accelerometer values handling in Java code, cleanup.
+880d03c Android: optimize and cleanup Java code.
+e614dd8 Android: implement 'no more mappping'.
+a1a8590 Android: new AndroidEngine class on C side.
+52027cb Android: correct APIUI::setAccConverter.
+197fa48 Cleanup.
+fb9b7eb Updated comments (in progress)
+e2af69e Added new -svg option to faust2graph and faust2sig to generate svg instead of pdf images
+b6ec549 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+cc93a6b Add APIUI::getAccConverter method.
+c51d372 APIUI: correct types.
+2a5a844 start on oscillator.lib markdown formatting, no functional changes
+8927e28 Add API for gyroscopes in APIUI.
+1ab5a19 Add API for gyroscopes in APIUI(2).
+d5e1e01 Add API for gyroscopes in APIUI(3).
+6236abf Remove bogus dependencies on /opt/local files which break 'make world' on Linux.
+057ba92 Correct MIDI handling in ca-qt.ccp and jack-qt.cpp files.
+c407605 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+008d6a6 iOS project support for 64 bits.
+862c686 Oliver Larkin Faust.plist file updated to support .lib files.
+cf758b1 Add a separated target in iOS project for 32 bits compilations. Add '-all' option in faust2ios to force 64/32 bits compilation.
+94994b6 Add 'code' field in JSON enconding.
+7c86f7f Add 'sha_key' in JSONUI class.
+8cda0a7 Cleanup JSONUI code.
+ed1ca16 Add a '-sc' parameter for 'scaled SVG'.
+a2bd438 instrument.lib moved from stk examples to architecture folder. In order to make instrument.lib more generis the foreign fonction of instrument.lib was removed and added directly to modalBar.dsp
+809f876 Correct JavaScript WebAudio resources.
+23028a4 Instrument.lib moved to architecture directory
+f5bd19e Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+2760af6 Correct jackaudio::default_connections method.
+b907ff7 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+cf81b10 Fix 64 bits compilation warning on iOS project.
+69a2156 Oliver patch for XCode 7 and iOS project.
+62e6943 Correct Max/MSP architecture to better display code caracteristics.
+a7d682e SDK Path redirected to /usr/local/include
+c29adc9 Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+851d8c4 Correct links in export-wrapper.html.
+b04040c Merge branch 'master' of ssh://git.code.sf.net/p/faudiostream/code
+2a49ba3 Add mssing Template_CoreAudio_32bits.xcscheme in iOS project.
+324f2d6 Correct faust2android to correctly take optional parameters in account (redo 2015-07-20 correction).
+207595a Correct faust2svg.
+d4b5bd1 Correct faust2svg(2).
+be5f018 Add vbargraph in Android architecture.
+47580e8 Correct androidaudio::start.
+25c5fed Android: change bargraph layout.
+1a47fa5 Add Gyroscope API handling.
+6d8ca2c Add gyroscope handing in Android code (in progress).
+8af809e Add gyroscope handing in Android code.
+e3d3317 Android acc/gyr UI improvement.
+280344f Add broadcast code in oscpack (taken from in-score).
+db689d3 Add broadcast code in oscpack (taken from in-score)(2).
+20d82b6 Correct OSC code.
+b5bba70 Android: correct exception handing in OSC code.
+3bbf054 Android: add WIFI multicast handling.
+2bce042 New SoundFileReader file, cleanup.
+9362b62 Cleanup.
+82d2e3c Cleanup(2).
+a7987ac Add sound2reader script.
+945a9ca SoundFileReader code now uses FAUSTFLOAT.
 
------------
-Libraries :
------------
-- effect.lib : moog_vcf_2bn added, minor zita_rev1 additions
-- filter.lib : tf2np, tf2snp, and general ladder/lattice filters added
-- osc : build for both i386 and x86_64 architectures on Mac OSX, corrects frames value in OSC IO architecture
-
-
-----------
-Examples :
-----------
-- improvements and bug corrections in faust-stk
-- new examples for Faust-STK in /examples/faust-stk/pd-patches/fancy
-- new description metadata tag in faust-stk examples
-
-
-----------
-Compiler :
-----------
-- Support for listings with accents and symbolic representation for numbers of type i/j.pi**k or i/j.e**k in automatic documentation system
-- improved and simplified infinite loop detection during compilation, default compiler timeout set to 10 mn
-- bug fix when counting recursive signals to draw
-- compiling error with VC++ 2008 fix 
-
-
----------
-Scripts :
----------
-- option -utf8 added to faust2mathdoc allowing to recode the .dsp file to UTF-8 before being processed
-- added -I/usr/local/lib/faust to faust2ladspa because faust2jack uses this solution for typical personal Linux
-- faust2sc: added checkInputs method to generated UGen; SynthDef input signals wrapped in In.ar()
-- faust2pd : updated to faust2pd-2.5
 
 
 ----------------
 Acknowledgments:
 ----------------
-
 Many persons have been contributing to the FAUST project by
 providing code for the compiler, architecture files, libraries,
 examples, documentation, scripts, bug reports, ideas, etc. 
 
-I would like to thank them and especially: Fons Adriaensen, Tim Blechmann,
-Tiziano Bole, Baktery Chanka, Thomas Charbonnel, Damien Cramet, Etienne Gaudrin,
-Albert Graef, Stefan Kersten, Victor Lazzarini, Matthieu Leberre, Mathieu Leroi,
-Kjetil Matheussen, Hermann Meyer, Romain Michon, Remy Muller, Sampo Savolainen,
-Nicolas Scaringella, Stephen Sinclair, Travis Skare, Julius Smith, Michael
-Wilson, as well as my colleagues at GRAME, in particular : Dominique Fober,
-Stephane Letz and Karim Barkati, and from the ASTREE project : Jerome Barthelemy
-(IRCAM), Alain Bonardi (IRCAM), Raffaele Ciavarella (IRCAM), Pierre Jouvelot
-(Mines/ParisTech), Laurent Pottier (U. Saint-Etienne)
-
-Yann Orlarey
+We would like to thank them and especially: Fons Adriaensen, Jerome
+Barthelemy, Tim Blechmann, Tiziano Bole, Alain Bonardi, Myles Borin,
+Baktery Chanka, Thomas Charbonnel, Brune de Chiffreville, Raffaele Ciavarella, Julien
+Colafrancesco, Damien Cramet, Robin Gareus, Etienne Gaudrin, Olivier
+Guillerminet, Albert Graef, Pierre Guillot, Pierre Jouvelot, Stefan
+Kersten, Victor Lazzarini, Matthieu Leberre, Mathieu Leroi, Fernando
+Lopez-Lezcano, Kjetil Matheussen, Hermann Meyer, Romain Michon, Remy
+Muller, Eliott Paris, Reza Payami, Laurent Pottier, Sampo Savolainen,
+Nicolas Scaringella, Anne Sedes, Priyanka Shekar, Stephen Sinclair,
+Travis Skare, Julius Smith, Michael Wilson, as well as our colleagues at
+GRAME, in particular : Karim Barkati, Sarah Denoux, Olivier
+Guillerminet, Christophe Lebreton and Mike Solomon.
+
+Yann Orlarey, Stephane Letz and Dominique Fober
 GRAME
 
diff --git a/architecture/AU/AUPublic/AUBase/AUBase.cpp b/architecture/AU/AUPublic/AUBase/AUBase.cpp
new file mode 100644
index 0000000..1e6de6d
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUBase.cpp
@@ -0,0 +1,2327 @@
+/*
+     File: AUBase.cpp 
+ Abstract:  AUBase.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUBase.h"
+#include "AUDispatch.h"
+#include "AUInputElement.h"
+#include "AUOutputElement.h"
+#include <algorithm>
+#include "CAAudioChannelLayout.h"
+#include "CAHostTimeBase.h"
+#include "CAVectorUnit.h"
+#include "CAXException.h"
+
+
+
+#if TARGET_OS_MAC && (TARGET_CPU_X86 || TARGET_CPU_X86_64)
+	// our compiler does ALL floating point with SSE
+	inline int  GETCSR ()    { int _result; asm volatile ("stmxcsr %0" : "=m" (*&_result) ); return _result; }
+	inline void SETCSR (int a)    { int _temp = a; asm volatile( "ldmxcsr %0" : : "m" (*&_temp ) ); }
+
+	#define DISABLE_DENORMALS int _savemxcsr = GETCSR(); SETCSR(_savemxcsr | 0x8040);
+	#define RESTORE_DENORMALS SETCSR(_savemxcsr);
+#else
+	#define DISABLE_DENORMALS
+	#define RESTORE_DENORMALS
+#endif
+
+static bool sAUBaseCFStringsInitialized = false;
+// this is used for the presets
+static CFStringRef kUntitledString = NULL;
+//these are the current keys for the class info document
+static CFStringRef kVersionString = NULL;
+static CFStringRef kTypeString = NULL;
+static CFStringRef kSubtypeString = NULL;
+static CFStringRef kManufacturerString = NULL;
+static CFStringRef kDataString = NULL;
+static CFStringRef kNameString = NULL;
+static CFStringRef kRenderQualityString = NULL;
+static CFStringRef kCPULoadString = NULL;
+static CFStringRef kElementNameString = NULL;
+static CFStringRef kPartString = NULL;
+
+SInt32 AUBase::sVectorUnitType = kVecUninitialized;
+
+//_____________________________________________________________________________
+//
+AUBase::AUBase(	AudioComponentInstance			inInstance, 
+				UInt32							numInputElements,
+				UInt32							numOutputElements,
+				UInt32							numGroupElements) :
+	ComponentBase(inInstance),
+	mElementsCreated(false),
+	mInitialized(false),
+	mHasBegunInitializing(false),
+	mInitNumInputEls(numInputElements), mInitNumOutputEls(numOutputElements), 
+#if !CA_BASIC_AU_FEATURES
+	mInitNumGroupEls(numGroupElements),
+#endif
+	mRenderCallbacksTouched(false),
+	mRenderThreadID (NULL),
+	mWantsRenderThreadID (false),
+	mLastRenderError(0),
+	mBuffersAllocated(false),
+	mLogString (NULL)
+	#if !CA_NO_AU_UI_FEATURES
+		,
+		mContextName(NULL)
+	#endif
+{
+	ResetRenderTime ();
+	
+	if(!sAUBaseCFStringsInitialized)
+	{
+		kUntitledString = CFSTR("Untitled");
+		kVersionString = CFSTR(kAUPresetVersionKey);
+		kTypeString = CFSTR(kAUPresetTypeKey);
+		kSubtypeString = CFSTR(kAUPresetSubtypeKey);
+		kManufacturerString = CFSTR(kAUPresetManufacturerKey);
+		kDataString = CFSTR(kAUPresetDataKey);
+		kNameString = CFSTR(kAUPresetNameKey);
+		kRenderQualityString = CFSTR(kAUPresetRenderQualityKey);
+		kCPULoadString = CFSTR(kAUPresetCPULoadKey);
+		kElementNameString = CFSTR(kAUPresetElementNameKey);
+		kPartString = CFSTR(kAUPresetPartKey);
+		sAUBaseCFStringsInitialized = true;
+	}
+
+	if (sVectorUnitType == kVecUninitialized) {
+		sVectorUnitType = CAVectorUnit::GetVectorUnitType() ;
+	}
+
+	mAudioUnitAPIVersion = 2;
+	
+	SetMaxFramesPerSlice(kAUDefaultMaxFramesPerSlice);
+
+	GlobalScope().Initialize(this, kAudioUnitScope_Global, 1);
+	
+	if (mAudioUnitAPIVersion > 1) 
+		mParamList.reserve (24);
+
+#if !CA_NO_AU_UI_FEATURES
+	memset (&mHostCallbackInfo, 0, sizeof (mHostCallbackInfo));
+#endif
+
+
+	mCurrentPreset.presetNumber = -1;
+	mCurrentPreset.presetName = kUntitledString;
+	CFRetain (mCurrentPreset.presetName);
+}
+
+//_____________________________________________________________________________
+//
+AUBase::~AUBase()
+{
+	if (mCurrentPreset.presetName) CFRelease (mCurrentPreset.presetName);
+#if !CA_NO_AU_UI_FEATURES
+	if (mContextName) CFRelease (mContextName);
+#endif
+	if (mLogString) delete [] mLogString;
+}
+
+//_____________________________________________________________________________
+//
+void	AUBase::CreateElements()
+{
+	if (!mElementsCreated) {
+		Inputs().Initialize(this, kAudioUnitScope_Input, mInitNumInputEls);
+		Outputs().Initialize(this, kAudioUnitScope_Output, mInitNumOutputEls);
+#if !CA_BASIC_AU_FEATURES
+		Groups().Initialize(this, kAudioUnitScope_Group, mInitNumGroupEls);
+#endif
+		CreateExtendedElements();
+		
+		mElementsCreated = true;
+	}
+}
+
+//_____________________________________________________________________________
+//
+void	AUBase::SetMaxFramesPerSlice(UInt32 nFrames)
+{
+	mMaxFramesPerSlice = nFrames;
+	if (mBuffersAllocated)
+		ReallocateBuffers();
+	PropertyChanged(kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0);
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::CanSetMaxFrames() const
+{
+	return IsInitialized() ? kAudioUnitErr_Initialized : OSStatus(noErr);
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::ReallocateBuffers()
+{
+	CreateElements();
+	
+	int i;
+	int nOutputs = Outputs().GetNumberOfElements();
+	for (i = 0; i < nOutputs; ++i) {
+		AUOutputElement *output = GetOutput(i);
+		output->AllocateBuffer();	// does no work if already allocated
+	}
+	int nInputs = Inputs().GetNumberOfElements();
+	for (i = 0; i < nInputs; ++i) {
+		AUInputElement *input = GetInput(i);
+		input->AllocateBuffer();	// does no work if already allocated
+	}
+	mBuffersAllocated = true;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::DoInitialize()
+{
+	OSStatus result = noErr;
+	
+	if (!mInitialized) {
+		result = Initialize();
+		if (result == noErr) {
+			mHasBegunInitializing = true;
+			ReallocateBuffers();	// calls CreateElements()
+			mInitialized = true;	// signal that it's okay to render
+			CAMemoryBarrier();
+		}
+	}
+
+	return result;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::Initialize()
+{
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::PreDestructor()
+{
+	DoCleanup();
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::DoCleanup()
+{
+	if (mInitialized)
+		Cleanup();
+		
+	ResetRenderTime ();
+
+	mInitialized = false;
+	mHasBegunInitializing = false;
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::Cleanup()
+{
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::Reset(					AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement)
+{
+	ResetRenderTime ();
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::DispatchGetPropertyInfo(AudioUnitPropertyID				inID,
+													AudioUnitScope					inScope,
+													AudioUnitElement				inElement,
+													UInt32 &						outDataSize,
+													Boolean &						outWritable)
+{
+	OSStatus result = noErr;
+	bool validateElement = true;
+	
+	switch (inID) {
+	case kAudioUnitProperty_MakeConnection:
+		ca_require(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(AudioUnitConnection);
+		outWritable = true;
+		break;
+		
+		
+	case kAudioUnitProperty_SetRenderCallback:
+		ca_require(AudioUnitAPIVersion() > 1, InvalidProperty);
+		ca_require(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(AURenderCallbackStruct);
+		outWritable = true;
+		break;
+		
+	case kAudioUnitProperty_StreamFormat:
+		outDataSize = sizeof(CAStreamBasicDescription);
+		outWritable = IsStreamFormatWritable(inScope, inElement);
+		break;
+
+	case kAudioUnitProperty_SampleRate:
+		outDataSize = sizeof(Float64);
+		outWritable = IsStreamFormatWritable(inScope, inElement);
+		break;
+
+	case kAudioUnitProperty_ClassInfo:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(CFPropertyListRef);
+		outWritable = true;
+		break;
+
+	case kAudioUnitProperty_FactoryPresets:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		result = GetPresets(NULL);
+		if (!result) {
+			outDataSize = sizeof(CFArrayRef);
+			outWritable = false;
+		}
+		break;
+		
+	case kAudioUnitProperty_PresentPreset:
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+#ifndef __LP64__
+	case kAudioUnitProperty_CurrentPreset:
+#endif
+#endif
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(AUPreset);
+		outWritable = true;
+		break;
+	
+	case kAudioUnitProperty_ElementName:
+		outDataSize = sizeof (CFStringRef);
+		outWritable = true;
+		break;
+	
+	case kAudioUnitProperty_ParameterList:
+		{
+			UInt32 nparams = 0;
+			result = GetParameterList(inScope, NULL, nparams);
+			
+			outDataSize = sizeof(AudioUnitParameterID) * nparams;
+			outWritable = false;
+			validateElement = false;
+		}
+		break;
+		
+	case kAudioUnitProperty_ParameterInfo:
+		outDataSize = sizeof(AudioUnitParameterInfo);
+		outWritable = false;
+		validateElement = false;
+		break;
+
+	case kAudioUnitProperty_ParameterHistoryInfo:
+		outDataSize = sizeof(AudioUnitParameterHistoryInfo);
+		outWritable = false;
+		validateElement = false;
+		break;
+
+	case kAudioUnitProperty_ElementCount:
+		outDataSize = sizeof(UInt32);
+		outWritable = BusCountWritable(inScope);
+		validateElement = false;
+		break;
+	
+	case kAudioUnitProperty_Latency:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(Float64);
+		outWritable = false;
+		break;
+	
+	case kAudioUnitProperty_TailTime:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		if (SupportsTail()) {
+			outDataSize = sizeof(Float64);
+			outWritable = false;
+		} else
+			goto InvalidProperty;
+		break;
+	
+	case kAudioUnitProperty_MaximumFramesPerSlice:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(UInt32);
+		outWritable = true;
+		break;
+	
+	case kAudioUnitProperty_LastRenderError:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(OSStatus);
+		outWritable = false;
+		break;
+		
+	case kAudioUnitProperty_SupportedNumChannels:
+	{
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		UInt32 num = SupportedNumChannels (NULL);
+		if (num) {
+			outDataSize = sizeof (AUChannelInfo) * num;
+			result = noErr;
+		} else
+			goto InvalidProperty;
+		outWritable = false;
+		break;
+	}
+	
+	case kAudioUnitProperty_SupportedChannelLayoutTags:
+	{
+		UInt32 numLayouts = GetChannelLayoutTags(inScope, inElement, NULL);
+		if (numLayouts) {
+			outDataSize = numLayouts * sizeof(AudioChannelLayoutTag);
+			result = noErr;
+		} else
+			goto InvalidProperty;
+		outWritable = false;
+		validateElement = false; //already done it
+		break;
+	}
+	
+	case kAudioUnitProperty_AudioChannelLayout:
+	{
+		outWritable = false;
+		outDataSize = GetAudioChannelLayout(inScope, inElement, NULL, outWritable);
+		if (outDataSize) {
+			result = noErr;
+		} else {
+			if (GetChannelLayoutTags(inScope, inElement, NULL) == 0)
+				goto InvalidProperty;
+			else
+				result = kAudioUnitErr_InvalidPropertyValue;
+		}
+		validateElement = false; //already done it
+		break;
+	}
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5) || TARGET_OS_IPHONE
+	case kAudioUnitProperty_ShouldAllocateBuffer:
+		ca_require((inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output), InvalidScope);
+		outWritable = true;
+		outDataSize = sizeof(UInt32);
+		break;
+#endif
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	case kAudioUnitProperty_FastDispatch:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		if (!IsCMgrObject()) goto InvalidProperty;
+		outDataSize = sizeof(void *);
+		outWritable = false;
+		validateElement = false;
+		break;
+
+	case kAudioUnitProperty_GetUIComponentList:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = GetNumCustomUIComponents();
+		if (outDataSize == 0)
+			goto InvalidProperty;
+		outDataSize *= sizeof (AudioComponentDescription);
+		
+		outWritable = false;
+		break;
+#endif
+	
+#if !CA_NO_AU_UI_FEATURES
+	case kAudioUnitProperty_ContextName:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof(CFStringRef);
+		outWritable = true;
+		break;
+	
+	case kAudioUnitProperty_ParameterValueStrings:
+		result = GetParameterValueStrings(inScope, inElement, NULL);
+		if (result == noErr) {
+			outDataSize = sizeof(CFArrayRef);
+			outWritable = false;
+			validateElement = false;
+		}
+		break;
+
+	case kAudioUnitProperty_HostCallbacks:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outDataSize = sizeof (HostCallbackInfo);
+		outWritable = true;
+		break;
+	
+	case kAudioUnitProperty_IconLocation:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		outWritable = false;
+		if (!HasIcon())
+			goto InvalidProperty;
+		outDataSize = sizeof(CFURLRef);
+		break;
+
+	case kAudioUnitProperty_ParameterClumpName:
+		outDataSize = sizeof(AudioUnitParameterNameInfo );
+		outWritable = false;
+		break;
+
+#endif // !CA_NO_AU_UI_FEATURES
+
+	case 'lrst' :  // kAudioUnitProperty_LastRenderedSampleTime
+		outDataSize = sizeof(Float64);
+		outWritable = false;
+		break;
+	
+	default:
+		result = GetPropertyInfo(inID, inScope, inElement, outDataSize, outWritable);
+		validateElement = false;
+		break;
+	}
+
+	if (result == noErr && validateElement) {
+		ca_require(GetElement(inScope, inElement) != NULL, InvalidElement);	
+	}
+	
+	return result;
+InvalidProperty:
+	return kAudioUnitErr_InvalidProperty;
+InvalidScope:
+	return kAudioUnitErr_InvalidScope;
+InvalidElement:
+	return kAudioUnitErr_InvalidElement;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::DispatchGetProperty(	AudioUnitPropertyID 			inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement			 	inElement,
+													void *							outData)
+{
+	// NOTE: We're currently only called from AUBase::ComponentEntryDispatch, which
+	// calls DispatchGetPropertyInfo first, which performs validation of the scope/element,
+	// and ensures that the outData buffer is non-null and large enough.
+	OSStatus result = noErr;
+
+	switch (inID) {
+	case kAudioUnitProperty_StreamFormat:
+		*(CAStreamBasicDescription *)outData = GetStreamFormat(inScope, inElement);
+		break;
+	
+	case kAudioUnitProperty_SampleRate:
+		*(Float64 *)outData = GetStreamFormat(inScope, inElement).mSampleRate;
+		break;
+	
+	case kAudioUnitProperty_ParameterList:
+		{
+			UInt32 nparams = 0;
+			result = GetParameterList(inScope, (AudioUnitParameterID *)outData, nparams);
+		}
+		break;
+
+	case kAudioUnitProperty_ParameterInfo:
+		result = GetParameterInfo(inScope, inElement, *(AudioUnitParameterInfo *)outData);
+		break;
+
+	case kAudioUnitProperty_ParameterHistoryInfo:
+		{
+			AudioUnitParameterHistoryInfo* info = (AudioUnitParameterHistoryInfo*)outData;
+			result = GetParameterHistoryInfo(inScope, inElement, info->updatesPerSecond, info->historyDurationInSeconds);
+		}
+		break;
+
+	case kAudioUnitProperty_ClassInfo:
+		{
+			*(CFPropertyListRef *)outData = NULL;
+			result = SaveState((CFPropertyListRef *)outData);
+		}
+		break;
+
+	case kAudioUnitProperty_FactoryPresets:
+		{
+			*(CFArrayRef *)outData = NULL;
+			result = GetPresets ((CFArrayRef *)outData);
+		}
+		break;
+	
+	case kAudioUnitProperty_PresentPreset:
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+#ifndef __LP64__
+	case kAudioUnitProperty_CurrentPreset:
+#endif
+#endif
+		{
+			*(AUPreset *)outData = mCurrentPreset;
+				
+				// retain current string (as client owns a reference to it and will release it)
+			if (inID == kAudioUnitProperty_PresentPreset && mCurrentPreset.presetName) 
+				CFRetain (mCurrentPreset.presetName);
+
+			result = noErr;
+		}
+		break;
+	
+	case kAudioUnitProperty_ElementName:
+		{
+			AUElement * element = GetElement(inScope, inElement);
+			if (element->HasName()) {
+				*(CFStringRef *)outData = element->GetName();
+				CFRetain (element->GetName());
+				result = noErr;
+			} else
+				result = kAudioUnitErr_InvalidPropertyValue;
+		}
+		break;
+
+	case kAudioUnitProperty_ElementCount:
+		*(UInt32 *)outData = GetScope(inScope).GetNumberOfElements();
+		break;
+	
+	case kAudioUnitProperty_Latency:
+		*(Float64 *)outData = GetLatency();
+		break;
+
+	case kAudioUnitProperty_TailTime:
+		if (SupportsTail())
+			*(Float64 *)outData = GetTailTime();
+		else
+			result = kAudioUnitErr_InvalidProperty;
+		break;
+	
+	case kAudioUnitProperty_MaximumFramesPerSlice:
+		*(UInt32 *)outData = mMaxFramesPerSlice;
+		break;
+
+	case kAudioUnitProperty_LastRenderError:
+		*(OSStatus *)outData = mLastRenderError;
+		mLastRenderError = 0;
+		break;
+
+	case kAudioUnitProperty_SupportedNumChannels:
+		{
+			const AUChannelInfo* infoPtr;
+			UInt32 num = SupportedNumChannels (&infoPtr);
+			memcpy (outData, infoPtr, num * sizeof (AUChannelInfo));
+		}
+		break;
+
+	case kAudioUnitProperty_SupportedChannelLayoutTags:
+		{
+			AudioChannelLayoutTag* ptr = outData ? static_cast<AudioChannelLayoutTag*>(outData) : NULL;
+			UInt32 numLayouts = GetChannelLayoutTags (inScope, inElement, ptr);
+			if (numLayouts == 0)
+				result = kAudioUnitErr_InvalidProperty;
+		}
+		break;
+		
+	case kAudioUnitProperty_AudioChannelLayout:
+	{	
+		AudioChannelLayout* ptr = outData ? static_cast<AudioChannelLayout*>(outData) : NULL;
+		Boolean writable;
+		UInt32 dataSize = GetAudioChannelLayout(inScope, inElement, ptr, writable);
+		if (!dataSize) {
+			result = kAudioUnitErr_InvalidProperty;
+		}
+		break;
+	}
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5) || TARGET_OS_IPHONE
+	case kAudioUnitProperty_ShouldAllocateBuffer:
+	{
+		AUIOElement * element = GetIOElement(inScope, inElement);
+		*(UInt32*)outData = element->WillAllocateBuffer();
+		break;
+	}
+#endif
+
+		
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	case kAudioUnitProperty_FastDispatch:
+		if (!IsCMgrObject()) result = kAudioUnitErr_InvalidProperty;
+		else {
+			switch (inElement) {
+			case kAudioUnitGetParameterSelect:
+				*(AudioUnitGetParameterProc *)outData = (AudioUnitGetParameterProc)CMgr_AudioUnitBaseGetParameter;
+				break;
+			case kAudioUnitSetParameterSelect:
+				*(AudioUnitSetParameterProc *)outData = (AudioUnitSetParameterProc)CMgr_AudioUnitBaseSetParameter;
+				break;
+			case kAudioUnitRenderSelect:
+				if (AudioUnitAPIVersion() > 1)
+					*(AudioUnitRenderProc *)outData = (AudioUnitRenderProc)CMgr_AudioUnitBaseRender;
+				else result = kAudioUnitErr_InvalidElement;
+				break;
+			default:
+				result = GetProperty(inID, inScope, inElement, outData);
+				break;
+			}
+		}
+		break;
+
+	case kAudioUnitProperty_GetUIComponentList:
+		GetUIComponentDescs ((ComponentDescription*)outData);
+		break;
+#endif
+
+#if !CA_NO_AU_UI_FEATURES
+ 	case kAudioUnitProperty_ParameterValueStrings:
+		result = GetParameterValueStrings(inScope, inElement, (CFArrayRef *)outData);
+		break;
+
+	case kAudioUnitProperty_IconLocation:
+		{
+			CFURLRef iconLocation = CopyIconLocation();
+			if (iconLocation) {
+				*(CFURLRef*)outData = iconLocation;
+			} else
+				result = kAudioUnitErr_InvalidProperty;
+		}
+		break;
+
+	case kAudioUnitProperty_HostCallbacks:
+		*(HostCallbackInfo *)outData = mHostCallbackInfo;
+		break;
+	
+	case kAudioUnitProperty_ContextName:
+		*(CFStringRef *)outData = mContextName;
+		if (mContextName) {
+			CFRetain(mContextName);
+			// retain CFString (if exists) since client will be responsible for its release
+			result = noErr;
+		} else {
+			result = kAudioUnitErr_InvalidPropertyValue;
+		}
+		break;
+		
+	case kAudioUnitProperty_ParameterClumpName:
+		{
+			AudioUnitParameterNameInfo * ioClumpInfo = (AudioUnitParameterNameInfo*) outData;
+			if (ioClumpInfo->inID == kAudioUnitClumpID_System)	// this ID value is reserved
+				result = kAudioUnitErr_InvalidPropertyValue;
+			else 
+			{
+				result = CopyClumpName(inScope, ioClumpInfo->inID, ioClumpInfo->inDesiredLength, &ioClumpInfo->outName);
+					
+					// this is provided for compatbility with existing implementations that don't know
+					// about this new mechanism
+				if (result == kAudioUnitErr_InvalidProperty)
+					result = GetProperty (inID, inScope, inElement, outData);
+			}	
+		}
+		break;
+
+#endif  // !CA_NO_AU_UI_FEATURES
+
+	case 'lrst' : // kAudioUnitProperty_LastRenderedSampleTime
+		*(Float64*)outData = mCurrentRenderTime.mSampleTime;
+		break;
+
+	default:
+		result = GetProperty(inID, inScope, inElement, outData);
+		break;
+	}
+	return result;
+}
+
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::DispatchSetProperty(	AudioUnitPropertyID 			inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement,
+													const void *					inData,
+													UInt32 							inDataSize)
+{
+	OSStatus result = noErr;
+
+	switch (inID) {
+	case kAudioUnitProperty_MakeConnection:
+		ca_require(inDataSize >= sizeof(AudioUnitConnection), InvalidPropertyValue);
+		{
+			AudioUnitConnection &connection = *(AudioUnitConnection *)inData;
+			result = SetConnection(connection);
+		}
+		break;
+
+		
+	case kAudioUnitProperty_SetRenderCallback:
+		{
+			ca_require(inDataSize >= sizeof(AURenderCallbackStruct), InvalidPropertyValue);
+			ca_require(AudioUnitAPIVersion() > 1, InvalidProperty);
+			AURenderCallbackStruct &callback = *(AURenderCallbackStruct*)inData;
+			result = SetInputCallback(kAudioUnitProperty_SetRenderCallback, inElement, callback.inputProc, callback.inputProcRefCon);
+		}
+		break;
+
+	case kAudioUnitProperty_ElementCount:
+		ca_require(inDataSize == sizeof(UInt32), InvalidPropertyValue);
+		ca_require(BusCountWritable(inScope), NotWritable);
+		result = SetBusCount(inScope, *(UInt32*)inData);
+		if (result == noErr) {
+			PropertyChanged(inID, inScope, inElement);
+		}
+		break;
+	
+	case kAudioUnitProperty_MaximumFramesPerSlice:
+		ca_require(inDataSize == sizeof(UInt32), InvalidPropertyValue);
+		result = CanSetMaxFrames();
+		if (result) return result;
+		SetMaxFramesPerSlice(*(UInt32 *)inData);
+		break;
+
+	case kAudioUnitProperty_StreamFormat:
+		{
+			if (inDataSize < 36) goto InvalidPropertyValue;
+			ca_require(GetElement(inScope, inElement) != NULL, InvalidElement);
+
+			CAStreamBasicDescription newDesc;
+				// now we're going to be ultra conservative! because of discrepancies between
+				// sizes of this struct based on aligment padding inconsistencies
+			memset (&newDesc, 0, sizeof(newDesc));
+			memcpy (&newDesc, inData, 36);
+
+			ca_require(ValidFormat(inScope, inElement, newDesc), InvalidFormat);
+
+			const CAStreamBasicDescription curDesc = GetStreamFormat(inScope, inElement);
+			
+			if ( !curDesc.IsEqual(newDesc, false) ) {
+				ca_require(IsStreamFormatWritable(inScope, inElement), NotWritable);
+				result = ChangeStreamFormat(inScope, inElement, curDesc, newDesc);
+			}
+		}
+		break;
+	
+	case kAudioUnitProperty_SampleRate:
+		{
+			ca_require(inDataSize == sizeof(Float64), InvalidPropertyValue);
+			ca_require(GetElement(inScope, inElement) != NULL, InvalidElement);
+
+			const CAStreamBasicDescription curDesc = GetStreamFormat(inScope, inElement);
+			CAStreamBasicDescription newDesc = curDesc;
+			newDesc.mSampleRate = *(Float64 *)inData;
+			
+			ca_require(ValidFormat(inScope, inElement, newDesc), InvalidFormat);
+			
+			if ( !curDesc.IsEqual(newDesc, false) ) {
+				ca_require(IsStreamFormatWritable(inScope, inElement), NotWritable);
+				result = ChangeStreamFormat(inScope, inElement, curDesc, newDesc);
+			}
+		}
+		break;
+
+	case kAudioUnitProperty_AudioChannelLayout:
+		{
+			const AudioChannelLayout *layout = static_cast<const AudioChannelLayout *>(inData);
+			ca_require(inDataSize >= offsetof(AudioChannelLayout, mChannelDescriptions) + layout->mNumberChannelDescriptions * sizeof(AudioChannelDescription), InvalidPropertyValue);
+			result = SetAudioChannelLayout(inScope, inElement, layout);
+			if (result == noErr)
+				PropertyChanged(inID, inScope, inElement);
+			break;
+		}
+	
+	case kAudioUnitProperty_ClassInfo:
+		ca_require(inDataSize == sizeof(CFPropertyListRef *), InvalidPropertyValue);
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		result = RestoreState(*(CFPropertyListRef *)inData);
+		break;
+
+	case kAudioUnitProperty_PresentPreset:
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+#ifndef __LP64__
+	case kAudioUnitProperty_CurrentPreset:
+#endif
+#endif
+		{
+			ca_require(inDataSize == sizeof(AUPreset), InvalidPropertyValue);
+			ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+			AUPreset & newPreset = *(AUPreset *)inData;
+			
+			if (newPreset.presetNumber >= 0)
+			{
+				result = NewFactoryPresetSet(newPreset);
+				// NewFactoryPresetSet SHOULD call SetAFactoryPreset if the preset is valid
+				// from its own list of preset number->name
+				if (!result)
+					PropertyChanged(inID, inScope, inElement);
+			}
+			else if (newPreset.presetName)
+			{
+				CFRelease (mCurrentPreset.presetName);
+				mCurrentPreset = newPreset;
+				CFRetain (mCurrentPreset.presetName);
+				PropertyChanged(inID, inScope, inElement);
+			}
+			else
+				result = kAudioUnitErr_InvalidPropertyValue;
+		}
+		break;
+	
+	case kAudioUnitProperty_ElementName:
+		{
+			ca_require(GetElement(inScope, inElement) != NULL, InvalidElement);
+			ca_require(inDataSize == sizeof(CFStringRef), InvalidPropertyValue);
+			AUElement * element = GetScope(inScope).GetElement (inElement);
+			element->SetName (*(CFStringRef *)inData);
+			PropertyChanged(inID, inScope, inElement);
+		}
+		break;
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5) || TARGET_OS_IPHONE
+	case kAudioUnitProperty_ShouldAllocateBuffer:
+		{
+			ca_require((inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output), InvalidScope);
+			ca_require(GetElement(inScope, inElement) != NULL, InvalidElement);
+			ca_require(inDataSize == sizeof(UInt32), InvalidPropertyValue);
+			ca_require(!IsInitialized(), Initialized);
+
+			AUIOElement * element = GetIOElement(inScope, inElement);
+			element->SetWillAllocateBuffer(*(UInt32 *)inData != 0);
+		}
+		break;
+#endif
+
+#if !CA_NO_AU_UI_FEATURES
+	case kAudioUnitProperty_SetExternalBuffer:
+		ca_require(inDataSize >= sizeof(AudioUnitExternalBuffer), InvalidPropertyValue);
+		ca_require(IsInitialized(), Uninitialized);
+		{
+			AudioUnitExternalBuffer &buf = *(AudioUnitExternalBuffer*)inData;
+			if (intptr_t(buf.buffer) & 0x0F) result = kAudio_ParamError;
+			else if (inScope == kAudioUnitScope_Input) {
+				AUInputElement *input = GetInput(inElement);
+				input->UseExternalBuffer(buf);
+			} else {
+				AUOutputElement *output = GetOutput(inElement);
+				output->UseExternalBuffer(buf);
+			}
+		}
+		break;
+
+	case kAudioUnitProperty_ContextName:
+		{
+			ca_require(inDataSize == sizeof(CFStringRef), InvalidPropertyValue);
+			ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+			CFStringRef inStr = *(CFStringRef *)inData;
+			if (mContextName) CFRelease(mContextName);
+			if (inStr) CFRetain(inStr);
+			mContextName = inStr;
+			PropertyChanged(inID, inScope, inElement);
+		}
+		break;
+
+	case kAudioUnitProperty_HostCallbacks:
+	{
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		UInt32 availSize = (inDataSize < sizeof (mHostCallbackInfo) ? inDataSize : sizeof (mHostCallbackInfo));
+		bool hasChanged = !memcmp (&mHostCallbackInfo, inData, availSize);
+		memset (&mHostCallbackInfo, 0, sizeof (mHostCallbackInfo));
+		memcpy (&mHostCallbackInfo, inData, availSize);
+		if (hasChanged)
+			PropertyChanged(inID, inScope, inElement);
+		break;
+	}
+#endif // !CA_NO_AU_UI_FEATURES
+	
+	default:
+		result = SetProperty(inID, inScope, inElement, inData, inDataSize);
+		if (result == noErr)
+			PropertyChanged(inID, inScope, inElement);
+		
+		break;
+	}
+	return result;
+NotWritable:
+	return kAudioUnitErr_PropertyNotWritable;
+InvalidFormat:
+	return kAudioUnitErr_FormatNotSupported;
+#if !CA_NO_AU_UI_FEATURES
+Uninitialized:
+	return kAudioUnitErr_Uninitialized;
+#endif
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5) || CA_USE_AUDIO_PLUGIN_ONLY
+Initialized:
+	return kAudioUnitErr_Initialized;
+#endif
+InvalidScope:
+	return kAudioUnitErr_InvalidScope;
+InvalidProperty:
+	return kAudioUnitErr_InvalidProperty;
+InvalidPropertyValue:
+	return kAudioUnitErr_InvalidPropertyValue;
+InvalidElement:
+	return kAudioUnitErr_InvalidElement;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::DispatchRemovePropertyValue (AudioUnitPropertyID		inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement)
+{
+	OSStatus result = noErr;
+	switch (inID)
+	{
+	case kAudioUnitProperty_AudioChannelLayout:
+	{
+		result = RemoveAudioChannelLayout(inScope, inElement);
+		if (result == noErr)
+			PropertyChanged(inID, inScope, inElement);
+		break;
+	}
+	
+#if !CA_NO_AU_UI_FEATURES
+	case kAudioUnitProperty_ContextName:
+		if (mContextName) CFRelease(mContextName);
+		mContextName = NULL;
+		result = noErr;
+		break;
+	
+	case kAudioUnitProperty_HostCallbacks:
+	{
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		bool hasValue = false;
+		void* ptr = &mHostCallbackInfo;
+		for (unsigned int i = 0; i <  sizeof (HostCallbackInfo); ++i) {
+			if (static_cast<char*>(ptr)[i]) {
+				hasValue = true;
+				break;
+			}
+		}
+		if (hasValue) {
+			memset (&mHostCallbackInfo, 0, sizeof (HostCallbackInfo));
+			PropertyChanged(inID, inScope, inElement);
+		}
+		break;
+	}
+#endif // !CA_NO_AU_UI_FEATURES	
+
+	default:
+		result = RemovePropertyValue (inID, inScope, inElement);		
+		break;
+	}
+		
+	return result;
+#if !CA_NO_AU_UI_FEATURES
+InvalidScope:
+	return kAudioUnitErr_InvalidScope;
+#endif
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::GetPropertyInfo(		AudioUnitPropertyID				inID,
+													AudioUnitScope					inScope,
+													AudioUnitElement				inElement,
+													UInt32 &						outDataSize,
+													Boolean &						outWritable)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::GetProperty(			AudioUnitPropertyID 			inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement			 	inElement,
+													void *							outData)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::SetProperty(			AudioUnitPropertyID 			inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement,
+													const void *					inData,
+													UInt32 							inDataSize)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::RemovePropertyValue (	AudioUnitPropertyID		 		inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement)
+{
+	return kAudioUnitErr_InvalidPropertyValue;
+}
+												
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::AddPropertyListener(	AudioUnitPropertyID				inID,
+													AudioUnitPropertyListenerProc	inProc,
+													void *							inProcRefCon)
+{
+	PropertyListener pl;
+	
+	pl.propertyID = inID;
+	pl.listenerProc = inProc;
+	pl.listenerRefCon = inProcRefCon;
+	
+	if (mPropertyListeners.empty())
+		mPropertyListeners.reserve(32);
+	mPropertyListeners.push_back(pl);
+
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::RemovePropertyListener(		AudioUnitPropertyID				inID,
+														AudioUnitPropertyListenerProc	inProc,
+														void *							inProcRefCon,
+														bool							refConSpecified)
+{
+	// iterate in reverse so that it's safe to erase in the middle of the vector
+	for (int i = mPropertyListeners.size(); --i >=0; ) {
+		PropertyListeners::iterator it = mPropertyListeners.begin() + i;
+		if ((*it).propertyID == inID && (*it).listenerProc == inProc && (!refConSpecified || (*it).listenerRefCon == inProcRefCon))
+			mPropertyListeners.erase(it);
+	}
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::PropertyChanged(			AudioUnitPropertyID				inID,
+														AudioUnitScope					inScope, 
+														AudioUnitElement				inElement)
+{
+	for (PropertyListeners::iterator it = mPropertyListeners.begin(); it != mPropertyListeners.end(); ++it)
+		if ((*it).propertyID == inID)
+			((*it).listenerProc)((*it).listenerRefCon, mComponentInstance, inID, inScope, inElement);
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::SetRenderNotification(	AURenderCallback		 		inProc,
+													void *							inRefCon)
+{
+	if (inProc == NULL)
+		return kAudio_ParamError;
+
+	mRenderCallbacksTouched = true;
+	mRenderCallbacks.deferred_add(RenderCallback(inProc, inRefCon));
+			// this will do nothing if it's already in the list
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::RemoveRenderNotification(	AURenderCallback			inProc,
+														void *						inRefCon)
+{
+	mRenderCallbacks.deferred_remove(RenderCallback(inProc, inRefCon));
+	return noErr;	// error?
+}
+
+//_____________________________________________________________________________
+//
+OSStatus 	AUBase::GetParameter(			AudioUnitParameterID			inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement,
+													AudioUnitParameterValue &		outValue)
+{
+	AUElement *elem = SafeGetElement(inScope, inElement);
+	outValue = elem->GetParameter(inID);
+	return noErr;
+}
+
+											
+//_____________________________________________________________________________
+//
+OSStatus 	AUBase::SetParameter(			AudioUnitParameterID			inID,
+													AudioUnitScope 					inScope,
+													AudioUnitElement 				inElement,
+													AudioUnitParameterValue			inValue,
+													UInt32							inBufferOffsetInFrames)
+{
+	AUElement *elem = SafeGetElement(inScope, inElement);
+	elem->SetParameter(inID, inValue);
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus 	AUBase::ScheduleParameter (	const AudioUnitParameterEvent 		*inParameterEvent,
+													UInt32							inNumEvents)
+{
+	for (UInt32 i = 0; i < inNumEvents; ++i) 
+	{
+		if (inParameterEvent[i].eventType == kParameterEvent_Immediate)
+		{
+			SetParameter (inParameterEvent[i].parameter,
+							inParameterEvent[i].scope, 
+							inParameterEvent[i].element,
+							inParameterEvent[i].eventValues.immediate.value, 
+							inParameterEvent[i].eventValues.immediate.bufferOffset);
+		} 
+		mParamList.push_back (inParameterEvent[i]);
+	}
+	
+	return noErr;
+}
+
+// ____________________________________________________________________________
+//
+static bool SortParameterEventList(const AudioUnitParameterEvent &ev1, const AudioUnitParameterEvent &ev2 )
+{
+	int offset1 = ev1.eventType == kParameterEvent_Immediate ?  ev1.eventValues.immediate.bufferOffset : ev1.eventValues.ramp.startBufferOffset;
+	int offset2 = ev2.eventType == kParameterEvent_Immediate ?  ev2.eventValues.immediate.bufferOffset : ev2.eventValues.ramp.startBufferOffset;
+
+	if(offset1 < offset2) return true;
+	return false;
+}
+
+
+// ____________________________________________________________________________
+//
+OSStatus 	AUBase::ProcessForScheduledParams(	ParameterEventList		&inParamList,
+														UInt32					inFramesToProcess,
+														void					*inUserData )
+{
+	OSStatus result = noErr;
+	
+	int totalFramesToProcess = inFramesToProcess;
+	
+	int framesRemaining = totalFramesToProcess;
+
+	unsigned int currentStartFrame = 0;	// start of the whole buffer
+
+
+
+	// sort the ParameterEventList by startBufferOffset
+	std::sort(inParamList.begin(), inParamList.end(), SortParameterEventList);
+
+	ParameterEventList::iterator iter = inParamList.begin();
+	
+	
+	while(framesRemaining > 0 )
+	{
+		// first of all, go through the ramped automation events and find out where the next
+		// division of our whole buffer will be
+		
+		int currentEndFrame = totalFramesToProcess;	// start out assuming we'll process all the way to
+													// the end of the buffer
+		
+		iter = inParamList.begin();
+		
+		// find the next break point
+		while(iter != inParamList.end() )
+		{
+			AudioUnitParameterEvent &event = *iter;
+			
+			int offset = event.eventType == kParameterEvent_Immediate ?  event.eventValues.immediate.bufferOffset : event.eventValues.ramp.startBufferOffset;
+
+			if(offset > (int)currentStartFrame && offset < currentEndFrame )
+			{
+				currentEndFrame = offset;
+				break;
+			}
+
+			// consider ramp end to be a possible choice (there may be gaps in the supplied ramp events)
+			if(event.eventType == kParameterEvent_Ramped )
+			{
+				offset = event.eventValues.ramp.startBufferOffset + event.eventValues.ramp.durationInFrames;
+	
+				if(offset > (int)currentStartFrame && offset < currentEndFrame )
+				{
+					currentEndFrame = offset;
+				}
+			}
+
+			iter++;
+		}
+	
+		int framesThisTime = currentEndFrame - currentStartFrame;
+
+		// next, setup the parameter maps to be current for the ramp parameters active during 
+		// this time segment...
+		
+		for(ParameterEventList::iterator iter2 = inParamList.begin(); iter2 != inParamList.end(); iter2++ )
+		{
+			AudioUnitParameterEvent &event = *iter2;
+			
+			bool eventFallsInSlice;
+			
+			
+			if(event.eventType == kParameterEvent_Ramped)
+				eventFallsInSlice = event.eventValues.ramp.startBufferOffset < currentEndFrame 
+					&& event.eventValues.ramp.startBufferOffset + event.eventValues.ramp.durationInFrames > currentStartFrame;
+			else /* kParameterEvent_Immediate */
+				// actually, for the same parameter, there may be future immediate events which override this one,
+				// but it's OK since the event list is sorted in time order, we're guaranteed to end up with the current one
+				eventFallsInSlice = event.eventValues.immediate.bufferOffset <= currentStartFrame;
+				
+			if(eventFallsInSlice)
+			{
+				AUElement *element = GetElement(event.scope, event.element );
+				
+				if(element) element->SetScheduledEvent(	event.parameter,
+														event,
+														currentStartFrame,
+														currentEndFrame - currentStartFrame );
+			}
+		}
+
+
+
+		// Finally, actually do the processing for this slice.....
+		
+		result = ProcessScheduledSlice(	inUserData,
+										currentStartFrame,
+										framesThisTime,
+										inFramesToProcess );
+								
+		if(result != noErr) break;
+		
+		framesRemaining -= framesThisTime;
+		currentStartFrame = currentEndFrame;	// now start from where we left off last time
+	}
+	
+	return result;
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::SetWantsRenderThreadID (bool inFlag)
+{
+	if (inFlag == mWantsRenderThreadID)	
+		return;
+	
+	mWantsRenderThreadID = inFlag;
+	if (!mWantsRenderThreadID)
+		mRenderThreadID = NULL;
+}
+
+//_____________________________________________________________________________
+//
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::DoRender(		AudioUnitRenderActionFlags &	ioActionFlags,
+											const AudioTimeStamp &			inTimeStamp,
+											UInt32							inBusNumber,
+											UInt32							inFramesToProcess,
+											AudioBufferList &				ioData)
+{
+	OSStatus theError;
+	RenderCallbackList::iterator rcit;
+	
+	AUTRACE(kCATrace_AUBaseRenderStart, mComponentInstance, (intptr_t)this, inBusNumber, inFramesToProcess, 0);
+	DISABLE_DENORMALS
+	
+	try {
+		ca_require(IsInitialized(), Uninitialized);
+		ca_require(mAudioUnitAPIVersion >= 2, ParamErr);
+		ca_require(inFramesToProcess <= mMaxFramesPerSlice, TooManyFrames);
+		
+		AUOutputElement *output = GetOutput(inBusNumber);	// will throw if non-existant
+		if (output->GetStreamFormat().NumberChannelStreams() != ioData.mNumberBuffers) {
+			DebugMessageN4("%s:%d ioData.mNumberBuffers=%u, output->GetStreamFormat().NumberChannelStreams()=%u; kAudio_ParamError",
+				__FILE__, __LINE__, (unsigned)ioData.mNumberBuffers, (unsigned)output->GetStreamFormat().NumberChannelStreams());
+			goto ParamErr;
+		}
+
+		unsigned expectedBufferByteSize = inFramesToProcess * output->GetStreamFormat().mBytesPerFrame;
+		for (unsigned ibuf = 0; ibuf < ioData.mNumberBuffers; ++ibuf) {
+			AudioBuffer &buf = ioData.mBuffers[ibuf];
+			if (buf.mData != NULL) {
+				// only care about the size if the buffer is non-null
+				if (buf.mDataByteSize < expectedBufferByteSize) {
+					// if the buffer is too small, we cannot render safely. kAudio_ParamError.
+					DebugMessageN7("%s:%d %u frames, %u bytes/frame, expected %u-byte buffer; ioData.mBuffers[%u].mDataByteSize=%u; kAudio_ParamError",
+						__FILE__, __LINE__, (unsigned)inFramesToProcess, (unsigned)output->GetStreamFormat().mBytesPerFrame, expectedBufferByteSize, ibuf, (unsigned)buf.mDataByteSize);
+					goto ParamErr;
+				}
+				// Some clients incorrectly pass bigger buffers than expectedBufferByteSize.
+				// We will generally set the buffer size at the end of rendering, before we return.
+				// However we should ensure that no one, DURING rendering, READS a
+				// potentially incorrect size. This can lead to doing too much work, or
+				// reading past the end of an input buffer into unmapped memory.
+				buf.mDataByteSize = expectedBufferByteSize;
+			}
+		}
+		
+		if (WantsRenderThreadID())
+		{
+			#if TARGET_OS_MAC
+				mRenderThreadID = pthread_self();
+			#elif TARGET_OS_WIN32
+				mRenderThreadID = GetCurrentThreadId();
+			#endif
+		}
+		
+		AudioUnitRenderActionFlags flags;
+		if (mRenderCallbacksTouched) {
+			mRenderCallbacks.update();
+			flags = ioActionFlags | kAudioUnitRenderAction_PreRender;
+			for (rcit = mRenderCallbacks.begin(); rcit != mRenderCallbacks.end(); ++rcit) {
+				RenderCallback &rc = *rcit;
+				AUTRACE(kCATrace_AUBaseRenderCallbackStart, mComponentInstance, (intptr_t)this, (intptr_t)rc.mRenderNotify, 1, 0);
+				(*(AURenderCallback)rc.mRenderNotify)(rc.mRenderNotifyRefCon, 
+								&flags,
+								&inTimeStamp, inBusNumber, inFramesToProcess, &ioData);
+				AUTRACE(kCATrace_AUBaseRenderCallbackEnd, mComponentInstance, (intptr_t)this, (intptr_t)rc.mRenderNotify, 1, 0);
+			}
+		}
+		
+		theError = DoRenderBus(ioActionFlags, inTimeStamp, inBusNumber, output, inFramesToProcess, ioData);
+		
+		flags = ioActionFlags | kAudioUnitRenderAction_PostRender;
+		
+		if (SetRenderError (theError)) {
+			flags |= kAudioUnitRenderAction_PostRenderError;		
+		}
+		
+		if (mRenderCallbacksTouched) {
+			for (rcit = mRenderCallbacks.begin(); rcit != mRenderCallbacks.end(); ++rcit) {
+				RenderCallback &rc = *rcit;
+				AUTRACE(kCATrace_AUBaseRenderCallbackStart, mComponentInstance, (intptr_t)this, (intptr_t)rc.mRenderNotify, 2, 0);
+				(*(AURenderCallback)rc.mRenderNotify)(rc.mRenderNotifyRefCon, 
+								&flags,
+								&inTimeStamp, inBusNumber, inFramesToProcess, &ioData);
+				AUTRACE(kCATrace_AUBaseRenderCallbackEnd, mComponentInstance, (intptr_t)this, (intptr_t)rc.mRenderNotify, 2, 0);
+			}
+		}
+
+		// The vector's being emptied
+		// because these events should only apply to this Render cycle, so anything
+		// left over is from a preceding cycle and should be dumped.  New scheduled
+		// parameters must be scheduled from the next pre-render callback.
+		if (!mParamList.empty())
+			mParamList.clear();
+
+	}
+	catch (OSStatus err) {
+		theError = err;
+		goto errexit;
+	}
+	catch (...) {
+		theError = -1;
+		goto errexit;
+	}
+done:	
+	RESTORE_DENORMALS
+	AUTRACE(kCATrace_AUBaseRenderEnd, mComponentInstance, (intptr_t)this, theError, ioActionFlags, ioData.mBuffers[0].mData != NULL ? *(int64_t *)ioData.mBuffers[0].mData : 0);
+	
+	return theError;
+	
+Uninitialized:	theError = kAudioUnitErr_Uninitialized;				goto errexit;
+ParamErr:		theError = kAudio_ParamError;						goto errexit;
+TooManyFrames:	theError = kAudioUnitErr_TooManyFramesToProcess;	goto errexit;
+errexit:
+	DebugMessageN2 ("  from %s, render err: %d", GetLoggingString(), (int)theError);
+	SetRenderError(theError);
+	goto done;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus	AUBase::DoProcess (	AudioUnitRenderActionFlags  &		ioActionFlags,
+								const AudioTimeStamp &				inTimeStamp,
+								UInt32								inFramesToProcess,
+								AudioBufferList &					ioData)
+{
+	OSStatus theError;
+	AUTRACE(kCATrace_AUBaseRenderStart, mComponentInstance, (intptr_t)this, inFramesToProcess, 0, 0);
+	DISABLE_DENORMALS
+
+	try {
+		
+		if (!(ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/)) {
+			ca_require(IsInitialized(), Uninitialized);
+			ca_require(inFramesToProcess <= mMaxFramesPerSlice, TooManyFrames);
+
+			AUInputElement *input = GetInput(0);	// will throw if non-existant
+			if (input->GetStreamFormat().NumberChannelStreams() != ioData.mNumberBuffers) {
+				DebugMessageN4("%s:%d ioData.mNumberBuffers=%u, input->GetStreamFormat().NumberChannelStreams()=%u; kAudio_ParamError",
+					__FILE__, __LINE__, (unsigned)ioData.mNumberBuffers, (unsigned)input->GetStreamFormat().NumberChannelStreams());
+				goto ParamErr;
+			}
+
+			unsigned expectedBufferByteSize = inFramesToProcess * input->GetStreamFormat().mBytesPerFrame;
+			for (unsigned ibuf = 0; ibuf < ioData.mNumberBuffers; ++ibuf) {
+				AudioBuffer &buf = ioData.mBuffers[ibuf];
+				if (buf.mData != NULL) {
+					// only care about the size if the buffer is non-null
+					if (buf.mDataByteSize < expectedBufferByteSize) {
+						// if the buffer is too small, we cannot render safely. kAudio_ParamError.
+						DebugMessageN7("%s:%d %u frames, %u bytes/frame, expected %u-byte buffer; ioData.mBuffers[%u].mDataByteSize=%u; kAudio_ParamError",
+							__FILE__, __LINE__, (unsigned)inFramesToProcess, (unsigned)input->GetStreamFormat().mBytesPerFrame, expectedBufferByteSize, ibuf, (unsigned)buf.mDataByteSize);
+						goto ParamErr;
+					}
+					// Some clients incorrectly pass bigger buffers than expectedBufferByteSize.
+					// We will generally set the buffer size at the end of rendering, before we return.
+					// However we should ensure that no one, DURING rendering, READS a
+					// potentially incorrect size. This can lead to doing too much work, or
+					// reading past the end of an input buffer into unmapped memory.
+					buf.mDataByteSize = expectedBufferByteSize;
+				}
+			}
+		}
+		
+		if (WantsRenderThreadID())
+		{
+			#if TARGET_OS_MAC
+				mRenderThreadID = pthread_self();
+			#elif TARGET_OS_WIN32
+				mRenderThreadID = GetCurrentThreadId();
+			#endif
+		}
+		
+		if (NeedsToRender (inTimeStamp)) {
+			theError = ProcessBufferLists (ioActionFlags, ioData, ioData, inFramesToProcess);
+		} else
+			theError = noErr;
+			
+	}
+	catch (OSStatus err) {
+		theError = err;
+		goto errexit;
+	}
+	catch (...) {
+		theError = -1;
+		goto errexit;
+	}
+done:	
+	RESTORE_DENORMALS
+	AUTRACE(kCATrace_AUBaseRenderEnd, mComponentInstance, (intptr_t)this, theError, ioActionFlags, ioData.mBuffers[0].mData != NULL ? *(int64_t *)ioData.mBuffers[0].mData : 0);
+	
+	return theError;
+	
+Uninitialized:	theError = kAudioUnitErr_Uninitialized;				goto errexit;
+ParamErr:		theError = kAudio_ParamError;						goto errexit;
+TooManyFrames:	theError = kAudioUnitErr_TooManyFramesToProcess;	goto errexit;
+errexit:
+	DebugMessageN2 ("  from %s, process err: %d", GetLoggingString(), (int)theError);
+	SetRenderError(theError);
+	goto done;
+}
+
+OSStatus	AUBase::DoProcessMultiple (	AudioUnitRenderActionFlags  & ioActionFlags,
+							   const AudioTimeStamp &				inTimeStamp,
+							   UInt32								inFramesToProcess,
+							   UInt32								inNumberInputBufferLists,
+							   const AudioBufferList **				inInputBufferLists,
+							   UInt32								inNumberOutputBufferLists,
+							   AudioBufferList **					ioOutputBufferLists)
+{
+	OSStatus theError;
+	DISABLE_DENORMALS
+	
+	try {
+		
+		if (!(ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/)) {
+			ca_require(IsInitialized(), Uninitialized);
+			ca_require(inFramesToProcess <= mMaxFramesPerSlice, TooManyFrames);
+			
+			for (unsigned ibl = 0; ibl < inNumberInputBufferLists; ++ibl) {
+				if (inInputBufferLists[ibl] != NULL) {
+					AUInputElement *input = GetInput(ibl);	// will throw if non-existant
+					unsigned expectedBufferByteSize = inFramesToProcess * input->GetStreamFormat().mBytesPerFrame;
+					
+					if (input->GetStreamFormat().NumberChannelStreams() != inInputBufferLists[ibl]->mNumberBuffers) {
+						DebugMessageN5("%s:%d inInputBufferLists[%u]->mNumberBuffers=%u, input->GetStreamFormat().NumberChannelStreams()=%u; kAudio_ParamError",
+									   __FILE__, __LINE__, ibl, (unsigned)inInputBufferLists[ibl]->mNumberBuffers, (unsigned)input->GetStreamFormat().NumberChannelStreams());
+						goto ParamErr;
+					}
+					
+					for (unsigned ibuf = 0; ibuf < inInputBufferLists[ibl]->mNumberBuffers; ++ibuf) {
+						const AudioBuffer &buf = inInputBufferLists[ibl]->mBuffers[ibuf];
+						if (buf.mData != NULL) {
+							if (buf.mDataByteSize < expectedBufferByteSize) {
+								// the buffer is too small
+								DebugMessageN8("%s:%d %u frames, %u bytes/frame, expected %u-byte buffer; inInputBufferLists[%u].mBuffers[%u].mDataByteSize=%u; kAudio_ParamError",
+											   __FILE__, __LINE__, (unsigned)inFramesToProcess, (unsigned)input->GetStreamFormat().mBytesPerFrame, expectedBufferByteSize, ibl, ibuf, (unsigned)buf.mDataByteSize);
+								goto ParamErr;
+							}
+						} else {
+							// the buffer must exist
+							goto ParamErr;
+						}
+					}
+				} else {
+					// skip NULL input audio buffer list
+				}
+			}
+			
+			for (unsigned obl = 0; obl < inNumberOutputBufferLists; ++obl) {
+				if (ioOutputBufferLists[obl] != NULL) {
+					AUOutputElement *output = GetOutput(obl);	// will throw if non-existant
+					unsigned expectedBufferByteSize = inFramesToProcess * output->GetStreamFormat().mBytesPerFrame;
+
+					if (output->GetStreamFormat().NumberChannelStreams() != ioOutputBufferLists[obl]->mNumberBuffers) {
+						DebugMessageN5("%s:%d ioOutputBufferLists[%u]->mNumberBuffers=%u, output->GetStreamFormat().NumberChannelStreams()=%u; kAudio_ParamError",
+									   __FILE__, __LINE__, obl, (unsigned)ioOutputBufferLists[obl]->mNumberBuffers, (unsigned)output->GetStreamFormat().NumberChannelStreams());
+						goto ParamErr;
+					}
+					
+					for (unsigned obuf = 0; obuf < ioOutputBufferLists[obl]->mNumberBuffers; ++obuf) {
+						AudioBuffer &buf = ioOutputBufferLists[obl]->mBuffers[obuf];
+						if (buf.mData != NULL) {
+							// only care about the size if the buffer is non-null
+							if (buf.mDataByteSize < expectedBufferByteSize) {
+								// if the buffer is too small, we cannot render safely. kAudio_ParamError.
+								DebugMessageN8("%s:%d %u frames, %u bytes/frame, expected %u-byte buffer; ioOutputBufferLists[%u]->mBuffers[%u].mDataByteSize=%u; kAudio_ParamError",
+											   __FILE__, __LINE__, (unsigned)inFramesToProcess, (unsigned)output->GetStreamFormat().mBytesPerFrame, expectedBufferByteSize, obl, obuf, (unsigned)buf.mDataByteSize);
+								goto ParamErr;
+							}
+							// Some clients incorrectly pass bigger buffers than expectedBufferByteSize.
+							// We will generally set the buffer size at the end of rendering, before we return.
+							// However we should ensure that no one, DURING rendering, READS a
+							// potentially incorrect size. This can lead to doing too much work, or
+							// reading past the end of an input buffer into unmapped memory.
+							buf.mDataByteSize = expectedBufferByteSize;
+						}
+					}
+				} else {
+					// skip NULL output audio buffer list
+				}
+			}
+		}
+		
+		if (WantsRenderThreadID())
+		{
+#if TARGET_OS_MAC
+			mRenderThreadID = pthread_self();
+#elif TARGET_OS_WIN32
+			mRenderThreadID = GetCurrentThreadId();
+#endif
+		}
+		
+		if (NeedsToRender (inTimeStamp)) {
+			if (inNumberInputBufferLists == 1 && inNumberOutputBufferLists == 1)
+				theError = ProcessBufferLists (ioActionFlags, *inInputBufferLists[0], *ioOutputBufferLists[0], inFramesToProcess);
+			else {
+				theError = ProcessMultipleBufferLists (ioActionFlags, inFramesToProcess, inNumberInputBufferLists, inInputBufferLists, inNumberOutputBufferLists, ioOutputBufferLists);
+			}
+		} else
+			theError = noErr;
+	}
+	catch (OSStatus err) {
+		theError = err;
+		goto errexit;
+	}
+	catch (...) {
+		theError = -1;
+		goto errexit;
+	}
+done:	
+	RESTORE_DENORMALS
+	
+	return theError;
+	
+Uninitialized:	theError = kAudioUnitErr_Uninitialized;				goto errexit;
+ParamErr:		theError = kAudio_ParamError;						goto errexit;
+TooManyFrames:	theError = kAudioUnitErr_TooManyFramesToProcess;	goto errexit;
+errexit:
+	DebugMessageN2 ("  from %s, processmultiple err: %d", GetLoggingString(), (int)theError);
+	SetRenderError(theError);
+	goto done;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::SetInputCallback(		UInt32							inPropertyID,
+													AudioUnitElement 				inElement, 
+													AURenderCallback				inProc,
+													void *							inRefCon)
+{
+	AUInputElement *input = GetInput(inElement);	// may throw
+	
+	input->SetInputCallback(inProc, inRefCon);
+	PropertyChanged(inPropertyID, kAudioUnitScope_Input, inElement);
+	
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::SetConnection(			const AudioUnitConnection &		inConnection)
+{
+
+	OSStatus err;
+	AUInputElement *input = GetInput(inConnection.destInputNumber);	// may throw
+		
+	if (inConnection.sourceAudioUnit) {
+		// connecting, not disconnecting
+		CAStreamBasicDescription sourceDesc;
+		UInt32 size = sizeof(CAStreamBasicDescription);
+		ca_require_noerr(err = AudioUnitGetProperty(
+										inConnection.sourceAudioUnit,
+										kAudioUnitProperty_StreamFormat,
+										kAudioUnitScope_Output,
+										inConnection.sourceOutputNumber,
+										&sourceDesc,
+										&size), errexit);
+		ca_require_noerr(err = DispatchSetProperty (kAudioUnitProperty_StreamFormat, 
+								kAudioUnitScope_Input, inConnection.destInputNumber, 
+								&sourceDesc, sizeof(CAStreamBasicDescription)), errexit);
+	}
+	input->SetConnection(inConnection);
+		
+	PropertyChanged(kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, inConnection.destInputNumber);
+	return noErr;
+
+errexit:
+	return err;
+}
+ 
+//_____________________________________________________________________________
+//
+UInt32				AUBase::SupportedNumChannels (	const AUChannelInfo** 			outInfo)
+{
+	return 0;
+}
+
+//_____________________________________________________________________________
+//
+bool				AUBase::ValidFormat(			AudioUnitScope					inScope,
+													AudioUnitElement				inElement,
+													const CAStreamBasicDescription &		inNewFormat)
+{
+	return FormatIsCanonical(inNewFormat);
+}
+
+//_____________________________________________________________________________
+//
+bool				AUBase::IsStreamFormatWritable(	AudioUnitScope					scope,
+													AudioUnitElement				element)
+{
+	switch (scope) {
+	case kAudioUnitScope_Input:
+		{
+			AUInputElement *input = GetInput(element);
+			if (input->HasConnection()) return false;	// can't write format when input comes from connection
+		}
+		// ... fall ...
+	case kAudioUnitScope_Output:
+		return StreamFormatWritable(scope, element);
+
+//#warning "aliasing of global scope format should be pushed to subclasses"
+	case kAudioUnitScope_Global:
+		return StreamFormatWritable(kAudioUnitScope_Output, 0);
+	}
+	return false;
+}
+
+//_____________________________________________________________________________
+//
+const CAStreamBasicDescription &
+					AUBase::GetStreamFormat(		AudioUnitScope					inScope,
+													AudioUnitElement				inElement)
+{
+//#warning "aliasing of global scope format should be pushed to subclasses"
+	AUIOElement *element;
+	
+	switch (inScope) {
+	case kAudioUnitScope_Input:
+		element = Inputs().GetIOElement(inElement);
+		break;
+	case kAudioUnitScope_Output:
+		element = Outputs().GetIOElement(inElement);
+		break;
+	case kAudioUnitScope_Global:	// global stream description is an alias for that of output 0
+		element = Outputs().GetIOElement(0);
+		break;
+	default:
+		COMPONENT_THROW(kAudioUnitErr_InvalidScope);
+	}
+	return element->GetStreamFormat();
+}
+
+OSStatus			AUBase::SetBusCount(	AudioUnitScope					inScope,
+											UInt32 							inCount)
+{
+	if (IsInitialized()) 
+		return kAudioUnitErr_Initialized;
+		
+	GetScope(inScope).SetNumberOfElements(inCount);
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::ChangeStreamFormat(		AudioUnitScope					inScope,
+													AudioUnitElement				inElement,
+													const CAStreamBasicDescription & inPrevFormat,
+													const CAStreamBasicDescription &	inNewFormat)
+{
+//#warning "aliasing of global scope format should be pushed to subclasses"
+	AUIOElement *element;
+	
+	switch (inScope) {
+	case kAudioUnitScope_Input:
+		element = Inputs().GetIOElement(inElement);
+		break;
+	case kAudioUnitScope_Output:
+		element = Outputs().GetIOElement(inElement);
+		break;
+	case kAudioUnitScope_Global:
+		element = Outputs().GetIOElement(0);
+		break;
+	default:
+		COMPONENT_THROW(kAudioUnitErr_InvalidScope);
+	}
+	element->SetStreamFormat(inNewFormat);
+	PropertyChanged(kAudioUnitProperty_StreamFormat, inScope, inElement);
+	return noErr;
+}
+
+UInt32		AUBase::GetChannelLayoutTags(	AudioUnitScope				inScope,
+											AudioUnitElement 			inElement,
+											AudioChannelLayoutTag *		outLayoutTags)
+{
+	return GetIOElement(inScope, inElement)->GetChannelLayoutTags(outLayoutTags);
+}
+
+UInt32		AUBase::GetAudioChannelLayout(	AudioUnitScope				scope,
+											AudioUnitElement 			element,
+											AudioChannelLayout *		outLayoutPtr,
+											Boolean &					outWritable)
+{
+	AUIOElement * el = GetIOElement(scope, element);
+	return el->GetAudioChannelLayout(outLayoutPtr, outWritable);
+}
+
+OSStatus	AUBase::RemoveAudioChannelLayout(			AudioUnitScope				inScope,
+														AudioUnitElement			inElement)
+{
+	OSStatus result = noErr;
+	AUIOElement * el = GetIOElement(inScope, inElement);
+	Boolean writable;
+	if (el->GetAudioChannelLayout(NULL, writable)) {
+		result = el->RemoveAudioChannelLayout();
+	}
+	return result;
+}
+
+OSStatus 	AUBase::SetAudioChannelLayout(				AudioUnitScope 				inScope, 
+														AudioUnitElement 			inElement,
+														const AudioChannelLayout *	inLayout)
+{
+	AUIOElement* ioEl = GetIOElement (inScope, inElement);
+
+	// the num channels of the layout HAS TO MATCH the current channels of the Element's stream format
+	UInt32 currentChannels = ioEl->GetStreamFormat().NumberChannels();
+	UInt32 numChannelsInLayout = CAAudioChannelLayout::NumberChannels(*inLayout);
+	if (currentChannels != numChannelsInLayout)
+		return kAudioUnitErr_InvalidPropertyValue;
+
+	UInt32 numLayouts = GetChannelLayoutTags (inScope, inElement, NULL);
+	if (numLayouts == 0)
+		return kAudioUnitErr_InvalidProperty;
+	AudioChannelLayoutTag *tags = (AudioChannelLayoutTag *)CA_malloc (numLayouts * sizeof (AudioChannelLayoutTag));
+	GetChannelLayoutTags (inScope, inElement, tags);
+	bool foundTag = false;
+	for (unsigned int i = 0; i < numLayouts; ++i) {
+		if (tags[i] == inLayout->mChannelLayoutTag || tags[i] == kAudioChannelLayoutTag_UseChannelDescriptions) {
+			foundTag = true;
+			break;
+		}
+	}
+	free(tags);
+	
+	if (foundTag == false)
+		return kAudioUnitErr_InvalidPropertyValue;
+
+	return ioEl->SetAudioChannelLayout(*inLayout);
+}
+
+static void AddNumToDictionary (CFMutableDictionaryRef dict, CFStringRef key, SInt32 value)
+{
+	CFNumberRef num = CFNumberCreate (NULL, kCFNumberSInt32Type, &value);
+	CFDictionarySetValue (dict, key, num);
+	CFRelease (num);
+}
+
+#define kCurrentSavedStateVersion 0
+
+OSStatus			AUBase::SaveState(		CFPropertyListRef * outData)
+{
+	AudioComponentDescription desc = GetComponentDescription();
+
+	CFMutableDictionaryRef dict = CFDictionaryCreateMutable	(NULL, 0, 
+								&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+// first step -> save the version to the data ref
+	SInt32 value = kCurrentSavedStateVersion;
+	AddNumToDictionary (dict, kVersionString, value);
+
+// second step -> save the component type, subtype, manu to the data ref
+	value = desc.componentType;
+	AddNumToDictionary (dict, kTypeString, value);
+
+	value = desc.componentSubType;
+	AddNumToDictionary (dict, kSubtypeString, value);
+	
+	value = desc.componentManufacturer;
+	AddNumToDictionary (dict, kManufacturerString, value);
+	
+// fourth step -> save the state of all parameters on all scopes and elements
+	CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
+	for (AudioUnitScope iscope = 0; iscope < 3; ++iscope) {
+		AUScope &scope = GetScope(iscope);
+		AudioUnitElement nElems = scope.GetNumberOfElements();
+		for (AudioUnitElement ielem = 0; ielem < nElems; ++ielem) {
+			AUElement *element = scope.GetElement(ielem);
+			UInt32 nparams = element->GetNumberOfParameters();
+			if (nparams > 0) {
+				struct {
+					UInt32	scope;
+					UInt32	element;
+				} hdr;
+				
+				hdr.scope = CFSwapInt32HostToBig(iscope);
+				hdr.element = CFSwapInt32HostToBig(ielem);
+				CFDataAppendBytes(data, (UInt8 *)&hdr, sizeof(hdr));
+				
+				element->SaveState(data);
+			}
+		}
+	}
+
+// save all this in the data section of the dictionary
+	CFDictionarySetValue(dict, kDataString, data);
+	CFRelease (data);
+	
+//OK - now we're going to do some properties 	
+//save the preset name...
+	CFDictionarySetValue (dict, kNameString, mCurrentPreset.presetName);
+
+// Does the unit support the RenderQuality property - if so, save it...
+	value = 0;
+	OSStatus result = DispatchGetProperty (kAudioUnitProperty_RenderQuality,
+								kAudioUnitScope_Global,
+								0,
+								&value);
+	
+	if (result == noErr) {
+		AddNumToDictionary (dict, kRenderQualityString, value);
+	}
+	
+// Does the unit support the CPULoad Quality property - if so, save it...
+	Float32 cpuLoad;
+	result = DispatchGetProperty (6/*kAudioUnitProperty_CPULoad*/,
+								kAudioUnitScope_Global,
+								0,
+								&cpuLoad);
+	
+	if (result == noErr) {
+		CFNumberRef num = CFNumberCreate (NULL, kCFNumberFloatType, &cpuLoad);
+		CFDictionarySetValue (dict, kCPULoadString, num);
+		CFRelease (num);
+	}
+
+// Do we have any element names for any of our scopes?	
+	// first check to see if we have any names...
+	bool foundName = false;
+	for (AudioUnitScope i = 0; i < kNumScopes; ++i) {
+		foundName = GetScope (i).HasElementWithName();
+		if (foundName) 
+			break;
+	}
+		// OK - we found a name away we go...
+	if (foundName) {
+		CFMutableDictionaryRef nameDict = CFDictionaryCreateMutable	(NULL, 0, 
+								&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+		for (AudioUnitScope i = 0; i < kNumScopes; ++i) {
+			GetScope (i).AddElementNamesToDict (nameDict);
+		}
+		
+		CFDictionarySetValue (dict, kElementNameString, nameDict);
+		CFRelease (nameDict);
+	}
+	
+// we're done!!!
+	*outData = dict;
+
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::RestoreState(	CFPropertyListRef	plist)
+{
+	if (CFGetTypeID(plist) != CFDictionaryGetTypeID()) return kAudioUnitErr_InvalidPropertyValue;
+	
+	AudioComponentDescription desc = GetComponentDescription();
+	
+	CFDictionaryRef dict = static_cast<CFDictionaryRef>(plist);
+
+// zeroeth step - make sure the Part key is NOT present, as this method is used
+// to restore the GLOBAL state of the dictionary	
+	if (CFDictionaryContainsKey (dict, kPartString))
+		return kAudioUnitErr_InvalidPropertyValue;
+		
+// first step -> check the saved version in the data ref
+// at this point we're only dealing with version==0
+	CFNumberRef cfnum = reinterpret_cast<CFNumberRef>(CFDictionaryGetValue (dict, kVersionString));
+	if (cfnum == NULL) return kAudioUnitErr_InvalidPropertyValue;
+	SInt32 value;
+	CFNumberGetValue (cfnum, kCFNumberSInt32Type, &value);
+	if (value != kCurrentSavedStateVersion) return kAudioUnitErr_InvalidPropertyValue;
+
+// second step -> check that this data belongs to this kind of audio unit
+// by checking the component subtype and manuID
+// We're not checking the type, since there may be different versions (effect, format-converter, offline)
+// of essentially the same AU
+	cfnum = reinterpret_cast<CFNumberRef>(CFDictionaryGetValue (dict, kSubtypeString));
+	if (cfnum == NULL) return kAudioUnitErr_InvalidPropertyValue;
+	CFNumberGetValue (cfnum, kCFNumberSInt32Type, &value);
+	if (UInt32(value) != desc.componentSubType) return kAudioUnitErr_InvalidPropertyValue;
+
+	cfnum = reinterpret_cast<CFNumberRef>(CFDictionaryGetValue (dict, kManufacturerString));
+	if (cfnum == NULL) return kAudioUnitErr_InvalidPropertyValue;
+	CFNumberGetValue (cfnum, kCFNumberSInt32Type, &value);
+	if (UInt32(value) != desc.componentManufacturer) return kAudioUnitErr_InvalidPropertyValue;
+
+// fourth step -> restore the state of all of the parameters for each scope and element	
+	CFDataRef data = reinterpret_cast<CFDataRef>(CFDictionaryGetValue (dict, kDataString));
+	if (data != NULL) 
+	{
+		const UInt8 *p, *pend;
+		
+		p = CFDataGetBytePtr(data);
+		pend = p + CFDataGetLength(data);
+		
+		// we have a zero length data, which may just mean there were no parameters to save!
+		//	if (p >= pend) return noErr; 
+	
+		while (p < pend) {
+			struct {
+				UInt32	scope;
+				UInt32	element;
+			} hdr;
+			
+			hdr.scope = CFSwapInt32BigToHost(*(UInt32 *)p);		p += sizeof(UInt32);
+			hdr.element = CFSwapInt32BigToHost(*(UInt32 *)p);	p += sizeof(UInt32);
+			
+			AUScope &scope = GetScope(hdr.scope);
+			AUElement *element = scope.GetElement(hdr.element);
+				// $$$ order of operations issue: what if the element does not yet exist?
+				// then we just break out of the loop
+			if (!element)
+				break;
+			p = element->RestoreState(p);
+		}
+	}
+
+//OK - now we're going to do some properties 	
+//restore the preset name...
+	CFStringRef name = reinterpret_cast<CFStringRef>(CFDictionaryGetValue (dict, kNameString));
+	if (mCurrentPreset.presetName) CFRelease (mCurrentPreset.presetName);
+	if (name)
+	{
+		mCurrentPreset.presetName = name;
+		mCurrentPreset.presetNumber = -1;
+	} 
+	else { // no name entry make the default one
+		mCurrentPreset.presetName = kUntitledString;
+		mCurrentPreset.presetNumber = -1;
+	}
+	
+	CFRetain (mCurrentPreset.presetName);
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+#ifndef __LP64__
+	PropertyChanged(kAudioUnitProperty_CurrentPreset, kAudioUnitScope_Global, 0);
+#endif
+#endif
+	PropertyChanged(kAudioUnitProperty_PresentPreset, kAudioUnitScope_Global, 0);
+
+// Does the dict contain render quality information?		
+	if (CFDictionaryGetValueIfPresent (dict, kRenderQualityString, reinterpret_cast<const void**>(&cfnum))) 
+	{
+		CFNumberGetValue (cfnum, kCFNumberSInt32Type, &value);
+		DispatchSetProperty (kAudioUnitProperty_RenderQuality,
+								kAudioUnitScope_Global,
+								0,
+								&value,
+								sizeof(value));
+	}
+	
+// Does the unit support the CPULoad Quality property - if so, save it...
+	if (CFDictionaryGetValueIfPresent (dict, kCPULoadString, reinterpret_cast<const void**>(&cfnum))) 
+	{
+		Float32 floatValue;
+		CFNumberGetValue (cfnum, kCFNumberFloatType, &floatValue);
+		DispatchSetProperty (6/*kAudioUnitProperty_CPULoad*/,
+								kAudioUnitScope_Global,
+								0,
+								&floatValue,
+								sizeof(floatValue));
+	}
+
+// Do we have any element names for any of our scopes?
+	CFDictionaryRef nameDict;
+	if (CFDictionaryGetValueIfPresent (dict, kElementNameString, reinterpret_cast<const void**>(&nameDict))) 
+	{
+		char string[64];
+		for (int i = 0; i < kNumScopes; ++i) 
+		{
+			sprintf (string, "%d", i);
+			CFStringRef key = CFStringCreateWithCString (NULL, string, kCFStringEncodingASCII);
+			CFDictionaryRef elementDict;
+			if (CFDictionaryGetValueIfPresent (nameDict, key, reinterpret_cast<const void**>(&elementDict))) 
+			{
+				bool didAddElements = GetScope (i).RestoreElementNames (elementDict);
+				if (didAddElements)
+					PropertyChanged (kAudioUnitProperty_ElementCount, i, 0);
+			}
+			CFRelease (key);				
+		}
+	}
+	
+	return noErr;
+}
+
+OSStatus			AUBase::GetPresets (			CFArrayRef * 					outData) const
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+OSStatus			AUBase::NewFactoryPresetSet (const AUPreset & inNewFactoryPreset)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+		// set the default preset for the unit -> the number of the preset MUST be >= 0
+		// and the name should be valid, or the preset WON'T take
+bool				AUBase::SetAFactoryPresetAsCurrent (const AUPreset & inPreset)
+{
+	if (inPreset.presetNumber < 0 || inPreset.presetName == NULL) return false;
+	CFRelease (mCurrentPreset.presetName);
+	mCurrentPreset = inPreset;
+	CFRetain (mCurrentPreset.presetName);
+	return true;
+}
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+int			AUBase::GetNumCustomUIComponents () 
+{
+	return 0;
+}
+
+void		AUBase::GetUIComponentDescs (ComponentDescription* inDescArray) {}
+#endif
+	
+bool		AUBase::HasIcon () 
+{
+#if !CA_NO_AU_UI_FEATURES
+	CFURLRef url = CopyIconLocation(); 
+	if (url) {
+		CFRelease (url);
+		return true;
+	}
+#endif
+	return false;
+}
+
+CFURLRef	AUBase::CopyIconLocation () 
+{
+	return NULL;
+}
+	
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::GetParameterList(		AudioUnitScope					inScope,
+													AudioUnitParameterID *			outParameterList,
+													UInt32 &						outNumParameters)
+{
+	AUScope &scope = GetScope(inScope);
+	AUElement *elementWithMostParameters = NULL;
+	UInt32 maxNumParams = 0;
+	
+	int nElems = scope.GetNumberOfElements();
+	for (int ielem = 0; ielem < nElems; ++ielem) {
+		AUElement *element = scope.GetElement(ielem);
+		UInt32 nParams = element->GetNumberOfParameters();
+		if (nParams > maxNumParams) {
+			maxNumParams = nParams;
+			elementWithMostParameters = element;
+		}
+	}
+	
+	if (outParameterList != NULL && elementWithMostParameters != NULL)
+		elementWithMostParameters->GetParameterList(outParameterList);
+	
+	outNumParameters = maxNumParams;
+	return noErr;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::GetParameterInfo(		AudioUnitScope			inScope,
+													AudioUnitParameterID	inParameterID,
+													AudioUnitParameterInfo	&outParameterInfo )
+{
+	return kAudioUnitErr_InvalidParameter;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::GetParameterValueStrings(AudioUnitScope			inScope,
+													AudioUnitParameterID	inParameterID,
+													CFArrayRef *			outStrings)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::GetParameterHistoryInfo(	AudioUnitScope					inScope,
+														AudioUnitParameterID			inParameterID,
+														Float32 &						outUpdatesPerSecond,
+														Float32 &						outHistoryDurationInSeconds)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+
+//_____________________________________________________________________________
+//
+OSStatus			AUBase::CopyClumpName(			AudioUnitScope			inScope, 
+													UInt32					inClumpID, 
+													UInt32					inDesiredNameLength,
+													CFStringRef *			outClumpName)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+//_____________________________________________________________________________
+//
+void				AUBase::SetNumberOfElements(	AudioUnitScope					inScope,
+													UInt32							numElements)
+{
+	if (inScope == kAudioUnitScope_Global && numElements != 1)
+		COMPONENT_THROW(kAudioUnitErr_InvalidScope);
+
+	GetScope(inScope).SetNumberOfElements(numElements);
+}
+
+//_____________________________________________________________________________
+//
+AUElement *			AUBase::CreateElement(			AudioUnitScope					scope,
+													AudioUnitElement				element)
+{
+	switch (scope) {
+	case kAudioUnitScope_Global:
+		return new AUElement(this);
+	case kAudioUnitScope_Input:
+		return new AUInputElement(this);
+	case kAudioUnitScope_Output:
+		return new AUOutputElement(this);
+#if !CA_BASIC_AU_FEATURES
+	case kAudioUnitScope_Group:
+		return new AUElement(this);
+	case kAudioUnitScope_Part:
+		return new AUElement(this);
+#endif
+	}
+	COMPONENT_THROW(kAudioUnitErr_InvalidScope);
+	
+	return NULL;	// get rid of compiler warning
+}
+
+//_____________________________________________________________________________
+//
+bool	AUBase::FormatIsCanonical(		const CAStreamBasicDescription &f)
+{
+	return (f.mFormatID == kAudioFormatLinearPCM
+		&&	f.mFramesPerPacket == 1
+		&&	f.mBytesPerPacket == f.mBytesPerFrame
+//		&&	f.mChannelsPerFrame >= 0	-- this is always true since it's unsigned
+		// so far, it's a valid PCM format
+#if CA_PREFER_FIXED_POINT
+		&&	(f.mFormatFlags & kLinearPCMFormatFlagIsFloat) == 0
+		&&	(((f.mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift) == kAudioUnitSampleFractionBits)
+#else
+		&&	(f.mFormatFlags & kLinearPCMFormatFlagIsFloat) != 0
+#endif
+        &&	((f.mChannelsPerFrame == 1) || ((f.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0) == (mAudioUnitAPIVersion == 1))
+#if TARGET_RT_BIG_ENDIAN
+		&&	(f.mFormatFlags & kLinearPCMFormatFlagIsBigEndian) != 0
+#else
+		&&	(f.mFormatFlags & kLinearPCMFormatFlagIsBigEndian) == 0
+#endif
+		&&	f.mBitsPerChannel == 8 * sizeof(AudioUnitSampleType)
+		&&	f.mBytesPerFrame == f.NumberInterleavedChannels() * sizeof(AudioUnitSampleType)
+		);
+}
+
+//_____________________________________________________________________________
+//
+void	AUBase::MakeCanonicalFormat(	CAStreamBasicDescription &		f,
+										int								nChannels)
+{
+	f.SetAUCanonical(nChannels, mAudioUnitAPIVersion < 2);	// interleaved for v1, non for v2
+	f.mSampleRate = 0.0;
+}
+
+const Float64 AUBase::kNoLastRenderedSampleTime = -1.;
+
+#include "AUBaseHelper.h"
+
+char*	AUBase::GetLoggingString () const
+{
+	if (mLogString) return mLogString;
+	
+	AudioComponentDescription desc = GetComponentDescription();
+	
+	const_cast<AUBase*>(this)->mLogString = new char[256];
+	char str[24];
+	char str1[24];
+	char str2[24];
+	sprintf (const_cast<AUBase*>(this)->mLogString, "AU (%p): %s %s %s",
+		GetComponentInstance(),
+		CAStringForOSType(desc.componentType, str),
+		CAStringForOSType(desc.componentSubType, str1),
+		CAStringForOSType(desc.componentManufacturer, str2));
+
+	return mLogString;
+}
+
diff --git a/architecture/AU/AUPublic/AUBase/AUBase.h b/architecture/AU/AUPublic/AUBase/AUBase.h
new file mode 100644
index 0000000..3bf074e
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUBase.h
@@ -0,0 +1,1019 @@
+/*
+     File: AUBase.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUBase_h__
+#define __AUBase_h__
+
+#include <TargetConditionals.h>
+
+#if TARGET_OS_MAC
+	#include <pthread.h>
+#elif TARGET_OS_WIN32
+	#include <windows.h>
+#else
+	#error Unsupported Operating System
+#endif
+
+#include <vector>
+
+#include "AUScopeElement.h"
+#include "AUInputElement.h"
+#include "AUOutputElement.h"
+#include "AUBuffer.h"
+#include "CAMath.h"
+#include "CAThreadSafeList.h"
+#include "CAVectorUnit.h"
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <AudioUnit/AudioUnit.h>
+	#if !CA_BASIC_AU_FEATURES
+		#include <AudioUnit/MusicDevice.h>
+	#endif
+#else
+	#include "AudioUnit.h"
+	#if !CA_BASIC_AU_FEATURES
+		#include "MusicDevice.h"
+	#endif
+#endif
+
+#ifndef AUTRACE
+	#define AUTRACE(code, obj, a, b, c, d)
+#endif	
+
+#include "AUPlugInDispatch.h"
+
+
+
+// ________________________________________________________________________
+// These are to be moved to the public AudioUnit headers
+
+#define kAUDefaultSampleRate		44100.0
+#if !TARGET_OS_WIN32
+#define kAUDefaultMaxFramesPerSlice	1156 
+//this allows enough default frames for a 512 dest 44K and SRC from 96K
+// add a padding of 4 frames for any altivec rounding
+#else
+#define kAUDefaultMaxFramesPerSlice	2048 
+#endif
+
+// ________________________________________________________________________
+
+/*! @class AUBase */
+class AUBase : public ComponentBase {
+public:
+
+	/*! @ctor AUBase */
+								AUBase(					AudioComponentInstance			inInstance, 
+														UInt32							numInputElements,
+														UInt32							numOutputElements,
+														UInt32							numGroupElements = 0);
+	/*! @dtor AUBase */
+	virtual						~AUBase();
+	
+	/*! @method PostConstructor */
+	virtual void				PostConstructor() { CreateElements(); }
+								
+	/*! @method PreDestructor */
+	virtual void				PreDestructor();
+
+	/*! @method CreateElements */
+	void						CreateElements();
+									// Called immediately after construction, when virtual methods work.
+									// Or, a subclass may call this in order to have access to elements
+									// in its constructor.
+
+	/*! @method CreateExtendedElements */
+	virtual void CreateExtendedElements() {}
+
+#pragma mark -
+#pragma mark AU dispatch
+	// ________________________________________________________________________
+	// Virtual methods (mostly) directly corresponding to the entry points.  Many of these
+	// have useful implementations here and will not need overriding.
+	
+	/*! @method DoInitialize */
+			OSStatus			DoInitialize();
+				// this implements the entry point and makes sure that initialization
+				// is only attempted exactly once...
+
+	/*! @method Initialize */
+	virtual OSStatus			Initialize();
+				// ... so that overrides to this method can assume that they will only
+				// be called exactly once.
+	
+	/*! @method IsInitialized */
+			bool				IsInitialized() const { return mInitialized; }
+	/*! @method HasBegunInitializing */
+			bool				HasBegunInitializing() const { return mHasBegunInitializing; }
+			
+	/*! @method DoCleanup */
+			void				DoCleanup();
+				// same pattern as with Initialize
+	
+	/*! @method Cleanup */
+	virtual void				Cleanup();
+
+	/*! @method Reset */
+	virtual OSStatus			Reset(					AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement);
+
+	// Note about GetPropertyInfo, GetProperty, SetProperty:
+	// Certain properties are trapped out in these dispatch functions and handled with different virtual 
+	// methods.  (To discourage hacks and keep vtable size down, these are non-virtual)
+
+	/*! @method DispatchGetPropertyInfo */
+			OSStatus			DispatchGetPropertyInfo(AudioUnitPropertyID				inID,
+														AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														UInt32 &						outDataSize,
+														Boolean &						outWritable);
+
+	/*! @method DispatchGetProperty */
+			OSStatus			DispatchGetProperty(	AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement,
+														void *							outData);
+
+	/*! @method DispatchSetProperty */
+			OSStatus			DispatchSetProperty(	AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement,
+														const void *					inData,
+														UInt32 							inDataSize);
+													
+			OSStatus			DispatchRemovePropertyValue(	AudioUnitPropertyID 	inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement);
+
+	/*! @method GetPropertyInfo */
+	virtual OSStatus			GetPropertyInfo(		AudioUnitPropertyID				inID,
+														AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														UInt32 &						outDataSize,
+														Boolean &						outWritable);
+
+	/*! @method GetProperty */
+	virtual OSStatus			GetProperty(			AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement,
+														void *							outData);
+
+	/*! @method SetProperty */
+	virtual OSStatus			SetProperty(			AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement,
+														const void *					inData,
+														UInt32 							inDataSize);
+													
+	/*! @method ClearPropertyUsage */
+	virtual OSStatus			RemovePropertyValue (	AudioUnitPropertyID		 		inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement);
+
+	/*! @method AddPropertyListener */
+	virtual OSStatus			AddPropertyListener(	AudioUnitPropertyID				inID,
+														AudioUnitPropertyListenerProc	inProc,
+														void *							inProcRefCon);
+														
+	/*! @method RemovePropertyListener */
+	virtual OSStatus			RemovePropertyListener(	AudioUnitPropertyID				inID,
+														AudioUnitPropertyListenerProc	inProc,
+														void *							inProcRefCon,
+														bool							refConSpecified);
+	
+	/*! @method SetRenderNotification */
+	virtual OSStatus			SetRenderNotification(	AURenderCallback		 		inProc,
+														void *							inRefCon);
+	
+	/*! @method RemoveRenderNotification */
+	virtual OSStatus			RemoveRenderNotification(
+														AURenderCallback		 		inProc,
+														void *							inRefCon);
+	
+	/*! @method GetParameter */
+	virtual OSStatus 	GetParameter(			AudioUnitParameterID			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement,
+														AudioUnitParameterValue &		outValue);
+												
+	/*! @method SetParameter */
+	virtual OSStatus 	SetParameter(			AudioUnitParameterID			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement,
+														AudioUnitParameterValue			inValue,
+														UInt32							inBufferOffsetInFrames);
+
+	/*! @method ScheduleParameter */
+	virtual OSStatus 	ScheduleParameter (		const AudioUnitParameterEvent 	*inParameterEvent,
+														UInt32							inNumEvents);
+	
+
+	/*! @method DoRender */
+	OSStatus 	DoRender(								AudioUnitRenderActionFlags &	ioActionFlags,
+														const AudioTimeStamp &			inTimeStamp,
+														UInt32							inBusNumber,
+														UInt32							inNumberFrames,
+														AudioBufferList &				ioData);
+	
+
+	/*! @method Process */
+	OSStatus	DoProcess (							AudioUnitRenderActionFlags  &		ioActionFlags,
+													const AudioTimeStamp &				inTimeStamp,
+													UInt32								inFramesToProcess,
+													AudioBufferList &					ioData);
+	
+	/*! @method ProcessMultiple */
+	OSStatus	DoProcessMultiple (					AudioUnitRenderActionFlags  &		ioActionFlags,
+													const AudioTimeStamp &				inTimeStamp,
+													UInt32								inFramesToProcess,
+													UInt32								inNumberInputBufferLists,
+													const AudioBufferList **			inInputBufferLists,
+													UInt32 								inNumberOutputBufferLists,
+													AudioBufferList **					ioOutputBufferLists);
+		
+	/*! @method ProcessBufferLists */
+	virtual OSStatus	ProcessBufferLists(			AudioUnitRenderActionFlags &		ioActionFlags,
+													const AudioBufferList &				inBuffer,
+													AudioBufferList &					outBuffer,
+													UInt32								inFramesToProcess )
+						{
+							return kAudio_UnimplementedError;
+						}
+
+	/*! @method ProcessMultipleBufferLists */
+	virtual OSStatus	ProcessMultipleBufferLists(	AudioUnitRenderActionFlags &		ioActionFlags,
+													UInt32								inFramesToProcess, 
+												    UInt32								inNumberInputBufferLists,
+												    const AudioBufferList **			inInputBufferLists,
+												    UInt32							 	inNumberOutputBufferLists,
+												    AudioBufferList **					ioOutputBufferLists)	
+						{
+							return kAudio_UnimplementedError;
+						}
+	
+	/*! @method ComplexRender */
+	virtual OSStatus	ComplexRender(				AudioUnitRenderActionFlags &		ioActionFlags, 
+													const AudioTimeStamp &				inTimeStamp, 
+													UInt32								inOutputBusNumber, 
+													UInt32								inNumberOfPackets, 
+													UInt32 *							outNumberOfPackets, 
+													AudioStreamPacketDescription *		outPacketDescriptions, 
+													AudioBufferList &					ioData, 
+													void *								outMetadata, 
+													UInt32 *							outMetadataByteSize) 
+						{	
+							return kAudio_UnimplementedError;
+						}
+
+	// Override this method if your AU processes multiple output busses completely independently --
+	// you'll want to just call Render without the NeedsToRender check.
+	// Otherwise, override Render().
+	//
+	// N.B. Implementations of this method can assume that the output's buffer list has already been
+	// prepared and access it with GetOutput(inBusNumber)->GetBufferList() instead of 
+	// GetOutput(inBusNumber)->PrepareBuffer(nFrames) -- if PrepareBuffer is called, a
+	// copy may occur after rendering.
+	/*! @method RenderBus */
+	virtual OSStatus			RenderBus(				AudioUnitRenderActionFlags &	ioActionFlags,
+														const AudioTimeStamp &			inTimeStamp,
+														UInt32							inBusNumber,
+														UInt32							inNumberFrames)
+								{
+									if (NeedsToRender(inTimeStamp))
+										return Render(ioActionFlags, inTimeStamp, inNumberFrames);
+									return noErr;	// was presumably already rendered via another bus
+								}
+
+	// N.B. For a unit with only one output bus, it can assume in its implementation of this
+	// method that the output's buffer list has already been prepared and access it with 
+	// GetOutput(0)->GetBufferList() instead of GetOutput(0)->PrepareBuffer(nFrames)
+	//  -- if PrepareBuffer is called, a copy may occur after rendering.
+	/*! @method Render */
+	virtual OSStatus			Render(					AudioUnitRenderActionFlags &	ioActionFlags,
+														const AudioTimeStamp &			inTimeStamp,
+														UInt32							inNumberFrames)
+								{
+									return noErr;
+								}
+
+								
+#pragma mark -
+#pragma mark Property Dispatch
+
+	static const Float64 kNoLastRenderedSampleTime;
+
+	// ________________________________________________________________________
+	// These are generated from DispatchGetProperty/DispatchGetPropertyInfo/DispatchSetProperty
+
+	/*! @method BusCountWritable */
+	virtual bool				BusCountWritable(		AudioUnitScope					inScope)
+								{
+									return false;
+								}
+	virtual OSStatus			SetBusCount(		AudioUnitScope					inScope,
+													UInt32							inCount);
+
+	/*! @method SetConnection */
+	virtual OSStatus			SetConnection(			const AudioUnitConnection &		inConnection);
+	
+	/*! @method SetInputCallback */
+	virtual OSStatus			SetInputCallback(		UInt32							inPropertyID,
+														AudioUnitElement 				inElement, 
+														AURenderCallback				inProc,
+														void *							inRefCon);
+
+	/*! @method GetParameterList */
+	virtual OSStatus			GetParameterList(		AudioUnitScope					inScope,
+														AudioUnitParameterID *			outParameterList,
+														UInt32 &						outNumParameters);
+															// outParameterList may be a null pointer
+
+	/*! @method GetParameterInfo */
+	virtual OSStatus			GetParameterInfo(		AudioUnitScope					inScope,
+														AudioUnitParameterID			inParameterID,
+														AudioUnitParameterInfo &		outParameterInfo);
+
+	virtual OSStatus			GetParameterHistoryInfo(AudioUnitScope					inScope,
+														AudioUnitParameterID			inParameterID,
+														Float32 &						outUpdatesPerSecond,
+														Float32 &						outHistoryDurationInSeconds);
+
+	/*! @method SaveState */
+	virtual OSStatus			SaveState(				CFPropertyListRef *				outData);
+
+	/*! @method RestoreState */
+	virtual OSStatus			RestoreState(			CFPropertyListRef				inData);
+
+	/*! @method GetParameterValueStrings */
+	virtual OSStatus			GetParameterValueStrings(AudioUnitScope					inScope,
+														AudioUnitParameterID			inParameterID,
+														CFArrayRef *					outStrings);
+
+	/*! @method CopyClumpName */
+	virtual OSStatus			CopyClumpName(			AudioUnitScope					inScope, 
+														UInt32							inClumpID, 
+														UInt32							inDesiredNameLength,
+														CFStringRef *					outClumpName);
+
+	/*! @method GetPresets */
+	virtual OSStatus			GetPresets (			CFArrayRef * 					outData) const;
+
+		// set the default preset for the unit -> the number of the preset MUST be >= 0
+		// and the name should be valid, or the preset WON'T take
+	/*! @method SetAFactoryPresetAsCurrent */
+	bool						SetAFactoryPresetAsCurrent (const AUPreset & inPreset);
+		
+		// Called when someone sets a new, valid preset
+		// If this is a valid preset, then the subclass sets its state to that preset
+		// and returns noErr.
+		// If not a valid preset, return an error, and the pre-existing preset is restored
+	/*! @method NewFactoryPresetSet */
+	virtual OSStatus			NewFactoryPresetSet (const AUPreset & inNewFactoryPreset);
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	/*! @method GetNumCustomUIComponents */
+	virtual int					GetNumCustomUIComponents ();
+
+	/*! @method GetUIComponentDescs */
+	virtual void				GetUIComponentDescs (ComponentDescription* inDescArray);
+#endif
+	
+	/*! @method CopyIconLocation */
+	virtual CFURLRef			CopyIconLocation ();
+	
+	// default is no latency, and unimplemented tail time
+	/*! @method GetLatency */
+    virtual Float64				GetLatency() {return 0.0;}
+	/*! @method GetTailTime */
+    virtual Float64				GetTailTime() {return 0;}
+	/*! @method SupportsRampAndTail */
+	virtual	bool				SupportsTail () { return false; }
+
+	/*! @method IsStreamFormatWritable */
+			bool				IsStreamFormatWritable(	AudioUnitScope					scope,
+														AudioUnitElement				element);
+	
+	/*! @method StreamFormatWritable */
+	virtual bool				StreamFormatWritable(	AudioUnitScope					scope,
+														AudioUnitElement				element) = 0;
+															// scope will always be input or output
+			
+			// pass in a pointer to get the struct, and num channel infos
+			// you can pass in NULL to just get the number
+			// a return value of 0 (the default in AUBase) means the property is not supported...
+	/*! @method SupportedNumChannels */
+	virtual UInt32				SupportedNumChannels (	const AUChannelInfo**			outInfo);
+																												
+	/*! @method ValidFormat */
+	virtual bool				ValidFormat(			AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														const CAStreamBasicDescription & inNewFormat);
+															// Will only be called after StreamFormatWritable
+															// has succeeded.
+															// Default implementation requires canonical format:
+															// native-endian 32-bit float, any sample rate,
+															// any number of channels; override when other
+															// formats are supported.  A subclass's override can
+															// choose to always return true and trap invalid 
+															// formats in ChangeStreamFormat.
+
+
+	/*! @method FormatIsCanonical */
+			bool				FormatIsCanonical(		const CAStreamBasicDescription &format);
+
+	/*! @method MakeCanonicalFormat */
+			void				MakeCanonicalFormat(	CAStreamBasicDescription &	outDesc,
+														int							numChannels = 2);
+
+	/*! @method GetStreamFormat */
+	virtual const CAStreamBasicDescription &
+								GetStreamFormat(		AudioUnitScope					inScope,
+														AudioUnitElement				inElement);
+
+	/*! @method ChangeStreamFormat */
+	virtual	OSStatus			ChangeStreamFormat(		AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														const CAStreamBasicDescription & inPrevFormat,
+														const CAStreamBasicDescription & inNewFormat);
+															// Will only be called after StreamFormatWritable
+															// and ValidFormat have succeeded.
+															
+	// ________________________________________________________________________
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	/*! @method ComponentEntryDispatch */
+	static OSStatus			ComponentEntryDispatch(	ComponentParameters *			params,
+														AUBase *						This);
+#endif
+
+	// ________________________________________________________________________
+	// Methods useful for subclasses
+	
+	/*! @method GetScope */
+	AUScope &					GetScope(				AudioUnitScope					inScope)
+	{
+		if (inScope >= kNumScopes) {
+			AUScope * scope = GetScopeExtended(inScope);
+			if (!scope) COMPONENT_THROW(kAudioUnitErr_InvalidScope);
+			return *scope;
+		}
+		return mScopes[inScope];
+	}
+	
+	/*! @method GetScopeExtended */
+	virtual AUScope *			GetScopeExtended (AudioUnitScope inScope) { return NULL; }
+	
+	/*! @method GlobalScope */
+	AUScope &					GlobalScope() { return mScopes[kAudioUnitScope_Global]; }
+	/*! @method Inputs */
+	AUScope &					Inputs()	{ return mScopes[kAudioUnitScope_Input]; }
+	/*! @method Outputs */
+	AUScope &					Outputs()	{ return mScopes[kAudioUnitScope_Output]; }
+#if !CA_BASIC_AU_FEATURES
+	/*! @method Groups */
+	AUScope &					Groups()	{ return mScopes[kAudioUnitScope_Group]; }
+#endif
+	/*! @method Globals */
+	AUElement *					Globals()	{ return mScopes[kAudioUnitScope_Global].GetElement(0); }
+	
+	/*! @method SetNumberOfElements */
+	void						SetNumberOfElements(	AudioUnitScope					inScope,
+														UInt32							numElements);
+
+	/*! @method GetElement */
+	AUElement *					GetElement(				AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement)
+	{
+		return GetScope(inScope).GetElement(inElement);
+	}
+	
+	/*! @method GetIOElement */
+	AUIOElement *				GetIOElement(			AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement)
+	{
+		return GetScope(inScope).GetIOElement(inElement);
+	}
+	
+	/*! @method SafeGetElement */
+	AUElement *					SafeGetElement(			AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement)
+	{
+		return GetScope(inScope).SafeGetElement(inElement);
+	}
+
+	/*! @method GetInput */
+	AUInputElement *			GetInput(				AudioUnitElement				inElement)
+	{
+		return static_cast<AUInputElement *>(Inputs().SafeGetElement(inElement));
+	}
+	
+	/*! @method GetOutput */
+	AUOutputElement *			GetOutput(				AudioUnitElement				inElement)
+	{
+		return static_cast<AUOutputElement *>(Outputs().SafeGetElement(inElement));
+	}
+	
+#if !CA_BASIC_AU_FEATURES
+	/*! @method GetGroup */
+	AUElement *					GetGroup(				AudioUnitElement				inElement)
+	{
+		return Groups().SafeGetElement(inElement);
+	}
+#endif
+	
+	/*! @method PullInput */
+	OSStatus					PullInput(				UInt32	 					inBusNumber,
+														AudioUnitRenderActionFlags &ioActionFlags,
+														const AudioTimeStamp &		inTimeStamp,
+														UInt32						inNumberFrames)
+	{
+		AUInputElement *input = GetInput(inBusNumber);	// throws if error
+		return input->PullInput(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames);
+	}
+
+	/*! @method GetMaxFramesPerSlice */
+	UInt32						GetMaxFramesPerSlice() const { return mMaxFramesPerSlice; }
+	
+	/*! @method GetVectorUnitType */
+	static SInt32				GetVectorUnitType() { return sVectorUnitType; }
+	/*! @method HasVectorUnit */
+	static bool					HasVectorUnit() { return sVectorUnitType > 0; }
+	/*! @method HasAltivec */
+	static bool					HasAltivec() { return sVectorUnitType == kVecAltivec; }
+	/*! @method HasSSE2 */
+	static bool					HasSSE2() { return sVectorUnitType >= kVecSSE2; }
+	/*! @method HasSSE3 */
+	static bool					HasSSE3() { return sVectorUnitType == kVecSSE3; }
+	
+	/*! @method AudioUnitAPIVersion */
+	UInt8						AudioUnitAPIVersion() const { return mAudioUnitAPIVersion; }
+	
+	/*! @method IsRenderThread */
+	bool						InRenderThread () const 
+								{
+#if TARGET_OS_MAC
+									return (mRenderThreadID ? pthread_equal (mRenderThreadID, pthread_self()) : false);
+#elif TARGET_OS_WIN32
+									return (mRenderThreadID ? mRenderThreadID == GetCurrentThreadId() : false);
+#endif
+								}
+
+	/*! @method HasInput */
+	bool						HasInput(				AudioUnitElement				inElement) {
+									AUInputElement *in = static_cast<AUInputElement *>(Inputs().GetElement(inElement));
+									return in != NULL && in->IsActive();
+								}
+									// says whether an input is connected or has a callback
+
+	/*! @method PropertyChanged */
+	virtual void				PropertyChanged(		AudioUnitPropertyID				inID,
+														AudioUnitScope					inScope, 
+														AudioUnitElement				inElement);
+
+#if !CA_NO_AU_UI_FEATURES
+	// These calls can be used to call a Host's Callbacks. The method returns -1 if the host
+	// hasn't supplied the callback. Any other result is returned by the host.
+	// As in the API contract, for a parameter's value, you specify a pointer
+	// to that data type. Specify NULL for a parameter that you are not interested
+	// as this can save work in the host.
+
+	/*! @method CallHostBeatAndTempo */
+	OSStatus	CallHostBeatAndTempo (Float64				*outCurrentBeat,  
+										Float64				*outCurrentTempo)
+	{
+		return (mHostCallbackInfo.beatAndTempoProc 
+						? (*mHostCallbackInfo.beatAndTempoProc) (mHostCallbackInfo.hostUserData, 
+																	outCurrentBeat, 
+																	outCurrentTempo)
+						: -1);
+	}
+
+	/*! @method CallHostMusicalTimeLocation */
+	OSStatus	CallHostMusicalTimeLocation (UInt32  		*outDeltaSampleOffsetToNextBeat,
+										Float32           	*outTimeSig_Numerator,
+										UInt32            	*outTimeSig_Denominator,
+										Float64           	*outCurrentMeasureDownBeat)
+	{
+		return (mHostCallbackInfo.musicalTimeLocationProc 
+						? (*mHostCallbackInfo.musicalTimeLocationProc) (mHostCallbackInfo.hostUserData,
+																			outDeltaSampleOffsetToNextBeat,
+																			outTimeSig_Numerator,
+																			outTimeSig_Denominator,
+																			outCurrentMeasureDownBeat)
+						: -1);
+	}											
+
+	/*! @method CallHostTransportState */
+	OSStatus	CallHostTransportState (Boolean 			*outIsPlaying,
+										Boolean 			*outTransportStateChanged,
+										Float64 			*outCurrentSampleInTimeLine,
+										Boolean 			*outIsCycling,
+										Float64 			*outCycleStartBeat,
+										Float64 			*outCycleEndBeat)
+	{
+		return (mHostCallbackInfo.transportStateProc 
+						? (*mHostCallbackInfo.transportStateProc) (mHostCallbackInfo.hostUserData,
+																		outIsPlaying,
+																		outTransportStateChanged,
+																		outCurrentSampleInTimeLine,
+																		outIsCycling,
+																		outCycleStartBeat,
+																		outCycleEndBeat)
+						: -1);
+	}
+#endif
+
+	char*						GetLoggingString () const;
+
+	// ________________________________________________________________________
+	/*! @method CreateElement */
+	virtual AUElement *			CreateElement(			AudioUnitScope					scope,
+														AudioUnitElement				element);
+
+#pragma mark -
+#pragma mark AU Output Base Dispatch
+	// ________________________________________________________________________
+	// ________________________________________________________________________
+	// ________________________________________________________________________
+	// output unit methods
+	/*! @method Start */
+	virtual OSStatus	Start() { return kAudio_UnimplementedError; }
+	/*! @method Stop */
+	virtual OSStatus	Stop() { return kAudio_UnimplementedError; }
+	
+#if !CA_BASIC_AU_FEATURES
+#pragma mark -
+#pragma mark AU Music Base Dispatch
+
+#if !TARGET_OS_IPHONE
+// these methods are deprecated, so we don't include them except for compatability
+	/*! @method PrepareInstrument */
+	virtual OSStatus			PrepareInstrument(MusicDeviceInstrumentID inInstrument) { return kAudio_UnimplementedError; }
+
+	/*! @method PrepareInstrument */
+	virtual OSStatus			ReleaseInstrument(MusicDeviceInstrumentID inInstrument) { return kAudio_UnimplementedError; }
+#endif
+	
+	// ________________________________________________________________________
+	// ________________________________________________________________________
+	// ________________________________________________________________________
+	// music device/music effect methods -- incomplete
+	/*! @method MIDIEvent */
+	virtual OSStatus	MIDIEvent(		UInt32 						inStatus, 
+										UInt32 						inData1, 
+										UInt32 						inData2, 
+										UInt32 						inOffsetSampleFrame) { return kAudio_UnimplementedError; }
+
+	/*! @method SysEx */
+	virtual OSStatus	SysEx(			const UInt8 *				inData, 
+										UInt32 						inLength) { return kAudio_UnimplementedError;}
+										
+	/*! @method StartNote */
+	virtual OSStatus	StartNote(		MusicDeviceInstrumentID 	inInstrument, 
+										MusicDeviceGroupID 			inGroupID, 
+										NoteInstanceID *			outNoteInstanceID, 
+										UInt32 						inOffsetSampleFrame, 
+										const MusicDeviceNoteParams &inParams) { return kAudio_UnimplementedError; }
+
+	/*! @method StopNote */
+	virtual OSStatus	StopNote(		MusicDeviceGroupID 			inGroupID, 
+										NoteInstanceID 				inNoteInstanceID, 
+										UInt32 						inOffsetSampleFrame) { return kAudio_UnimplementedError; }
+#endif
+
+	// ________________________________________________________________________
+	// ________________________________________________________________________
+	// ________________________________________________________________________
+	
+protected:
+#pragma mark -
+#pragma mark Implementation methods
+
+	/*! @method ReallocateBuffers */
+	virtual void				ReallocateBuffers();
+									// needs to be called when mMaxFramesPerSlice changes
+		
+	/*! @method FillInParameterName */
+	static void					FillInParameterName (AudioUnitParameterInfo& ioInfo, CFStringRef inName, bool inShouldRelease)
+	{
+		ioInfo.cfNameString = inName;
+		ioInfo.flags |= kAudioUnitParameterFlag_HasCFNameString;
+		if (inShouldRelease)
+			ioInfo.flags |= kAudioUnitParameterFlag_CFNameRelease;
+		CFStringGetCString (inName, ioInfo.name, offsetof (AudioUnitParameterInfo, clumpID), kCFStringEncodingUTF8);
+	}
+	
+	static void					HasClump (AudioUnitParameterInfo& ioInfo, UInt32 inClumpID)				
+	{
+		ioInfo.clumpID = inClumpID;
+		ioInfo.flags |= kAudioUnitParameterFlag_HasClump;
+	}
+	
+	/*! @method SetMaxFramesPerSlice */
+	virtual void				SetMaxFramesPerSlice(UInt32 nFrames);
+
+	/*! @method CanSetMaxFrames */
+	virtual OSStatus			CanSetMaxFrames() const;
+	
+	/*! @method WantsRenderThreadID */
+	bool						WantsRenderThreadID () const { return mWantsRenderThreadID; }
+	
+	/*! @method SetWantsRenderThreadID */
+	void						SetWantsRenderThreadID (bool inFlag);
+	
+	/*! @method SetRenderError */
+	OSStatus					SetRenderError (OSStatus inErr)
+	{
+		if (inErr && mLastRenderError == 0) {
+			mLastRenderError = inErr;
+			PropertyChanged(kAudioUnitProperty_LastRenderError, kAudioUnitScope_Global, 0);
+		}
+		return inErr;
+	}
+	
+private:
+	/*! @method DoRenderBus */
+	// shared between Render and RenderSlice, inlined to minimize function call overhead
+	OSStatus					DoRenderBus(			AudioUnitRenderActionFlags &	ioActionFlags,
+														const AudioTimeStamp &			inTimeStamp,
+														UInt32							inBusNumber,
+														AUOutputElement *				theOutput,
+														UInt32							inNumberFrames,
+														AudioBufferList &				ioData)
+	{
+		if (ioData.mBuffers[0].mData == NULL || (theOutput->WillAllocateBuffer() && Outputs().GetNumberOfElements() > 1))
+			// will render into cache buffer
+			theOutput->PrepareBuffer(inNumberFrames);
+		else
+			// will render into caller's buffer
+			theOutput->SetBufferList(ioData);
+		OSStatus result = RenderBus(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames);
+		if (result == noErr) {
+			if (ioData.mBuffers[0].mData == NULL) {
+				theOutput->CopyBufferListTo(ioData);
+				AUTRACE(kCATrace_AUBaseDoRenderBus, mComponentInstance, inNumberFrames, (intptr_t)theOutput->GetBufferList().mBuffers[0].mData, 0, *(UInt32 *)ioData.mBuffers[0].mData);
+			} else {
+				theOutput->CopyBufferContentsTo(ioData);
+				AUTRACE(kCATrace_AUBaseDoRenderBus, mComponentInstance, inNumberFrames, (intptr_t)theOutput->GetBufferList().mBuffers[0].mData, (intptr_t)ioData.mBuffers[0].mData, *(UInt32 *)ioData.mBuffers[0].mData);
+				theOutput->InvalidateBufferList();
+			}
+		}
+		return result;
+	}
+
+	/*! @method HasIcon */
+	bool						HasIcon ();
+
+	/*! @method ResetRenderTime */
+	void						ResetRenderTime ()
+								{
+									memset (&mCurrentRenderTime, 0, sizeof(mCurrentRenderTime));
+									mCurrentRenderTime.mSampleTime = kNoLastRenderedSampleTime;
+								}
+				
+protected:
+	/*! @method GetAudioChannelLayout */
+	virtual UInt32				GetChannelLayoutTags(	AudioUnitScope				scope,
+														AudioUnitElement 			element,
+														AudioChannelLayoutTag *		outLayoutTags);
+														
+	/*! @method GetAudioChannelLayout */
+	virtual UInt32				GetAudioChannelLayout(	AudioUnitScope				scope,
+														AudioUnitElement 			element,
+														AudioChannelLayout *		outLayoutPtr,
+														Boolean &					outWritable);
+
+	/*! @method SetAudioChannelLayout */
+	virtual OSStatus			SetAudioChannelLayout(	AudioUnitScope 				scope, 
+														AudioUnitElement 			element,
+														const AudioChannelLayout *	inLayout);
+
+	/*! @method RemoveAudioChannelLayout */
+	virtual OSStatus			RemoveAudioChannelLayout(AudioUnitScope scope, AudioUnitElement element);
+	
+	/*! @method NeedsToRender */
+	bool						NeedsToRender(			const AudioTimeStamp &		inTimeStamp)
+								{
+									bool needsToRender = fnotequal(inTimeStamp.mSampleTime, mCurrentRenderTime.mSampleTime);
+									if (needsToRender)	// only copy this if we need to render
+										mCurrentRenderTime = inTimeStamp;
+									return needsToRender;
+								}
+	
+	// Scheduled parameter implementation:
+
+	typedef std::vector<AudioUnitParameterEvent> ParameterEventList;
+
+	// Usually, you won't override this method.  You only need to call this if your DSP code
+	// is prepared to handle scheduled immediate and ramped parameter changes.
+	// Before calling this method, it is assumed you have already called PullInput() on the input busses
+	// for which the DSP code depends.  ProcessForScheduledParams() will call (potentially repeatedly)
+	// virtual method ProcessScheduledSlice() to perform the actual DSP for a given sub-division of
+	// the buffer.  The job of ProcessForScheduledParams() is to sub-divide the buffer into smaller
+	// pieces according to the scheduled times found in the ParameterEventList (usually coming 
+	// directly from a previous call to ScheduleParameter() ), setting the appropriate immediate or
+	// ramped parameter values for the corresponding scopes and elements, then calling ProcessScheduledSlice()
+	// to do the actual DSP for each of these divisions.
+	virtual OSStatus 	ProcessForScheduledParams(	ParameterEventList		&inParamList,
+															UInt32					inFramesToProcess,
+															void					*inUserData );
+	
+	//	This method is called (potentially repeatedly) by ProcessForScheduledParams()
+	//	in order to perform the actual DSP required for this portion of the entire buffer
+	//	being processed.  The entire buffer can be divided up into smaller "slices"
+	//	according to the timestamps on the scheduled parameters...
+	//
+	//	sub-classes wishing to handle scheduled parameter changes should override this method
+	//  in order to do the appropriate DSP.  AUEffectBase already overrides this for standard
+	//	effect AudioUnits.
+	virtual OSStatus			ProcessScheduledSlice(	void				*inUserData,
+														UInt32				inStartFrameInBuffer,
+														UInt32				inSliceFramesToProcess,
+														UInt32				inTotalBufferFrames ) {return noErr;};	// default impl does nothing...
+	
+	
+	/*! @method CurrentRenderTime */
+	const AudioTimeStamp &		CurrentRenderTime () const { return mCurrentRenderTime; }
+	
+	// ________________________________________________________________________
+	//	Private data members to discourage hacking in subclasses
+private:
+	struct RenderCallback {
+		RenderCallback(AURenderCallback proc, void *ref) :
+			mRenderNotify(proc),
+			mRenderNotifyRefCon(ref)
+		{ }
+		
+		AURenderCallback			mRenderNotify;
+		void *						mRenderNotifyRefCon;
+		
+		bool operator == (const RenderCallback &other) {
+			return this->mRenderNotify == other.mRenderNotify &&
+					this->mRenderNotifyRefCon == other.mRenderNotifyRefCon;
+		}
+	};
+	typedef TThreadSafeList<RenderCallback>	RenderCallbackList;
+	
+#if !CA_BASIC_AU_FEATURES
+	enum { kNumScopes = 4 };
+#else
+	enum { kNumScopes = 3 };
+#endif
+	
+	/*! @var mElementsCreated */
+	bool						mElementsCreated;
+protected:
+	/*! @var mInitialized */
+	bool						mInitialized;
+	/*! @var mHasBegunInitializing */
+	bool						mHasBegunInitializing;
+private:
+	/*! @var mAudioUnitAPIVersion */
+	UInt8						mAudioUnitAPIVersion;
+	
+	/*! @var mInitNumInputEls */
+	const UInt32				mInitNumInputEls;
+	/*! @var mInitNumOutputEls */
+	const UInt32				mInitNumOutputEls;
+#if !CA_BASIC_AU_FEATURES
+	/*! @var mInitNumGroupEls */
+	const UInt32				mInitNumGroupEls;
+#endif
+	/*! @var mScopes */
+	AUScope						mScopes[kNumScopes];
+	
+	/*! @var mRenderCallbacks */
+	RenderCallbackList			mRenderCallbacks;
+	bool						mRenderCallbacksTouched;
+	
+	/*! @var mRenderThreadID */
+#if TARGET_OS_MAC
+	pthread_t					mRenderThreadID;
+#elif TARGET_OS_WIN32
+	UInt32						mRenderThreadID;
+#endif
+	
+	/*! @var mWantsRenderThreadID */
+	bool						mWantsRenderThreadID;
+		
+	/*! @var mCurrentRenderTime */
+	AudioTimeStamp				mCurrentRenderTime;
+	
+	/*! @var mMaxFramesPerSlice */
+	UInt32						mMaxFramesPerSlice;
+	
+	/*! @var mLastRenderError */
+	OSStatus					mLastRenderError;
+	/*! @var mCurrentPreset */
+	AUPreset					mCurrentPreset;
+	
+protected:
+	struct PropertyListener {
+		AudioUnitPropertyID				propertyID;
+		AudioUnitPropertyListenerProc	listenerProc;
+		void *							listenerRefCon;
+	};
+	typedef std::vector<PropertyListener>	PropertyListeners;
+
+	/*! @var mParamList */
+	ParameterEventList			mParamList;
+	/*! @var mPropertyListeners */
+	PropertyListeners			mPropertyListeners;
+	
+	/*! @var mBuffersAllocated */
+	bool						mBuffersAllocated;
+	
+	/*! @var mLogString */
+	// if this is NOT null, it will contain identifying info about this AU.
+	char*						mLogString;
+
+private:
+	/*! @var sVectorUnitType */
+	static SInt32	sVectorUnitType;
+
+#if !CA_NO_AU_UI_FEATURES
+protected:
+	/*! @var mHostCallbackInfo */
+	HostCallbackInfo 			mHostCallbackInfo;
+
+	/*! @var mContextInfo */
+	CFStringRef					mContextName;
+#endif
+};
+
+inline 	OSStatus	AUInputElement::PullInputWithBufferList(	
+												AudioUnitRenderActionFlags &  	ioActionFlags,
+												const AudioTimeStamp &			inTimeStamp,
+												AudioUnitElement				inElement,
+												UInt32							nFrames,
+												AudioBufferList *				inBufferList)
+{
+	OSStatus theResult;
+	
+	if (HasConnection()) {
+			// only support connections for V2 audio units
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+		if (mConnRenderProc != NULL)
+			theResult = reinterpret_cast<AudioUnitRenderProc>(mConnRenderProc)(
+							mConnInstanceStorage, &ioActionFlags, &inTimeStamp, mConnection.sourceOutputNumber, nFrames, inBufferList);
+		else
+#endif
+			theResult = AudioUnitRender(
+							mConnection.sourceAudioUnit, &ioActionFlags, &inTimeStamp, mConnection.sourceOutputNumber, nFrames, inBufferList);
+	} else {
+		// kFromCallback:
+			theResult = (mInputProc)(
+							mInputProcRefCon, &ioActionFlags, &inTimeStamp, inElement, nFrames, inBufferList);
+	}
+	
+	if (mInputType == kNoInput)	// defense: the guy upstream could have disconnected
+								// it's a horrible thing to do, but may happen!
+		return kAudioUnitErr_NoConnection;
+
+
+	return theResult;
+}
+
+#endif // __AUBase_h__
diff --git a/architecture/AU/AUPublic/AUBase/AUDispatch.cpp b/architecture/AU/AUPublic/AUBase/AUDispatch.cpp
new file mode 100644
index 0000000..004c35c
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUDispatch.cpp
@@ -0,0 +1,423 @@
+/*
+     File: AUDispatch.cpp 
+ Abstract:  AUDispatch.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUBase.h"
+#include "CAXException.h"
+#include "AUDispatch.h"
+
+
+
+#if TARGET_OS_MAC
+	#if __LP64__
+		// comp instance, parameters in forward order
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_index + 1];
+	#else
+		// parameters in reverse order, then comp instance
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_nparams - 1 - _index];
+	#endif
+#elif TARGET_OS_WIN32
+		// (no comp instance), parameters in forward order
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_index];
+#endif
+
+
+OSStatus		AUBase::ComponentEntryDispatch(ComponentParameters *params, AUBase *This)
+{
+	if (This == NULL) return kAudio_ParamError;
+
+	OSStatus result = noErr;
+
+	switch (params->what) {
+	case kComponentCanDoSelect:
+		switch (GetSelectorForCanDo(params)) {
+	// any selectors
+			case kAudioUnitInitializeSelect:
+			case kAudioUnitUninitializeSelect:
+			case kAudioUnitGetPropertyInfoSelect:
+			case kAudioUnitGetPropertySelect:
+			case kAudioUnitSetPropertySelect:
+			case kAudioUnitAddPropertyListenerSelect:
+#if (!__LP64__)
+			case kAudioUnitRemovePropertyListenerSelect:
+#endif
+			case kAudioUnitGetParameterSelect:
+			case kAudioUnitSetParameterSelect:
+			case kAudioUnitResetSelect:
+				result = 1;
+				break;
+	// v1 selectors
+
+	// v2 selectors
+			case kAudioUnitRemovePropertyListenerWithUserDataSelect:
+			case kAudioUnitAddRenderNotifySelect:
+			case kAudioUnitRemoveRenderNotifySelect:
+			case kAudioUnitScheduleParametersSelect:
+			case kAudioUnitRenderSelect:
+				result = (This->AudioUnitAPIVersion() > 1);
+				break;
+				
+			default:
+				return ComponentBase::ComponentEntryDispatch(params, This);
+		}
+		break;
+		
+	case kAudioUnitInitializeSelect:
+	{
+		result = This->DoInitialize();
+	}
+		break;
+		
+	case kAudioUnitUninitializeSelect:
+	{
+		This->DoCleanup();
+		result = noErr;
+	}
+		break;
+
+	case kAudioUnitGetPropertyInfoSelect:
+		{
+			PARAM(AudioUnitPropertyID, pinID, 0, 5);
+			PARAM(AudioUnitScope, pinScope, 1, 5);
+			PARAM(AudioUnitElement, pinElement, 2, 5);
+			PARAM(UInt32 *, poutDataSize, 3, 5);
+			PARAM(Boolean *, poutWritable, 4, 5);
+
+			// pass our own copies so that we assume responsibility for testing
+			// the caller's pointers against null and our C++ classes can
+			// always assume they're non-null
+			UInt32 dataSize;
+			Boolean writable;
+			
+			result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable);
+			if (poutDataSize != NULL)
+				*poutDataSize = dataSize;
+			if (poutWritable != NULL)
+				*poutWritable = writable;
+		}
+		break;
+
+	case kAudioUnitGetPropertySelect:
+		{
+			PARAM(AudioUnitPropertyID, pinID, 0, 5);
+			PARAM(AudioUnitScope, pinScope, 1, 5);
+			PARAM(AudioUnitElement, pinElement, 2, 5);
+			PARAM(void *, poutData, 3, 5);
+			PARAM(UInt32 *, pioDataSize, 4, 5);
+
+			UInt32 actualPropertySize, clientBufferSize;
+			Boolean writable;
+			char *tempBuffer;
+			void *destBuffer;
+			
+			if (pioDataSize == NULL) {
+				ca_debug_string("AudioUnitGetProperty: null size pointer");
+				result = kAudio_ParamError;
+				goto finishGetProperty;
+			}
+			if (poutData == NULL) {
+				UInt32 dataSize;
+				
+				result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable);
+				*pioDataSize = dataSize;
+				goto finishGetProperty;
+			}
+			
+			clientBufferSize = *pioDataSize;
+			if (clientBufferSize == 0)
+			{
+				ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry");
+				// $$$ or should we allow this as a shortcut for finding the size?
+				result = kAudio_ParamError;
+				goto finishGetProperty;
+			}
+			
+			result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, 
+													actualPropertySize, writable);
+			if (result) 
+				goto finishGetProperty;
+			
+			if (clientBufferSize < actualPropertySize) 
+			{
+				tempBuffer = new char[actualPropertySize];
+				destBuffer = tempBuffer;
+			} else {
+				tempBuffer = NULL;
+				destBuffer = poutData;
+			}
+			
+			result = This->DispatchGetProperty(pinID, pinScope, pinElement, destBuffer);
+			
+			if (result == noErr) {
+				if (tempBuffer && clientBufferSize < actualPropertySize) 
+				{
+					memcpy(poutData, tempBuffer, clientBufferSize);
+					delete[] tempBuffer;
+					// pioDataSize remains correct, the number of bytes we wrote
+				} else
+					*pioDataSize = actualPropertySize;
+			} else
+				*pioDataSize = 0;
+
+			finishGetProperty:
+				;
+
+		}
+		break;
+		
+	case kAudioUnitSetPropertySelect:
+		{
+			PARAM(AudioUnitPropertyID, pinID, 0, 5);
+			PARAM(AudioUnitScope, pinScope, 1, 5);
+			PARAM(AudioUnitElement, pinElement, 2, 5);
+			PARAM(const void *, pinData, 3, 5);
+			PARAM(UInt32, pinDataSize, 4, 5);
+			
+			if (pinData && pinDataSize)
+				result = This->DispatchSetProperty(pinID, pinScope, pinElement, pinData, pinDataSize);
+			else {
+				if (pinData == NULL && pinDataSize == 0) {
+					result = This->DispatchRemovePropertyValue (pinID, pinScope, pinElement);
+				} else {
+					if (pinData == NULL) {
+						ca_debug_string("AudioUnitSetProperty: inData == NULL");
+						result = kAudio_ParamError;
+						goto finishSetProperty;
+					}
+
+					if (pinDataSize == 0) {
+						ca_debug_string("AudioUnitSetProperty: inDataSize == 0");
+						result = kAudio_ParamError;
+						goto finishSetProperty;
+					}
+				}
+			}
+			finishSetProperty:
+					;
+
+		}
+		break;
+		
+	case kAudioUnitAddPropertyListenerSelect:
+		{
+			PARAM(AudioUnitPropertyID, pinID, 0, 3);
+			PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3);
+			PARAM(void *, pinProcRefCon, 2, 3);
+			result = This->AddPropertyListener(pinID, pinProc, pinProcRefCon);
+		}
+		break;
+
+#if (!__LP64__)
+	case kAudioUnitRemovePropertyListenerSelect:
+		{
+			PARAM(AudioUnitPropertyID, pinID, 0, 2);
+			PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 2);
+			result = This->RemovePropertyListener(pinID, pinProc, NULL, false);
+		}
+		break;
+#endif
+
+	case kAudioUnitRemovePropertyListenerWithUserDataSelect:
+		{
+			PARAM(AudioUnitPropertyID, pinID, 0, 3);
+			PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3);
+			PARAM(void *, pinProcRefCon, 2, 3);
+			result = This->RemovePropertyListener(pinID, pinProc, pinProcRefCon, true);
+		}
+		break;
+		
+	case kAudioUnitAddRenderNotifySelect:
+		{
+			PARAM(AURenderCallback, pinProc, 0, 2);
+			PARAM(void *, pinProcRefCon, 1, 2);
+			result = This->SetRenderNotification (pinProc, pinProcRefCon);
+		}
+		break;
+
+	case kAudioUnitRemoveRenderNotifySelect:
+		{
+			PARAM(AURenderCallback, pinProc, 0, 2);
+			PARAM(void *, pinProcRefCon, 1, 2);
+			result = This->RemoveRenderNotification (pinProc, pinProcRefCon);
+		}
+		break;
+
+	case kAudioUnitGetParameterSelect:
+		{
+			PARAM(AudioUnitParameterID, pinID, 0, 4);
+			PARAM(AudioUnitScope, pinScope, 1, 4);
+			PARAM(AudioUnitElement, pinElement, 2, 4);
+			PARAM(AudioUnitParameterValue *, poutValue, 3, 4);
+			result = (poutValue == NULL ? kAudio_ParamError : This->GetParameter(pinID, pinScope, pinElement, *poutValue));
+		}
+		break;
+
+	case kAudioUnitSetParameterSelect:
+		{
+			PARAM(AudioUnitParameterID, pinID, 0, 5);
+			PARAM(AudioUnitScope, pinScope, 1, 5);
+			PARAM(AudioUnitElement, pinElement, 2, 5);
+			PARAM(AudioUnitParameterValue, pinValue, 3, 5);
+			PARAM(UInt32, pinBufferOffsetInFrames, 4, 5);
+			result = This->SetParameter(pinID, pinScope, pinElement, pinValue, pinBufferOffsetInFrames);
+		}
+		break;
+
+	case kAudioUnitScheduleParametersSelect:
+		{
+			if (This->AudioUnitAPIVersion() > 1)
+			{
+				PARAM(AudioUnitParameterEvent *, pinParameterEvent, 0, 2);
+				PARAM(UInt32, pinNumParamEvents, 1, 2);
+				result = This->ScheduleParameter (pinParameterEvent, pinNumParamEvents);
+			} else
+				result = badComponentSelector;
+		}
+		break;
+
+
+	case kAudioUnitRenderSelect:
+		{
+			{
+				PARAM(AudioUnitRenderActionFlags *, pinActionFlags, 0, 5);
+				PARAM(const AudioTimeStamp *, pinTimeStamp, 1, 5);
+				PARAM(UInt32, pinOutputBusNumber, 2, 5);
+				PARAM(UInt32, pinNumberFrames, 3, 5);
+				PARAM(AudioBufferList *, pioData, 4, 5);
+				AudioUnitRenderActionFlags tempFlags;
+				
+				if (pinTimeStamp == NULL || pioData == NULL)
+					result = kAudio_ParamError;
+				else {
+					if (pinActionFlags == NULL) {
+						tempFlags = 0;
+						pinActionFlags = &tempFlags;
+					}
+					result = This->DoRender(*pinActionFlags, *pinTimeStamp, pinOutputBusNumber, pinNumberFrames, *pioData);
+				}
+			}			
+		}
+		break;
+
+	case kAudioUnitResetSelect:
+		{
+			PARAM(AudioUnitScope, pinScope, 0, 2);
+			PARAM(AudioUnitElement, pinElement, 1, 2);
+			This->ResetRenderTime();
+			result = This->Reset(pinScope, pinElement);
+		}
+		break;
+
+	default:
+		result = ComponentBase::ComponentEntryDispatch(params, This);
+		break;
+	}
+
+	return result;
+}
+
+// Fast dispatch entry points -- these need to replicate all error-checking logic from above
+
+OSStatus CMgr_AudioUnitBaseGetParameter(	AUBase *				This,
+											AudioUnitParameterID	inID,
+											AudioUnitScope			inScope,
+											AudioUnitElement		inElement,
+											float					*outValue)
+{
+	OSStatus result = AUBase::noErr;
+	
+	try {
+		if (This == NULL || outValue == NULL) return kAudio_ParamError;
+		result = This->GetParameter(inID, inScope, inElement, *outValue);
+	}
+	COMPONENT_CATCH
+	
+	return result;
+}
+
+OSStatus CMgr_AudioUnitBaseSetParameter(	AUBase * 				This,
+											AudioUnitParameterID	inID,
+											AudioUnitScope			inScope,
+											AudioUnitElement		inElement,
+											float					inValue,
+											UInt32					inBufferOffset)
+{
+	OSStatus result = AUBase::noErr;
+	
+	try {
+		if (This == NULL) return kAudio_ParamError;
+		result = This->SetParameter(inID, inScope, inElement, inValue, inBufferOffset);
+	}
+	COMPONENT_CATCH
+	
+	return result;
+}
+
+OSStatus CMgr_AudioUnitBaseRender(			AUBase *				This,
+											AudioUnitRenderActionFlags *ioActionFlags,
+											const AudioTimeStamp *	inTimeStamp,
+											UInt32					inBusNumber,
+											UInt32					inNumberFrames,
+											AudioBufferList *		ioData)
+{
+	if (inTimeStamp == NULL || ioData == NULL) return kAudio_ParamError;
+	
+	OSStatus result = AUBase::noErr;
+	AudioUnitRenderActionFlags tempFlags;
+	
+	try {
+		if (ioActionFlags == NULL) {
+			tempFlags = 0;
+			ioActionFlags = &tempFlags;
+		}
+		result = This->DoRender(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, *ioData);
+	}
+	COMPONENT_CATCH
+	
+	return result;
+}
diff --git a/architecture/AU/AUPublic/AUBase/AUDispatch.h b/architecture/AU/AUPublic/AUBase/AUDispatch.h
new file mode 100644
index 0000000..a63139b
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUDispatch.h
@@ -0,0 +1,82 @@
+/*
+     File: AUDispatch.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUDispatch_h__
+#define __AUDispatch_h__
+
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <AudioUnit/AudioUnit.h>
+#else
+	#include "AudioUnit.h"
+#endif
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+/*! @function AudioUnitBaseGetParameter */
+OSStatus CMgr_AudioUnitBaseGetParameter(	AUBase *				This,
+											AudioUnitParameterID	inID,
+											AudioUnitScope			inScope,
+											AudioUnitElement		inElement,
+											float *					outValue);
+
+/*! @function AudioUnitBaseSetParameter */
+OSStatus CMgr_AudioUnitBaseSetParameter(	AUBase *		 		This,
+											AudioUnitParameterID	inID,
+											AudioUnitScope			inScope,
+											AudioUnitElement		inElement,
+											float					inValue,
+											UInt32					inBufferOffset);
+
+/*! @function AudioUnitBaseRender */
+OSStatus CMgr_AudioUnitBaseRender(			AUBase *				This,
+											AudioUnitRenderActionFlags *ioActionFlags,
+											const AudioTimeStamp *	inTimeStamp,
+											UInt32					inBusNumber,
+											UInt32					inNumberFrames,
+											AudioBufferList *		ioData);
+#endif
+
+#endif // __AUDispatch_h__
diff --git a/architecture/AU/AUPublic/AUBase/AUInputElement.cpp b/architecture/AU/AUPublic/AUBase/AUInputElement.cpp
new file mode 100644
index 0000000..edd76e7
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUInputElement.cpp
@@ -0,0 +1,151 @@
+/*
+     File: AUInputElement.cpp 
+ Abstract:  AUInputElement.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUBase.h"
+
+inline bool	HasGoodBufferPointers(const AudioBufferList &abl, UInt32 nBytes)
+{
+	const AudioBuffer *buf = abl.mBuffers;
+	for (UInt32 i = abl.mNumberBuffers; i--;++buf) {
+		if (buf->mData == NULL || buf->mDataByteSize < nBytes)
+			return false;
+	}
+	return true;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//	AUInputElement::AUInputElement
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AUInputElement::AUInputElement(AUBase *audioUnit) :
+	AUIOElement(audioUnit),
+	mInputType(kNoInput)
+{
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//	AUInputElement::SetConnection
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void	AUInputElement::SetConnection(const AudioUnitConnection &conn)
+{
+	if (conn.sourceAudioUnit == 0) {
+		Disconnect();
+		return;
+	}	
+	
+	mInputType = kFromConnection;
+	mConnection = conn;
+	AllocateBuffer();
+
+	mConnInstanceStorage = NULL;
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	mConnRenderProc = NULL;
+	UInt32 size = sizeof(AudioUnitRenderProc);
+	OSStatus result = AudioUnitGetProperty(	conn.sourceAudioUnit,
+							kAudioUnitProperty_FastDispatch,
+							kAudioUnitScope_Global,
+							kAudioUnitRenderSelect,
+							&mConnRenderProc,
+							&size);
+	if (result == noErr)
+		mConnInstanceStorage = CMgr_GetComponentInstanceStorage (conn.sourceAudioUnit);
+	else
+		mConnRenderProc = NULL;
+#endif
+}
+
+void	AUInputElement::Disconnect()
+{
+	mInputType = kNoInput;
+	mIOBuffer.Deallocate();
+}
+
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//	AUInputElement::SetInputCallback
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void	AUInputElement::SetInputCallback(AURenderCallback proc, void *refCon)
+{
+	if (proc == NULL)
+		Disconnect();
+	else {
+		mInputType = kFromCallback;
+		mInputProc = proc;
+		mInputProcRefCon = refCon;
+		AllocateBuffer();
+	}
+}
+
+OSStatus	AUInputElement::SetStreamFormat(const CAStreamBasicDescription &fmt)
+{
+	OSStatus err = AUIOElement::SetStreamFormat(fmt);
+	if (err == AUBase::noErr)
+		AllocateBuffer();
+	return err;
+}
+
+OSStatus		AUInputElement::PullInput(	AudioUnitRenderActionFlags &  	ioActionFlags,
+											const AudioTimeStamp &			inTimeStamp,
+											AudioUnitElement				inElement,
+											UInt32							nFrames)
+{	
+	if (!IsActive())
+		return kAudioUnitErr_NoConnection;
+		
+	AudioBufferList *pullBuffer;
+	
+	if (HasConnection() || !WillAllocateBuffer())
+		pullBuffer = &mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames);
+	else
+		pullBuffer = &mIOBuffer.PrepareBuffer(mStreamFormat, nFrames);
+	
+	return PullInputWithBufferList (ioActionFlags, inTimeStamp, inElement, nFrames, pullBuffer);
+}
diff --git a/architecture/AU/AUPublic/AUBase/AUInputElement.h b/architecture/AU/AUPublic/AUBase/AUInputElement.h
new file mode 100644
index 0000000..72c42c0
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUInputElement.h
@@ -0,0 +1,119 @@
+/*
+     File: AUInputElement.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUInput_h__
+#define __AUInput_h__
+
+#include "AUScopeElement.h"
+#include "AUBuffer.h"
+
+/*! @class AUInputElement */
+class AUInputElement : public AUIOElement {
+public:
+	
+	/*! @ctor AUInputElement */
+						AUInputElement(AUBase *audioUnit);
+	/*! @dtor ~AUInputElement */
+	virtual				~AUInputElement() { }
+
+	// AUElement override
+	/*! @method SetStreamFormat */
+	virtual OSStatus	SetStreamFormat(const CAStreamBasicDescription &desc);
+	/*! @method NeedsBufferSpace */
+	virtual bool		NeedsBufferSpace() const { return IsCallback(); }
+
+	/*! @method SetConnection */
+	void				SetConnection(const AudioUnitConnection &conn);
+	/*! @method SetInputCallback */
+	void				SetInputCallback(AURenderCallback proc, void *refCon);
+
+	/*! @method IsActive */
+	bool				IsActive() const { return mInputType != kNoInput; }
+	/*! @method IsCallback */
+	bool				IsCallback() const { return mInputType == kFromCallback; }
+	/*! @method HasConnection */
+	bool				HasConnection() const { return mInputType == kFromConnection; }
+
+	/*! @method PullInput */
+	OSStatus			PullInput(	AudioUnitRenderActionFlags &  	ioActionFlags,
+									const AudioTimeStamp &			inTimeStamp,
+									AudioUnitElement				inElement,
+									UInt32							inNumberFrames);
+
+	/*! @method PullInputWithBufferList */
+	OSStatus			PullInputWithBufferList(	AudioUnitRenderActionFlags &  	ioActionFlags,
+													const AudioTimeStamp &			inTimeStamp,
+													AudioUnitElement				inElement,
+													UInt32							nFrames,
+													AudioBufferList *				inBufferList);
+protected:
+	/*! @method Disconnect */
+	void				Disconnect();
+
+	enum EInputType { kNoInput, kFromConnection, kFromCallback };
+
+	/*! @var mInputType */
+	EInputType					mInputType;
+
+	// if from callback:
+	/*! @var mInputProc */
+	AURenderCallback			mInputProc;
+	/*! @var mInputProcRefCon */
+	void *						mInputProcRefCon;
+	
+	// if from connection:
+	/*! @var mConnection */
+	AudioUnitConnection			mConnection;
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	/*! @var mConnRenderProc */
+	AudioUnitRenderProc			mConnRenderProc;
+#endif
+	/*! @var mConnInstanceStorage */
+	void *						mConnInstanceStorage;		// for the input component
+};
+
+
+#endif // __AUInput_h__
diff --git a/architecture/AU/AUPublic/AUBase/AUOutputElement.cpp b/architecture/AU/AUPublic/AUBase/AUOutputElement.cpp
new file mode 100644
index 0000000..db30939
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUOutputElement.cpp
@@ -0,0 +1,62 @@
+/*
+     File: AUOutputElement.cpp 
+ Abstract:  AUOutputElement.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUOutputElement.h"
+#include "AUBase.h"
+
+AUOutputElement::AUOutputElement(AUBase *audioUnit) : 
+	AUIOElement(audioUnit)
+{
+	AllocateBuffer();
+}
+
+OSStatus	AUOutputElement::SetStreamFormat(const CAStreamBasicDescription &desc)
+{
+	OSStatus result = AUIOElement::SetStreamFormat(desc);	// inherited
+	if (result == AUBase::noErr)
+		AllocateBuffer();
+	return result;
+}
diff --git a/architecture/AU/AUPublic/AUBase/AUOutputElement.h b/architecture/AU/AUPublic/AUBase/AUOutputElement.h
new file mode 100644
index 0000000..c948634
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUOutputElement.h
@@ -0,0 +1,66 @@
+/*
+     File: AUOutputElement.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUOutput_h__
+#define __AUOutput_h__
+
+#include "AUScopeElement.h"
+#include "AUBuffer.h"
+
+	/*! @class AUOutputElement */
+class AUOutputElement : public AUIOElement {
+public:
+	/*! @ctor AUOutputElement */
+						AUOutputElement(AUBase *audioUnit);
+
+	// AUElement override
+	/*! @method SetStreamFormat */
+	virtual OSStatus	SetStreamFormat(const CAStreamBasicDescription &desc);
+	/*! @method NeedsBufferSpace */
+	virtual bool		NeedsBufferSpace() const { return true; }
+};
+
+#endif // __AUOutput_h__
diff --git a/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.cpp b/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.cpp
new file mode 100644
index 0000000..c7d6225
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.cpp
@@ -0,0 +1,615 @@
+/*
+     File: AUPlugInDispatch.cpp 
+ Abstract:  AUPlugInDispatch.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUPlugInDispatch.h"
+#include "CAXException.h"
+#include "ComponentBase.h"
+#include "AUBase.h"
+
+#define ACPI ((AudioComponentPlugInInstance *)self)
+#define AUI	((AUBase *)&ACPI->mInstanceStorage)
+
+// ------------------------------------------------------------------------------------------------
+static OSStatus AUMethodInitialize(void *self)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->DoInitialize();
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodUninitialize(void *self)
+{
+	OSStatus result = noErr;
+	try {
+		AUI->DoCleanup();
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodGetPropertyInfo(void *self, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement elem, UInt32 *outDataSize, Boolean *outWritable)
+{
+	OSStatus result = noErr;
+	try {
+		UInt32 dataSize;
+		Boolean writable;
+		
+		result = AUI->DispatchGetPropertyInfo(prop, scope, elem, dataSize, writable);
+		if (outDataSize != NULL)
+			*outDataSize = dataSize;
+		if (outWritable != NULL)
+			*outWritable = writable;
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodGetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void *outData, UInt32 *ioDataSize)
+{
+	OSStatus result = noErr;
+	try {
+		UInt32 actualPropertySize, clientBufferSize;
+		Boolean writable;
+		char *tempBuffer;
+		void *destBuffer;
+		
+		if (ioDataSize == NULL) {
+			ca_debug_string("AudioUnitGetProperty: null size pointer");
+			result = kAudio_ParamError;
+			goto finishGetProperty;
+		}
+		if (outData == NULL) {
+			UInt32 dataSize;
+			
+			result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, dataSize, writable);
+			*ioDataSize = dataSize;
+			goto finishGetProperty;
+		}
+		
+		clientBufferSize = *ioDataSize;
+		if (clientBufferSize == 0)
+		{
+			ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry");
+			// $$$ or should we allow this as a shortcut for finding the size?
+			result = kAudio_ParamError;
+			goto finishGetProperty;
+		}
+		
+		result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, actualPropertySize, writable);
+		if (result != noErr) 
+			goto finishGetProperty;
+		
+		if (clientBufferSize < actualPropertySize) 
+		{
+			tempBuffer = new char[actualPropertySize];
+			destBuffer = tempBuffer;
+		} else {
+			tempBuffer = NULL;
+			destBuffer = outData;
+		}
+		
+		result = AUI->DispatchGetProperty(inID, inScope, inElement, destBuffer);
+		
+		if (result == noErr) {
+			if (tempBuffer && clientBufferSize < actualPropertySize) 
+			{
+				memcpy(outData, tempBuffer, clientBufferSize);
+				delete[] tempBuffer;
+				// ioDataSize remains correct, the number of bytes we wrote
+			} else
+				*ioDataSize = actualPropertySize;
+		} else
+			*ioDataSize = 0;
+	}
+	COMPONENT_CATCH
+finishGetProperty:
+	return result;
+}
+
+static OSStatus AUMethodSetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void *inData, UInt32 inDataSize)
+{
+	OSStatus result = noErr;
+	try {
+		if (inData && inDataSize)
+			result = AUI->DispatchSetProperty(inID, inScope, inElement, inData, inDataSize);
+		else {
+			if (inData == NULL && inDataSize == 0) {
+				result = AUI->DispatchRemovePropertyValue(inID, inScope, inElement);
+			} else {
+				if (inData == NULL) {
+					ca_debug_string("AudioUnitSetProperty: inData == NULL");
+					result = kAudio_ParamError;
+					goto finishSetProperty;
+				}
+
+				if (inDataSize == 0) {
+					ca_debug_string("AudioUnitSetProperty: inDataSize == 0");
+					result = kAudio_ParamError;
+					goto finishSetProperty;
+				}
+			}
+		}
+	}
+	COMPONENT_CATCH
+finishSetProperty:
+	return result;
+}
+
+static OSStatus AUMethodAddPropertyListener(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void *userData)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->AddPropertyListener(prop, proc, userData);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodRemovePropertyListener(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->RemovePropertyListener(prop, proc, NULL, false);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodRemovePropertyListenerWithUserData(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void *userData)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->RemovePropertyListener(prop, proc, userData, true);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodAddRenderNotify(void *self, AURenderCallback proc, void *userData)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->SetRenderNotification(proc, userData);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodRemoveRenderNotify(void *self, AURenderCallback proc, void *userData)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->RemoveRenderNotification(proc, userData);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodGetParameter(void *self, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue *value)
+{
+	OSStatus result = noErr;
+	try {
+		result = (value == NULL ? kAudio_ParamError : AUI->GetParameter(param, scope, elem, *value));
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodSetParameter(void *self, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue value, UInt32 bufferOffset)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->SetParameter(param, scope, elem, value, bufferOffset);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodScheduleParameters(void *self, const AudioUnitParameterEvent *events, UInt32 numEvents)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->ScheduleParameter(events, numEvents);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodRender(void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
+{
+	OSStatus result = noErr;
+
+#if !TARGET_OS_IPHONE
+	try {
+#endif
+		AudioUnitRenderActionFlags tempFlags;
+		
+		if (inTimeStamp == NULL || ioData == NULL)
+			result = kAudio_ParamError;
+		else {
+			if (ioActionFlags == NULL) {
+				tempFlags = 0;
+				ioActionFlags = &tempFlags;
+			}
+			result = AUI->DoRender(*ioActionFlags, *inTimeStamp, inOutputBusNumber, inNumberFrames, *ioData);
+		}
+
+#if !TARGET_OS_IPHONE
+	}
+	COMPONENT_CATCH
+#endif
+
+	return result;
+}
+
+static OSStatus AUMethodComplexRender(void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberOfPackets, UInt32 *outNumberOfPackets, AudioStreamPacketDescription *outPacketDescriptions, AudioBufferList *ioData, void *outMetadata, UInt32 *outMetadataByteSize)
+{
+	OSStatus result = noErr;
+
+#if !TARGET_OS_IPHONE
+	try {
+#endif
+		AudioUnitRenderActionFlags tempFlags;
+		
+		if (inTimeStamp == NULL || ioData == NULL)
+			result = kAudio_ParamError;
+		else {
+			if (ioActionFlags == NULL) {
+				tempFlags = 0;
+				ioActionFlags = &tempFlags;
+			}
+			result = AUI->ComplexRender(*ioActionFlags, *inTimeStamp, inOutputBusNumber, inNumberOfPackets, outNumberOfPackets, outPacketDescriptions, *ioData, outMetadata, outMetadataByteSize);
+		}
+
+#if !TARGET_OS_IPHONE
+	}
+	COMPONENT_CATCH
+#endif
+
+	return result;
+}
+
+static OSStatus AUMethodReset(void *self, AudioUnitScope scope, AudioUnitElement elem)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->Reset(scope, elem);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodProcess (void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData)
+{
+	OSStatus result = noErr;
+
+#if !TARGET_OS_IPHONE
+	try {
+#endif
+		bool doParamCheck = true;
+
+		AudioUnitRenderActionFlags tempFlags;
+
+		if (ioActionFlags == NULL) {
+			tempFlags = 0;
+			ioActionFlags = &tempFlags;
+		} else {
+			if (*ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/)
+				doParamCheck = false;
+		}
+		
+		if (doParamCheck && (inTimeStamp == NULL || ioData == NULL))
+			result = kAudio_ParamError;
+		else {
+			result = AUI->DoProcess(*ioActionFlags, *inTimeStamp, inNumberFrames, *ioData);
+		}
+
+#if !TARGET_OS_IPHONE
+	}
+	COMPONENT_CATCH
+#endif
+
+	return result;
+}
+
+static OSStatus AUMethodProcessMultiple (void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, UInt32 inNumberInputBufferLists, const AudioBufferList **inInputBufferLists, UInt32 inNumberOutputBufferLists, AudioBufferList **ioOutputBufferLists)
+{
+	OSStatus result = noErr;
+	
+#if !TARGET_OS_IPHONE
+	try {
+#endif
+		bool doParamCheck = true;
+		
+		AudioUnitRenderActionFlags tempFlags;
+		
+		if (ioActionFlags == NULL) {
+			tempFlags = 0;
+			ioActionFlags = &tempFlags;
+		} else {
+			if (*ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/)
+				doParamCheck = false;
+		}
+
+		if (doParamCheck && (inTimeStamp == NULL || inInputBufferLists == NULL || ioOutputBufferLists == NULL))
+			result = kAudio_ParamError;
+		else {
+			result = AUI->DoProcessMultiple(*ioActionFlags, *inTimeStamp, inNumberFrames, inNumberInputBufferLists, inInputBufferLists, inNumberOutputBufferLists, ioOutputBufferLists);
+		}
+		
+#if !TARGET_OS_IPHONE
+	}
+	COMPONENT_CATCH
+#endif
+
+	return result;
+}
+// ------------------------------------------------------------------------------------------------
+
+static OSStatus AUMethodStart(void *self)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->Start();
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodStop(void *self)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->Stop();
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+// ------------------------------------------------------------------------------------------------
+
+#if !CA_BASIC_AU_FEATURES
+// I don't know what I'm doing here; conflicts with the multiple inheritence in MusicDeviceBase.
+static OSStatus AUMethodMIDIEvent(void *self, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodSysEx(void *self, const UInt8 *inData, UInt32 inLength)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->SysEx(inData, inLength);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodStartNote(void *self, MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams)
+{
+	OSStatus result = noErr;
+	try {
+		if (inParams == NULL || outNoteInstanceID == NULL) 
+			result = kAudio_ParamError;
+		else
+			result = AUI->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodStopNote(void *self, MusicDeviceGroupID inGroupID, NoteInstanceID inNoteInstanceID, UInt32 inOffsetSampleFrame)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+#if !TARGET_OS_IPHONE
+static OSStatus AUMethodPrepareInstrument (void *self, MusicDeviceInstrumentID inInstrument)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->PrepareInstrument(inInstrument);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+static OSStatus AUMethodReleaseInstrument (void *self, MusicDeviceInstrumentID inInstrument)
+{
+	OSStatus result = noErr;
+	try {
+		result = AUI->ReleaseInstrument(inInstrument);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+#endif // TARGET_OS_IPHONE
+#endif // CA_BASIC_AU_FEATURES
+
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#pragma mark -
+#pragma mark Lookup Methods
+
+AudioComponentMethod AUBaseLookup::Lookup (SInt16 selector)
+{
+	switch (selector) {
+		case kAudioUnitInitializeSelect:		return (AudioComponentMethod)AUMethodInitialize;
+		case kAudioUnitUninitializeSelect:		return (AudioComponentMethod)AUMethodUninitialize;
+		case kAudioUnitGetPropertyInfoSelect:	return (AudioComponentMethod)AUMethodGetPropertyInfo;
+		case kAudioUnitGetPropertySelect:		return (AudioComponentMethod)AUMethodGetProperty;
+		case kAudioUnitSetPropertySelect:		return (AudioComponentMethod)AUMethodSetProperty;
+		case kAudioUnitAddPropertyListenerSelect:return (AudioComponentMethod)AUMethodAddPropertyListener;
+		case kAudioUnitRemovePropertyListenerSelect:
+												return (AudioComponentMethod)AUMethodRemovePropertyListener;
+		case kAudioUnitRemovePropertyListenerWithUserDataSelect:
+												return (AudioComponentMethod)AUMethodRemovePropertyListenerWithUserData;
+		case kAudioUnitAddRenderNotifySelect:	return (AudioComponentMethod)AUMethodAddRenderNotify;
+		case kAudioUnitRemoveRenderNotifySelect:return (AudioComponentMethod)AUMethodRemoveRenderNotify;
+		case kAudioUnitGetParameterSelect:		return (AudioComponentMethod)AUMethodGetParameter;
+		case kAudioUnitSetParameterSelect:		return (AudioComponentMethod)AUMethodSetParameter;
+		case kAudioUnitScheduleParametersSelect:return (AudioComponentMethod)AUMethodScheduleParameters;
+		case kAudioUnitRenderSelect:			return (AudioComponentMethod)AUMethodRender;
+		case kAudioUnitResetSelect:				return (AudioComponentMethod)AUMethodReset;
+		default:
+			break;
+	}
+	return NULL;
+}
+
+AudioComponentMethod AUOutputLookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
+	if (method) return method;
+
+	switch (selector) {
+		case kAudioOutputUnitStartSelect:	return (AudioComponentMethod)AUMethodStart;
+		case kAudioOutputUnitStopSelect:	return (AudioComponentMethod)AUMethodStop;
+		default:
+			break;
+	}
+	return NULL;
+}
+
+AudioComponentMethod AUComplexOutputLookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
+	if (method) return method;
+	
+	method = AUOutputLookup::Lookup(selector);
+	if (method) return method;
+	
+	if (selector == kAudioUnitComplexRenderSelect)
+		return (AudioComponentMethod)AUMethodComplexRender;
+	return NULL;
+}
+
+AudioComponentMethod AUBaseProcessLookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
+	if (method) return method;
+	
+	if (selector == kAudioUnitProcessSelect)
+		return (AudioComponentMethod)AUMethodProcess;
+	
+	return NULL;
+}
+
+AudioComponentMethod AUBaseProcessMultipleLookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
+	if (method) return method;
+
+	method = AUBaseProcessLookup::Lookup(selector);
+	if (method) return method;
+
+	if (selector == kAudioUnitProcessMultipleSelect)
+		return (AudioComponentMethod)AUMethodProcessMultiple;
+	
+	return NULL;
+}
+
+#if !CA_BASIC_AU_FEATURES
+inline AudioComponentMethod MIDI_Lookup (SInt16 selector)
+{
+	switch (selector) {
+		case kMusicDeviceMIDIEventSelect:	return (AudioComponentMethod)AUMethodMIDIEvent;
+		case kMusicDeviceSysExSelect:		return (AudioComponentMethod)AUMethodSysEx;
+		default:
+			break;
+	}
+	return NULL;
+}
+
+AudioComponentMethod AUMIDILookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
+	if (method) return method;
+	
+	return MIDI_Lookup(selector);
+}
+
+AudioComponentMethod AUMIDIProcessLookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseProcessLookup::Lookup(selector);
+	if (method) return method;
+	
+	return MIDI_Lookup(selector);
+}
+
+AudioComponentMethod AUMusicLookup::Lookup (SInt16 selector)
+{
+	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
+	if (method) return method;
+
+	switch (selector) {
+		case kMusicDeviceStartNoteSelect:	return (AudioComponentMethod)AUMethodStartNote;
+		case kMusicDeviceStopNoteSelect:	return (AudioComponentMethod)AUMethodStopNote;
+#if !TARGET_OS_IPHONE
+		case kMusicDevicePrepareInstrumentSelect:	return (AudioComponentMethod)AUMethodPrepareInstrument;
+		case kMusicDeviceReleaseInstrumentSelect:	return (AudioComponentMethod)AUMethodReleaseInstrument;
+#endif
+		default:		
+			break;
+	}
+	return MIDI_Lookup (selector);
+}
+
+#endif
+
diff --git a/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.h b/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.h
new file mode 100644
index 0000000..2093bba
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.h
@@ -0,0 +1,128 @@
+/*
+     File: AUPlugInDispatch.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUPlugInBase_h__
+#define __AUPlugInBase_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <AudioUnit/AudioComponent.h>
+	#if !CA_BASIC_AU_FEATURES
+		#include <AudioUnit/MusicDevice.h>
+	#endif
+#else
+	#include "AudioComponent.h"
+	#include "MusicDevice.h"
+#endif
+
+#include "ComponentBase.h"
+
+struct AUBaseLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUBaseFactory : public APFactory<AUBaseLookup, Implementor>
+{
+};
+
+struct AUOutputLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUOutputBaseFactory : public APFactory<AUOutputLookup, Implementor>
+{
+};
+
+struct AUComplexOutputLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUOutputComplexBaseFactory : public APFactory<AUComplexOutputLookup, Implementor>
+{
+};
+
+struct AUBaseProcessLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUBaseProcessFactory : public APFactory<AUBaseProcessLookup, Implementor>
+{
+};
+
+struct AUBaseProcessMultipleLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUBaseProcessMultipleFactory : public APFactory<AUBaseProcessMultipleLookup, Implementor>
+{
+};
+
+#if !CA_BASIC_AU_FEATURES
+struct AUMIDILookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUMIDIEffectFactory : public APFactory<AUMIDILookup, Implementor>
+{
+};
+
+struct AUMIDIProcessLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUMIDIProcessFactory : public APFactory<AUMIDIProcessLookup, Implementor>
+{
+};
+
+struct AUMusicLookup {
+	static AudioComponentMethod Lookup (SInt16 selector);
+};
+template <class Implementor>
+class AUMusicDeviceFactory : public APFactory<AUMusicLookup, Implementor>
+{
+};
+#endif // CA_BASIC_AU_FEATURES
+
+#endif // __AUPlugInBase_h__
diff --git a/architecture/AU/AUPublic/AUBase/AUScopeElement.cpp b/architecture/AU/AUPublic/AUBase/AUScopeElement.cpp
new file mode 100644
index 0000000..0dab57b
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUScopeElement.cpp
@@ -0,0 +1,512 @@
+/*
+     File: AUScopeElement.cpp 
+ Abstract:  AUScopeElement.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUScopeElement.h"
+#include "AUBase.h"
+
+//_____________________________________________________________________________
+//
+//	By default, parameterIDs may be arbitrarily spaced, and an STL map
+//  will be used for access.  Calling UseIndexedParameters() will
+//	instead use an STL vector for faster indexed access.
+//	This assumes the paramIDs are numbered 0.....inNumberOfParameters-1
+//	Call this before defining/adding any parameters with SetParameter()
+//
+void	AUElement::UseIndexedParameters(int inNumberOfParameters)
+{
+	mIndexedParameters.resize (inNumberOfParameters);	
+	mUseIndexedParameters = true;
+}
+
+//_____________________________________________________________________________
+//
+//	Helper method.
+//	returns the ParameterMapEvent object associated with the paramID
+//
+inline ParameterMapEvent&	AUElement::GetParamEvent(AudioUnitParameterID paramID)
+{
+	ParameterMapEvent *event;
+	
+	if(mUseIndexedParameters)
+	{
+		if(paramID >= mIndexedParameters.size() )
+			COMPONENT_THROW(kAudioUnitErr_InvalidParameter);
+		
+		event = &mIndexedParameters[paramID];
+	}
+	else
+	{
+		ParameterMap::iterator i = mParameters.find(paramID);
+		if (i == mParameters.end())
+			COMPONENT_THROW(kAudioUnitErr_InvalidParameter);
+			
+		event = &(*i).second;
+	}
+	
+	return *event;
+}
+
+//_____________________________________________________________________________
+//
+//	caller assumes that this is actually an immediate parameter
+//
+AudioUnitParameterValue		AUElement::GetParameter(AudioUnitParameterID paramID)
+{
+	ParameterMapEvent &event = GetParamEvent(paramID);
+	
+	return event.GetValue();
+}
+
+
+//_____________________________________________________________________________
+//
+void			AUElement::GetRampSliceStartEnd(	AudioUnitParameterID		paramID,
+													AudioUnitParameterValue &	outStartValue,
+													AudioUnitParameterValue &	outEndValue,
+													AudioUnitParameterValue &	outValuePerFrameDelta )
+
+{
+	ParameterMapEvent &event = GetParamEvent(paramID);
+		
+	// works even if the value is constant (immediate parameter value)
+	event.GetRampSliceStartEnd(outStartValue, outEndValue, outValuePerFrameDelta );
+}
+
+//_____________________________________________________________________________
+//
+AudioUnitParameterValue			AUElement::GetEndValue(	AudioUnitParameterID		paramID)
+
+{
+	ParameterMapEvent &event = GetParamEvent(paramID);
+		
+	// works even if the value is constant (immediate parameter value)
+	return event.GetEndValue();
+}
+
+//_____________________________________________________________________________
+//
+void			AUElement::SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue inValue, bool okWhenInitialized)
+{
+	if(mUseIndexedParameters)
+	{
+		ParameterMapEvent &event = GetParamEvent(paramID);
+		event.SetValue(inValue);
+	}
+	else
+	{
+		ParameterMap::iterator i = mParameters.find(paramID);
+	
+		if (i == mParameters.end())
+		{
+			if (mAudioUnit->IsInitialized() && !okWhenInitialized) {
+				// The AU should not be creating new parameters once initialized.
+				// If a client tries to set an undefined parameter, we could throw as follows, 
+				// but this might cause a regression. So it is better to just fail silently.
+				// COMPONENT_THROW(kAudioUnitErr_InvalidParameter);
+#if DEBUG
+				fprintf(stderr, "WARNING: %s SetParameter for undefined param ID %d while initialized. Ignoring..\n", 
+								mAudioUnit->GetLoggingString(), (int)paramID);
+#endif
+			} else {
+				// create new entry in map for the paramID (only happens first time)
+				ParameterMapEvent event(inValue);		
+				mParameters[paramID] = event;
+			}
+		}
+		else
+		{
+			// paramID already exists in map so simply change its value
+			ParameterMapEvent &event = (*i).second;
+			event.SetValue(inValue);
+		}
+	}
+}
+
+//_____________________________________________________________________________
+//
+void			AUElement::SetScheduledEvent(	AudioUnitParameterID 			paramID,
+												const AudioUnitParameterEvent 	&inEvent,
+												UInt32 							inSliceOffsetInBuffer,
+												UInt32							inSliceDurationFrames,
+												bool							okWhenInitialized )
+{
+	if(mUseIndexedParameters)
+	{
+		ParameterMapEvent &event = GetParamEvent(paramID);
+		event.SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames );
+	}
+	else
+	{
+		ParameterMap::iterator i = mParameters.find(paramID);
+	
+		if (i == mParameters.end())
+		{
+			if (mAudioUnit->IsInitialized() && !okWhenInitialized) {
+				// The AU should not be creating new parameters once initialized.
+				// If a client tries to set an undefined parameter, we could throw as follows, 
+				// but this might cause a regression. So it is better to just fail silently.
+				// COMPONENT_THROW(kAudioUnitErr_InvalidParameter);
+#if DEBUG
+				fprintf(stderr, "WARNING: %s SetScheduledEvent for undefined param ID %d while initialized. Ignoring..\n", 
+								mAudioUnit->GetLoggingString(), (int)paramID);
+#endif
+			} else {
+				// create new entry in map for the paramID (only happens first time)
+				ParameterMapEvent event(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames);		
+				mParameters[paramID] = event;
+			}
+		}
+		else
+		{
+			// paramID already exists in map so simply change its value
+			ParameterMapEvent &event = (*i).second;
+			
+			event.SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames );
+		}
+	}
+}
+
+
+
+//_____________________________________________________________________________
+//
+void			AUElement::GetParameterList(AudioUnitParameterID *outList)
+{
+	if(mUseIndexedParameters)
+	{
+		UInt32 nparams = mIndexedParameters.size();
+		for (UInt32 i = 0; i < nparams; i++ )
+			*outList++ = (AudioUnitParameterID)i;
+	}
+	else
+	{
+		for (ParameterMap::iterator i = mParameters.begin(); i != mParameters.end(); ++i)
+			*outList++ = (*i).first;
+	}
+}
+
+//_____________________________________________________________________________
+//
+void			AUElement::SaveState(CFMutableDataRef data)
+{
+	if(mUseIndexedParameters)
+	{
+		UInt32 nparams = mIndexedParameters.size();
+		UInt32 theData = CFSwapInt32HostToBig(nparams);
+		CFDataAppendBytes(data, (UInt8 *)&theData, sizeof(nparams));
+	
+		for (UInt32 i = 0; i < nparams; i++)
+		{
+			struct {
+				UInt32				paramID;
+				//CFSwappedFloat32	value; crashes gcc3 PFE
+				UInt32				value;	// really a big-endian float
+			} entry;
+			
+			entry.paramID = CFSwapInt32HostToBig(i);
+	
+			AudioUnitParameterValue v = mIndexedParameters[i].GetValue();
+			entry.value = CFSwapInt32HostToBig(*(UInt32 *)&v );
+	
+			CFDataAppendBytes(data, (UInt8 *)&entry, sizeof(entry));
+		}
+	}
+	else
+	{
+		UInt32 nparams = CFSwapInt32HostToBig(mParameters.size());
+		CFDataAppendBytes(data, (UInt8 *)&nparams, sizeof(nparams));
+	
+		for (ParameterMap::iterator i = mParameters.begin(); i != mParameters.end(); ++i) {
+			struct {
+				UInt32				paramID;
+				//CFSwappedFloat32	value; crashes gcc3 PFE
+				UInt32				value;	// really a big-endian float
+			} entry;
+			
+			entry.paramID = CFSwapInt32HostToBig((*i).first);
+	
+			AudioUnitParameterValue v = (*i).second.GetValue();
+			entry.value = CFSwapInt32HostToBig(*(UInt32 *)&v );
+	
+			CFDataAppendBytes(data, (UInt8 *)&entry, sizeof(entry));
+		}
+	}
+}
+
+//_____________________________________________________________________________
+//
+const UInt8 *	AUElement::RestoreState(const UInt8 *state)
+{
+	union FloatInt32 { UInt32 i; AudioUnitParameterValue f; };
+	const UInt8 *p = state;
+	UInt32 nparams = CFSwapInt32BigToHost(*(UInt32 *)p);
+	p += sizeof(UInt32);
+	
+	for (UInt32 i = 0; i < nparams; ++i) {
+		struct {
+			AudioUnitParameterID		paramID;
+			AudioUnitParameterValue		value;
+		} entry;
+		
+		entry.paramID = CFSwapInt32BigToHost(*(UInt32 *)p);
+		p += sizeof(UInt32);
+		FloatInt32 temp;
+		temp.i = CFSwapInt32BigToHost(*(UInt32 *)p);
+		entry.value = temp.f;
+		p += sizeof(AudioUnitParameterValue);
+		
+		SetParameter(entry.paramID, entry.value);
+	}
+	return p;
+}
+
+//_____________________________________________________________________________
+//
+void	AUElement::SetName (CFStringRef inName) 
+{ 
+	if (mElementName) CFRelease (mElementName);
+	mElementName = inName; 
+	if (mElementName) CFRetain (mElementName);
+}
+
+
+//_____________________________________________________________________________
+//
+AUIOElement::AUIOElement(AUBase *audioUnit) :
+	AUElement(audioUnit),
+	mWillAllocate (true)
+{
+	mStreamFormat.SetAUCanonical(2,	// stereo
+		audioUnit->AudioUnitAPIVersion() == 1);
+		// interleaved if API version 1, deinterleaved if version 2
+	mStreamFormat.mSampleRate = kAUDefaultSampleRate;
+}
+
+//_____________________________________________________________________________
+//
+OSStatus		AUIOElement::SetStreamFormat(const CAStreamBasicDescription &desc)
+{
+	mStreamFormat = desc;
+	return AUBase::noErr;
+}
+
+//_____________________________________________________________________________
+// inFramesToAllocate == 0 implies the AudioUnit's max-frames-per-slice will be used
+void			AUIOElement::AllocateBuffer(UInt32 inFramesToAllocate)
+{
+	if (GetAudioUnit()->HasBegunInitializing())
+	{
+		UInt32 framesToAllocate = inFramesToAllocate > 0 ? inFramesToAllocate : GetAudioUnit()->GetMaxFramesPerSlice();
+		
+//		printf ("will allocate: %d\n", (int)((mWillAllocate && NeedsBufferSpace()) ? framesToAllocate : 0));
+		
+		mIOBuffer.Allocate(mStreamFormat, (mWillAllocate && NeedsBufferSpace()) ? framesToAllocate : 0);
+	}
+}
+
+//_____________________________________________________________________________
+//
+void			AUIOElement::DeallocateBuffer()
+{
+	mIOBuffer.Deallocate();
+}
+
+//_____________________________________________________________________________
+//
+//		AudioChannelLayout support
+
+// outLayoutTagsPtr WILL be NULL if called to find out how many
+// layouts that Audio Unit will report 
+// return 0 (ie. NO channel layouts) if the AU doesn't require channel layout knowledge
+UInt32		AUIOElement::GetChannelLayoutTags (AudioChannelLayoutTag		*outLayoutTagsPtr)
+{
+	return 0;
+}
+		
+// As the AudioChannelLayout can be a variable length structure 
+// (though in most cases it won't be!!!)
+// The size of the ACL is always returned by the method
+// if outMapPtr is NOT-NULL, then AU should copy into this pointer (outMapPtr) the current ACL that it has in use. 
+// the AU should also return whether the property is writable (that is the client can provide any arbitrary ACL that the audio unit will then honour)
+// or if the property is read only - which is the generally preferred mode.
+// If the AU doesn't require an AudioChannelLayout, then just return 0.
+UInt32		AUIOElement::GetAudioChannelLayout (AudioChannelLayout		*outMapPtr, 
+											Boolean				&outWritable)
+{
+	return 0;
+}
+
+// the incoming channel map will be at least as big as a basic AudioChannelLayout
+// but its contents will determine its actual size
+// Subclass should overide if channel map is writable
+OSStatus	AUIOElement::SetAudioChannelLayout (const AudioChannelLayout &inData)
+{
+	return kAudioUnitErr_InvalidProperty;
+}
+
+// Some units support optional usage of channel maps - typically converter units
+// that can do channel remapping between different maps. In that optional case
+// the user should be able to remove a channel map if that is possible.
+// Typically this is NOT the case (e.g., the 3DMixer even in the stereo case
+// needs to know if it is rendering to speakers or headphones)
+OSStatus	AUIOElement::RemoveAudioChannelLayout ()
+{
+	return kAudioUnitErr_InvalidPropertyValue;
+}
+
+
+//_____________________________________________________________________________
+//
+AUScope::~AUScope()
+{
+	for (ElementVector::iterator it = mElements.begin(); it != mElements.end(); ++it)
+		delete *it;
+}
+
+//_____________________________________________________________________________
+//
+void	AUScope::SetNumberOfElements(UInt32 numElements)
+{
+	if (mDelegate)
+		return mDelegate->SetNumberOfElements(numElements);
+
+	if (numElements > mElements.size()) {
+		mElements.reserve(numElements);
+		while (numElements > mElements.size()) {
+			AUElement *elem = mCreator->CreateElement(GetScope(), mElements.size());
+			mElements.push_back(elem);
+		}
+	} else
+		while (numElements < mElements.size()) {
+			AUElement *elem = mElements.back();
+			mElements.pop_back();
+			delete elem;
+		}
+}
+
+//_____________________________________________________________________________
+//
+bool	AUScope::HasElementWithName () const
+{
+	for (UInt32 i = 0; i < GetNumberOfElements(); ++i) {
+		AUElement *	el = const_cast<AUScope*>(this)->GetElement (i);
+		if (el && el->HasName()) {
+			return true;
+		}
+	}
+	return false;
+}
+
+//_____________________________________________________________________________
+//
+
+void	AUScope::AddElementNamesToDict (CFMutableDictionaryRef & inNameDict)
+{
+	if (HasElementWithName())
+	{
+		static char string[32];
+		CFMutableDictionaryRef elementDict = CFDictionaryCreateMutable	(NULL, 0,
+								&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+		CFStringRef str;
+		for (UInt32 i = 0; i < GetNumberOfElements(); ++i) {
+			AUElement *	el = GetElement (i);
+			if (el && el->HasName()) {
+				snprintf (string, sizeof(string), "%d", int(i));
+				str = CFStringCreateWithCString (NULL, string, kCFStringEncodingASCII);
+				CFDictionarySetValue (elementDict, str, el->GetName());
+				CFRelease (str);
+			}
+		}
+
+		snprintf (string, sizeof(string), "%d", int(mScope));
+		str = CFStringCreateWithCString (NULL, string, kCFStringEncodingASCII);
+		CFDictionarySetValue (inNameDict, str, elementDict);
+		CFRelease (str);
+		CFRelease (elementDict);
+	}
+}
+
+//_____________________________________________________________________________
+//
+bool	AUScope::RestoreElementNames (CFDictionaryRef& inNameDict)
+{
+	static char string[32];
+
+	//first we have to see if we have enough elements and if not create them
+	bool didAddElements = false;
+	unsigned int maxElNum = 0;
+	
+	int dictSize = CFDictionaryGetCount(inNameDict);
+	CFStringRef * keys = (CFStringRef*)CA_malloc (dictSize * sizeof (CFStringRef));
+	CFDictionaryGetKeysAndValues (inNameDict, reinterpret_cast<const void**>(keys), NULL);
+	for (int i = 0; i < dictSize; i++)
+	{
+		unsigned int intKey;
+		CFStringGetCString (keys[i], string, 32, kCFStringEncodingASCII);
+		sscanf (string, "%u", &intKey);
+		if (UInt32(intKey) > maxElNum)
+			maxElNum = intKey;
+	}
+	
+	if (maxElNum >= GetNumberOfElements()) {
+		SetNumberOfElements (maxElNum+1);
+		didAddElements = true;
+	}
+		
+		// OK, now we have the number of elements that we need - lets restate their names
+	for (int i = 0; i < dictSize; i++)
+	{
+		CFStringRef elName = reinterpret_cast<CFStringRef>(CFDictionaryGetValue (inNameDict,  keys[i]));
+		int intKey;
+		CFStringGetCString (keys[i], string, 32, kCFStringEncodingASCII);
+		sscanf (string, "%d", &intKey);
+		GetElement (intKey)->SetName (elName);
+	}
+	free (keys);
+	
+	return didAddElements;
+}
+
diff --git a/architecture/AU/AUPublic/AUBase/AUScopeElement.h b/architecture/AU/AUPublic/AUBase/AUScopeElement.h
new file mode 100644
index 0000000..054684f
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/AUScopeElement.h
@@ -0,0 +1,544 @@
+/*
+     File: AUScopeElement.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUScopeElement_h__
+#define __AUScopeElement_h__
+
+#include <map>
+#include <vector>
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <AudioUnit/AudioUnit.h>
+#else
+	#include <AudioUnit.h>
+#endif
+#include "ComponentBase.h"
+#include "AUBuffer.h"
+
+
+class AUBase;
+
+// ____________________________________________________________________________
+//
+// represents a parameter's value (either constant or ramped)
+/*! @class ParameterMapEvent */
+class ParameterMapEvent
+{
+public:
+/*! @ctor ParameterMapEvent */
+	ParameterMapEvent() 
+		: mEventType(kParameterEvent_Immediate), mBufferOffset(0), mDurationInFrames(0), mValue1(0.0f), mValue2(0.0f), mSliceDurationFrames(0) 
+		{}
+
+/*! @ctor ParameterMapEvent */
+	ParameterMapEvent(AudioUnitParameterValue inValue)
+		: mEventType(kParameterEvent_Immediate), mBufferOffset(0), mDurationInFrames(0), mValue1(inValue), mValue2(inValue), mSliceDurationFrames(0) 
+		{}
+		
+	// constructor for scheduled event
+/*! @ctor ParameterMapEvent */
+	ParameterMapEvent(	const AudioUnitParameterEvent 	&inEvent,
+						UInt32 							inSliceOffsetInBuffer,
+						UInt32							inSliceDurationFrames )
+	{
+		SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames );
+	};
+	
+/*! @method SetScheduledEvent */
+	void SetScheduledEvent(	const AudioUnitParameterEvent 	&inEvent,
+							UInt32 							inSliceOffsetInBuffer,
+							UInt32							inSliceDurationFrames )
+	{
+		mEventType = inEvent.eventType;
+		mSliceDurationFrames = inSliceDurationFrames;
+		
+		if(mEventType == kParameterEvent_Immediate )
+		{
+			// constant immediate value for the whole slice
+			mValue1 = inEvent.eventValues.immediate.value;
+			mValue2 = mValue1;
+			mDurationInFrames = inSliceDurationFrames;
+			mBufferOffset = 0;
+		}
+		else
+		{
+			mDurationInFrames 	= 	inEvent.eventValues.ramp.durationInFrames;
+			mBufferOffset 		= 	inEvent.eventValues.ramp.startBufferOffset - inSliceOffsetInBuffer;	// shift over for this slice
+			mValue1 			= 	inEvent.eventValues.ramp.startValue;
+			mValue2 			= 	inEvent.eventValues.ramp.endValue;
+		}
+	};
+	
+	
+	
+/*! @method GetEventType */
+	AUParameterEventType		GetEventType() const {return mEventType;};
+
+/*! @method GetValue */
+	AudioUnitParameterValue		GetValue() const {return mValue1;};	// only valid if immediate event type
+/*! @method GetEndValue */
+	AudioUnitParameterValue		GetEndValue() const {return mValue2;};	// only valid if immediate event type
+/*! @method SetValue */
+	void						SetValue(AudioUnitParameterValue inValue) 
+								{
+									mEventType = kParameterEvent_Immediate; 
+									mValue1 = inValue; 
+									mValue2 = inValue;
+								}
+	
+	// interpolates the start and end values corresponding to the current processing slice
+	// most ramp parameter implementations will want to use this method
+	// the start value will correspond to the start of the slice
+	// the end value will correspond to the end of the slice
+/*! @method GetRampSliceStartEnd */
+	void					GetRampSliceStartEnd(	AudioUnitParameterValue &	outStartValue,
+													AudioUnitParameterValue &	outEndValue,
+													AudioUnitParameterValue &	outValuePerFrameDelta )
+	{
+		if (mEventType == kParameterEvent_Ramped) {
+			outValuePerFrameDelta = (mValue2 - mValue1) / mDurationInFrames;
+		
+			outStartValue = mValue1 + outValuePerFrameDelta * (-mBufferOffset);	// corresponds to frame 0 of this slice
+			outEndValue = outStartValue +  outValuePerFrameDelta * mSliceDurationFrames;
+		} else {
+			outValuePerFrameDelta = 0;
+			outStartValue = outEndValue = mValue1;
+		}
+	};
+
+	// Some ramp parameter implementations will want to interpret the ramp using their
+	// own interpolation method (perhaps non-linear)
+	// This method gives the raw ramp information, relative to this processing slice
+	// for the client to interpret as desired
+/*! @method GetRampInfo */
+	void					GetRampInfo(	SInt32 	&					outBufferOffset,
+											UInt32 	&					outDurationInFrames,
+											AudioUnitParameterValue &	outStartValue,
+											AudioUnitParameterValue &	outEndValue )
+	{
+		outBufferOffset = mBufferOffset;
+		outDurationInFrames = mDurationInFrames;
+		outStartValue = mValue1;
+		outEndValue = mValue2;
+	};
+
+#if DEBUG
+	void					Print()
+	{
+		printf("ParameterEvent @ %p\n", this);
+		printf("	mEventType = %d\n", (int)mEventType);
+		printf("	mBufferOffset = %d\n", (int)mBufferOffset);
+		printf("	mDurationInFrames = %d\n", (int)mDurationInFrames);
+		printf("	mSliceDurationFrames = %d\n", (int)mSliceDurationFrames);
+		printf("	mValue1 = %.5f\n", mValue1);
+		printf("	mValue2 = %.5f\n", mValue2);
+	}
+#endif
+
+private:	
+	AUParameterEventType		mEventType;
+	
+	SInt32						mBufferOffset;		// ramp start offset relative to start of this slice (may be negative)
+	UInt32						mDurationInFrames;	// total duration of ramp parameter
+	AudioUnitParameterValue     mValue1;				// value if immediate : startValue if ramp
+	AudioUnitParameterValue		mValue2;				// endValue (only used for ramp)
+	
+	UInt32					mSliceDurationFrames;	// duration of this processing slice 
+};
+
+
+
+// ____________________________________________________________________________
+//
+class AUIOElement;
+
+/*! @class AUElement */
+class AUElement {
+public:
+/*! @ctor AUElement */
+								AUElement(AUBase *audioUnit) : mAudioUnit(audioUnit),
+									mUseIndexedParameters(false), mElementName(0) { }
+	
+/*! @dtor ~AUElement */
+	virtual						~AUElement() { if (mElementName) CFRelease (mElementName); }
+	
+/*! @method GetNumberOfParameters */
+	virtual UInt32				GetNumberOfParameters()
+	{
+		if(mUseIndexedParameters) return mIndexedParameters.size(); else return mParameters.size();
+	}
+/*! @method GetParameterList */
+	virtual void				GetParameterList(AudioUnitParameterID *outList);
+		
+/*! @method GetParameter */
+	AudioUnitParameterValue		GetParameter(AudioUnitParameterID paramID);
+/*! @method SetParameter */
+	void						SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value, bool okWhenInitialized = false);
+	// Only set okWhenInitialized to true when you know the outside world cannot access this element. Otherwise the parameter map could get corrupted. 
+
+	// interpolates the start and end values corresponding to the current processing slice
+	// most ramp parameter implementations will want to use this method
+/*! @method GetRampSliceStartEnd */
+	void						GetRampSliceStartEnd(	AudioUnitParameterID	paramID,
+													AudioUnitParameterValue &	outStartValue,
+													AudioUnitParameterValue &	outEndValue,
+													AudioUnitParameterValue &	outValuePerFrameDelta );
+													
+/*! @method GetEndValue */
+	AudioUnitParameterValue		GetEndValue(	AudioUnitParameterID		paramID);
+
+/*! @method SetRampParameter */
+	void						SetScheduledEvent(	AudioUnitParameterID 			paramID,
+													const AudioUnitParameterEvent 	&inEvent,
+													UInt32 							inSliceOffsetInBuffer,
+													UInt32							inSliceDurationFrames,
+													bool							okWhenInitialized = false );
+	// Only set okWhenInitialized to true when you know the outside world cannot access this element. Otherwise the parameter map could get corrupted. 
+
+
+/*! @method GetAudioUnit */
+	AUBase *					GetAudioUnit() const { return mAudioUnit; };
+
+/*! @method SaveState */
+	void						SaveState(CFMutableDataRef data);
+/*! @method RestoreState */
+	const UInt8 *				RestoreState(const UInt8 *state);
+/*! @method GetName */
+	CFStringRef					GetName () const { return mElementName; }
+/*! @method SetName */
+	void						SetName (CFStringRef inName);
+/*! @method HasName */
+	bool						HasName () const { return mElementName != 0; }
+/*! @method UseIndexedParameters */
+	virtual void				UseIndexedParameters(int inNumberOfParameters);
+
+/*! @method AsIOElement*/
+	virtual AUIOElement*		AsIOElement () { return NULL; }
+	
+protected:
+	inline ParameterMapEvent&	GetParamEvent(AudioUnitParameterID paramID);
+	
+private:
+	typedef std::map<AudioUnitParameterID, ParameterMapEvent, std::less<AudioUnitParameterID> > ParameterMap;
+	
+/*! @var mAudioUnit */
+	AUBase *						mAudioUnit;
+/*! @var mParameters */
+	ParameterMap					mParameters;
+
+/*! @var mUseIndexedParameters */
+	bool							mUseIndexedParameters;
+/*! @var mIndexedParameters */
+	std::vector<ParameterMapEvent>	mIndexedParameters;
+	
+/*! @var mElementName */
+	CFStringRef						mElementName;
+};
+
+
+
+// ____________________________________________________________________________
+//
+/*! @class AUIOElement */
+class AUIOElement : public AUElement {
+public:
+/*! @ctor AUIOElement */
+								AUIOElement(AUBase *audioUnit);
+
+/*! @method GetStreamFormat */
+	const CAStreamBasicDescription &GetStreamFormat() const { return mStreamFormat; }
+	
+/*! @method SetStreamFormat */
+	virtual OSStatus			SetStreamFormat(const CAStreamBasicDescription &desc);
+
+/*! @method AllocateBuffer */
+	virtual void				AllocateBuffer(UInt32 inFramesToAllocate = 0);
+/*! @method DeallocateBuffer */
+	void						DeallocateBuffer();
+/*! @method NeedsBufferSpace */
+	virtual bool				NeedsBufferSpace() const = 0;
+
+/*! @method DeallocateBuffer */
+	void						SetWillAllocateBuffer(bool inFlag) { 
+									mWillAllocate = inFlag; 
+								}
+/*! @method DeallocateBuffer */
+	bool						WillAllocateBuffer() const { 
+									return mWillAllocate; 
+								}
+	
+/*! @method UseExternalBuffer */
+	void						UseExternalBuffer(const AudioUnitExternalBuffer &buf) {
+									mIOBuffer.UseExternalBuffer(mStreamFormat, buf);
+								}
+/*! @method PrepareBuffer */
+	AudioBufferList &			PrepareBuffer(UInt32 nFrames) {
+									if (mWillAllocate)
+										return mIOBuffer.PrepareBuffer(mStreamFormat, nFrames);
+									throw OSStatus(kAudioUnitErr_InvalidPropertyValue);
+								}
+/*! @method PrepareNullBuffer */
+	AudioBufferList &			PrepareNullBuffer(UInt32 nFrames) {
+									return mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames);
+								}
+/*! @method SetBufferList */
+	AudioBufferList &			SetBufferList(AudioBufferList &abl) { return mIOBuffer.SetBufferList(abl); }
+/*! @method SetBuffer */
+	void						SetBuffer(UInt32 index, AudioBuffer &ab) { mIOBuffer.SetBuffer(index, ab); }
+/*! @method InvalidateBufferList */
+	void						InvalidateBufferList() { mIOBuffer.InvalidateBufferList(); }
+
+/*! @method GetBufferList */
+	AudioBufferList &			GetBufferList() const { return mIOBuffer.GetBufferList(); }
+
+/*! @method GetChannelData */
+	AudioUnitSampleType *		GetChannelData(int ch) const {
+									if (mStreamFormat.IsInterleaved())
+										return static_cast<AudioUnitSampleType *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch;
+									else
+										return static_cast<AudioUnitSampleType *>(mIOBuffer.GetBufferList().mBuffers[ch].mData);
+								}
+	Float32 *					GetFloat32ChannelData(int ch) const {
+									if (mStreamFormat.IsInterleaved())
+										return static_cast<Float32 *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch;
+									else
+										return static_cast<Float32 *>(mIOBuffer.GetBufferList().mBuffers[ch].mData);
+								}
+	SInt32 *					GetSInt32ChannelData(int ch) const {
+									if (mStreamFormat.IsInterleaved())
+										return static_cast<SInt32 *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch;
+									else
+										return static_cast<SInt32 *>(mIOBuffer.GetBufferList().mBuffers[ch].mData);
+								}
+	SInt16 *					GetInt16ChannelData(int ch) const {
+									if (mStreamFormat.IsInterleaved())
+										return static_cast<SInt16 *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch;
+									else
+										return static_cast<SInt16 *>(mIOBuffer.GetBufferList().mBuffers[ch].mData);
+								}
+
+/*! @method CopyBufferListTo */
+	void						CopyBufferListTo(AudioBufferList &abl) const {
+									mIOBuffer.CopyBufferListTo(abl);
+								}
+/*! @method CopyBufferContentsTo */
+	void						CopyBufferContentsTo(AudioBufferList &abl) const {
+									mIOBuffer.CopyBufferContentsTo(abl);
+								}
+
+/*	UInt32						BytesToFrames(UInt32 nBytes) { return nBytes / mStreamFormat.mBytesPerFrame; }
+	UInt32						BytesToFrames(AudioBufferList &abl) {
+									return BytesToFrames(abl.mBuffers[0].mDataByteSize);
+								}
+	UInt32						FramesToBytes(UInt32 nFrames) { return nFrames * mStreamFormat.mBytesPerFrame; }*/
+
+/*! @method IsInterleaved */
+	bool						IsInterleaved() const { return mStreamFormat.IsInterleaved(); }
+/*! @method NumberChannels */
+	UInt32						NumberChannels() const { return mStreamFormat.NumberChannels(); }
+/*! @method NumberInterleavedChannels */
+	UInt32						NumberInterleavedChannels() const { return mStreamFormat.NumberInterleavedChannels(); }
+
+/*! @method GetChannelMapTags */
+	virtual UInt32				GetChannelLayoutTags (AudioChannelLayoutTag	*outLayoutTagsPtr);
+
+/*! @method GetAudioChannelLayout */
+	virtual UInt32				GetAudioChannelLayout (AudioChannelLayout	*outMapPtr, Boolean	&outWritable);
+
+/*! @method SetAudioChannelLayout */
+	virtual OSStatus			SetAudioChannelLayout (const AudioChannelLayout &inData);
+		
+/*! @method RemoveAudioChannelLayout */
+	virtual OSStatus			RemoveAudioChannelLayout ();
+
+/*! @method AsIOElement*/
+	virtual AUIOElement*		AsIOElement () { return this; }
+
+protected:
+/*! @var mStreamFormat */
+	CAStreamBasicDescription	mStreamFormat;
+/*! @var mIOBuffer */
+	AUBufferList				mIOBuffer;	// for input: input proc buffer, only allocated when needed
+											// for output: output cache, usually allocated early on
+/*! @var mWillAllocate */
+	bool						mWillAllocate;
+};
+
+// ____________________________________________________________________________
+//
+// AUScopeDelegates are a way to get virtual scopes.
+/*! @class AUScopeDelegate */
+class AUScopeDelegate {
+public:
+/*! @ctor AUScopeDelegate */
+					AUScopeDelegate() : mCreator(NULL), mScope(0) { }	
+/*! @dtor ~AUScopeDelegate */
+					virtual ~AUScopeDelegate() {}
+	
+/*! @method Initialize */
+	void					Initialize(	AUBase *creator, 
+										AudioUnitScope scope, 
+										UInt32 numElements)
+	{
+		mCreator = creator;
+		mScope = scope;
+		SetNumberOfElements(numElements);
+	}
+	
+/*! @method SetNumberOfElements */
+	virtual void			SetNumberOfElements(UInt32 numElements) = 0;
+	
+/*! @method GetNumberOfElements */
+	virtual UInt32			GetNumberOfElements()	 = 0;
+	
+/*! @method GetElement */
+	virtual AUElement *		GetElement(UInt32 elementIndex) = 0;
+	
+	AUBase *			GetCreator() const { return mCreator; }
+	AudioUnitScope		GetScope() const { return mScope; }
+	
+
+private:
+/*! @var mCreator */
+	AUBase *					mCreator;
+/*! @var mScope */
+	AudioUnitScope				mScope;
+};
+
+
+
+// ____________________________________________________________________________
+//
+/*! @class AUScope */
+class AUScope {
+public:
+/*! @ctor AUScope */
+					AUScope() : mCreator(NULL), mScope(0), mDelegate(0) { }	
+/*! @dtor ~AUScope */
+					~AUScope();
+	
+/*! @method Initialize */
+	void			Initialize(AUBase *creator, 
+								AudioUnitScope scope, 
+								UInt32 numElements)
+	{
+		if (mDelegate)
+			return mDelegate->Initialize(creator, scope, numElements);
+			
+		mCreator = creator;
+		mScope = scope;
+		SetNumberOfElements(numElements);
+	}
+	
+/*! @method SetNumberOfElements */
+	void			SetNumberOfElements(UInt32 numElements);
+	
+/*! @method GetNumberOfElements */
+	UInt32			GetNumberOfElements()	const	
+	{
+		if (mDelegate)
+			return mDelegate->GetNumberOfElements();
+			
+		return mElements.size(); 
+	}
+	
+/*! @method GetElement */
+	AUElement *		GetElement(UInt32 elementIndex) const
+	{
+		if (mDelegate)
+			return mDelegate->GetElement(elementIndex);
+
+		ElementVector::const_iterator i = mElements.begin() + elementIndex;
+			// catch passing -1 in as the elementIndex - causes a wrap around
+		return (i >= mElements.end() || i < mElements.begin()) ? NULL : *i;
+	}
+	
+/*! @method SafeGetElement */
+	AUElement *		SafeGetElement(UInt32 elementIndex)
+	{
+		AUElement *element = GetElement(elementIndex);
+		if (element == NULL)
+			COMPONENT_THROW(kAudioUnitErr_InvalidElement);
+		return element;
+	}
+	
+/*! @method GetIOElement */
+	AUIOElement *	GetIOElement(UInt32 elementIndex) const
+	{
+		AUElement *element = GetElement(elementIndex);
+		AUIOElement *ioel = element ? element->AsIOElement () : NULL;
+		if (!ioel)
+			COMPONENT_THROW (kAudioUnitErr_InvalidElement);
+		return ioel;
+	}
+	
+/*! @method HasElementWithName */
+	bool			HasElementWithName () const;
+	
+/*! @method AddElementNamesToDict */
+	void			AddElementNamesToDict (CFMutableDictionaryRef & inNameDict);
+	
+	bool			RestoreElementNames (CFDictionaryRef& inNameDict);
+	
+	AudioUnitScope		GetScope() const { return mScope; }
+
+	void SetDelegate(AUScopeDelegate* inDelegate) { mDelegate = inDelegate; }
+	
+private:
+	typedef std::vector<AUElement *> ElementVector;
+/*! @var mCreator */
+	AUBase *					mCreator;
+/*! @var mScope */
+	AudioUnitScope				mScope;
+/*! @var mElements */
+	ElementVector				mElements;
+/*! @var mDelegate */
+	AUScopeDelegate *			mDelegate;
+};
+
+
+
+#endif // __AUScopeElement_h__
diff --git a/architecture/AU/AUPublic/AUBase/ComponentBase.cpp b/architecture/AU/AUPublic/AUBase/ComponentBase.cpp
new file mode 100644
index 0000000..d33bbc7
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/ComponentBase.cpp
@@ -0,0 +1,370 @@
+/*
+     File: ComponentBase.cpp 
+ Abstract:  ComponentBase.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "ComponentBase.h"
+#include "CAXException.h"
+
+#if TARGET_OS_MAC
+pthread_mutex_t ComponentInitLocker::sComponentOpenMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_once_t ComponentInitLocker::sOnce = PTHREAD_ONCE_INIT;
+
+void ComponentInitLocker::InitComponentInitLocker()
+{
+	// have to do this because OS X lacks PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP
+	pthread_mutexattr_t attr;
+	pthread_mutexattr_init(&attr);
+	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+	pthread_mutex_init(&sComponentOpenMutex, &attr);
+	pthread_mutexattr_destroy(&attr);
+}
+
+#elif TARGET_OS_WIN32
+CAGuard	ComponentInitLocker::sComponentOpenGuard("sComponentOpenGuard");
+#endif
+
+ComponentBase::EInstanceType ComponentBase::sNewInstanceType;
+
+static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc);
+#if !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_WIN32
+	static OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc);
+#endif
+
+ComponentBase::ComponentBase(AudioComponentInstance inInstance) 
+	: mComponentInstance(inInstance), 
+	  mInstanceType(sNewInstanceType) 
+{ 
+	GetComponentDescription(); 
+}
+
+ComponentBase::~ComponentBase()
+{
+}
+
+void			ComponentBase::PostConstructor()
+{
+}
+
+void			ComponentBase::PreDestructor()
+{
+}
+
+#define ACPI	((AudioComponentPlugInInstance *)self)
+#define ACImp	((ComponentBase *)&ACPI->mInstanceStorage)
+
+OSStatus ComponentBase::AP_Open(void *self, AudioUnit compInstance)
+{
+	OSStatus result = noErr;
+	try {
+		ComponentInitLocker lock;
+		
+		ComponentBase::sNewInstanceType = ComponentBase::kAudioComponentInstance;
+		ComponentBase *cb = (ComponentBase *)(*ACPI->mConstruct)(&ACPI->mInstanceStorage, compInstance);
+		cb->PostConstructor();	// allows base class to do additional initialization
+		// once the derived class is fully constructed
+		result = noErr;
+	}
+	COMPONENT_CATCH
+	if (result)
+		delete ACPI;
+	return result;
+}
+
+OSStatus ComponentBase::AP_Close(void *self)
+{
+	OSStatus result = noErr;
+	try {
+		if (ACImp) {
+			ACImp->PreDestructor();
+			(*ACPI->mDestruct)(&ACPI->mInstanceStorage);
+			free(self);
+		}
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+OSStatus		ComponentBase::Version()
+{
+	return 0x00000001;
+}
+
+OSStatus		ComponentBase::ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This)
+{
+	if (This == NULL) return kAudio_ParamError;
+
+	OSStatus result = noErr;
+	
+	switch (p->what) {
+	case kComponentCloseSelect:
+		This->PreDestructor();
+		delete This;
+		break;
+	
+	case kComponentVersionSelect:
+		result = This->Version();
+		break;
+
+	case kComponentCanDoSelect:
+		switch (GetSelectorForCanDo(p)) {
+		case kComponentOpenSelect:
+		case kComponentCloseSelect:
+		case kComponentVersionSelect:
+		case kComponentCanDoSelect:
+			return 1;
+		default:
+			return 0;
+		}
+		
+	default:
+		result = badComponentSelector;
+		break;
+	}
+	return result;
+}
+
+SInt16		ComponentBase::GetSelectorForCanDo(ComponentParameters *params)
+{
+	if (params->what != kComponentCanDoSelect) return 0;
+	
+	#if TARGET_CPU_X86
+		SInt16 sel = params->params[0];
+	#elif TARGET_CPU_X86_64
+		SInt16 sel = params->params[1];
+	#elif TARGET_CPU_PPC
+		SInt16 sel = (params->params[0] >> 16);
+	#else
+		SInt16 sel = params->params[0];
+	#endif
+	
+	return sel;
+/*		
+		printf ("flags:%d, paramSize: %d, what: %d\n\t", params->flags, params->paramSize, params->what);
+		for (int i = 0; i < params->paramSize; ++i) {
+			printf ("[%d]:%d(0x%x), ", i, params->params[i], params->params[i]);
+		}
+		printf("\n\tsel:%d\n", sel);
+*/
+}
+
+#endif
+
+#if CA_DO_NOT_USE_AUDIO_COMPONENT 
+static OSStatus ComponentBase_GetComponentDescription (const AudioComponentInstance & inInstance, AudioComponentDescription &outDesc);
+#endif
+
+AudioComponentDescription ComponentBase::GetComponentDescription() const
+{
+	AudioComponentDescription desc;
+	OSStatus result = 1;
+	
+	if (IsPluginObject()) {
+		ca_require_noerr(result = CB_GetComponentDescription (mComponentInstance, &desc), home);
+	}
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	else {
+		ca_require_noerr(result = CMgr_GetComponentDescription (mComponentInstance, &desc), home);	
+	}
+#endif
+
+home:
+	if (result)
+		memset (&desc, 0, sizeof(AudioComponentDescription));
+	
+	return desc;
+}
+
+#if CA_USE_AUDIO_PLUGIN_ONLY
+// everything we need is there and we should be linking against it
+static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
+{
+	AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
+	if (comp)
+		return AudioComponentGetDescription(comp, outDesc);
+
+	return kAudio_ParamError;
+}
+
+#elif !TARGET_OS_WIN32
+// these are the direct dependencies on ComponentMgr calls that an AU
+// that is a component mgr is dependent on
+
+// these are dynamically loaded so that these calls will work on Leopard
+#include <dlfcn.h>
+
+static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
+{
+	typedef AudioComponent (*AudioComponentInstanceGetComponentProc) (AudioComponentInstance);
+	static AudioComponentInstanceGetComponentProc aciGCProc = NULL;
+	
+	typedef OSStatus (*AudioComponentGetDescriptionProc)(AudioComponent, AudioComponentDescription *);
+	static AudioComponentGetDescriptionProc acGDProc = NULL;
+	
+	static int doneInit = 0;
+	if (doneInit == 0) {
+		doneInit = 1;	
+		void* theImage = dlopen("/System/Library/Frameworks/AudioUnit.framework/AudioUnit", RTLD_LAZY);
+		if (theImage != NULL)
+		{
+			aciGCProc = (AudioComponentInstanceGetComponentProc)dlsym (theImage, "AudioComponentInstanceGetComponent");
+			if (aciGCProc) {
+				acGDProc = (AudioComponentGetDescriptionProc)dlsym (theImage, "AudioComponentGetDescription");
+			}
+		}
+	}
+	
+	OSStatus result = kAudio_UnimplementedError;
+	if (acGDProc && aciGCProc) {
+		AudioComponent comp = (*aciGCProc)(inInstance);
+		if (comp)
+			result = (*acGDProc)(comp, outDesc);
+	} 
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	else {
+		result = CMgr_GetComponentDescription (inInstance, outDesc);
+	}
+#endif
+
+	return result;
+}
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+// these are the direct dependencies on ComponentMgr calls that an AU
+// that is a component mgr is dependent on
+
+// these are dynamically loaded
+
+#include <CoreServices/CoreServices.h>
+#include <AudioUnit/AudioUnit.h>
+#include "CAXException.h"
+#include "ComponentBase.h"
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Component Manager
+// Used for fast dispatch with audio units
+typedef Handle (*GetComponentInstanceStorageProc)(ComponentInstance aComponentInstance);
+static GetComponentInstanceStorageProc sGetComponentInstanceStorageProc = NULL;
+
+typedef OSErr (*GetComponentInfoProc)(Component, ComponentDescription *, void*, void*, void*);
+static GetComponentInfoProc sGetComponentInfoProc = NULL;
+
+typedef void (*SetComponentInstanceStorageProc)(ComponentInstance, Handle);
+static SetComponentInstanceStorageProc sSetComponentInstanceStorageProc = NULL;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+static void CSInitOnce(void* /*unused*/)
+{
+	void *theImage = dlopen("/System/Library/Frameworks/CoreServices.framework/CoreServices", RTLD_LAZY);
+	if (!theImage) return;
+
+	sGetComponentInstanceStorageProc = (GetComponentInstanceStorageProc) dlsym(theImage, "GetComponentInstanceStorage");
+	sGetComponentInfoProc = (GetComponentInfoProc)dlsym (theImage, "GetComponentInfo");
+	sSetComponentInstanceStorageProc = (SetComponentInstanceStorageProc) dlsym(theImage, "SetComponentInstanceStorage");
+}
+
+#if TARGET_OS_MAC
+
+#include <dispatch/dispatch.h>
+
+static dispatch_once_t sCSInitOnce = 0;
+
+static void CSInit ()
+{
+	dispatch_once_f(&sCSInitOnce, NULL, CSInitOnce);
+}
+
+#else 
+
+static void CSInit ()
+{
+	static int sDoCSLoad = 1;
+	if (sDoCSLoad) {
+		sDoCSLoad = 0;
+		CSInitOnce(NULL);
+	}
+}
+
+#endif
+
+OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
+{
+	CSInit();
+	if (sGetComponentInfoProc)
+		return (*sGetComponentInfoProc)((Component)inInstance, (ComponentDescription*)outDesc, NULL, NULL, NULL);
+	return kAudio_UnimplementedError;
+}
+
+Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance)
+{
+	CSInit();
+	if (sGetComponentInstanceStorageProc)
+		return (*sGetComponentInstanceStorageProc)(aComponentInstance);
+	return NULL;
+}
+
+void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage)
+{
+	CSInit();
+	if (sSetComponentInstanceStorageProc)
+		(*sSetComponentInstanceStorageProc)(aComponentInstance, theStorage);
+}
+#endif // !CA_USE_AUDIO_PLUGIN_ONLY
+
+#else
+//#include "ComponentManagerDependenciesWin.h"
+// everything we need is there and we should be linking against it
+static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
+{
+	AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
+	if (comp)
+		return AudioComponentGetDescription(comp, outDesc);
+
+	return kAudio_ParamError;
+}
+
+#endif
+
diff --git a/architecture/AU/AUPublic/AUBase/ComponentBase.h b/architecture/AU/AUPublic/AUBase/ComponentBase.h
new file mode 100644
index 0000000..88dcb63
--- /dev/null
+++ b/architecture/AU/AUPublic/AUBase/ComponentBase.h
@@ -0,0 +1,340 @@
+/*
+     File: ComponentBase.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __ComponentBase_h__
+#define __ComponentBase_h__
+
+#include <new>
+#include "CADebugMacros.h"
+#include "CAXException.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+	#include <AudioUnit/AudioUnit.h>
+
+	#if !CA_USE_AUDIO_PLUGIN_ONLY
+		#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/Components.h>
+	
+		#if	(MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
+			#define AudioComponentInstance			ComponentInstance
+			#define AudioComponentDescription		ComponentDescription
+			#define	AudioComponent					Component
+		#endif
+		Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance);
+		void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage);
+	#endif
+
+	#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
+		typedef Float32 AudioUnitParameterValue;
+	#endif
+	#if COREAUDIOTYPES_VERSION < 1051
+		typedef Float32 AudioUnitSampleType;
+	#endif
+
+	#if !TARGET_OS_WIN32
+		#include <pthread.h>
+	#endif
+
+	#if TARGET_OS_WIN32
+		#include "CAGuard.h"
+	#endif
+#else
+	#include "CoreAudioTypes.h"
+	#if !CA_USE_AUDIO_PLUGIN_ONLY
+		#include "ComponentManagerDependenciesWin.h"
+	#endif
+	#include "AudioUnit.h"
+	#include "CAGuard.h"
+#endif
+
+#ifndef COMPONENT_THROW
+	#if VERBOSE_COMPONENT_THROW
+		#define COMPONENT_THROW(throw_err) \
+			do { DebugMessage(#throw_err); throw static_cast<OSStatus>(throw_err); } while (0)
+	#else
+		#define COMPONENT_THROW(throw_err) \
+			throw static_cast<OSStatus>(throw_err)
+	#endif
+#endif
+
+#define COMPONENT_CATCH \
+	catch (const CAXException &ex) { result = ex.mError; } \
+	catch (std::bad_alloc &) { result = kAudio_MemFullError; } \
+	catch (OSStatus catch_err) { result = catch_err; } \
+	catch (OSErr catch_err) { result = catch_err; } \
+	catch (...) { result = -1; }
+
+/*! @class ComponentBase */
+class ComponentBase {
+public:
+	// classic MacErrors
+	enum { noErr = 0};
+
+	/*! @ctor ComponentBase */
+				ComponentBase(AudioComponentInstance inInstance);
+				
+	/*! @dtor ~ComponentBase */
+	virtual 	~ComponentBase();
+	
+	/*! @method PostConstructor */
+	virtual void			PostConstructor();
+	
+	/*! @method PreDestructor */
+	virtual void			PreDestructor();
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+	/*! @method Version */
+	virtual OSStatus		Version();
+
+	/*! @method ComponentEntryDispatch */
+	static OSStatus		ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This);
+
+	/*! GetSelectorForCanDo */
+	static SInt16		GetSelectorForCanDo(ComponentParameters *params);
+#endif
+	
+	/*! @method GetComponentInstance */
+	AudioComponentInstance		GetComponentInstance() const { return mComponentInstance; }
+
+	/*! @method GetComponentDescription */
+	AudioComponentDescription	GetComponentDescription() const;
+
+	// This global variable is so that new instances know how they were instantiated: via the Component Manager, 
+	// or as AudioComponents. It's ugly, but preferable to altering the constructor of every class in the hierarchy.
+	// It's safe because construction is protected by ComponentInitLocker.
+	enum EInstanceType { kComponentMgrInstance, kAudioComponentInstance };
+	static EInstanceType sNewInstanceType;
+
+	/*! @method IsPluginObject */
+	bool			IsPluginObject () const { return mInstanceType == kAudioComponentInstance; }
+	/*! @method IsCMgrObject */
+	bool			IsCMgrObject () const { return mInstanceType == kComponentMgrInstance; }
+
+	/*! @method AP_Open */
+	static OSStatus AP_Open(void *self, AudioUnit compInstance);
+
+	/*! @method AP_Close */
+	static OSStatus AP_Close(void *self);
+	
+protected:
+	/*! @var mComponentInstance */
+	AudioComponentInstance		mComponentInstance;
+	EInstanceType				mInstanceType;
+};
+
+class ComponentInitLocker 
+{
+#if TARGET_OS_MAC
+public:
+	ComponentInitLocker() 
+	{ 
+		pthread_once(&sOnce, InitComponentInitLocker);
+		pthread_mutex_lock(&sComponentOpenMutex); 
+		mPreviousNewInstanceType = ComponentBase::sNewInstanceType;
+	}
+	~ComponentInitLocker() 
+	{ 
+		ComponentBase::sNewInstanceType = mPreviousNewInstanceType;
+		pthread_mutex_unlock(&sComponentOpenMutex); 
+	}
+private:
+	static pthread_mutex_t sComponentOpenMutex;
+	static pthread_once_t sOnce;
+	static void InitComponentInitLocker();
+	
+#elif TARGET_OS_WIN32
+public:
+	bool sNeedsUnlocking;
+	ComponentInitLocker() { sNeedsUnlocking = sComponentOpenGuard.Lock(); }
+	~ComponentInitLocker() { if(sNeedsUnlocking) { sComponentOpenGuard.Unlock(); } }
+private:
+	static CAGuard	sComponentOpenGuard;
+#endif
+	
+private:
+	ComponentBase::EInstanceType	mPreviousNewInstanceType;
+};
+
+/*! @class AudioComponentPlugInInstance */ 
+struct AudioComponentPlugInInstance {
+	AudioComponentPlugInInterface		mPlugInInterface;
+	void *								(*mConstruct)(void *memory, AudioComponentInstance ci);
+	void								(*mDestruct)(void *memory);
+	void *								mPad[2];				// pad to a 16-byte boundary (in either 32 or 64 bit mode)
+	UInt32								mInstanceStorage;		// the ACI implementation object is constructed into this memory
+																// this member is just a placeholder. it is aligned to a 16byte boundary
+};
+
+/*! @class APFactory */ 
+template <class APMethodLookup, class Implementor>
+class APFactory {
+public:
+	static void *Construct(void *memory, AudioComponentInstance compInstance)
+	{
+		return new(memory) Implementor(compInstance);
+	}
+	
+	static void Destruct(void *memory)
+	{
+		((Implementor *)memory)->~Implementor();
+	}
+
+	// This is the AudioComponentFactoryFunction. It returns an AudioComponentPlugInInstance.
+	// The actual implementation object is not created until Open().
+	static AudioComponentPlugInInterface *Factory(const AudioComponentDescription *inDesc) 
+	{
+		AudioComponentPlugInInstance *acpi = 
+				(AudioComponentPlugInInstance *)malloc( offsetof(AudioComponentPlugInInstance, mInstanceStorage) + sizeof(Implementor) );
+		acpi->mPlugInInterface.Open = ComponentBase::AP_Open;
+		acpi->mPlugInInterface.Close = ComponentBase::AP_Close;
+		acpi->mPlugInInterface.Lookup = APMethodLookup::Lookup;
+		acpi->mPlugInInterface.reserved = NULL;
+		acpi->mConstruct = Construct;
+		acpi->mDestruct = Destruct;
+		acpi->mPad[0] = NULL;
+		acpi->mPad[1] = NULL;
+		return (AudioComponentPlugInInterface*)acpi;
+	}
+	
+	// This is for runtime registration (not for plug-ins loaded from bundles).
+	static AudioComponent Register(UInt32 type, UInt32 subtype, UInt32 manuf, CFStringRef name, UInt32 vers, UInt32 flags=0)
+	{
+		AudioComponentDescription desc = { type, subtype, manuf, flags, 0 };
+		return AudioComponentRegister(&desc, name, vers, Factory); 
+	}
+};
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+/*! @class ComponentEntryPoint 
+ *	@discussion This is only used for a component manager version
+*/
+template <class Class>
+class ComponentEntryPoint {
+public:
+	/*! @method Dispatch */
+	static OSStatus Dispatch(ComponentParameters *params, Class *obj)
+	{
+		OSStatus result = noErr;
+		
+		try {
+			if (params->what == kComponentOpenSelect) {
+				// solve a host of initialization thread safety issues.
+				ComponentInitLocker lock;
+
+				ComponentBase::sNewInstanceType = ComponentBase::kComponentMgrInstance;
+				ComponentInstance ci = (ComponentInstance)(params->params[0]);
+				Class *This = new Class((AudioComponentInstance)ci);
+				This->PostConstructor();	// allows base class to do additional initialization
+											// once the derived class is fully constructed
+				
+				CMgr_SetComponentInstanceStorage(ci, (Handle)This);
+			} else
+				result = Class::ComponentEntryDispatch(params, obj);
+		}
+		COMPONENT_CATCH
+		
+		return result;
+	}
+	
+	/*! @method Register */
+	static Component Register(OSType compType, OSType subType, OSType manufacturer)
+	{
+		ComponentDescription	description = {compType, subType, manufacturer, 0, 0};
+		Component	component = RegisterComponent(&description, (ComponentRoutineUPP) Dispatch, registerComponentGlobal, NULL, NULL, NULL);
+		if (component != NULL) {
+			SetDefaultComponent(component, defaultComponentAnyFlagsAnyManufacturerAnySubType);
+		}
+		return component;
+	}
+};
+
+// these are the macros that are used to generate the Entry Points for a given Audio Plugin
+#if CA_USE_AUDIO_PLUGIN_ONLY
+	#define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \
+		extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \
+		extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \
+			return FactoryType<Class>::Factory(inDesc); \
+		}
+#else
+		// you should be using this macros as it registers both
+		// a plugin and a component mgr version. this can and should be used 
+		// with new and existing audio components (backwards compatible to SL)
+	#define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \
+		extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \
+		extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \
+			return ComponentEntryPoint<Class>::Dispatch(params, obj); \
+		} \
+		extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \
+		extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \
+			return FactoryType<Class>::Factory(inDesc); \
+		}
+		// the only component we still support are the carbon based view components
+		// you should be using this macro now to exclusively register those types
+	#define VIEW_COMPONENT_ENTRY(Class) \
+		extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \
+		extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \
+			return ComponentEntryPoint<Class>::Dispatch(params, obj); \
+		}
+#endif	
+
+	/*! @class ComponentRegistrar */
+template <class Class, OSType Type, OSType Subtype, OSType Manufacturer>
+class ComponentRegistrar {
+public:
+	/*! @ctor ComponentRegistrar */
+	ComponentRegistrar() { ComponentEntryPoint<Class>::Register(Type, Subtype, Manufacturer); }
+};
+
+#define	COMPONENT_REGISTER(Class,Type,Subtype,Manufacturer) \
+	static ComponentRegistrar<Class, Type, Subtype, Manufacturer>	gRegistrar##Class
+#else
+#define COMPONENT_ENTRY(Class)
+#define COMPONENT_REGISTER(Class)
+#define AUDIOCOMPONENT_ENTRY(FactoryType, Class)
+#endif // !CA_USE_AUDIO_PLUGIN_ONLY
+
+
+#endif // __ComponentBase_h__
diff --git a/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.cpp b/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.cpp
new file mode 100644
index 0000000..1ba4f10
--- /dev/null
+++ b/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.cpp
@@ -0,0 +1,463 @@
+/*
+     File: AUEffectBase.cpp 
+ Abstract:  AUEffectBase.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUEffectBase.h"
+
+/* 
+	This class does not deal as well as it should with N-M effects...
+	
+	The problem areas are (if the channels don't match):
+		ProcessInPlace if the channels don't match - there will be problems if InputChan != OutputChan
+		Bypass - its just passing the buffers through when not processing them
+
+	This will be fixed in a future update...
+*/
+
+//_____________________________________________________________________________
+//
+AUEffectBase::AUEffectBase(	AudioComponentInstance	audioUnit,
+							bool					inProcessesInPlace ) :
+	AUBase(audioUnit, 1, 1),		// 1 in bus, 1 out bus
+	mBypassEffect(false),
+	mParamSRDep (false),
+	mProcessesInPlace(inProcessesInPlace),
+	mMainOutput(NULL), mMainInput(NULL)
+#if TARGET_OS_IPHONE
+	, mOnlyOneKernel(false)
+#endif
+{
+}
+
+//_____________________________________________________________________________
+//
+AUEffectBase::~AUEffectBase()
+{
+	Cleanup();
+}
+
+//_____________________________________________________________________________
+//
+void AUEffectBase::Cleanup()
+{
+	for (KernelList::iterator it = mKernelList.begin(); it != mKernelList.end(); ++it)
+		delete *it;
+		
+	mKernelList.clear();
+	mMainOutput = NULL;
+	mMainInput = NULL;
+}
+
+
+//_____________________________________________________________________________
+//
+OSStatus AUEffectBase::Initialize()
+{
+		// get our current numChannels for input and output
+	SInt16 auNumInputs = (SInt16) GetInput(0)->GetStreamFormat().mChannelsPerFrame;
+	SInt16 auNumOutputs = (SInt16) GetOutput(0)->GetStreamFormat().mChannelsPerFrame;
+
+		// does the unit publish specific information about channel configurations?
+    const AUChannelInfo *auChannelConfigs = NULL;
+    UInt32 numIOconfigs = SupportedNumChannels(&auChannelConfigs);
+
+    if ((numIOconfigs > 0) && (auChannelConfigs != NULL))
+    {
+        bool foundMatch = false;
+        for (UInt32 i = 0; (i < numIOconfigs) && !foundMatch; ++i)
+        {
+            SInt16 configNumInputs = auChannelConfigs[i].inChannels;
+            SInt16 configNumOutputs = auChannelConfigs[i].outChannels;
+            if ((configNumInputs < 0) && (configNumOutputs < 0))
+            {
+					// unit accepts any number of channels on input and output
+                if (((configNumInputs == -1) && (configNumOutputs == -2)) 
+					|| ((configNumInputs == -2) && (configNumOutputs == -1)))
+                {
+				    foundMatch = true;
+					// unit accepts any number of channels on input and output IFF they are the same number on both scopes
+                }
+				else if (((configNumInputs == -1) && (configNumOutputs == -1)) && (auNumInputs == auNumOutputs))
+                {
+				    foundMatch = true;
+					// unit has specified a particular number of channels on both scopes
+                }
+				else
+                    continue;
+            }
+            else
+            {
+					// the -1 case on either scope is saying that the unit doesn't care about the 
+					// number of channels on that scope
+                bool inputMatch = (auNumInputs == configNumInputs) || (configNumInputs == -1);
+                bool outputMatch = (auNumOutputs == configNumOutputs) || (configNumOutputs == -1);
+                if (inputMatch && outputMatch)
+                    foundMatch = true;
+            }
+        }
+        if (!foundMatch)
+            return kAudioUnitErr_FormatNotSupported;
+    }
+    else
+    {
+			// there is no specifically published channel info
+			// so for those kinds of effects, the assumption is that the channels (whatever their number)
+			// should match on both scopes
+        if ((auNumOutputs != auNumInputs) || (auNumOutputs == 0))
+		{
+		    return kAudioUnitErr_FormatNotSupported;
+		}
+    }
+
+    MaintainKernels();
+	
+	mMainOutput = GetOutput(0);
+	mMainInput = GetInput(0);
+	
+	const CAStreamBasicDescription& format = GetStreamFormat(kAudioUnitScope_Output, 0);
+	format.IdentifyCommonPCMFormat(mCommonPCMFormat, NULL);
+	mBytesPerFrame = format.mBytesPerFrame;
+	
+    return noErr;
+}
+
+OSStatus			AUEffectBase::Reset(		AudioUnitScope 		inScope,
+								 				AudioUnitElement 	inElement)
+{
+	for (KernelList::iterator it = mKernelList.begin(); it != mKernelList.end(); ++it) {
+		AUKernelBase *kernel = *it;
+		if (kernel != NULL)
+			kernel->Reset();
+	}
+	
+	return AUBase::Reset(inScope, inElement);
+}
+
+OSStatus			AUEffectBase::GetPropertyInfo (AudioUnitPropertyID	inID,
+												AudioUnitScope					inScope,
+												AudioUnitElement				inElement,
+												UInt32 &						outDataSize,
+												Boolean &						outWritable)
+{
+	if (inScope == kAudioUnitScope_Global) {
+		switch (inID) {
+			case kAudioUnitProperty_BypassEffect:
+				outWritable = true;
+				outDataSize = sizeof (UInt32);
+				return noErr;
+			case kAudioUnitProperty_InPlaceProcessing:
+				outWritable = true;
+				outDataSize = sizeof (UInt32);
+				return noErr;
+		}
+	}
+	return AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+}
+
+
+OSStatus			AUEffectBase::GetProperty (AudioUnitPropertyID 		inID,
+									  AudioUnitScope 					inScope,
+									  AudioUnitElement			 		inElement,
+									  void *							outData)
+{
+	if (inScope == kAudioUnitScope_Global) {
+		switch (inID) {
+			case kAudioUnitProperty_BypassEffect:
+				*((UInt32*)outData) = (IsBypassEffect() ? 1 : 0);
+				return noErr;
+			case kAudioUnitProperty_InPlaceProcessing:
+				*((UInt32*)outData) = (mProcessesInPlace ? 1 : 0);
+				return noErr;
+		}
+	}
+	return AUBase::GetProperty (inID, inScope, inElement, outData);
+}
+
+
+OSStatus			AUEffectBase::SetProperty(		AudioUnitPropertyID inID,
+									   AudioUnitScope 		inScope,
+									   AudioUnitElement 	inElement,
+									   const void *			inData,
+									   UInt32 				inDataSize)
+{
+	if (inScope == kAudioUnitScope_Global) {
+		switch (inID) {
+			case kAudioUnitProperty_BypassEffect:
+			{
+				if (inDataSize < sizeof(UInt32))
+					return kAudioUnitErr_InvalidPropertyValue;
+					
+				bool tempNewSetting = *((UInt32*)inData) != 0;
+					// we're changing the state of bypass
+				if (tempNewSetting != IsBypassEffect()) 
+				{
+					if (!tempNewSetting && IsBypassEffect() && IsInitialized()) // turning bypass off and we're initialized
+						Reset(0, 0);
+					SetBypassEffect (tempNewSetting);
+				}
+				return noErr;
+			}
+			case kAudioUnitProperty_InPlaceProcessing:
+				mProcessesInPlace = (*((UInt32*)inData) != 0);
+				return noErr;
+		}
+	}
+	return AUBase::SetProperty (inID, inScope, inElement, inData, inDataSize);
+}
+ 
+
+void	AUEffectBase::MaintainKernels()
+{
+#if TARGET_OS_IPHONE
+	UInt32 nKernels = mOnlyOneKernel ? 1 : GetNumberOfChannels();
+#else 
+	UInt32 nKernels = GetNumberOfChannels();
+#endif
+	
+	if (mKernelList.size() < nKernels) {
+		mKernelList.reserve(nKernels);
+		for (UInt32 i = mKernelList.size(); i < nKernels; ++i)
+			mKernelList.push_back(NewKernel());
+	} else {
+		while (mKernelList.size() > nKernels) {
+			AUKernelBase *kernel = mKernelList.back();
+			delete kernel;
+			mKernelList.pop_back();
+		}
+	}
+	
+	for(unsigned int i = 0; i < nKernels; i++ )
+	{
+		if(mKernelList[i]) {
+			mKernelList[i]->SetChannelNum (i);
+		}
+	}
+}
+
+bool		AUEffectBase::StreamFormatWritable(	AudioUnitScope					scope,
+												AudioUnitElement				element)
+{
+	return IsInitialized() ? false : true;
+}
+
+OSStatus			AUEffectBase::ChangeStreamFormat(	AudioUnitScope				inScope,
+														AudioUnitElement			inElement,
+														const CAStreamBasicDescription & inPrevFormat,
+														const CAStreamBasicDescription & inNewFormat)
+{
+	OSStatus result = AUBase::ChangeStreamFormat(inScope, inElement, inPrevFormat, inNewFormat);
+	if (result == noErr)
+	{	
+		// for the moment this only dependency we know about
+		// where a parameter's range may change is with the sample rate
+		// and effects are only publishing parameters in the global scope!
+		if (GetParamHasSampleRateDependency() && fnotequal(inPrevFormat.mSampleRate, inNewFormat.mSampleRate))
+			PropertyChanged(kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0);
+	}
+
+	return result;
+}
+
+
+// ____________________________________________________________________________
+//
+//	This method is called (potentially repeatedly) by ProcessForScheduledParams()
+//	in order to perform the actual DSP required for this portion of the entire buffer
+//	being processed.  The entire buffer can be divided up into smaller "slices"
+//	according to the timestamps on the scheduled parameters...
+//
+OSStatus		AUEffectBase::ProcessScheduledSlice(	void				*inUserData,
+														UInt32				inStartFrameInBuffer,
+														UInt32				inSliceFramesToProcess,
+														UInt32				inTotalBufferFrames )
+{
+	ScheduledProcessParams	&sliceParams = *((ScheduledProcessParams*)inUserData);
+	
+	AudioUnitRenderActionFlags 	&actionFlags = *sliceParams.actionFlags;
+	AudioBufferList 			&inputBufferList = *sliceParams.inputBufferList;
+	AudioBufferList 			&outputBufferList = *sliceParams.outputBufferList;
+	
+	UInt32 channelSize = inSliceFramesToProcess * mBytesPerFrame;
+		// fix the size of the buffer we're operating on before we render this slice of time
+	for(unsigned int i = 0; i < inputBufferList.mNumberBuffers; i++ ) {
+		inputBufferList.mBuffers[i].mDataByteSize = inputBufferList.mBuffers[i].mNumberChannels * channelSize;
+	}
+
+	for(unsigned int i = 0; i < outputBufferList.mNumberBuffers; i++ ) {
+		outputBufferList.mBuffers[i].mDataByteSize = outputBufferList.mBuffers[i].mNumberChannels * channelSize;
+	}
+		// process the buffer
+	OSStatus result = ProcessBufferLists(actionFlags, inputBufferList, outputBufferList, inSliceFramesToProcess );
+
+		// we just partially processed the buffers, so increment the data pointers to the next part of the buffer to process
+	for(unsigned int i = 0; i < inputBufferList.mNumberBuffers; i++ ) {
+		inputBufferList.mBuffers[i].mData = 
+			(char *)inputBufferList.mBuffers[i].mData + inputBufferList.mBuffers[i].mNumberChannels * channelSize;
+	}
+	
+	for(unsigned int i = 0; i < outputBufferList.mNumberBuffers; i++ ) {
+		outputBufferList.mBuffers[i].mData = 
+			(char *)outputBufferList.mBuffers[i].mData + outputBufferList.mBuffers[i].mNumberChannels * channelSize;
+	}
+	
+	return result;
+}
+
+// ____________________________________________________________________________
+//
+
+OSStatus 	AUEffectBase::Render(	AudioUnitRenderActionFlags &ioActionFlags,
+											const AudioTimeStamp &		inTimeStamp,
+											UInt32						nFrames)
+{
+	if (!HasInput(0))
+		return kAudioUnitErr_NoConnection;
+
+	OSStatus result = noErr;
+
+	result = mMainInput->PullInput(ioActionFlags, inTimeStamp, 0 /* element */, nFrames);
+	
+	if (result == noErr)
+	{
+		if(ProcessesInPlace() && mMainOutput->WillAllocateBuffer())
+		{
+			mMainOutput->SetBufferList(mMainInput->GetBufferList() );
+		}
+
+		if (ShouldBypassEffect())
+		{
+			// leave silence bit alone
+			
+			if(!ProcessesInPlace() )
+			{
+				mMainInput->CopyBufferContentsTo (mMainOutput->GetBufferList());
+			}
+		}
+		else
+		{
+			if(mParamList.size() == 0 )
+			{
+				// this will read/write silence bit
+				result = ProcessBufferLists(ioActionFlags, mMainInput->GetBufferList(), mMainOutput->GetBufferList(), nFrames);
+			}
+			else
+			{
+				// deal with scheduled parameters...
+				
+				AudioBufferList &inputBufferList = mMainInput->GetBufferList();
+				AudioBufferList &outputBufferList = mMainOutput->GetBufferList();
+				
+				ScheduledProcessParams processParams;
+				processParams.actionFlags = &ioActionFlags;
+				processParams.inputBufferList = &inputBufferList;
+				processParams.outputBufferList = &outputBufferList;
+	
+				// divide up the buffer into slices according to scheduled params then
+				// do the DSP for each slice (ProcessScheduledSlice() called for each slice)
+				result = ProcessForScheduledParams(	mParamList,
+													nFrames,
+													&processParams );
+	
+				
+				// fixup the buffer pointers to how they were before we started
+				UInt32 channelSize = nFrames * mBytesPerFrame;
+				for(unsigned int i = 0; i < inputBufferList.mNumberBuffers; i++ ) {
+					UInt32 size = inputBufferList.mBuffers[i].mNumberChannels * channelSize;
+					inputBufferList.mBuffers[i].mData = (char *)inputBufferList.mBuffers[i].mData - size;
+					inputBufferList.mBuffers[i].mDataByteSize = size;
+				}
+				
+				for(unsigned int i = 0; i < outputBufferList.mNumberBuffers; i++ ) {
+					UInt32 size = outputBufferList.mBuffers[i].mNumberChannels * channelSize;
+					outputBufferList.mBuffers[i].mData = (char *)outputBufferList.mBuffers[i].mData - size;
+					outputBufferList.mBuffers[i].mDataByteSize = size;
+				}
+			}
+		}
+	
+		if ( (ioActionFlags & kAudioUnitRenderAction_OutputIsSilence) && !ProcessesInPlace() )
+		{
+			AUBufferList::ZeroBuffer(mMainOutput->GetBufferList() );
+		}
+	}
+	
+	return result;
+}
+
+
+OSStatus	AUEffectBase::ProcessBufferLists(
+									AudioUnitRenderActionFlags &	ioActionFlags,
+									const AudioBufferList &			inBuffer,
+									AudioBufferList &				outBuffer,
+									UInt32							inFramesToProcess )
+{
+	// interleaved (or mono)
+	switch (mCommonPCMFormat) {
+		case CAStreamBasicDescription::kPCMFormatFloat32 :
+			ProcessBufferListsT<Float32>(ioActionFlags, inBuffer, outBuffer, inFramesToProcess);
+			break;
+		case CAStreamBasicDescription::kPCMFormatFixed824 :
+			ProcessBufferListsT<SInt32>(ioActionFlags, inBuffer, outBuffer, inFramesToProcess);
+			break;
+		case CAStreamBasicDescription::kPCMFormatInt16 :
+			ProcessBufferListsT<SInt16>(ioActionFlags, inBuffer, outBuffer, inFramesToProcess);
+			break;
+		default :
+			throw CAException(kAudio_UnimplementedError);
+	}
+	
+	return noErr;
+}
+
+Float64		AUEffectBase::GetSampleRate()
+{
+	return GetOutput(0)->GetStreamFormat().mSampleRate;
+}
+
+UInt32		AUEffectBase::GetNumberOfChannels()
+{
+	return GetOutput(0)->GetStreamFormat().mChannelsPerFrame;
+}
+
diff --git a/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.h b/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.h
new file mode 100644
index 0000000..7d38d97
--- /dev/null
+++ b/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.h
@@ -0,0 +1,391 @@
+/*
+     File: AUEffectBase.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUEffectBase_h__
+#define __AUEffectBase_h__
+
+#include "AUBase.h"
+#include "AUSilentTimeout.h"
+#include "CAException.h"
+
+class AUKernelBase;
+
+//	Base class for an effect with one input stream, one output stream,
+//	any number of channels.
+	/*! @class AUEffectBase */
+class AUEffectBase : public AUBase {
+public:
+	/*! @ctor AUEffectBase */
+								AUEffectBase(	AudioComponentInstance		audioUnit,
+												bool						inProcessesInPlace = true );
+	/*! @dtor ~AUEffectBase */
+								~AUEffectBase();
+	
+	/*! @method Initialize */
+	virtual OSStatus			Initialize();
+
+	/*! @method Cleanup */
+	virtual void				Cleanup();
+
+
+	/*! @method Reset */
+	virtual OSStatus			Reset(		AudioUnitScope 				inScope,
+											AudioUnitElement 			inElement);
+
+	/*! @method GetPropertyInfo */
+	virtual OSStatus			GetPropertyInfo (AudioUnitPropertyID	inID,
+											AudioUnitScope				inScope,
+											AudioUnitElement			inElement,
+											UInt32 &					outDataSize,
+											Boolean &					outWritable);
+
+	/*! @method GetProperty */
+	virtual OSStatus			GetProperty (AudioUnitPropertyID 		inID,
+											AudioUnitScope 				inScope,
+											AudioUnitElement	 		inElement,
+											void *						outData);
+
+	/*! @method SetProperty */
+	virtual OSStatus			SetProperty(AudioUnitPropertyID 		inID,
+											AudioUnitScope 				inScope,
+											AudioUnitElement 			inElement,
+											const void *				inData,
+											UInt32 						inDataSize);
+
+	/*! @method StreamFormatWritable */
+	virtual bool				StreamFormatWritable (AudioUnitScope	scope,
+											AudioUnitElement			element);
+
+	/*! @method ChangeStreamFormat */
+	virtual	OSStatus			ChangeStreamFormat (
+										AudioUnitScope						inScope,
+										AudioUnitElement					inElement,
+										const CAStreamBasicDescription & 	inPrevFormat,
+										const CAStreamBasicDescription &	inNewFormat);
+
+	/*! @method Render */
+	virtual OSStatus 	Render(AudioUnitRenderActionFlags &		ioActionFlags,
+										const AudioTimeStamp &			inTimeStamp,
+										UInt32							inNumberFrames);
+
+	// our virtual methods
+	
+	// If your unit processes N to N channels, and there are no interactions between channels,
+	// it can override NewKernel to create a mono processing object per channel.  Otherwise,
+	// don't override NewKernel, and instead, override ProcessBufferLists.
+	/*! @method NewKernel */
+	virtual AUKernelBase *		NewKernel() { return NULL; }
+
+	/*! @method ProcessBufferLists */
+	virtual OSStatus			ProcessBufferLists(
+											AudioUnitRenderActionFlags &	ioActionFlags,
+											const AudioBufferList &			inBuffer,
+											AudioBufferList &				outBuffer,
+											UInt32							inFramesToProcess );
+
+	// convenience format accessors (use output 0's format)
+	/*! @method GetSampleRate */
+	Float64						GetSampleRate();
+	
+	/*! @method GetNumberOfChannels */
+	UInt32						GetNumberOfChannels();
+
+	// convenience wrappers for accessing parameters in the global scope
+	/*! @method SetParameter */
+	void						SetParameter(			AudioUnitParameterID			paramID,
+														AudioUnitParameterValue			value)
+								{
+									Globals()->SetParameter(paramID, value);
+								}
+    // since we overload SetParameter() as above, the following method is required to
+    // not hide the virtual function in base class
+    /*! @method SetParameter */
+	virtual OSStatus 	SetParameter(AudioUnitParameterID			inID,
+                                     AudioUnitScope 				inScope,
+                                     AudioUnitElement 				inElement,
+                                     AudioUnitParameterValue		inValue,
+                                     UInt32							inBufferOffsetInFrames)
+                        {
+                            return AUBase::SetParameter(inID, inScope, inElement, inValue, inBufferOffsetInFrames);
+                        }
+
+	/*! @method GetParameter */
+	AudioUnitParameterValue		GetParameter(			AudioUnitParameterID			paramID )
+								{
+									return Globals()->GetParameter(paramID );
+								}
+
+    // since we overload GetParameter() as above, the following method is required to
+    // not hide the virtual function in base class
+    /*! @method GetParameter */
+    virtual OSStatus 	GetParameter(AudioUnitParameterID			inID,
+                                     AudioUnitScope 				inScope,
+                                     AudioUnitElement 				inElement,
+                                     AudioUnitParameterValue &		outValue)
+                        {
+                            return AUBase::GetParameter(inID, inScope, inElement, outValue);
+                        }
+    
+
+	/*! @method IsBypassEffect */
+	// This is used for the property value - to reflect to the UI if an effect is bypassed
+	bool						IsBypassEffect () { return mBypassEffect; }
+	
+protected:
+											
+	/*! @method MaintainKernels */
+	void						MaintainKernels();
+
+	/*! @method ShouldBypassEffect */
+	// This is used in the render call to see if an effect is bypassed
+	// It can return a different status than IsBypassEffect (though it MUST take that into account)
+	virtual	bool				ShouldBypassEffect () { return IsBypassEffect(); }
+					
+public:
+	/*! @method SetBypassEffect */
+	virtual void				SetBypassEffect (bool inFlag) { mBypassEffect = inFlag; }
+	
+	/*! @method SetParamHasSampleRateDependency */
+	void						SetParamHasSampleRateDependency (bool inFlag) 
+								{ 
+									mParamSRDep = inFlag; 
+								}
+	
+	/*! @method GetParamHasSampleRateDependency */
+	bool						GetParamHasSampleRateDependency () const { return mParamSRDep; }
+
+
+	struct ScheduledProcessParams	// pointer passed in as void* userData param for ProcessScheduledSlice()
+	{
+		AudioUnitRenderActionFlags 	*actionFlags;
+		AudioBufferList 			*inputBufferList;
+		AudioBufferList 			*outputBufferList;
+	};
+
+	virtual OSStatus			ProcessScheduledSlice(	void				*inUserData,
+														UInt32				inStartFrameInBuffer,
+														UInt32				inSliceFramesToProcess,
+														UInt32				inTotalBufferFrames );
+
+
+	bool							ProcessesInPlace() const {return mProcessesInPlace;};
+	void							SetProcessesInPlace(bool inProcessesInPlace) {mProcessesInPlace = inProcessesInPlace;};
+		
+	typedef std::vector<AUKernelBase *> KernelList;
+	
+	
+
+protected:	
+	/*! @var mKernelList */
+	KernelList						mKernelList;
+
+	AUKernelBase* GetKernel(UInt32 index) { return mKernelList[index]; }
+
+	/*! @method IsInputSilent */
+	bool 							IsInputSilent (AudioUnitRenderActionFlags 	inActionFlags, UInt32 inFramesToProcess)
+									{
+										bool inputSilent = (inActionFlags & kAudioUnitRenderAction_OutputIsSilence) != 0;
+									
+										// take latency and tail time into account when propagating the silent bit
+										UInt32 silentTimeoutFrames = UInt32(GetSampleRate() * (GetLatency() + GetTailTime()));
+										mSilentTimeout.Process (inFramesToProcess, silentTimeoutFrames, inputSilent);
+										return inputSilent;
+									}
+									
+#if TARGET_OS_IPHONE
+	void SetOnlyOneKernel(bool inUseOnlyOneKernel) { mOnlyOneKernel = inUseOnlyOneKernel; } // set in ctor of subclass that wants it.
+#endif
+
+	template <typename T>
+	void	ProcessBufferListsT(
+										AudioUnitRenderActionFlags &	ioActionFlags,
+										const AudioBufferList &			inBuffer,
+										AudioBufferList &				outBuffer,
+										UInt32							inFramesToProcess );
+	
+
+private:
+	/*! @var mBypassEffect */
+	bool							mBypassEffect;
+	/*! @var mParamSRDep */
+	bool							mParamSRDep;
+	
+	/*! @var mProcessesInplace */
+	bool							mProcessesInPlace;
+	
+	/*! @var mSilentTimeout */
+	AUSilentTimeout					mSilentTimeout;
+
+	/*! @var mMainOutput */
+	AUOutputElement *				mMainOutput;
+	
+	/*! @var mMainInput */
+	AUInputElement *				mMainInput;
+	
+#if TARGET_OS_IPHONE
+	/*! @var mOnlyOneKernel */
+	bool							mOnlyOneKernel;
+#endif
+
+	/*! @var mCommonPCMFormat */
+	CAStreamBasicDescription::CommonPCMFormat		mCommonPCMFormat;
+	UInt32							mBytesPerFrame;
+};
+
+
+//	Base class for a "kernel", an object that performs DSP on one channel of an interleaved stream.
+	/*! @class AUKernelBase */
+class AUKernelBase {
+public:
+	/*! @ctor AUKernelBase */
+								AUKernelBase(AUEffectBase *inAudioUnit ) :
+									mAudioUnit(inAudioUnit) { }
+
+	/*! @dtor ~AUKernelBase */
+	virtual						~AUKernelBase() { }
+
+	/*! @method Reset */
+	virtual void				Reset() { }
+
+	/*! @method Process */
+	virtual void 				Process(	const Float32 *						inSourceP,
+											Float32 *							inDestP,
+											UInt32								inFramesToProcess,
+											UInt32								inNumChannels,
+											bool &								ioSilence) { throw CAException(kAudio_UnimplementedError ); }
+
+	/*! @method Process */
+	virtual void 				Process(	const SInt32 *						inSourceP,
+											SInt32 *							inDestP,
+											UInt32								inFramesToProcess,
+											UInt32								inNumChannels,
+											bool &								ioSilence) { throw CAException(kAudio_UnimplementedError ); }
+
+	/*! @method Process */
+	virtual void 				Process(	const SInt16 *						inSourceP,
+											SInt16 *							inDestP,
+											UInt32								inFramesToProcess,
+											UInt32								inNumChannels,
+											bool &								ioSilence) { throw CAException(kAudio_UnimplementedError ); }
+
+	/*! @method GetSampleRate */
+	Float64						GetSampleRate()
+								{
+									return mAudioUnit->GetSampleRate();
+								}
+								
+	/*! @method GetParameter */
+	AudioUnitParameterValue		GetParameter (AudioUnitParameterID	paramID) 
+								{
+									return mAudioUnit->GetParameter(paramID);
+								}
+	
+	void						SetChannelNum (UInt32 inChan) { mChannelNum = inChan; }
+	UInt32						GetChannelNum () { return mChannelNum; }
+	
+protected:
+	/*! @var mAudioUnit */
+	AUEffectBase * 		mAudioUnit;
+	UInt32				mChannelNum;
+
+};
+
+template <typename T>
+void	AUEffectBase::ProcessBufferListsT(
+									AudioUnitRenderActionFlags &	ioActionFlags,
+									const AudioBufferList &			inBuffer,
+									AudioBufferList &				outBuffer,
+									UInt32							inFramesToProcess )
+{
+	bool ioSilence;
+
+	bool silentInput = IsInputSilent (ioActionFlags, inFramesToProcess);
+	ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
+
+	// call the kernels to handle either interleaved or deinterleaved
+	if (inBuffer.mNumberBuffers == 1) {
+		for (UInt32 channel = 0; channel < mKernelList.size(); ++channel) {
+			AUKernelBase *kernel = mKernelList[channel];
+			
+			if (kernel == NULL) continue;
+			ioSilence = silentInput;
+			
+			// process each interleaved channel individually
+			kernel->Process(
+				(const T *)inBuffer.mBuffers[0].mData + channel, 
+				(T *)outBuffer.mBuffers[0].mData + channel,
+				inFramesToProcess,
+				inBuffer.mBuffers[0].mNumberChannels,
+				ioSilence);
+				
+			if (!ioSilence)
+				ioActionFlags &= ~kAudioUnitRenderAction_OutputIsSilence;
+		}
+	} else {
+		for (UInt32 channel = 0; channel < mKernelList.size(); ++channel) {
+			AUKernelBase *kernel = mKernelList[channel];
+			
+			if (kernel == NULL) continue;
+			
+			ioSilence = silentInput;
+			const AudioBuffer *srcBuffer = &inBuffer.mBuffers[channel];
+			AudioBuffer *destBuffer = &outBuffer.mBuffers[channel];
+			
+			kernel->Process(
+				(const T *)srcBuffer->mData, 
+				(T *)destBuffer->mData, 
+				inFramesToProcess,
+				1,
+				ioSilence);
+				
+			if (!ioSilence)
+				ioActionFlags &= ~kAudioUnitRenderAction_OutputIsSilence;
+		}
+	}
+}
+
+
+#endif // __AUEffectBase_h__
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.cpp b/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.cpp
new file mode 100644
index 0000000..50bf93a
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.cpp
@@ -0,0 +1,837 @@
+/*
+     File: AUInstrumentBase.cpp
+ Abstract: AUInstrumentBase.h
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include "AUInstrumentBase.h"
+#include "AUMIDIDefs.h"
+
+#if DEBUG
+	#define DEBUG_PRINT 0
+	#define DEBUG_PRINT_NOTE 0
+	#define DEBUG_PRINT_RENDER 0
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const UInt32 kEventQueueSize = 1024;
+
+AUInstrumentBase::AUInstrumentBase(
+							AudioComponentInstance			inInstance, 
+							UInt32							numInputs,
+							UInt32							numOutputs,
+							UInt32							numGroups,
+							UInt32							numParts)
+	: MusicDeviceBase(inInstance, numInputs, numOutputs, numGroups), 
+	mAbsoluteSampleFrame(0),
+	mEventQueue(kEventQueueSize),
+	mNumNotes(0),
+	mNumActiveNotes(0),
+	mMaxActiveNotes(0),
+	mNotes(0),
+	mNoteSize(0),
+	mInitNumPartEls(numParts)
+{
+#if DEBUG_PRINT
+	printf("new AUInstrumentBase\n");
+#endif
+	mFreeNotes.mState = kNoteState_Free;
+	SetWantsRenderThreadID(true);
+}
+	
+
+AUInstrumentBase::~AUInstrumentBase()
+{
+#if DEBUG_PRINT
+	printf("delete AUInstrumentBase\n");
+#endif
+}
+
+AUElement *	AUInstrumentBase::CreateElement(AudioUnitScope inScope, AudioUnitElement element)
+{
+	switch (inScope)
+	{
+		case kAudioUnitScope_Group:
+			return new SynthGroupElement(this, element, new MidiControls);
+		case kAudioUnitScope_Part:
+			return new SynthPartElement (this, element);
+	}
+	return MusicDeviceBase::CreateElement(inScope, element);
+}
+
+void		AUInstrumentBase::CreateExtendedElements() 
+{
+	Parts().Initialize(this, kAudioUnitScope_Part, mInitNumPartEls);
+}
+
+AUScope *	AUInstrumentBase::GetScopeExtended (AudioUnitScope inScope) 
+{
+	if (inScope == kAudioUnitScope_Part)
+		return &mPartScope;
+	return NULL;
+}
+
+
+void		AUInstrumentBase::SetNotes(UInt32 inNumNotes, UInt32 inMaxActiveNotes, SynthNote* inNotes, UInt32 inNoteDataSize)
+{
+#if DEBUG_PRINT_NOTE
+	printf("AUInstrumentBase::SetNotes %d %d %p %d\n", inNumNotes, inMaxActiveNotes, inNotes, inNoteDataSize);
+#endif
+	mNumNotes = inNumNotes;
+	mMaxActiveNotes = inMaxActiveNotes;
+	mNoteSize = inNoteDataSize;
+	mNotes = inNotes;
+	
+	for (UInt32 i=0; i<mNumNotes; ++i)
+	{
+			SynthNote *note = GetNote(i);
+			note->Reset();
+			mFreeNotes.AddNote(note);
+	}
+}
+
+UInt32		AUInstrumentBase::CountActiveNotes()
+{
+	// debugging tool.
+	UInt32 sum = 0;
+	for (UInt32 i=0; i<mNumNotes; ++i)
+	{
+		SynthNote *note = GetNote(i);
+		if (note->GetState() <= kNoteState_Released) 
+			sum++;
+	}
+	return sum;
+}
+
+void		AUInstrumentBase::AddFreeNote(SynthNote* inNote)
+{
+	// Fast-released notes are already considered inactive and have already decr'd the active count
+	if (inNote->GetState() != kNoteState_FastReleased) {
+		DecNumActiveNotes();
+	}
+#if DEBUG_PRINT_NOTE
+	else {
+			printf("AUInstrumentBase::AddFreeNote: adding fast-released note %p\n", inNote);
+	}
+	printf("AUInstrumentBase::AddFreeNote (%p)  mNumActiveNotes %lu\n", inNote, mNumActiveNotes);
+#endif
+	mFreeNotes.AddNote(inNote);
+}
+
+OSStatus			AUInstrumentBase::Initialize()
+{
+/*
+TO DO:
+	Currently ValidFormat will check and validate that the num channels is not being
+	changed if the AU doesn't support the SupportedNumChannels property - which is correct
+	
+	What needs to happen here is that IFF the AU does support this property, (ie, the AU
+	can be configured to have different num channels than its original configuration) then
+	the state of the AU at Initialization needs to be validated.
+	
+	This is work still to be done - see AUEffectBase for the kind of logic that needs to be applied here
+*/
+
+	// override to call SetNotes
+	
+	mNoteIDCounter = 128; // reset this every time we initialise
+	mAbsoluteSampleFrame = 0;
+	return noErr;
+}
+
+void				AUInstrumentBase::Cleanup()
+{
+}
+
+
+OSStatus			AUInstrumentBase::Reset(			AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement)
+{
+#if DEBUG_PRINT
+	printf("AUInstrumentBase::Reset\n");
+#endif
+	if (inScope == kAudioUnitScope_Global)
+	{
+		// kill all notes..
+		mFreeNotes.Empty();
+		for (UInt32 i=0; i<mNumNotes; ++i)
+		{
+			SynthNote *note = GetNote(i);
+			if (note->IsSounding()) 
+				note->Kill(0);
+			note->ListRemove();
+			mFreeNotes.AddNote(note);
+		}
+		mNumActiveNotes = 0;
+		mAbsoluteSampleFrame = 0;
+
+		// empty lists.
+		UInt32 numGroups = Groups().GetNumberOfElements();
+		for (UInt32 j = 0; j < numGroups; ++j)
+		{
+			SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
+			group->Reset();
+		}
+	}
+	return MusicDeviceBase::Reset(inScope, inElement);
+}
+
+void		AUInstrumentBase::PerformEvents(const AudioTimeStamp& inTimeStamp)
+{
+#if DEBUG_PRINT_RENDER
+	printf("AUInstrumentBase::PerformEvents\n");
+#endif
+	SynthEvent *event;
+	SynthGroupElement *group;
+	
+	while ((event = mEventQueue.ReadItem()) != NULL)
+	{
+#if DEBUG_PRINT_RENDER
+		printf("event %08X %d\n", event, event->GetEventType());
+#endif
+		switch(event->GetEventType())
+		{
+			case SynthEvent::kEventType_NoteOn :
+				RealTimeStartNote(GetElForGroupID (event->GetGroupID()), event->GetNoteID(),
+									event->GetOffsetSampleFrame(), *event->GetParams());
+				break;
+			case SynthEvent::kEventType_NoteOff :
+				RealTimeStopNote(event->GetGroupID(), event->GetNoteID(),
+					event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_SustainOn :
+				group = GetElForGroupID (event->GetGroupID());
+				group->SustainOn(event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_SustainOff :
+				group = GetElForGroupID (event->GetGroupID());
+				group->SustainOff(event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_SostenutoOn :
+				group = GetElForGroupID (event->GetGroupID());
+				group->SostenutoOn(event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_SostenutoOff :
+				group = GetElForGroupID (event->GetGroupID());
+				group->SostenutoOff(event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_AllNotesOff :
+				group = GetElForGroupID (event->GetGroupID());
+				group->AllNotesOff(event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_AllSoundOff :
+				group = GetElForGroupID (event->GetGroupID());
+				group->AllSoundOff(event->GetOffsetSampleFrame());
+				break;
+			case SynthEvent::kEventType_ResetAllControllers :
+				group = GetElForGroupID (event->GetGroupID());
+				group->ResetAllControllers(event->GetOffsetSampleFrame());
+				break;
+		}
+		
+		mEventQueue.AdvanceReadPtr();
+	}
+}
+
+														
+OSStatus			AUInstrumentBase::Render(   AudioUnitRenderActionFlags &	ioActionFlags,
+												const AudioTimeStamp &			inTimeStamp,
+												UInt32							inNumberFrames)
+{
+	PerformEvents(inTimeStamp);
+
+	AUScope &outputs = Outputs();
+	UInt32 numOutputs = outputs.GetNumberOfElements();
+	for (UInt32 j = 0; j < numOutputs; ++j)
+	{
+		GetOutput(j)->PrepareBuffer(inNumberFrames);	// AUBase::DoRenderBus() only does this for the first output element
+		AudioBufferList& bufferList = GetOutput(j)->GetBufferList();
+		for (UInt32 k = 0; k < bufferList.mNumberBuffers; ++k)
+		{
+			memset(bufferList.mBuffers[k].mData, 0, bufferList.mBuffers[k].mDataByteSize);
+		}
+	}
+	
+	UInt32 numGroups = Groups().GetNumberOfElements();
+	for (UInt32 j = 0; j < numGroups; ++j)
+	{
+		SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
+		OSStatus err = group->Render((SInt64)inTimeStamp.mSampleTime, inNumberFrames, outputs);
+		if (err) return err;
+	}
+	mAbsoluteSampleFrame += inNumberFrames;
+	return noErr;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//	AUInstrumentBase::ValidFormat
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+bool				AUInstrumentBase::ValidFormat(	AudioUnitScope					inScope,
+													AudioUnitElement				inElement,
+													const CAStreamBasicDescription  & inNewFormat)
+{	
+		// if the AU supports this, then we should just let this go through to the Init call
+	if (SupportedNumChannels (NULL)) 
+		return MusicDeviceBase::ValidFormat(inScope, inElement, inNewFormat);
+
+	bool isGood = MusicDeviceBase::ValidFormat (inScope, inElement, inNewFormat);
+	if (!isGood) return false;
+	
+		// if we get to here, then the basic criteria is that the
+		// num channels cannot change on an existing bus
+	AUIOElement *el = GetIOElement (inScope, inElement);
+	return (el->GetStreamFormat().NumberChannels() == inNewFormat.NumberChannels()); 
+}
+
+
+bool				AUInstrumentBase::StreamFormatWritable(	AudioUnitScope					scope,
+															AudioUnitElement				element)
+{
+	return IsInitialized() ? false : true;
+}
+
+OSStatus			AUInstrumentBase::RealTimeStartNote(	SynthGroupElement 			*inGroup,
+															NoteInstanceID 				inNoteInstanceID, 
+															UInt32 						inOffsetSampleFrame, 
+															const MusicDeviceNoteParams &inParams)
+{
+	return noErr;
+}
+
+SynthPartElement *	AUInstrumentBase::GetPartElement (AudioUnitElement inPartElement)
+{
+	AUScope & parts = Parts();
+	unsigned int numEls = parts.GetNumberOfElements();
+	for (unsigned int i = 0; i < numEls; ++i) {
+		SynthPartElement* el = reinterpret_cast<SynthPartElement*>(parts.GetElement(i));
+		if (el->GetIndex() == inPartElement) {
+			return el;
+		}
+	}
+	return NULL;
+}
+
+SynthGroupElement *	AUInstrumentBase::GetElForGroupID (MusicDeviceGroupID	inGroupID)
+{
+	AUScope & groups = Groups();
+	unsigned int numEls = groups.GetNumberOfElements();
+	SynthGroupElement* unassignedEl = NULL;
+	
+	for (unsigned int i = 0; i < numEls; ++i) {
+		SynthGroupElement* el = reinterpret_cast<SynthGroupElement*>(groups.GetElement(i));
+		if (el->GroupID() == inGroupID) 
+			return el;
+		if (el->GroupID() == SynthGroupElement::kUnassignedGroup) {
+			unassignedEl = el;
+			break; // we fill this up from the start of the group scope vector
+		}
+	}
+	if (unassignedEl) {
+		unassignedEl->SetGroupID(inGroupID);
+		return unassignedEl;
+	}
+	throw static_cast<OSStatus>(kAudioUnitErr_InvalidElement);
+}
+
+OSStatus			AUInstrumentBase::RealTimeStopNote(
+												MusicDeviceGroupID 			inGroupID, 
+												NoteInstanceID 				inNoteInstanceID, 
+												UInt32 						inOffsetSampleFrame)
+{
+#if DEBUG_PRINT
+	printf("AUInstrumentBase::RealTimeStopNote ch %d id %d\n", inGroupID, inNoteInstanceID);
+#endif
+	
+	SynthGroupElement *gp = (inGroupID == kMusicNoteEvent_Unused
+								? GetElForNoteID (inNoteInstanceID)
+								: GetElForGroupID(inGroupID));
+	if (gp)
+	{
+		gp->NoteOff (inNoteInstanceID, inOffsetSampleFrame);
+	}
+	
+	return noErr;
+}
+
+SynthGroupElement *	AUInstrumentBase::GetElForNoteID (NoteInstanceID inNoteID)
+{
+#if DEBUG_PRINT
+	printf("GetElForNoteID id %u\n", inNoteID);
+#endif
+	AUScope & groups = Groups();
+	unsigned int numEls = groups.GetNumberOfElements();
+	
+	for (unsigned int i = 0; i < numEls; ++i) {
+		SynthGroupElement* el = reinterpret_cast<SynthGroupElement*>(groups.GetElement(i));
+		if (el->GetNote(inNoteID) != NULL)	// searches for any note state
+			return el;
+	}
+	throw static_cast<OSStatus>(kAudioUnitErr_InvalidElement);
+}
+
+OSStatus			AUInstrumentBase::StartNote(	MusicDeviceInstrumentID 	inInstrument, 
+													MusicDeviceGroupID 			inGroupID, 
+													NoteInstanceID *			outNoteInstanceID, 
+													UInt32 						inOffsetSampleFrame, 
+													const MusicDeviceNoteParams &inParams)
+{
+	OSStatus err = noErr;
+	
+	NoteInstanceID noteID; 
+	if (outNoteInstanceID) {
+		noteID = NextNoteID();
+		*outNoteInstanceID = noteID;
+	} else
+		noteID = (UInt32)inParams.mPitch;
+	
+#if DEBUG_PRINT
+	printf("AUInstrumentBase::StartNote ch %u, key %u, offset %u\n", inGroupID, (unsigned) inParams.mPitch, inOffsetSampleFrame);
+#endif
+
+	if (InRenderThread ())
+	{		
+		err = RealTimeStartNote(
+					GetElForGroupID(inGroupID),
+					noteID,
+					inOffsetSampleFrame,
+					inParams);
+	}
+	else
+	{
+		SynthEvent *event = mEventQueue.WriteItem();
+		if (!event) return -1; // queue full
+
+		event->Set(
+			SynthEvent::kEventType_NoteOn,
+			inGroupID,
+			noteID,
+			inOffsetSampleFrame,
+			&inParams
+		);
+		
+		mEventQueue.AdvanceWritePtr();
+	}
+	return err;
+}
+
+OSStatus			AUInstrumentBase::StopNote( MusicDeviceGroupID 			inGroupID, 
+												NoteInstanceID 				inNoteInstanceID, 
+												UInt32 						inOffsetSampleFrame)
+{
+#if DEBUG_PRINT
+	printf("AUInstrumentBase::StopNote ch %u, id %u, offset %u\n", (unsigned)inGroupID, (unsigned)inNoteInstanceID, inOffsetSampleFrame);
+#endif
+	OSStatus err = noErr;
+
+	if (InRenderThread ())
+	{		
+		err = RealTimeStopNote(
+			inGroupID,
+			inNoteInstanceID,
+			inOffsetSampleFrame);
+	}
+	else
+	{
+		SynthEvent *event = mEventQueue.WriteItem();
+		if (!event) return -1; // queue full
+
+		event->Set(
+			SynthEvent::kEventType_NoteOff,
+			inGroupID,
+			inNoteInstanceID,
+			inOffsetSampleFrame,
+			NULL
+		);
+		
+		mEventQueue.AdvanceWritePtr();
+	}
+	return err;
+}
+
+OSStatus	AUInstrumentBase::SendPedalEvent(MusicDeviceGroupID inGroupID, UInt32 inEventType, UInt32 inOffsetSampleFrame)
+{
+	
+	if (InRenderThread ())
+	{
+		SynthGroupElement *group = GetElForGroupID(inGroupID);
+		if (!group)
+			return kAudioUnitErr_InvalidElement;
+		
+		switch (inEventType)
+		{
+			case SynthEvent::kEventType_SustainOn :
+				group->SustainOn(inOffsetSampleFrame);
+				break;
+			case SynthEvent::kEventType_SustainOff :
+				group->SustainOff(inOffsetSampleFrame);
+				break;
+			case SynthEvent::kEventType_SostenutoOn :
+				group->SostenutoOn(inOffsetSampleFrame);
+				break;
+			case SynthEvent::kEventType_SostenutoOff :
+				group->SostenutoOff(inOffsetSampleFrame);
+				break;
+			case SynthEvent::kEventType_AllNotesOff :
+				group->AllNotesOff(inOffsetSampleFrame);
+				mNumActiveNotes = CountActiveNotes();
+				break;
+			case SynthEvent::kEventType_AllSoundOff :
+				group->AllSoundOff(inOffsetSampleFrame);
+				mNumActiveNotes = CountActiveNotes();
+				break;
+			case SynthEvent::kEventType_ResetAllControllers :
+				group->ResetAllControllers(inOffsetSampleFrame);
+				break;
+		}
+	}
+	else
+	{
+		SynthEvent *event = mEventQueue.WriteItem();
+		if (!event) return -1; // queue full
+
+		event->Set(inEventType, inGroupID, 0, 0, NULL);
+		
+		mEventQueue.AdvanceWritePtr();
+	}
+	return noErr;
+}
+
+OSStatus	AUInstrumentBase::HandleControlChange(	UInt8 	inChannel,
+													UInt8 	inController,
+													UInt8 	inValue,
+													UInt32	inStartFrame)
+{
+#if DEBUG_PRINT
+	printf("AUInstrumentBase::HandleControlChange ch %u ctlr: %u val: %u frm: %u\n", inChannel, inController, inValue, inStartFrame);
+#endif
+	SynthGroupElement *gp = GetElForGroupID(inChannel);
+	if (gp)
+	{
+		gp->ChannelMessage(inController, inValue);
+	}
+	else
+		return kAudioUnitErr_InvalidElement;
+	switch (inController)
+	{
+		case kMidiController_Sustain :
+			if (inValue >= 64)
+				SendPedalEvent(inChannel, SynthEvent::kEventType_SustainOn, inStartFrame);
+			else
+				SendPedalEvent(inChannel, SynthEvent::kEventType_SustainOff, inStartFrame);
+			break;
+		case kMidiController_Sostenuto :
+			if (inValue >= 64)
+				SendPedalEvent(inChannel, SynthEvent::kEventType_SostenutoOn, inStartFrame);
+			else
+				SendPedalEvent(inChannel, SynthEvent::kEventType_SostenutoOff, inStartFrame);
+			break;
+	}
+	return noErr;
+}
+												
+OSStatus	AUInstrumentBase::HandlePitchWheel(		UInt8 	inChannel,
+													UInt8 	inPitch1,	// LSB
+													UInt8 	inPitch2,	// MSB
+													UInt32	inStartFrame)
+{
+	SynthGroupElement *gp = GetElForGroupID(inChannel);
+	if (gp)
+	{
+		gp->ChannelMessage(kMidiMessage_PitchWheel, (inPitch2 << 7) | inPitch1);
+		return noErr;
+	}
+	else
+		return kAudioUnitErr_InvalidElement;
+}
+
+												
+OSStatus	AUInstrumentBase::HandleChannelPressure(UInt8 	inChannel,
+													UInt8 	inValue,
+													UInt32	inStartFrame)
+{
+	SynthGroupElement *gp = GetElForGroupID(inChannel);
+	if (gp)
+	{
+		gp->ChannelMessage(kMidiMessage_ChannelPressure, inValue);
+		return noErr;
+	}
+	else
+		return kAudioUnitErr_InvalidElement;
+}
+
+
+OSStatus	AUInstrumentBase::HandleProgramChange(	UInt8 	inChannel,
+													UInt8 	inValue)
+{
+#if DEBUG_PRINT
+	printf("AUInstrumentBase::HandleProgramChange %u %u\n", inChannel, inValue);
+#endif
+	SynthGroupElement *gp = GetElForGroupID(inChannel);
+	if (gp)
+	{
+		gp->ChannelMessage(kMidiMessage_ProgramChange, inValue);
+		return noErr;
+	}
+	else
+		return kAudioUnitErr_InvalidElement;
+}
+
+
+OSStatus	AUInstrumentBase::HandlePolyPressure(	UInt8 	inChannel,
+													UInt8 	inKey,
+													UInt8	inValue,
+													UInt32	inStartFrame)
+{
+	SynthGroupElement *gp = GetElForGroupID(inChannel);
+	if (gp)
+	{
+		// Combine key and value into single argument.  UGLY!
+		gp->ChannelMessage(kMidiMessage_PolyPressure, (inKey << 7) | inValue);
+		return noErr;
+	}
+	else
+		return kAudioUnitErr_InvalidElement;
+}
+
+
+OSStatus	AUInstrumentBase::HandleResetAllControllers(	UInt8 	inChannel)
+{
+	return SendPedalEvent (inChannel, SynthEvent::kEventType_ResetAllControllers, 0);
+}
+
+	
+OSStatus	AUInstrumentBase::HandleAllNotesOff(			UInt8 	inChannel)
+{
+	return SendPedalEvent (inChannel, SynthEvent::kEventType_AllNotesOff, 0);
+}
+
+	
+OSStatus	AUInstrumentBase::HandleAllSoundOff(			UInt8 	inChannel)
+{
+	return SendPedalEvent (inChannel, SynthEvent::kEventType_AllSoundOff, 0);
+}
+
+SynthNote*  AUInstrumentBase::GetAFreeNote(UInt32 inFrame)
+{
+#if DEBUG_PRINT_NOTE
+	printf("AUInstrumentBase::GetAFreeNote:  %lu available\n", mFreeNotes.Length());
+#endif
+	SynthNote *note = mFreeNotes.mHead;
+	if (note)
+	{
+		mFreeNotes.RemoveNote(note);
+		return note;
+	}
+	
+	return VoiceStealing(inFrame, true);
+}
+
+SynthNote*  AUInstrumentBase::VoiceStealing(UInt32 inFrame, bool inKillIt)
+{
+
+#if DEBUG_PRINT_NOTE
+	printf("AUInstrumentBase::VoiceStealing\n");
+#endif
+	// free list was empty so we need to kill a note.
+	UInt32 startState = inKillIt ? kNoteState_FastReleased : kNoteState_Released;
+	for (UInt32 i = startState; i <= startState; --i)
+	{
+#if DEBUG_PRINT_NOTE
+		printf(" checking state %d...\n", i);
+#endif
+		UInt32 numGroups = Groups().GetNumberOfElements();
+		for (UInt32 j = 0; j < numGroups; ++j)
+		{
+			SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
+#if DEBUG_PRINT_NOTE
+			printf("\tsteal group %d   size %d\n", j, group->mNoteList[i].Length());
+#endif
+			if (group->mNoteList[i].NotEmpty()) {
+#if DEBUG_PRINT_NOTE
+				printf("\t-- not empty\n");
+#endif
+				SynthNote *note = group->mNoteList[i].FindMostQuietNote();
+				if (inKillIt) {
+#if DEBUG_PRINT_NOTE
+					printf("\t--=== KILL ===---\n");
+#endif
+					note->Kill(inFrame);
+					group->mNoteList[i].RemoveNote(note);
+					if (i != kNoteState_FastReleased)
+						DecNumActiveNotes();
+					return note;
+				} else {
+#if DEBUG_PRINT_NOTE
+					printf("\t--=== FAST RELEASE ===---\n");
+#endif
+					group->mNoteList[i].RemoveNote(note);
+					note->FastRelease(inFrame);
+					group->mNoteList[kNoteState_FastReleased].AddNote(note);
+					DecNumActiveNotes(); // kNoteState_FastReleased counts as inactive for voice stealing purposes.
+					return NULL;
+				}
+			}
+		}
+	}
+#if DEBUG_PRINT_NOTE
+	printf("no notes to steal????\n");
+#endif
+	return NULL; // It should be impossible to get here. It means there were no notes to kill in any state. 
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+AUMonotimbralInstrumentBase::AUMonotimbralInstrumentBase(
+							AudioComponentInstance			inInstance, 
+							UInt32							numInputs,
+							UInt32							numOutputs,
+							UInt32							numGroups,
+							UInt32							numParts)
+	: AUInstrumentBase(inInstance, numInputs, numOutputs, numGroups, numParts)
+{
+}
+
+OSStatus			AUMonotimbralInstrumentBase::RealTimeStartNote(	
+															SynthGroupElement 			*inGroup, 
+															NoteInstanceID 				inNoteInstanceID, 
+															UInt32 						inOffsetSampleFrame, 
+															const MusicDeviceNoteParams &inParams)
+{
+#if DEBUG_PRINT_RENDER
+	printf("AUMonotimbralInstrumentBase::RealTimeStartNote %d\n", inNoteInstanceID);
+#endif
+
+	if (NumActiveNotes() + 1 > MaxActiveNotes()) 
+	{
+		VoiceStealing(inOffsetSampleFrame, false);
+	}
+	SynthNote *note = GetAFreeNote(inOffsetSampleFrame);
+	if (!note) return -1;
+	
+	SynthPartElement *part = GetPartElement (0);	// Only one part for monotimbral
+	
+	IncNumActiveNotes();
+	inGroup->NoteOn(note, part, inNoteInstanceID, inOffsetSampleFrame, inParams);
+	
+	return noErr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+OSStatus			AUMultitimbralInstrumentBase::GetPropertyInfo(AudioUnitPropertyID	inID,
+												AudioUnitScope				inScope,
+												AudioUnitElement			inElement,
+												UInt32 &					outDataSize,
+												Boolean &					outWritable)
+{
+	OSStatus result = noErr;
+	
+	switch (inID) 
+	{
+#if !TARGET_OS_IPHONE
+		case kMusicDeviceProperty_PartGroup:
+			if (inScope != kAudioUnitScope_Part) return kAudioUnitErr_InvalidScope;
+			outDataSize = sizeof(UInt32);
+			outWritable = true;
+			break;
+#endif
+		default:
+			result = AUInstrumentBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+	}
+	return result;
+}
+
+OSStatus			AUMultitimbralInstrumentBase::GetProperty(	AudioUnitPropertyID 	inID,
+												AudioUnitScope 				inScope,
+												AudioUnitElement		 	inElement,
+												void *						outData)
+{
+	OSStatus result = noErr;
+
+	switch (inID) 
+	{
+#if !TARGET_OS_IPHONE
+		case kMusicDeviceProperty_PartGroup:
+			if (inScope != kAudioUnitScope_Group) return kAudioUnitErr_InvalidScope;
+			// ??
+			return -1; //unimpl
+			break;
+#endif
+		default:
+			result = AUInstrumentBase::GetProperty (inID, inScope, inElement, outData);
+	}
+	
+	return result;
+}
+
+
+
+OSStatus			AUMultitimbralInstrumentBase::SetProperty(  AudioUnitPropertyID 			inID,
+																AudioUnitScope 					inScope,
+																AudioUnitElement 				inElement,
+																const void *					inData,
+																UInt32 							inDataSize)
+{
+	OSStatus result = noErr;
+
+	switch (inID) 
+	{
+#if !TARGET_OS_IPHONE
+		case kMusicDeviceProperty_PartGroup:
+			if (inScope != kAudioUnitScope_Group) return kAudioUnitErr_InvalidScope;
+			// ??
+			return -1; //unimpl
+			break;
+#endif
+		default:
+			result = MusicDeviceBase::SetProperty (inID, inScope, inElement, inData, inDataSize);
+	}
+	
+	return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.h b/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.h
new file mode 100644
index 0000000..924f4fc
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.h
@@ -0,0 +1,267 @@
+/*
+     File: AUInstrumentBase.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __AUInstrumentBase__
+#define __AUInstrumentBase__
+
+#include <vector>
+#include <stdexcept>
+#include <AudioUnit/AudioUnit.h>
+#include <CoreAudio/CoreAudio.h>
+#include <libkern/OSAtomic.h>
+#include "MusicDeviceBase.h"
+#include "LockFreeFIFO.h"
+#include "SynthEvent.h"
+#include "SynthNote.h"
+#include "SynthElement.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef LockFreeFIFOWithFree<SynthEvent> SynthEventQueue;
+
+class AUInstrumentBase : public MusicDeviceBase
+{
+public:
+			AUInstrumentBase(
+							AudioComponentInstance			inInstance, 
+							UInt32							numInputs,
+							UInt32							numOutputs,
+							UInt32							numGroups = 16,
+							UInt32							numParts = 1);
+	virtual ~AUInstrumentBase();
+
+	virtual OSStatus			Initialize();
+	
+	/*! @method Parts */
+	AUScope &					Parts()	{ return mPartScope; }
+
+	/*! @method GetPart */
+	AUElement *					GetPart( AudioUnitElement inElement)
+	{
+		return mPartScope.SafeGetElement(inElement);
+	}
+
+	virtual AUScope *			GetScopeExtended (AudioUnitScope inScope);
+
+	virtual AUElement *			CreateElement(			AudioUnitScope					inScope,
+														AudioUnitElement				inElement);
+
+	virtual void				CreateExtendedElements();
+
+	virtual void				Cleanup();
+	
+	virtual OSStatus			Reset(					AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement);
+														
+	virtual bool				ValidFormat(			AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														const CAStreamBasicDescription  & inNewFormat);
+
+	virtual bool				StreamFormatWritable(	AudioUnitScope					scope,
+														AudioUnitElement				element);
+
+	virtual OSStatus			Render(					AudioUnitRenderActionFlags &	ioActionFlags,
+														const AudioTimeStamp &			inTimeStamp,
+														UInt32							inNumberFrames);
+
+	virtual OSStatus			StartNote(		MusicDeviceInstrumentID 	inInstrument, 
+												MusicDeviceGroupID 			inGroupID, 
+												NoteInstanceID *			outNoteInstanceID, 
+												UInt32 						inOffsetSampleFrame, 
+												const MusicDeviceNoteParams &inParams);
+
+	virtual OSStatus			StopNote(		MusicDeviceGroupID 			inGroupID, 
+												NoteInstanceID 				inNoteInstanceID, 
+												UInt32 						inOffsetSampleFrame);
+
+	virtual OSStatus			RealTimeStartNote(		SynthGroupElement 			*inGroup,
+														NoteInstanceID 				inNoteInstanceID, 
+														UInt32 						inOffsetSampleFrame, 
+														const MusicDeviceNoteParams &inParams);
+	
+	virtual OSStatus			RealTimeStopNote(		MusicDeviceGroupID 			inGroupID, 
+														NoteInstanceID 				inNoteInstanceID, 
+														UInt32 						inOffsetSampleFrame);
+	
+	virtual OSStatus	HandleControlChange(	UInt8	inChannel,
+												UInt8 	inController,
+												UInt8 	inValue,
+												UInt32	inStartFrame);
+												
+	virtual OSStatus	HandlePitchWheel(		UInt8 	inChannel,
+												UInt8 	inPitch1,
+												UInt8 	inPitch2,
+												UInt32	inStartFrame);
+												
+	virtual OSStatus	HandleChannelPressure(	UInt8 	inChannel,
+												UInt8 	inValue,
+												UInt32	inStartFrame);
+
+	virtual OSStatus	HandleProgramChange(	UInt8	inChannel,
+												UInt8 	inValue);
+
+	virtual OSStatus	HandlePolyPressure(		UInt8 	inChannel,
+												UInt8 	inKey,
+												UInt8	inValue,
+												UInt32	inStartFrame);
+
+	virtual OSStatus	HandleResetAllControllers(		UInt8 	inChannel);
+	
+	virtual OSStatus	HandleAllNotesOff(				UInt8 	inChannel);
+	
+	virtual OSStatus	HandleAllSoundOff(				UInt8 	inChannel);
+
+	SynthNote*			GetNote(UInt32 inIndex) 
+						{ 
+							if (!mNotes)
+								throw std::runtime_error("no notes");
+							return (SynthNote*)((char*)mNotes + inIndex * mNoteSize); 
+						}
+	
+	SynthNote*			GetAFreeNote(UInt32 inFrame);
+	void				AddFreeNote(SynthNote* inNote);
+	
+	friend class SynthGroupElement;
+protected:
+
+	UInt32				NextNoteID() { return OSAtomicIncrement32((int32_t *)&mNoteIDCounter); }
+	
+	
+	// call SetNotes in your Initialize() method to give the base class your note structures and to set the maximum 
+	// number of active notes. inNoteData should be an array of size inMaxActiveNotes.
+	void				SetNotes(UInt32 inNumNotes, UInt32 inMaxActiveNotes, SynthNote* inNotes, UInt32 inNoteSize);
+	
+	void				PerformEvents(   const AudioTimeStamp &			inTimeStamp);
+	OSStatus			SendPedalEvent(MusicDeviceGroupID inGroupID, UInt32 inEventType, UInt32 inOffsetSampleFrame);
+	virtual SynthNote*  VoiceStealing(UInt32 inFrame, bool inKillIt);
+	UInt32				MaxActiveNotes() const { return mMaxActiveNotes; }
+	UInt32				NumActiveNotes() const { return mNumActiveNotes; }
+	void				IncNumActiveNotes() { ++mNumActiveNotes; }
+	void				DecNumActiveNotes() { --mNumActiveNotes; }
+	UInt32				CountActiveNotes();
+	
+	SynthPartElement *	GetPartElement (AudioUnitElement inPartElement);
+	
+			// this call throws if there's no assigned element for the group ID
+	virtual SynthGroupElement *	GetElForGroupID (MusicDeviceGroupID	inGroupID);
+	virtual SynthGroupElement *	GetElForNoteID (NoteInstanceID inNoteID);
+
+	SInt64 mAbsoluteSampleFrame;
+
+	
+private:
+				
+	SInt32 mNoteIDCounter;
+	
+	SynthEventQueue mEventQueue;
+	
+	UInt32 mNumNotes;
+	UInt32 mNumActiveNotes;
+	UInt32 mMaxActiveNotes;
+	SynthNote* mNotes;	
+	SynthNoteList mFreeNotes;
+	UInt32 mNoteSize;
+	
+	AUScope			mPartScope;
+	const UInt32	mInitNumPartEls;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class AUMonotimbralInstrumentBase : public AUInstrumentBase
+{
+public:
+	AUMonotimbralInstrumentBase(
+							AudioComponentInstance			inInstance, 
+							UInt32							numInputs,
+							UInt32							numOutputs,
+							UInt32							numGroups = 16,
+							UInt32							numParts = 1);
+										
+	virtual OSStatus			RealTimeStartNote(			SynthGroupElement 			*inGroup, 
+															NoteInstanceID 				inNoteInstanceID, 
+															UInt32 						inOffsetSampleFrame, 
+															const MusicDeviceNoteParams &inParams);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// this is a work in progress! The mono-timbral one is finished though!
+class AUMultitimbralInstrumentBase : public AUInstrumentBase
+{
+public:
+	AUMultitimbralInstrumentBase(
+							AudioComponentInstance			inInstance, 
+							UInt32							numInputs,
+							UInt32							numOutputs,
+							UInt32							numGroups,
+							UInt32							numParts);
+							
+	virtual OSStatus			GetPropertyInfo(		AudioUnitPropertyID				inID,
+														AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														UInt32 &						outDataSize,
+														Boolean &						outWritable);
+
+	virtual OSStatus			GetProperty(			AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement,
+														void *							outData);
+
+	virtual OSStatus			SetProperty(			AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement,
+														const void *					inData,
+														UInt32 							inDataSize);
+
+private:
+
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.cpp b/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.cpp
new file mode 100644
index 0000000..35bacb8
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.cpp
@@ -0,0 +1,495 @@
+/*
+     File: AUMIDIBase.cpp
+ Abstract: AUMIDIBase.h
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include "AUMIDIBase.h"
+#include <CoreMIDI/CoreMIDI.h>
+#include "CAXException.h"
+
+//temporaray location
+enum
+{
+	kMidiMessage_NoteOff 			= 0x80,
+	kMidiMessage_NoteOn 			= 0x90,
+	kMidiMessage_PolyPressure 		= 0xA0,
+	kMidiMessage_ControlChange 		= 0xB0,
+	kMidiMessage_ProgramChange 		= 0xC0,
+	kMidiMessage_ChannelPressure 	= 0xD0,
+	kMidiMessage_PitchWheel 		= 0xE0,
+
+	kMidiController_AllSoundOff			= 120,
+	kMidiController_ResetAllControllers	= 121,
+	kMidiController_AllNotesOff			= 123
+};
+
+AUMIDIBase::AUMIDIBase(AUBase* inBase) 
+	: mAUBaseInstance (*inBase) 
+{
+#if CA_AUTO_MIDI_MAP
+	mMapManager = new CAAUMIDIMapManager();
+#endif
+}
+
+AUMIDIBase::~AUMIDIBase() 
+{
+#if CA_AUTO_MIDI_MAP
+	if (mMapManager) 
+		delete mMapManager;
+#endif
+}
+
+#if TARGET_API_MAC_OSX
+OSStatus			AUMIDIBase::DelegateGetPropertyInfo(AudioUnitPropertyID				inID,
+														AudioUnitScope					inScope,
+														AudioUnitElement				inElement,
+														UInt32 &						outDataSize,
+														Boolean &						outWritable)
+{
+	OSStatus result = noErr;
+	
+	switch (inID) {
+#if !TARGET_OS_IPHONE
+	case kMusicDeviceProperty_MIDIXMLNames:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		if (GetXMLNames(NULL) == noErr) {
+			outDataSize = sizeof(CFURLRef);
+			outWritable = false;
+		} else
+			result = kAudioUnitErr_InvalidProperty;
+		break;
+#endif		
+#if CA_AUTO_MIDI_MAP				
+	case kAudioUnitProperty_AllParameterMIDIMappings:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		outWritable = true;
+		outDataSize = sizeof (AUParameterMIDIMapping)*mMapManager->NumMaps();
+		result = noErr;
+		break;
+	
+	case kAudioUnitProperty_HotMapParameterMIDIMapping:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		outWritable = true;
+		outDataSize = sizeof (AUParameterMIDIMapping); 
+		result = noErr;
+		break;
+		
+	case kAudioUnitProperty_AddParameterMIDIMapping:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		outWritable = true;
+		outDataSize = sizeof (AUParameterMIDIMapping);
+		result = noErr;
+		break;
+		
+	case kAudioUnitProperty_RemoveParameterMIDIMapping:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		outWritable = true;
+		outDataSize = sizeof (AUParameterMIDIMapping); 
+		result = noErr;
+		break;
+#endif
+
+	default:
+		result = kAudioUnitErr_InvalidProperty;
+		break;
+	}
+	return result;
+
+#if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE)
+InvalidScope:
+	return kAudioUnitErr_InvalidScope;
+InvalidElement:
+	return kAudioUnitErr_InvalidElement;
+#endif
+}
+
+OSStatus			AUMIDIBase::DelegateGetProperty(	AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement,
+														void *							outData)
+{
+	OSStatus result;
+	
+	switch (inID) {
+#if !TARGET_OS_IPHONE
+	case kMusicDeviceProperty_MIDIXMLNames:
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		result = GetXMLNames((CFURLRef *)outData);
+		break;
+#endif		
+#if CA_AUTO_MIDI_MAP
+	case kAudioUnitProperty_AllParameterMIDIMappings:{
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		AUParameterMIDIMapping*  maps =  (static_cast<AUParameterMIDIMapping*>(outData));
+		mMapManager->GetMaps(maps);
+//		printf ("GETTING MAPS\n");
+//		mMapManager->Print();
+		result = noErr;
+		break;
+	}
+		
+	case kAudioUnitProperty_HotMapParameterMIDIMapping:{
+		ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+		ca_require(inElement == 0, InvalidElement);
+		AUParameterMIDIMapping *  map =  (static_cast<AUParameterMIDIMapping*>(outData));
+		mMapManager->GetHotParameterMap (*map);
+		result = noErr;
+		break;
+	}
+#endif
+	
+	default:
+		result = kAudioUnitErr_InvalidProperty;
+		break;
+	}
+	return result;
+
+#if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE)
+InvalidScope:
+	return kAudioUnitErr_InvalidScope;
+InvalidElement:
+	return kAudioUnitErr_InvalidElement;
+#endif
+}
+
+OSStatus			AUMIDIBase::DelegateSetProperty(	AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement			 	inElement,
+														const void *					inData,
+														UInt32							inDataSize)
+{
+	OSStatus result;
+	
+	switch (inID) {
+#if CA_AUTO_MIDI_MAP
+		case kAudioUnitProperty_AddParameterMIDIMapping:{
+			ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+			ca_require(inElement == 0, InvalidElement);
+			AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData;
+			mMapManager->SortedInsertToParamaterMaps (maps, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance);
+			mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0);	 
+			result = noErr;
+			break;
+		}
+			
+		case kAudioUnitProperty_RemoveParameterMIDIMapping:{
+			ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+			ca_require(inElement == 0, InvalidElement);
+			AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData;
+			bool didChange;
+			mMapManager->SortedRemoveFromParameterMaps(maps, (inDataSize / sizeof(AUParameterMIDIMapping)), didChange);
+			if (didChange)
+				mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0);	 
+			result = noErr;
+			break;
+		}
+					
+		case kAudioUnitProperty_HotMapParameterMIDIMapping:{
+			ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+			ca_require(inElement == 0, InvalidElement);
+			AUParameterMIDIMapping & map = *((AUParameterMIDIMapping*)inData);
+			mMapManager->SetHotMapping (map);			
+			result = noErr;
+			break;
+		}
+		case kAudioUnitProperty_AllParameterMIDIMappings:{
+			ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
+			ca_require(inElement == 0, InvalidElement);
+			AUParameterMIDIMapping * mappings = (AUParameterMIDIMapping*)inData;
+			mMapManager->ReplaceAllMaps (mappings, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance);
+			result = noErr;
+			break;
+		}
+#endif
+		
+	default:
+		result = kAudioUnitErr_InvalidProperty;
+		break;
+	}
+	return result;
+#if CA_AUTO_MIDI_MAP
+	InvalidScope:
+		return kAudioUnitErr_InvalidScope;
+	InvalidElement:
+		return kAudioUnitErr_InvalidElement;
+#endif
+}
+
+
+
+#endif //TARGET_API_MAC_OSX
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#pragma mark ____MidiDispatch
+
+
+inline const Byte *	NextMIDIEvent(const Byte *event, const Byte *end)
+{
+	Byte c = *event;
+	switch (c >> 4) {
+	default:	// data byte -- assume in sysex
+		while ((*++event & 0x80) == 0 && event < end)
+			;
+		break;
+	case 0x8:
+	case 0x9:
+	case 0xA:
+	case 0xB:
+	case 0xE:
+		event += 3;
+		break;
+	case 0xC:
+	case 0xD:
+		event += 2;
+		break;
+	case 0xF:
+		switch (c) {
+		case 0xF0:
+			while ((*++event & 0x80) == 0 && event < end)
+				;
+			break;
+		case 0xF1:
+		case 0xF3:
+			event += 2;
+			break;
+		case 0xF2:
+			event += 3;
+			break;
+		default:
+			++event;
+			break;
+		}
+	}
+	return (event >= end) ? end : event;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//	AUMIDIBase::HandleMIDIPacketList
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+OSStatus			AUMIDIBase::HandleMIDIPacketList(const MIDIPacketList *pktlist)
+{
+	if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
+	
+	int nPackets = pktlist->numPackets;
+	const MIDIPacket *pkt = pktlist->packet;
+	
+	while (nPackets-- > 0) {
+		const Byte *event = pkt->data, *packetEnd = event + pkt->length;
+		long startFrame = (long)pkt->timeStamp;
+		while (event < packetEnd) {
+			Byte status = event[0];
+			if (status & 0x80) {
+				// really a status byte (not sysex continuation)
+				HandleMidiEvent(status & 0xF0, status & 0x0F, event[1], event[2], startFrame);
+					// note that we're generating a bogus channel number for system messages (0xF0-FF)
+			}
+			event = NextMIDIEvent(event, packetEnd);
+		}
+		pkt = reinterpret_cast<const MIDIPacket *>(packetEnd);
+	}
+	return noErr;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//	AUMIDIBase::HandleMidiEvent
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+OSStatus 	AUMIDIBase::HandleMidiEvent(UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
+{
+	if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
+		
+#if CA_AUTO_MIDI_MAP	
+// you potentially have a choice to make here - if a param mapping matches, do you still want to process the 
+// MIDI event or not. The default behaviour is to continue on with the MIDI event.
+	if (mMapManager->HandleHotMapping (status, channel, data1, mAUBaseInstance)) {
+		mAUBaseInstance.PropertyChanged (kAudioUnitProperty_HotMapParameterMIDIMapping, kAudioUnitScope_Global, 0);
+	}
+	else {
+		mMapManager->FindParameterMapEventMatch(status, channel, data1, data2, inStartFrame, mAUBaseInstance);
+	}	
+#endif	
+	
+	OSStatus result = noErr;
+	
+	switch(status)
+	{
+		case kMidiMessage_NoteOn:
+			if(data2)
+			{
+				result = HandleNoteOn(channel, data1, data2, inStartFrame);
+			}
+			else
+			{
+				// zero velocity translates to note off
+				result = HandleNoteOff(channel, data1, data2, inStartFrame);
+			}
+			break;
+			
+		case kMidiMessage_NoteOff:
+			result = HandleNoteOff(channel, data1, data2, inStartFrame);
+			break;
+		
+		default:
+			result = HandleNonNoteEvent (status, channel, data1, data2, inStartFrame);
+			break;
+	}
+	
+	return result;
+}
+
+OSStatus	AUMIDIBase::HandleNonNoteEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
+{
+	OSStatus result = noErr;
+
+	switch (status)
+	{
+		case kMidiMessage_PitchWheel:
+			result = HandlePitchWheel(channel, data1, data2, inStartFrame);
+			break;
+			
+		case kMidiMessage_ProgramChange:
+			result = HandleProgramChange(channel, data1);
+			break;
+			
+		case kMidiMessage_ChannelPressure:
+			result = HandleChannelPressure(channel, data1, inStartFrame);
+			break;
+			
+		case kMidiMessage_ControlChange:
+		{
+			switch (data1) {
+				case kMidiController_AllNotesOff:
+					result = HandleAllNotesOff(channel);
+					break;
+
+				case kMidiController_ResetAllControllers:
+					result = HandleResetAllControllers(channel);
+					break;
+
+				case kMidiController_AllSoundOff:
+					result = HandleAllSoundOff(channel);
+					break;
+								
+				default:
+					result = HandleControlChange(channel, data1, data2, inStartFrame);
+					break;
+			}
+			break;
+		}
+		case kMidiMessage_PolyPressure:
+			result = HandlePolyPressure (channel, data1, data2, inStartFrame);
+			break;
+	}
+	return result;
+}
+
+OSStatus 	AUMIDIBase::SysEx (const UInt8 *	inData, 
+										UInt32			inLength)
+{
+	if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
+
+	return HandleSysEx(inData, inLength );
+}
+
+
+
+#if TARGET_OS_MAC
+	#if __LP64__
+		// comp instance, parameters in forward order
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_index + 1];
+	#else
+		// parameters in reverse order, then comp instance
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_nparams - 1 - _index];
+	#endif
+#elif TARGET_OS_WIN32
+		// (no comp instance), parameters in forward order
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_index];
+#endif
+
+#if !TARGET_OS_IPHONE
+OSStatus			AUMIDIBase::ComponentEntryDispatch(	ComponentParameters *			params,
+															AUMIDIBase *				This)
+{
+	if (This == NULL) return kAudio_ParamError;
+
+	OSStatus result;
+	
+	switch (params->what) {
+	case kMusicDeviceMIDIEventSelect:
+		{
+			PARAM(UInt32, pbinStatus, 0, 4);
+			PARAM(UInt32, pbinData1, 1, 4);
+			PARAM(UInt32, pbinData2, 2, 4);
+			PARAM(UInt32, pbinOffsetSampleFrame, 3, 4);
+			result = This->MIDIEvent(pbinStatus, pbinData1, pbinData2, pbinOffsetSampleFrame);
+		}
+		break;
+	case kMusicDeviceSysExSelect:
+		{
+			PARAM(const UInt8 *, pbinData, 0, 2);
+			PARAM(UInt32, pbinLength, 1, 2);
+			result = This->SysEx(pbinData, pbinLength);
+		}
+		break;
+
+	default:
+		result = badComponentSelector;
+		break;
+	}
+	
+	return result;
+}
+#endif
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.h b/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.h
new file mode 100644
index 0000000..cff1e97
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.h
@@ -0,0 +1,213 @@
+/*
+     File: AUMIDIBase.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __AUMIDIBase_h__
+#define __AUMIDIBase_h__
+
+#include "AUBase.h"
+
+#if CA_AUTO_MIDI_MAP
+	#include "CAAUMIDIMapManager.h"
+#endif
+
+struct MIDIPacketList;
+
+// ________________________________________________________________________
+//	MusicDeviceBase
+//
+	/*! @class AUMIDIBase */
+class AUMIDIBase {
+public:
+									// this is NOT a copy constructor!
+	/*! @ctor AUMIDIBase */
+								AUMIDIBase(AUBase* inBase);
+	/*! @dtor ~AUMIDIBase */
+	virtual						~AUMIDIBase();
+	
+	/*! @method MIDIEvent */
+	virtual OSStatus	MIDIEvent(		UInt32 						inStatus, 
+										UInt32 						inData1, 
+										UInt32 						inData2, 
+										UInt32 						inOffsetSampleFrame)
+	{
+		UInt32 strippedStatus = inStatus & 0xf0;
+		UInt32 channel = inStatus & 0x0f;
+	
+		return HandleMidiEvent(strippedStatus, channel, inData1, inData2, inOffsetSampleFrame);
+	}
+	
+	/*! @method HandleMIDIPacketList */
+	OSStatus			HandleMIDIPacketList(const MIDIPacketList *pktlist);
+	
+	/*! @method SysEx */
+	virtual OSStatus	SysEx(			const UInt8 *				inData, 
+										UInt32 						inLength);
+
+#if TARGET_API_MAC_OSX
+	/*! @method DelegateGetPropertyInfo */
+	virtual OSStatus			DelegateGetPropertyInfo(AudioUnitPropertyID			inID,
+														AudioUnitScope				inScope,
+														AudioUnitElement			inElement,
+														UInt32 &					outDataSize,
+														Boolean &					outWritable);
+
+	/*! @method DelegateGetProperty */
+	virtual OSStatus			DelegateGetProperty(	AudioUnitPropertyID 		inID,
+														AudioUnitScope 				inScope,
+														AudioUnitElement		 	inElement,
+														void *						outData);
+														
+	/*! @method DelegateSetProperty */
+	virtual OSStatus			DelegateSetProperty(	AudioUnitPropertyID 		inID,
+														AudioUnitScope 				inScope,
+														AudioUnitElement		 	inElement,
+														const void *				inData,
+														UInt32						inDataSize);
+#endif
+
+protected:
+	// MIDI dispatch
+	/*! @method HandleMidiEvent */
+	virtual OSStatus	HandleMidiEvent(		UInt8 	inStatus,
+												UInt8 	inChannel,
+												UInt8 	inData1,
+												UInt8 	inData2,
+												UInt32 	inStartFrame);
+
+	/*! @method HandleNonNoteEvent */
+	virtual OSStatus	HandleNonNoteEvent (	UInt8	status, 
+												UInt8	channel, 
+												UInt8	data1, 
+												UInt8	data2, 
+												UInt32	inStartFrame);
+
+#if TARGET_API_MAC_OSX
+	/*! @method GetXMLNames */
+	virtual OSStatus			GetXMLNames(CFURLRef *outNameDocument) 
+	{ return kAudioUnitErr_InvalidProperty; }	// if not overridden, it's unsupported
+#endif
+
+// channel messages
+	/*! @method HandleNoteOn */
+	virtual OSStatus	HandleNoteOn(			UInt8 	inChannel,
+												UInt8 	inNoteNumber,
+												UInt8 	inVelocity,
+												UInt32 	inStartFrame) { return noErr; }
+												
+	/*! @method HandleNoteOff */
+	virtual OSStatus	HandleNoteOff(			UInt8 	inChannel,
+												UInt8 	inNoteNumber,
+												UInt8 	inVelocity,
+												UInt32 	inStartFrame) { return noErr; }
+												
+	/*! @method HandleControlChange */
+	virtual OSStatus	HandleControlChange(	UInt8 	inChannel,
+												UInt8 	inController,
+												UInt8 	inValue,
+												UInt32	inStartFrame) { return noErr; }
+												
+	/*! @method HandlePitchWheel */
+	virtual OSStatus	HandlePitchWheel(		UInt8 	inChannel,
+												UInt8 	inPitch1,
+												UInt8 	inPitch2,
+												UInt32	inStartFrame) { return noErr; }
+												
+	/*! @method HandleChannelPressure */
+	virtual OSStatus	HandleChannelPressure(	UInt8 	inChannel,
+												UInt8 	inValue,
+												UInt32	inStartFrame) { return noErr; }
+
+	/*! @method HandleProgramChange */
+	virtual OSStatus	HandleProgramChange(	UInt8 	inChannel,
+												UInt8 	inValue) { return noErr; }
+
+	/*! @method HandlePolyPressure */
+	virtual OSStatus	HandlePolyPressure(		UInt8 	inChannel,
+												UInt8 	inKey,
+												UInt8	inValue,
+												UInt32	inStartFrame) { return noErr; }
+
+	/*! @method HandleResetAllControllers */
+	virtual OSStatus	HandleResetAllControllers(UInt8 inChannel) { return noErr; }
+	
+	/*! @method HandleAllNotesOff */
+	virtual OSStatus	HandleAllNotesOff(		UInt8	inChannel) { return noErr; }
+	
+	/*! @method HandleAllSoundOff */
+	virtual OSStatus	HandleAllSoundOff(		UInt8	inChannel) { return noErr; }
+
+
+//System messages   
+	/*! @method HandleSysEx */
+	virtual OSStatus	HandleSysEx(			const UInt8 *	inData,
+                                        		UInt32			inLength ) { return noErr; }
+
+#if CA_AUTO_MIDI_MAP
+	/* map manager */
+	CAAUMIDIMapManager			*GetMIDIMapManager() {return mMapManager;};
+	
+#endif
+
+												
+private:
+	/*! @var mAUBaseInstance */
+	AUBase						& mAUBaseInstance;
+	
+#if CA_AUTO_MIDI_MAP
+	/* map manager */
+	CAAUMIDIMapManager			* mMapManager;
+#endif
+	
+public:
+#if !TARGET_OS_IPHONE
+	// component dispatcher
+	/*! @method ComponentEntryDispatch */
+	static OSStatus			ComponentEntryDispatch(	ComponentParameters 		*params,
+														AUMIDIBase 					*This);
+#endif
+};
+
+#endif // __AUMIDIBase_h__
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/LockFreeFIFO.h b/architecture/AU/AUPublic/AUInstrumentBase/LockFreeFIFO.h
new file mode 100644
index 0000000..2469b66
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/LockFreeFIFO.h
@@ -0,0 +1,168 @@
+/*
+     File: LockFreeFIFO.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include <libkern/OSAtomic.h>
+
+template <class ITEM>
+class LockFreeFIFOWithFree
+{
+	LockFreeFIFOWithFree(); // private, unimplemented.
+public:
+	LockFreeFIFOWithFree(UInt32 inMaxSize)
+		: mReadIndex(0), mWriteIndex(0), mFreeIndex(0)
+	{
+		//assert(IsPowerOfTwo(inMaxSize));
+		mItems = new ITEM[inMaxSize];
+		mMask = inMaxSize - 1;
+	}
+	
+	~LockFreeFIFOWithFree()
+	{
+		delete [] mItems;
+	}
+
+	
+	void Reset() 
+	{
+		FreeItems();
+		mReadIndex = 0;
+		mWriteIndex = 0;
+		mFreeIndex = 0;
+	}
+	
+	ITEM* WriteItem() 
+	{
+		//printf("WriteItem %d %d\n", mReadIndex, mWriteIndex);
+		FreeItems(); // free items on the write thread.
+		UInt32 nextWriteIndex = (mWriteIndex + 1) & mMask;
+		if (nextWriteIndex == mFreeIndex) return NULL;
+		return &mItems[mWriteIndex];
+	}
+	
+	ITEM* ReadItem() 
+	{
+		//printf("ReadItem %d %d\n", mReadIndex, mWriteIndex);
+		if (mReadIndex == mWriteIndex) return NULL;
+		return &mItems[mReadIndex];
+	}
+	void AdvanceWritePtr() { OSAtomicCompareAndSwap32(mWriteIndex, (mWriteIndex + 1) & mMask, (int32_t*)&mWriteIndex); }
+	void AdvanceReadPtr()  { OSAtomicCompareAndSwap32(mReadIndex,  (mReadIndex  + 1) & mMask, (int32_t*)&mReadIndex); }
+private:
+	ITEM* FreeItem() 
+	{
+		if (mFreeIndex == mReadIndex) return NULL;
+		return &mItems[mFreeIndex];
+	}
+	void AdvanceFreePtr() { OSAtomicCompareAndSwap32(mFreeIndex, (mFreeIndex + 1) & mMask, (int32_t*)&mFreeIndex); }
+	
+	void FreeItems() 
+	{
+		ITEM* item;
+		while ((item = FreeItem()) != NULL)
+		{
+			item->Free();
+			AdvanceFreePtr();
+		}
+	}
+	
+	volatile UInt32 mReadIndex, mWriteIndex, mFreeIndex;
+	UInt32 mMask;
+	ITEM *mItems;
+};
+
+
+
+// Same as above but no free.
+
+template <class ITEM>
+class LockFreeFIFO
+{
+	LockFreeFIFO(); // private, unimplemented.
+public:
+	LockFreeFIFO(UInt32 inMaxSize)
+		: mReadIndex(0), mWriteIndex(0)
+	{
+		//assert(IsPowerOfTwo(inMaxSize));
+		mItems = new ITEM[inMaxSize];
+		mMask = inMaxSize - 1;
+	}
+	
+	~LockFreeFIFO()
+	{
+		delete [] mItems;
+	}
+	
+	void Reset() 
+	{
+		mReadIndex = 0;
+		mWriteIndex = 0;
+	}
+	
+	ITEM* WriteItem() 
+	{
+		UInt32 nextWriteIndex = (mWriteIndex + 1) & mMask;
+		if (nextWriteIndex == mReadIndex) return NULL;
+		return &mItems[mWriteIndex];
+	}
+	
+	ITEM* ReadItem() 
+	{
+		if (mReadIndex == mWriteIndex) return NULL;
+		return &mItems[mReadIndex];
+	}
+	
+		// the CompareAndSwap will always succeed. We use CompareAndSwap because it calls the PowerPC sync instruction,
+		// plus any processor bug workarounds for various CPUs.
+	void AdvanceWritePtr() { OSAtomicCompareAndSwap32(mWriteIndex, (mWriteIndex + 1) & mMask, (UInt32*)&mWriteIndex); }
+	void AdvanceReadPtr()  { OSAtomicCompareAndSwap32(mReadIndex,  (mReadIndex  + 1) & mMask, (UInt32*)&mReadIndex); }
+	
+private:
+	
+	volatile UInt32 mReadIndex, mWriteIndex;
+	UInt32 mMask;
+	ITEM *mItems;
+};
+
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/MIDIControlHandler.h b/architecture/AU/AUPublic/AUInstrumentBase/MIDIControlHandler.h
new file mode 100644
index 0000000..fe86cac
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/MIDIControlHandler.h
@@ -0,0 +1,92 @@
+/*
+     File: MIDIControlHandler.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __MIDICONTROLHANDLER_H__
+#define	__MIDICONTROLHANDLER_H__
+
+#include <CoreAudio/CoreAudio.h>
+
+/*! Abstract interface base class for classes which handle all incoming MIDI data */
+
+class MIDIControlHandler
+{
+public:
+	virtual			~MIDIControlHandler() {}
+	virtual void	Reset() = 0;								//! Restore all state to defaults
+	virtual bool	SetProgramChange(UInt16	inProgram) = 0;
+	virtual bool	SetPitchWheel(UInt16 inValue) = 0;
+	virtual bool	SetChannelPressure(UInt8 inValue) = 0;
+	virtual bool	SetPolyPressure(UInt8 inKey, UInt8 inValue) = 0;
+	virtual bool	SetController(UInt8 inControllerNumber, UInt8 inValue) = 0;
+	virtual bool	SetSysex(void *inSysexMsg) = 0;
+	
+	virtual float	GetPitchBend() const = 0;
+
+	/*! Default controller values.  These represent MSB values unless indicated in the name */
+	
+	enum
+	{
+		kDefault_Midpoint				= 0x40,		//! Used for all center-null-point controllers
+		kDefault_Volume				= 100,
+		kDefault_Pan					= kDefault_Midpoint,
+		kDefault_ModWheel				= 0,
+		kDefault_Pitch					= kDefault_Midpoint,
+		kDefault_Expression			= 0x7f,
+		kDefault_ChannelPressure	= 0,
+		kDefault_ReverbSend			= 40,
+		kDefault_ChorusSend			= 0,
+		
+		kDefault_RPN_LSB				= 0x7f,
+		kDefault_RPN_MSB				= 0x7f,
+		kDefault_PitchBendRange		= 2,
+		kDefault_FineTuning			= kDefault_Midpoint,
+		kDefault_CoarseTuning		= kDefault_Midpoint,
+		kDefault_ModDepthRange		= 0,
+		kDefault_ModDepthRangeLSB	= kDefault_Midpoint
+	};
+};
+
+#endif	// __MIDICONTROLHANDLER_H__
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.cpp b/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.cpp
new file mode 100644
index 0000000..5b9509c
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.cpp
@@ -0,0 +1,354 @@
+/*
+     File: MusicDeviceBase.cpp
+ Abstract: MusicDeviceBase.h
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include "MusicDeviceBase.h"
+
+// compatibility with older OS SDK releases
+typedef OSStatus
+(*TEMP_MusicDeviceMIDIEventProc)(	void *			inComponentStorage,
+							UInt32					inStatus,
+							UInt32					inData1,
+							UInt32					inData2,
+							UInt32					inOffsetSampleFrame);
+
+typedef OSStatus
+(*TEMP_MusicDeviceStartNoteProc)(	void *				inComponentStorage,
+						MusicDeviceInstrumentID			inInstrument,
+						MusicDeviceGroupID				inGroupID,
+						NoteInstanceID *				outNoteInstanceID,
+						UInt32							inOffsetSampleFrame,
+						const MusicDeviceNoteParams *	inParams);
+
+typedef OSStatus
+(*TEMP_MusicDeviceStopNoteProc)(void *					inComponentStorage,
+						MusicDeviceGroupID				inGroupID,
+						NoteInstanceID					inNoteInstanceID,
+						UInt32							inOffsetSampleFrame);
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+
+static OSStatus		MusicDeviceBaseMIDIEvent(void *			inComponentStorage,
+						UInt32				inStatus,
+						UInt32				inData1,
+						UInt32				inData2,
+						UInt32				inOffsetSampleFrame);
+
+static OSStatus		MusicDeviceBaseStartNote(	void *		inComponentStorage,
+						MusicDeviceInstrumentID			inInstrument,
+						MusicDeviceGroupID				inGroupID,
+						NoteInstanceID *				outNoteInstanceID,
+						UInt32							inOffsetSampleFrame,
+						const MusicDeviceNoteParams *	inParams);
+
+static OSStatus		MusicDeviceBaseStopNote(void *			inComponentStorage,
+						MusicDeviceGroupID				inGroupID,
+						NoteInstanceID					inNoteInstanceID,
+						UInt32							inOffsetSampleFrame);
+
+#endif
+
+MusicDeviceBase::MusicDeviceBase(AudioComponentInstance			inInstance, 
+									UInt32						numInputs,
+									UInt32						numOutputs,
+									UInt32						numGroups) 
+	: AUBase(inInstance, numInputs, numOutputs, numGroups),
+	  AUMIDIBase(this)
+{
+}
+
+OSStatus			MusicDeviceBase::GetPropertyInfo(AudioUnitPropertyID	inID,
+							AudioUnitScope				inScope,
+							AudioUnitElement			inElement,
+							UInt32 &				outDataSize,
+							Boolean &				outWritable)
+{
+	OSStatus result;
+	
+	switch (inID) 
+	{
+#if !TARGET_OS_IPHONE
+		case kMusicDeviceProperty_InstrumentCount:
+			if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope;
+			outDataSize = sizeof(UInt32);
+			outWritable = false;
+			result = noErr;
+			break;
+#endif
+		default:
+			result = AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+			
+			if (result == kAudioUnitErr_InvalidProperty)
+				result = AUMIDIBase::DelegateGetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+			break;
+	}
+	return result;
+}
+
+OSStatus			MusicDeviceBase::GetProperty(	AudioUnitPropertyID			inID,
+							AudioUnitScope 				inScope,
+							AudioUnitElement		 	inElement,
+							void *					outData)
+{
+	OSStatus result;
+
+	switch (inID) 
+	{
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+		case kAudioUnitProperty_FastDispatch:
+			if (!IsCMgrObject()) return kAudioUnitErr_InvalidProperty;
+			if (inElement == kMusicDeviceMIDIEventSelect) {
+				*(TEMP_MusicDeviceMIDIEventProc *)outData = MusicDeviceBaseMIDIEvent;
+				return noErr;
+			}
+			else if (inElement == kMusicDeviceStartNoteSelect) {
+				*(TEMP_MusicDeviceStartNoteProc *)outData = MusicDeviceBaseStartNote;
+				return noErr;
+			}	
+			else if (inElement == kMusicDeviceStopNoteSelect) {
+				*(TEMP_MusicDeviceStopNoteProc *)outData = MusicDeviceBaseStopNote;
+				return noErr;
+			}
+			return kAudioUnitErr_InvalidElement;
+#endif
+
+#if !TARGET_OS_IPHONE
+		case kMusicDeviceProperty_InstrumentCount:
+			if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope;
+			return GetInstrumentCount (*(UInt32*)outData);
+#endif
+		default:
+			result = AUBase::GetProperty (inID, inScope, inElement, outData);
+			
+			if (result == kAudioUnitErr_InvalidProperty)
+				result = AUMIDIBase::DelegateGetProperty (inID, inScope, inElement, outData);
+	}
+	
+	return result;
+}
+
+
+OSStatus			MusicDeviceBase::SetProperty(	AudioUnitPropertyID 			inID,
+							AudioUnitScope 				inScope,
+							AudioUnitElement 			inElement,
+							const void *				inData,
+							UInt32 					inDataSize)
+
+{
+
+	OSStatus result = AUBase::SetProperty (inID, inScope, inElement, inData, inDataSize);
+		
+	if (result == kAudioUnitErr_InvalidProperty)
+		result = AUMIDIBase::DelegateSetProperty (inID, inScope, inElement, inData, inDataSize);
+		
+	return result;
+}
+
+// For a MusicDevice that doesn't support separate instruments (ie. is mono-timbral)
+// then this call should return an instrument count of zero and noErr
+OSStatus			MusicDeviceBase::GetInstrumentCount (UInt32 &outInstCount) const
+{
+	outInstCount = 0;
+	return noErr;
+}
+
+OSStatus	MusicDeviceBase::HandleNoteOn(	UInt8 	inChannel,
+											UInt8 	inNoteNumber,
+											UInt8 	inVelocity,
+											UInt32 	inStartFrame)
+{
+	MusicDeviceNoteParams params;
+	params.argCount = 2;
+	params.mPitch = inNoteNumber;
+	params.mVelocity = inVelocity;
+	return StartNote (kMusicNoteEvent_UseGroupInstrument, inChannel, NULL, inStartFrame, params);
+}
+											
+OSStatus	MusicDeviceBase::HandleNoteOff(	UInt8 	inChannel,
+											UInt8 	inNoteNumber,
+											UInt8 	inVelocity,
+											UInt32 	inStartFrame)
+{
+	return StopNote (inChannel, inNoteNumber, inStartFrame);
+}
+
+OSStatus			
+MusicDeviceBase::HandleStartNoteMessage (MusicDeviceInstrumentID		inInstrument, 
+										MusicDeviceGroupID				inGroupID, 
+										NoteInstanceID *				outNoteInstanceID, 
+										UInt32							inOffsetSampleFrame, 
+										const MusicDeviceNoteParams *	inParams)
+{
+	if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError;
+
+	if (!IsInitialized()) return kAudioUnitErr_Uninitialized;
+	
+	return StartNote (inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
+}
+
+#if TARGET_OS_MAC
+	#if __LP64__
+		// comp instance, parameters in forward order
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_index + 1];
+	#else
+		// parameters in reverse order, then comp instance
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_nparams - 1 - _index];
+	#endif
+#elif TARGET_OS_WIN32
+		// (no comp instance), parameters in forward order
+		#define PARAM(_typ, _name, _index, _nparams) \
+			_typ _name = *(_typ *)&params->params[_index];
+#endif
+
+#if !TARGET_OS_IPHONE
+OSStatus			MusicDeviceBase::ComponentEntryDispatch(	ComponentParameters *		params,
+																MusicDeviceBase *			This)
+{
+	if (This == NULL) return kAudio_ParamError;
+
+	OSStatus result;
+	
+	switch (params->what) {
+	case kMusicDeviceMIDIEventSelect:
+	case kMusicDeviceSysExSelect:
+		{
+			result = AUMIDIBase::ComponentEntryDispatch (params, This);
+		}
+		break;
+	case kMusicDevicePrepareInstrumentSelect:
+		{
+			PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1);
+			result = This->PrepareInstrument(inInstrument);
+		}
+		break;
+	case kMusicDeviceReleaseInstrumentSelect:
+		{
+			PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1);
+			result = This->ReleaseInstrument(inInstrument);
+		}
+		break;
+	case kMusicDeviceStartNoteSelect:
+		{
+			PARAM(MusicDeviceInstrumentID, pbinInstrument, 0, 5);
+			PARAM(MusicDeviceGroupID, pbinGroupID, 1, 5);
+			PARAM(NoteInstanceID *, pboutNoteInstanceID, 2, 5);
+			PARAM(UInt32, pbinOffsetSampleFrame, 3, 5);
+			PARAM(const MusicDeviceNoteParams *, pbinParams, 4, 5);
+			result = This->HandleStartNoteMessage(pbinInstrument, pbinGroupID, pboutNoteInstanceID, pbinOffsetSampleFrame, pbinParams);
+		}
+		break;
+	case kMusicDeviceStopNoteSelect:
+		{
+			PARAM(MusicDeviceGroupID, pbinGroupID, 0, 3);
+			PARAM(NoteInstanceID, pbinNoteInstanceID, 1, 3);
+			PARAM(UInt32, pbinOffsetSampleFrame, 2, 3);
+			result = This->StopNote(pbinGroupID, pbinNoteInstanceID, pbinOffsetSampleFrame);
+		}
+		break;
+
+	default:
+		result = AUBase::ComponentEntryDispatch(params, This);
+		break;
+	}
+	
+	return result;
+}
+#endif
+
+#if !CA_USE_AUDIO_PLUGIN_ONLY
+
+// fast dispatch
+static OSStatus		MusicDeviceBaseMIDIEvent(void *					inComponentStorage,
+						UInt32					inStatus,
+						UInt32					inData1,
+						UInt32					inData2,
+						UInt32					inOffsetSampleFrame)
+{
+	OSStatus result = noErr;
+	try {
+		MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
+		if (This == NULL) return kAudio_ParamError;
+		result = This->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+OSStatus		MusicDeviceBaseStartNote(	void *		inComponentStorage,
+						MusicDeviceInstrumentID			inInstrument,
+						MusicDeviceGroupID				inGroupID,
+						NoteInstanceID *				outNoteInstanceID,
+						UInt32							inOffsetSampleFrame,
+						const MusicDeviceNoteParams *	inParams)
+{
+	OSStatus result = noErr;
+	try {
+		if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError;
+		MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
+		if (This == NULL) return kAudio_ParamError;
+		result = This->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+OSStatus		MusicDeviceBaseStopNote(void *			inComponentStorage,
+						MusicDeviceGroupID				inGroupID,
+						NoteInstanceID					inNoteInstanceID,
+						UInt32							inOffsetSampleFrame)
+{
+	OSStatus result = noErr;
+	try {
+		MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
+		if (This == NULL) return kAudio_ParamError;
+		result = This->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame);
+	}
+	COMPONENT_CATCH
+	return result;
+}
+
+#endif
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.h b/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.h
new file mode 100644
index 0000000..d4387e5
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.h
@@ -0,0 +1,126 @@
+/*
+     File: MusicDeviceBase.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __MusicDeviceBase_h__
+#define __MusicDeviceBase_h__
+
+#include "AUMIDIBase.h"
+
+// ________________________________________________________________________
+//	MusicDeviceBase
+//
+
+/*! @class MusicDeviceBase */
+class MusicDeviceBase : public AUBase, public AUMIDIBase {
+public:
+	/*! @ctor MusicDeviceBase */
+								MusicDeviceBase(		AudioComponentInstance			inInstance, 
+														UInt32							numInputs,
+														UInt32							numOutputs,
+														UInt32							numGroups = 0);
+
+
+	virtual OSStatus	MIDIEvent(		UInt32 						inStatus, 
+										UInt32 						inData1, 
+										UInt32 						inData2, 
+										UInt32 						inOffsetSampleFrame)
+	{
+		return AUMIDIBase::MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame);
+	}
+
+	/*! @method SysEx */
+	virtual OSStatus	SysEx(			const UInt8 *				inData, 
+										UInt32 						inLength) 
+	{
+		return AUMIDIBase::SysEx (inData, inLength);
+	}
+
+	/*! @method GetPropertyInfo */
+	virtual OSStatus			GetPropertyInfo(AudioUnitPropertyID			inID,
+												AudioUnitScope				inScope,
+												AudioUnitElement			inElement,
+												UInt32 &					outDataSize,
+												Boolean &					outWritable);
+
+	/*! @method GetProperty */
+	virtual OSStatus			GetProperty(	AudioUnitPropertyID 		inID,
+												AudioUnitScope 				inScope,
+												AudioUnitElement		 	inElement,
+												void *						outData);
+												
+	/*! @method SetProperty */
+	virtual OSStatus			SetProperty(			AudioUnitPropertyID 			inID,
+														AudioUnitScope 					inScope,
+														AudioUnitElement 				inElement,
+														const void *					inData,
+														UInt32 							inDataSize);
+
+	/*! @method HandleNoteOn */
+	virtual OSStatus			HandleNoteOn(	UInt8 	inChannel,
+												UInt8 	inNoteNumber,
+												UInt8 	inVelocity,
+												UInt32 	inStartFrame);
+																								
+	/*! @method HandleNoteOff */
+	virtual OSStatus			HandleNoteOff(	UInt8 	inChannel,
+												UInt8 	inNoteNumber,
+												UInt8 	inVelocity,
+												UInt32 	inStartFrame);
+
+	/*! @method GetInstrumentCount */
+	virtual OSStatus			GetInstrumentCount (	UInt32 &outInstCount) const;
+
+#if !TARGET_OS_IPHONE
+	// component dispatcher
+	/*! @method ComponentEntryDispatch */
+	static OSStatus			ComponentEntryDispatch(	ComponentParameters *			params,
+														MusicDeviceBase *				This);
+#endif
+private:
+	OSStatus				HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams);
+};
+
+#endif // __MusicDeviceBase_h__
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.cpp b/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.cpp
new file mode 100644
index 0000000..8ac22f6
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.cpp
@@ -0,0 +1,419 @@
+/*
+     File: SynthElement.cpp
+ Abstract: SynthElement.h
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include "SynthElement.h"
+#include "AUInstrumentBase.h"
+#include "AUMIDIDefs.h"
+
+#undef DEBUG_PRINT
+#define DEBUG_PRINT 0
+#define DEBUG_PRINT_NOTE 0
+#define DEBUG_PRINT_RENDER 0
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+MidiControls::MidiControls()
+{
+	Reset();
+}
+
+void MidiControls::Reset()
+{
+	memset(mControls, 0, sizeof(mControls));
+	memset(mPolyPressure, 0, sizeof(mPolyPressure));
+	mMonoPressure = 0;
+	mProgramChange = 0;
+	mPitchBend = 0;
+	mActiveRPN = 0;
+	mActiveNRPN = 0;
+	mActiveRPValue = 0;
+	mActiveNRPValue = 0;
+	mControls[kMidiController_Pan] = 64;
+	mControls[kMidiController_Expression] = 127;
+	mPitchBendDepth = 24 << 7;
+	mFPitchBendDepth = 24.0f;
+	mFPitchBend = 0.0f;
+}
+
+
+SynthElement::SynthElement(AUInstrumentBase *audioUnit, UInt32 inElement) 
+	: AUElement(audioUnit), mIndex(inElement)
+{
+}
+
+SynthElement::~SynthElement()
+{
+}
+
+SynthGroupElement::SynthGroupElement(AUInstrumentBase *audioUnit, UInt32 inElement, MIDIControlHandler *inHandler) 
+	: SynthElement(audioUnit, inElement),
+	mCurrentAbsoluteFrame(-1),
+	mMidiControlHandler(inHandler),
+	mSustainIsOn(false), mSostenutoIsOn(false), mOutputBus(0), mGroupID(kUnassignedGroup)
+{
+	for (UInt32 i=0; i<kNumberOfSoundingNoteStates; ++i)
+		mNoteList[i].mState = (SynthNoteState) i;
+}
+
+SynthGroupElement::~SynthGroupElement()
+{
+	delete mMidiControlHandler;
+}
+
+void	SynthGroupElement::SetGroupID (MusicDeviceGroupID inGroup)
+{
+		// can't re-assign a group once its been assigned
+	if (mGroupID != kUnassignedGroup) throw static_cast<OSStatus>(kAudioUnitErr_InvalidElement);
+	mGroupID = inGroup;
+}
+
+void SynthGroupElement::Reset() 
+{
+#if DEBUG_PRINT
+	printf("SynthGroupElement::Reset\n");
+#endif
+	mMidiControlHandler->Reset();
+	for (UInt32 i=0; i<kNumberOfSoundingNoteStates; ++i)
+		mNoteList[i].Empty();
+}
+
+SynthPartElement::SynthPartElement(AUInstrumentBase *audioUnit, UInt32 inElement) 
+	: SynthElement(audioUnit, inElement)
+{
+}
+
+// Return the SynthNote with the given inNoteID, if found.  If unreleasedOnly is true, only look for
+// attacked and sostenutoed notes, otherwise search all states.  Return state of found note via outNoteState.
+
+SynthNote *SynthGroupElement::GetNote(NoteInstanceID inNoteID, bool unreleasedOnly, UInt32 *outNoteState)
+{
+#if DEBUG_PRINT_RENDER
+	printf("SynthGroupElement::GetNote %d, unreleased = %d\n", inNoteID, unreleasedOnly);
+#endif
+	const UInt32 lastNoteState = unreleasedOnly ? 
+									(mSostenutoIsOn ? kNoteState_Sostenutoed : kNoteState_Attacked)
+										: kNoteState_Released;
+	SynthNote *note = NULL;
+	// Search for notes in each successive state
+	for (UInt32 noteState = kNoteState_Attacked; noteState <= lastNoteState; ++noteState)
+	{
+		if (outNoteState) *outNoteState = noteState;	// even if we find nothing
+		note = mNoteList[noteState].mHead;
+		while (note && note->mNoteID != inNoteID)
+		{
+#if DEBUG_PRINT_RENDER
+			printf("   checking %p id: %d\n", note, note->mNoteID);
+#endif
+			note = note->mNext;
+		}
+		if (note)
+		{
+#if DEBUG_PRINT_RENDER
+			printf("  found %p\n", note);
+#endif
+			break;
+		}
+	}
+	return note;
+}
+
+void SynthGroupElement::NoteOn(SynthNote *note,
+							   SynthPartElement *part,
+							   NoteInstanceID inNoteID,
+							   UInt32 inOffsetSampleFrame,
+							   const MusicDeviceNoteParams &inParams)
+{
+#if DEBUG_PRINT_NOTE
+	printf("SynthGroupElement::NoteOn %d\n", inNoteID);
+#endif
+	// TODO: CONSIDER FIXING this to not need to initialize mCurrentAbsoluteFrame to -1.
+	UInt64 absoluteFrame = (mCurrentAbsoluteFrame == -1) ? inOffsetSampleFrame : mCurrentAbsoluteFrame + inOffsetSampleFrame;
+	if (note->AttackNote(part, this, inNoteID, absoluteFrame, inOffsetSampleFrame, inParams)) {
+		mNoteList[kNoteState_Attacked].AddNote(note);
+	}
+}
+
+void SynthGroupElement::NoteOff(NoteInstanceID inNoteID, UInt32 inFrame)
+{	
+#if DEBUG_PRINT_NOTE
+	printf("SynthGroupElement::NoteOff %d\n", inNoteID);
+#endif
+	UInt32 noteState = kNoteState_Attacked;
+	SynthNote *note = GetNote(inNoteID, true, &noteState);	// asking for unreleased only
+	if (note)
+	{
+#if DEBUG_PRINT_NOTE
+		printf("  old note state: %d\n", note->mState);
+#endif
+		if (noteState == kNoteState_Attacked)
+		{
+			mNoteList[noteState].RemoveNote(note);
+			if (mSustainIsOn) {
+				mNoteList[kNoteState_ReleasedButSustained].AddNote(note);
+			} else {
+				note->Release(inFrame);
+				mNoteList[kNoteState_Released].AddNote(note);
+			}
+#if DEBUG_PRINT_NOTE
+			printf("  new note state: %d\n", note->mState);
+#endif
+		}
+		else /* if (noteState == kNoteState_Sostenutoed) */
+		{
+			mNoteList[kNoteState_Sostenutoed].RemoveNote(note);
+			mNoteList[kNoteState_ReleasedButSostenutoed].AddNote(note);
+		}
+	}
+}
+
+void SynthGroupElement::NoteEnded(SynthNote *inNote, UInt32 inFrame)
+{
+#if DEBUG_PRINT_NOTE
+	printf("SynthGroupElement::NoteEnded: id %d state %d\n", inNote->mNoteID, inNote->mState);
+#endif
+	if (inNote->IsSounding()) {
+		SynthNoteList *list = &mNoteList[inNote->GetState()];
+		list->RemoveNote(inNote);
+	}
+	
+	GetAUInstrument()->AddFreeNote(inNote);
+}
+
+void SynthGroupElement::NoteFastReleased(SynthNote *inNote)
+{
+#if DEBUG_PRINT_NOTE
+	printf("SynthGroupElement::NoteFastReleased id %d state %d\n", inNote->mNoteID, inNote->mState);
+#endif
+	if (inNote->IsActive()) {
+		mNoteList[inNote->GetState()].RemoveNote(inNote);
+		GetAUInstrument()->DecNumActiveNotes();
+		mNoteList[kNoteState_FastReleased].AddNote(inNote);
+	}
+	else {
+		Assert(true, "ASSERT FAILED:  Attempting to fast-release non-active note");
+	}
+}
+
+bool SynthGroupElement::ChannelMessage(UInt16 controllerID, UInt16 inValue)
+{
+	bool handled = true;
+#if DEBUG_PRINT
+	printf("SynthGroupElement::ChannelMessage(0x%x, %u)\n", controllerID, inValue);
+#endif
+	// Sustain and sostenuto are "pedal events", and are handled during render cycle
+	if (controllerID <= kMidiController_RPN_MSB && controllerID != kMidiController_Sustain && controllerID != kMidiController_Sostenuto)
+		handled = mMidiControlHandler->SetController(controllerID, UInt8(inValue));
+	else 
+	{
+		switch (controllerID)
+		{
+			case kMidiMessage_ProgramChange:
+				handled = mMidiControlHandler->SetProgramChange(inValue);
+				break;
+			case kMidiMessage_PitchWheel:
+				handled = mMidiControlHandler->SetPitchWheel(inValue);
+				break;
+			case kMidiMessage_ChannelPressure:
+#if DEBUG_PRINT
+				printf("SynthGroupElement::ChannelMessage: Channel Pressure %u\n", inValue);
+#endif
+				handled = mMidiControlHandler->SetChannelPressure(UInt8(inValue));
+				break;
+			case kMidiMessage_PolyPressure:
+			{	UInt8 inKey = inValue >> 7;
+				UInt8 val = inValue & 0xf;
+				handled = mMidiControlHandler->SetPolyPressure(inKey, val);
+				break;
+			}
+			default:
+				handled = false;
+				break;
+		}
+	}
+	return handled;
+}
+
+void SynthGroupElement::SostenutoOn(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+	printf("SynthGroupElement::SostenutoOn\n");
+#endif
+	if (!mSostenutoIsOn) {
+		mMidiControlHandler->SetController(kMidiController_Sostenuto, 127);
+		mSostenutoIsOn = true;
+		mNoteList[kNoteState_Sostenutoed].TransferAllFrom(&mNoteList[kNoteState_Attacked], inFrame);
+	}
+}
+
+void SynthGroupElement::SostenutoOff(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+	printf("SynthGroupElement::SostenutoOff\n");
+#endif
+	if (mSostenutoIsOn) {
+		mMidiControlHandler->SetController(kMidiController_Sostenuto, 0);
+		mSostenutoIsOn = false;
+		mNoteList[kNoteState_Attacked].TransferAllFrom(&mNoteList[kNoteState_Sostenutoed], inFrame);
+		if (mSustainIsOn) 
+			mNoteList[kNoteState_ReleasedButSustained].TransferAllFrom(&mNoteList[kNoteState_ReleasedButSostenutoed], inFrame);
+		else
+			mNoteList[kNoteState_Released].TransferAllFrom(&mNoteList[kNoteState_ReleasedButSostenutoed], inFrame);
+	}
+}
+
+
+void SynthGroupElement::SustainOn(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+//	printf("SynthGroupElement::SustainOn\n");
+#endif
+	if (!mSustainIsOn) {
+		mMidiControlHandler->SetController(kMidiController_Sustain, 127);
+		mSustainIsOn = true;
+	}
+}
+
+void SynthGroupElement::SustainOff(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+//	printf("SynthGroupElement::SustainOff\n");
+#endif
+	if (mSustainIsOn) {
+		mMidiControlHandler->SetController(kMidiController_Sustain, 0);
+		mSustainIsOn = false;
+	
+		mNoteList[kNoteState_Released].TransferAllFrom(&mNoteList[kNoteState_ReleasedButSustained], inFrame);
+	}
+}
+
+void SynthGroupElement::AllNotesOff(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+	printf("SynthGroupElement::AllNotesOff\n");
+#endif
+	SynthNote *note;
+	for (UInt32 i=0 ; i<=kNoteState_Sostenutoed; ++i)
+	{
+		UInt32 newState = (i == kNoteState_Attacked) ?
+			kNoteState_Released : kNoteState_ReleasedButSostenutoed;
+		note = mNoteList[i].mHead;
+		while (note)
+		{
+			SynthNote *nextNote = note->mNext;
+			
+			mNoteList[i].RemoveNote(note);
+			note->Release(inFrame);
+			mNoteList[newState].AddNote(note);
+			
+			note = nextNote;
+		}
+	}	
+}
+
+void SynthGroupElement::AllSoundOff(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+	printf("SynthGroupElement::AllSoundOff\n");
+#endif
+	SynthNote *note;
+	
+	for (UInt32 i=0 ; i<kNumberOfActiveNoteStates; ++i)
+	{
+		note = mNoteList[i].mHead;
+		while (note)
+		{
+			SynthNote *nextNote = note->mNext;
+			
+			mNoteList[i].RemoveNote(note);
+			note->FastRelease(inFrame);
+			mNoteList[kNoteState_FastReleased].AddNote(note);
+			GetAUInstrument()->DecNumActiveNotes();
+			note = nextNote;
+		}
+	}	
+}
+
+void SynthGroupElement::ResetAllControllers(UInt32 inFrame)
+{
+#if DEBUG_PRINT
+	printf("SynthGroupElement::ResetAllControllers\n");
+#endif
+	mMidiControlHandler->Reset();
+}
+
+OSStatus SynthGroupElement::Render(SInt64 inAbsoluteSampleFrame, UInt32 inNumberFrames, AUScope &outputs)
+{
+	// Avoid duplicate calls at same sample offset
+	if (inAbsoluteSampleFrame != mCurrentAbsoluteFrame)
+	{
+		mCurrentAbsoluteFrame = inAbsoluteSampleFrame;
+		AudioBufferList* buffArray[16];
+		UInt32 numOutputs = outputs.GetNumberOfElements();
+		for (UInt32 outBus = 0; outBus < numOutputs && outBus < 16; ++outBus)
+		{
+			buffArray[outBus] = &GetAudioUnit()->GetOutput(outBus)->GetBufferList();
+		}
+		
+		for (UInt32 i=0 ; i<kNumberOfSoundingNoteStates; ++i)
+		{
+			SynthNote *note = mNoteList[i].mHead;
+			while (note)
+			{
+#if DEBUG_PRINT_RENDER
+				printf("SynthGroupElement::Render: state %d, note %p\n", i, note);
+#endif
+				SynthNote *nextNote = note->mNext;
+				
+				OSStatus err = note->Render(inAbsoluteSampleFrame, inNumberFrames, buffArray, numOutputs);
+				if (err) return err;
+				
+				note = nextNote;
+			}
+		}
+	}
+	return noErr;
+}
+
+
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.h b/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.h
new file mode 100644
index 0000000..e1e4f2e
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.h
@@ -0,0 +1,227 @@
+/*
+     File: SynthElement.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __SynthElement__
+#define __SynthElement__
+
+#include <AudioUnit/AudioUnit.h>
+#include "MusicDeviceBase.h"
+#include "SynthNoteList.h"
+#include "MIDIControlHandler.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class AUInstrumentBase;
+
+class SynthElement : public AUElement
+{
+public:
+	SynthElement(AUInstrumentBase *audioUnit, UInt32 inElement);
+	virtual ~SynthElement();
+
+	UInt32 GetIndex() const { return mIndex; }
+	
+	AUInstrumentBase* GetAUInstrument() { return (AUInstrumentBase*)GetAudioUnit(); }
+	
+private:
+	UInt32 mIndex;
+};
+
+class MidiControls : public MIDIControlHandler
+{
+	enum { kMaxControls = 128 };
+public:
+	MidiControls();
+	virtual ~MidiControls() {}
+	virtual void	Reset();
+	virtual bool	SetProgramChange(UInt16	inProgram) { mProgramChange = inProgram; return true; }
+	virtual bool	SetPitchWheel(UInt16 inValue) {
+		mPitchBend = inValue;
+		mFPitchBend = (float)(((SInt16)mPitchBend - 8192) / 8192.);
+		return true;
+	}
+	virtual bool	SetChannelPressure(UInt8 inValue) { mMonoPressure = inValue; return true; }
+	virtual bool	SetPolyPressure(UInt8 inKey, UInt8 inValue) {
+		mPolyPressure[inKey] = inValue;
+		return true;
+	}
+	virtual bool	SetController(UInt8 inControllerNumber, UInt8 inValue) {
+		if (inControllerNumber < kMaxControls) {
+			mControls[inControllerNumber] = inValue;
+			return true;
+		}
+		return false;
+	}
+	virtual bool	SetSysex(void *inSysexMsg) { return false; }
+
+	virtual float GetPitchBend() const { return mFPitchBend * mFPitchBendDepth; }
+
+	SInt16 GetHiResControl(UInt32 inIndex) const 
+	{   
+		return ((mControls[inIndex] & 127) << 7) | (mControls[inIndex + 32] & 127);
+	}
+	
+	float GetControl(UInt32 inIndex) const
+	{
+		if (inIndex < 32) {
+			return (float)(mControls[inIndex] + (mControls[inIndex + 32] / 127.));
+		} else {
+			return (float)mControls[inIndex];
+		}
+	}
+	
+	
+private:
+	
+	UInt8 mControls[128];
+	UInt8 mPolyPressure[128];
+	UInt8 mMonoPressure;
+	UInt8 mProgramChange;
+	UInt16 mPitchBend;
+	UInt16 mActiveRPN;
+	UInt16 mActiveNRPN;
+	UInt16 mActiveRPValue;
+	UInt16 mActiveNRPValue;
+	
+	UInt16 mPitchBendDepth;
+	float mFPitchBendDepth;
+	float mFPitchBend;
+	
+	void SetHiResControl(UInt32 inIndex, UInt8 inMSB, UInt8 inLSB)
+		{ 
+			mControls[inIndex] = inMSB;
+			mControls[inIndex + 32] = inLSB;
+		}
+		
+};
+
+
+class SynthGroupElement : public SynthElement
+{
+public:
+	enum {
+		kUnassignedGroup = 0xFFFFFFFF
+	};
+	
+	SynthGroupElement(AUInstrumentBase *audioUnit, UInt32 inElement, MIDIControlHandler *inHandler);
+	virtual					~SynthGroupElement();
+
+	virtual void			NoteOn(SynthNote *note, SynthPartElement *part, NoteInstanceID inNoteID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams &inParams);
+	virtual void			NoteOff(NoteInstanceID inNoteID, UInt32 inOffsetSampleFrame);
+	void						SustainOn(UInt32 inFrame);
+	void						SustainOff(UInt32 inFrame);
+	void						SostenutoOn(UInt32 inFrame);
+	void						SostenutoOff(UInt32 inFrame);
+
+	void						NoteEnded(SynthNote *inNote, UInt32 inFrame);
+	void						NoteFastReleased(SynthNote *inNote);
+	
+	virtual bool			ChannelMessage(UInt16 controlID, UInt16 controlValue);
+	void						AllNotesOff(UInt32 inFrame);
+	void						AllSoundOff(UInt32 inFrame);
+	void						ResetAllControllers(UInt32 inFrame);
+	
+	SynthNote *				GetNote(NoteInstanceID inNoteID, bool unreleasedOnly=false, UInt32 *outNoteState=NULL);
+	
+	void						Reset();
+	
+	virtual OSStatus		Render(SInt64 inAbsoluteSampleFrame, UInt32 inNumberFrames, AUScope &outputs);
+	
+	float						GetPitchBend() const { return mMidiControlHandler->GetPitchBend(); }
+	SInt64					GetCurrentAbsoluteFrame() const { return mCurrentAbsoluteFrame; }
+	
+	MusicDeviceGroupID	GroupID () const { return mGroupID; }
+	virtual void			SetGroupID (MusicDeviceGroupID inGroup);
+
+	MIDIControlHandler *	GetMIDIControlHandler() const { return mMidiControlHandler; }
+	
+protected:	
+	SInt64					mCurrentAbsoluteFrame;
+	SynthNoteList 			mNoteList[kNumberOfSoundingNoteStates];
+	MIDIControlHandler		*mMidiControlHandler;
+
+private:
+	friend class AUInstrumentBase;
+	friend class AUMonotimbralInstrumentBase;
+	friend class AUMultitimbralInstrumentBase;
+	
+	bool					mSustainIsOn;
+	bool					mSostenutoIsOn;
+	UInt32					mOutputBus;
+	MusicDeviceGroupID		mGroupID;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+struct SynthKeyZone
+{
+	UInt8 mLoNote;
+	UInt8 mHiNote;
+	UInt8 mLoVelocity;
+	UInt8 mHiVelocity;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const UInt32 kUnlimitedPolyphony = 0xFFFFFFFF;
+
+class SynthPartElement : public SynthElement
+{
+public:
+	SynthPartElement(AUInstrumentBase *audioUnit, UInt32 inElement);
+
+	UInt32		GetGroupIndex() const { return mGroupIndex; }
+	bool		InRange(Float32 inNote, Float32 inVelocity);
+	
+	UInt32		GetMaxPolyphony() const { return mMaxPolyphony; }
+	void		SetMaxPolyphony(UInt32 inMaxPolyphony) { mMaxPolyphony = inMaxPolyphony; }
+	
+private:
+	UInt32							mGroupIndex;
+	UInt32							mPatchIndex;
+	UInt32							mMaxPolyphony;
+	SynthKeyZone					mKeyZone;	
+};
+
+#endif
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthEvent.h b/architecture/AU/AUPublic/AUInstrumentBase/SynthEvent.h
new file mode 100644
index 0000000..bd68d9f
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthEvent.h
@@ -0,0 +1,145 @@
+/*
+     File: SynthEvent.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+/* You can either fill in code here or remove this and create or add new files. */
+
+#ifndef __SynthEvent__
+#define __SynthEvent__
+
+#include <AudioUnit/AudioUnit.h>
+#include <CoreAudio/CoreAudio.h>
+#include "MusicDeviceBase.h"
+#include <stdexcept>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+class SynthEvent
+{
+public:
+	enum {
+		kEventType_NoteOn = 1,
+		kEventType_NoteOff = 2,
+		kEventType_SustainOn = 3,
+		kEventType_SustainOff = 4,
+		kEventType_SostenutoOn = 5,
+		kEventType_SostenutoOff = 6,
+		kEventType_AllNotesOff = 7,
+		kEventType_AllSoundOff = 8,
+		kEventType_ResetAllControllers = 9
+	};
+
+
+	SynthEvent() {}
+	~SynthEvent() {}
+
+	void Set(   
+				UInt32							inEventType,
+				MusicDeviceGroupID				inGroupID,
+				NoteInstanceID					inNoteID,
+				UInt32							inOffsetSampleFrame,
+				const MusicDeviceNoteParams*	inNoteParams
+		)
+	{
+		mEventType = inEventType;
+		mGroupID = inGroupID;
+		mNoteID = inNoteID;
+		mOffsetSampleFrame = inOffsetSampleFrame;
+		
+		if (inNoteParams)
+		{
+			UInt32 paramSize = offsetof(MusicDeviceNoteParams, mControls) + (inNoteParams->argCount-2)*sizeof(NoteParamsControlValue); 
+			mNoteParams = inNoteParams->argCount > 3 
+								? (MusicDeviceNoteParams*)malloc(paramSize) 
+								: &mSmallNoteParams;
+			memcpy(mNoteParams, inNoteParams, paramSize);
+		}
+		else 
+			mNoteParams = NULL;
+	}
+	
+	
+	void Free()
+	{
+		if (mNoteParams)
+		{
+			if (mNoteParams->argCount > 3)
+				free(mNoteParams);
+			mNoteParams = NULL;
+		}
+	}
+	
+	UInt32					GetEventType() const { return mEventType; }
+	MusicDeviceGroupID		GetGroupID() const { return mGroupID; }
+	NoteInstanceID			GetNoteID() const { return mNoteID; }
+	UInt32					GetOffsetSampleFrame() const { return mOffsetSampleFrame; }
+	
+	MusicDeviceNoteParams*  GetParams() const { return mNoteParams; }
+
+	UInt32					GetArgCount() const { return mNoteParams->argCount; }
+	UInt32					NumberParameters() const { return mNoteParams->argCount - 2; }
+	
+	Float32					GetNote() const { return mNoteParams->mPitch; }
+	Float32					GetVelocity() const { return mNoteParams->mVelocity; }
+	
+	NoteParamsControlValue  GetParameter(UInt32 inIndex) const 
+							{
+								if (inIndex >= NumberParameters()) 
+									throw std::runtime_error("index out of range");
+								return mNoteParams->mControls[inIndex]; 
+							}
+	
+private:
+	UInt32					mEventType;
+	MusicDeviceGroupID		mGroupID;
+	NoteInstanceID			mNoteID;
+	UInt32					mOffsetSampleFrame;
+	MusicDeviceNoteParams*  mNoteParams;
+	MusicDeviceNoteParams   mSmallNoteParams; // inline a small one to eliminate malloc for the simple case.
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.cpp b/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.cpp
new file mode 100644
index 0000000..8f18a44
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.cpp
@@ -0,0 +1,140 @@
+/*
+     File: SynthNote.cpp
+ Abstract: SynthNote.h
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include "SynthNote.h"
+#include "SynthElement.h"
+#include "AUInstrumentBase.h"
+
+bool SynthNote::AttackNote(
+			SynthPartElement *				inPart,
+			SynthGroupElement *				inGroup,
+			NoteInstanceID					inNoteID, 
+			UInt64							inAbsoluteSampleFrame, 
+			UInt32							inOffsetSampleFrame, 
+			const MusicDeviceNoteParams		&inParams)
+{
+#if DEBUG_PRINT
+	printf("SynthNote::AttackNote %lu %lu abs frame %llu rel frame %lu\n", (UInt32)inGroup->GroupID(), (UInt32)inNoteID, inAbsoluteSampleFrame, inOffsetSampleFrame);
+#endif
+	mPart = inPart;
+	mGroup = inGroup;
+	mNoteID = inNoteID;
+
+	mAbsoluteStartFrame = inAbsoluteSampleFrame;
+	mRelativeStartFrame = inOffsetSampleFrame;
+	mRelativeReleaseFrame = -1;
+	mRelativeKillFrame = -1;
+
+	mPitch = inParams.mPitch;
+	mVelocity = inParams.mVelocity;
+	
+	
+	return Attack(inParams);
+}
+
+
+void SynthNote::Reset()
+{
+	mPart = 0;
+	mGroup = 0;
+	mAbsoluteStartFrame = 0;
+	mRelativeStartFrame = 0;
+	mRelativeReleaseFrame = 0;
+	mRelativeKillFrame = 0;
+}
+
+void SynthNote::Kill(UInt32 inFrame)
+{
+	mRelativeKillFrame = inFrame;
+}
+
+void SynthNote::Release(UInt32 inFrame)
+{
+	mRelativeReleaseFrame = inFrame;
+}
+
+void SynthNote::FastRelease(UInt32 inFrame)
+{
+	mRelativeReleaseFrame = inFrame;
+}
+
+double SynthNote::TuningA() const
+{
+	return 440.0;
+}
+
+double SynthNote::Frequency()
+{
+	return TuningA() * pow(2., (mPitch - 69. + GetPitchBend()) / 12.);
+}
+
+double SynthNote::SampleRate()
+{
+	return GetAudioUnit()->GetOutput(0)->GetStreamFormat().mSampleRate;
+}
+
+AUInstrumentBase* SynthNote::GetAudioUnit() const 
+{ 
+	return (AUInstrumentBase*)mGroup->GetAudioUnit(); 
+}
+
+Float32 SynthNote::GetGlobalParameter(AudioUnitParameterID inParamID) const 
+{
+	return mGroup->GetAudioUnit()->Globals()->GetParameter(inParamID);
+}
+
+void SynthNote::NoteEnded(UInt32 inFrame) 
+{ 
+	mGroup->NoteEnded(this, inFrame);
+	mNoteID = 0xFFFFFFFF; 
+}
+
+float SynthNote::GetPitchBend() const 
+{ 
+	return mGroup->GetPitchBend(); 
+}
+
+
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.h b/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.h
new file mode 100644
index 0000000..92bbc09
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.h
@@ -0,0 +1,186 @@
+/*
+     File: SynthNote.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __SynthNote__
+#define __SynthNote__
+
+#include <AudioUnit/AudioUnit.h>
+#include <CoreAudio/CoreAudio.h>
+#include "MusicDeviceBase.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+enum SynthNoteState {
+	kNoteState_Attacked = 0,
+	kNoteState_Sostenutoed = 1,
+	kNoteState_ReleasedButSostenutoed = 2,
+	kNoteState_ReleasedButSustained = 3,
+	kNoteState_Released = 4,
+	kNoteState_FastReleased = 5,
+	kNoteState_Free = 6,
+	kNumberOfActiveNoteStates = 5,
+	kNumberOfSoundingNoteStates = 6,
+	kNumberOfNoteStates = 7,
+	kNoteState_Unset = kNumberOfNoteStates
+};
+
+/*
+		This table describes the state transitions for SynthNotes
+
+        EVENT                   CURRENT STATE                                   NEW STATE
+        note on                 free                                            attacked
+        note off                attacked (and sustain on)                       released but sustained
+        note off                attacked                                        released
+        note off                sostenutoed                                     released but sostenutoed
+        sustain on              -- no changes --
+        sustain off             released but sustained                          released
+        sostenuto on            attacked                                        sostenutoed
+        sostenuto off           sostenutoed                                     attacked
+        sostenuto off           released but sostenutoed (and sustain on)       released but sustained
+        sostenuto off           released but sostenutoed                        released
+        end of note             any state                                       free
+		soft voice stealing     any state                                       fast released
+		hard voice stealing     any state                                       free
+		
+		soft voice stealing happens when there is a note on event and NumActiveNotes > MaxActiveNotes
+		hard voice stealing happens when there is a note on event and NumActiveNotes == NumNotes (no free notes)
+		voice stealing removes the quietest note in the highest numbered state that has sounding notes.
+*/
+
+class SynthGroupElement;
+class SynthPartElement;
+class AUInstrumentBase;
+
+struct SynthNote
+{
+	SynthNote() :
+		mPrev(0), mNext(0), mPart(0), mGroup(0),
+		mNoteID(0xffffffff),
+		mState(kNoteState_Unset),
+		mAbsoluteStartFrame(0),
+		mRelativeStartFrame(0),
+		mRelativeReleaseFrame(-1),
+		mRelativeKillFrame(-1),
+		mPitch(0.0f),
+		mVelocity(0.0f)
+	{
+	}
+	
+	virtual					~SynthNote() {}
+	
+	virtual void			Reset();
+	//! Returns true if active note resulted from this call, otherwise false
+	virtual bool			AttackNote(
+									SynthPartElement *				inPart,
+									SynthGroupElement *				inGroup,
+									NoteInstanceID					inNoteID, 
+									UInt64							inAbsoluteSampleFrame, 
+									UInt32							inOffsetSampleFrame, 
+									const MusicDeviceNoteParams		&inParams
+							);
+								
+	virtual OSStatus		Render(UInt64 inAbsoluteSampleFrame, UInt32 inNumFrames, AudioBufferList** inBufferList, UInt32 inOutBusCount) = 0;
+	//! Returns true if active note resulted from this call, otherwise false
+	virtual bool			Attack(const MusicDeviceNoteParams &inParams) = 0;
+	virtual void			Kill(UInt32 inFrame); // voice is being stolen.
+	virtual void			Release(UInt32 inFrame);
+	virtual void			FastRelease(UInt32 inFrame);
+	virtual Float32			Amplitude() = 0; // used for finding quietest note for voice stealing.
+
+	virtual void			NoteEnded(UInt32 inFrame);
+
+	SynthGroupElement*		GetGroup() const { return mGroup; }
+	SynthPartElement*		GetPart() const { return mPart; }
+	
+	AUInstrumentBase*		GetAudioUnit() const;
+
+	Float32					GetGlobalParameter(AudioUnitParameterID inParamID) const;
+
+	NoteInstanceID			GetNoteID() const { return mNoteID; }
+	SynthNoteState			GetState() const { return mState; }
+	UInt8					GetMidiKey() const { return (UInt8) mPitch; }
+	UInt8					GetMidiVelocity() const { return (UInt8) mVelocity; }
+	
+	Boolean					IsSounding() const { return mState < kNumberOfSoundingNoteStates; }
+	Boolean					IsActive() const { return mState < kNumberOfActiveNoteStates; }
+	UInt64					GetAbsoluteStartFrame() const { return mAbsoluteStartFrame; }
+	SInt32					GetRelativeStartFrame() const { return mRelativeStartFrame; }
+	SInt32					GetRelativeReleaseFrame() const { return mRelativeReleaseFrame; }
+	SInt32					GetRelativeKillFrame() const { return mRelativeKillFrame; }
+
+	void					ListRemove() { mPrev = mNext = 0; } // only use when lists will be reset.
+
+	float					GetPitchBend() const;
+	double					TuningA() const;
+	
+	virtual double			Frequency(); // returns the frequency of note + pitch bend.
+	virtual double			SampleRate();
+
+	// linked list pointers
+	SynthNote				*mPrev;
+	SynthNote				*mNext;
+	
+	friend class			SynthGroupElement;
+	friend struct			SynthNoteList;
+protected:
+	void					SetState(SynthNoteState inState) { mState = inState; }
+private:
+	SynthPartElement*		mPart;
+	SynthGroupElement*	mGroup;
+		
+	NoteInstanceID			mNoteID;
+	SynthNoteState			mState;
+	UInt64					mAbsoluteStartFrame;
+	SInt32					mRelativeStartFrame;
+	SInt32					mRelativeReleaseFrame;
+	SInt32					mRelativeKillFrame;
+	
+	Float32					mPitch;
+	Float32					mVelocity;
+};
+
+#endif
+
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.cpp b/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.cpp
new file mode 100644
index 0000000..ab99ca5
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.cpp
@@ -0,0 +1,93 @@
+/*
+     File: SynthNoteList.cpp
+ Abstract: SynthNoteList.h
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#include "SynthNoteList.h"
+#include <stdexcept>
+
+void SynthNoteList::SanityCheck() const
+{
+	if (mState >= kNoteState_Unset) {
+		throw std::runtime_error("SanityCheck: mState is bad");
+	}
+	
+	if (mHead == NULL) {
+		if (mTail != NULL) 
+			throw std::runtime_error("SanityCheck: mHead is NULL but not mTail");
+		return;
+	}
+	if (mTail == NULL) {
+		throw std::runtime_error("SanityCheck: mTail is NULL but not mHead");
+	}
+	
+	if (mHead->mPrev) {
+		throw std::runtime_error("SanityCheck: mHead has a mPrev");
+	}
+	if (mTail->mNext) {
+		throw std::runtime_error("SanityCheck: mTail has a mNext");
+	}
+	
+	SynthNote *note = mHead;
+	while (note)
+	{
+		if (note->mState != mState)
+			throw std::runtime_error("SanityCheck: note in wrong state");
+		if (note->mNext) {
+			if (note->mNext->mPrev != note)
+				throw std::runtime_error("SanityCheck: bad link 1");
+		} else {
+			if (mTail != note)
+				throw std::runtime_error("SanityCheck: note->mNext is nil, but mTail != note");
+		}
+		if (note->mPrev) {
+			if (note->mPrev->mNext != note)
+				throw std::runtime_error("SanityCheck: bad link 2");
+		} else {
+			if (mHead != note)
+				throw std::runtime_error("SanityCheck: note->mPrev is nil, but mHead != note");
+		}
+		note = note->mNext;
+	}
+}
diff --git a/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.h b/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.h
new file mode 100644
index 0000000..f3f1de0
--- /dev/null
+++ b/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.h
@@ -0,0 +1,232 @@
+/*
+     File: SynthNoteList.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __SynthNoteList__
+#define __SynthNoteList__
+
+#include "SynthNote.h"
+
+#if DEBUG
+#ifndef DEBUG_PRINT
+	#define DEBUG_PRINT 0
+#endif
+	#define USE_SANITY_CHECK 0
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct SynthNoteList
+{
+	SynthNoteList() : mState(kNoteState_Unset), mHead(0), mTail(0) {}
+	
+	bool NotEmpty() const { return mHead != NULL; }
+	bool IsEmpty() const { return mHead == NULL; }
+	void Empty() { 
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+		mHead = mTail = NULL; 
+	}
+	
+	UInt32 Length() const {
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+		UInt32 length = 0;
+		for (SynthNote* note = mHead; note; note = note->mNext) 
+			length++;
+		return length;
+	};
+	
+	void AddNote(SynthNote *inNote)
+	{
+#if DEBUG_PRINT
+		printf("AddNote(inNote=%p) to state: %lu\n", inNote, mState);
+#endif
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+		inNote->SetState(mState);
+		inNote->mNext = mHead;
+		inNote->mPrev = NULL;
+		
+		if (mHead) { mHead->mPrev = inNote; mHead = inNote; }
+		else mHead = mTail = inNote;
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+	}
+	
+	void RemoveNote(SynthNote *inNote)
+	{
+#if DEBUG_PRINT
+		printf("RemoveNote(inNote=%p) from state: %lu\n", inNote, mState);
+#endif
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+		if (inNote->mPrev) inNote->mPrev->mNext = inNote->mNext;
+		else mHead = inNote->mNext;
+
+		if (inNote->mNext) inNote->mNext->mPrev = inNote->mPrev;
+		else mTail = inNote->mPrev;
+		
+		inNote->mPrev = 0;
+		inNote->mNext = 0;
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+	}
+
+	void TransferAllFrom(SynthNoteList *inNoteList, UInt32 inFrame)
+	{
+#if DEBUG_PRINT
+		printf("TransferAllFrom: from state %lu into state %lu\n", inNoteList->mState, mState);
+#endif
+#if USE_SANITY_CHECK
+		SanityCheck();
+		inNoteList->SanityCheck();
+#endif
+		if (!inNoteList->mTail) return;
+		
+		if (mState == kNoteState_Released)
+		{
+			for (SynthNote* note = inNoteList->mHead; note; note = note->mNext)
+			{
+#if DEBUG_PRINT
+				printf("TransferAllFrom: releasing note %p\n", note);
+#endif
+				note->Release(inFrame);
+				note->SetState(mState);
+			}
+		}
+		else
+		{
+			for (SynthNote* note = inNoteList->mHead; note; note = note->mNext)
+			{
+				note->SetState(mState);
+			}
+		}
+		
+		inNoteList->mTail->mNext = mHead;
+		
+		if (mHead) mHead->mPrev = inNoteList->mTail;
+		else mTail = inNoteList->mTail;
+		
+		mHead = inNoteList->mHead;
+		
+		inNoteList->mHead = NULL;
+		inNoteList->mTail = NULL;
+#if USE_SANITY_CHECK
+		SanityCheck();
+		inNoteList->SanityCheck();
+#endif
+	}
+	
+	SynthNote* FindOldestNote()
+	{
+#if DEBUG_PRINT
+		printf("FindOldestNote\n");
+#endif
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+		UInt64 minStartFrame = -1;
+		SynthNote* oldestNote = NULL;
+		for (SynthNote* note = mHead; note; note = note->mNext)
+		{
+			if (note->mAbsoluteStartFrame < minStartFrame)
+			{
+				oldestNote = note;
+				minStartFrame = note->mAbsoluteStartFrame;
+			}
+		}
+		return oldestNote;
+	}
+	
+	SynthNote* FindMostQuietNote()
+	{
+#if DEBUG_PRINT
+		printf("FindMostQuietNote\n");
+#endif
+		Float32 minAmplitude = 1e9f;
+		UInt64 minStartFrame = -1;
+		SynthNote* mostQuietNote = NULL;
+		for (SynthNote* note = mHead; note; note = note->mNext)
+		{
+			Float32 amp = note->Amplitude();
+#if DEBUG_PRINT
+			printf("   amp %g   minAmplitude %g\n", amp, minAmplitude);
+#endif
+			if (amp < minAmplitude)
+			{
+				mostQuietNote = note;
+				minAmplitude = amp;
+				minStartFrame = note->mAbsoluteStartFrame;
+			}
+			else if (amp == minAmplitude && note->mAbsoluteStartFrame < minStartFrame)
+			{
+				// use earliest start time as a tie breaker
+				mostQuietNote = note;
+				minStartFrame = note->mAbsoluteStartFrame;
+			}
+		}
+#if USE_SANITY_CHECK
+		SanityCheck();
+#endif
+		return mostQuietNote;
+	}
+	
+	void SanityCheck() const;
+	
+	SynthNoteState	mState;
+	SynthNote *		mHead;
+	SynthNote *		mTail;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/architecture/AU/AUPublic/Utility/AUBaseHelper.cpp b/architecture/AU/AUPublic/Utility/AUBaseHelper.cpp
new file mode 100644
index 0000000..001ad0f
--- /dev/null
+++ b/architecture/AU/AUPublic/Utility/AUBaseHelper.cpp
@@ -0,0 +1,134 @@
+/*
+     File: AUBaseHelper.cpp 
+ Abstract:  AUBaseHelper.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUBaseHelper.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <AudioUnit/AudioUnitProperties.h>
+#else
+	#include <AudioUnitProperties.h>
+#endif
+
+OSStatus	GetFileRefPath (CFDictionaryRef parent, CFStringRef frKey, CFStringRef * fPath)
+{	
+	static CFStringRef kFRString = CFSTR (kAUPresetExternalFileRefs);
+	
+	const void* frVal = CFDictionaryGetValue(parent, kFRString);
+	if (!frVal) return kAudioUnitErr_InvalidPropertyValue;
+
+	const void* frString = CFDictionaryGetValue ((CFDictionaryRef)frVal, frKey);
+	if (!frString) return kAudioUnitErr_InvalidPropertyValue;
+		
+	if (fPath)
+		*fPath = (CFStringRef)frString;
+	
+	return noErr;
+}
+
+// write valid samples check, with bool for zapping
+
+UInt32 FindInvalidSamples(Float32 *inSource, UInt32 inFramesToProcess, bool &outHasNonZero, bool zapInvalidSamples)
+{
+	float *sourceP = inSource;
+	
+	UInt32 badSamplesDetected = 0;
+	for (UInt32 i=0; i < inFramesToProcess; i++)
+	{
+		float  input = *sourceP;
+		
+		if(input > 0) 
+			outHasNonZero = true;
+
+		float absx = fabs(input);
+		
+		// a bad number!
+		if (!(absx < 1e15))
+		{
+			if (!(absx == 0))
+			{
+				//printf("\tbad sample: %f\n", input);
+				badSamplesDetected++;
+				if (zapInvalidSamples)
+					*sourceP = 0;
+			}
+		}
+        sourceP++;
+	}
+	
+	return badSamplesDetected;
+}
+
+
+CFMutableDictionaryRef CreateFileRefDict (CFStringRef fKey, CFStringRef fPath, CFMutableDictionaryRef fileRefDict)
+{
+	if (!fileRefDict)
+		fileRefDict = CFDictionaryCreateMutable	(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+	CFDictionarySetValue (fileRefDict, fKey, fPath);
+	
+	return fileRefDict;
+}
+
+#if DEBUG
+//_____________________________________________________________________________
+//
+void PrintAUParamEvent (AudioUnitParameterEvent& event, FILE* f)
+{
+		bool isRamp = event.eventType == kParameterEvent_Ramped;
+		fprintf (f, "\tParamID=%ld,Scope=%ld,Element=%ld\n", (long)event.parameter, (long)event.scope, (long)event.element);
+		fprintf (f, "\tEvent Type:%s,", (isRamp ? "ramp" : "immediate"));
+		if (isRamp)
+			fprintf (f, "start=%ld,dur=%ld,startValue=%f,endValue=%f\n",
+					(long)event.eventValues.ramp.startBufferOffset, (long)event.eventValues.ramp.durationInFrames, 
+					event.eventValues.ramp.startValue, event.eventValues.ramp.endValue);
+		else
+			fprintf (f, "start=%ld,value=%f\n", 
+					(long)event.eventValues.immediate.bufferOffset, 
+					event.eventValues.immediate.value);
+		fprintf (f, "- - - - - - - - - - - - - - - -\n");
+}
+#endif
+
diff --git a/architecture/AU/AUPublic/Utility/AUBaseHelper.h b/architecture/AU/AUPublic/Utility/AUBaseHelper.h
new file mode 100644
index 0000000..5143586
--- /dev/null
+++ b/architecture/AU/AUPublic/Utility/AUBaseHelper.h
@@ -0,0 +1,80 @@
+/*
+     File: AUBaseHelper.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUBaseHelper_h__
+#define __AUBaseHelper_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreFoundation/CoreFoundation.h>
+	#include <AudioUnit/AUComponent.h>
+#else
+	#include <CoreFoundation.h>
+	#include <AUComponent.h>
+#endif
+
+#include "AUBase.h"
+
+
+UInt32 FindInvalidSamples(Float32 *inSource, UInt32 inFramesToProcess, bool &hasNonZero, bool zapInvalidSamples);
+
+
+// helpers for dealing with the file-references dictionary in an AUPreset
+
+extern "C" OSStatus	
+GetFileRefPath (CFDictionaryRef parent, CFStringRef frKey, CFStringRef * fPath);
+
+// if fileRefDict is NULL, this call creates one
+// if not NULL, then the key value is added to it
+extern "C" CFMutableDictionaryRef 
+CreateFileRefDict (CFStringRef fKey, CFStringRef fPath, CFMutableDictionaryRef fileRefDict);
+
+#if DEBUG
+	void PrintAUParamEvent (AudioUnitParameterEvent& event, FILE* f);
+#endif
+
+
+
+#endif // __AUBaseHelper_h__
\ No newline at end of file
diff --git a/architecture/AU/AUPublic/Utility/AUBuffer.cpp b/architecture/AU/AUPublic/Utility/AUBuffer.cpp
new file mode 100644
index 0000000..96120a6
--- /dev/null
+++ b/architecture/AU/AUPublic/Utility/AUBuffer.cpp
@@ -0,0 +1,217 @@
+/*
+     File: AUBuffer.cpp 
+ Abstract:  AUBuffer.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "AUBuffer.h"
+#include <stdlib.h>
+
+AUBufferList::~AUBufferList()
+{
+	Deallocate();
+	if (mPtrs)
+		free(mPtrs);
+}
+
+// a * b + c
+static UInt32 SafeMultiplyAddUInt32(UInt32 a, UInt32 b, UInt32 c)
+{
+	if (a == 0 || b == 0) return c;  // prevent zero divide
+	
+	if (a > (0xFFFFFFFF - c) / b)
+		throw std::bad_alloc();
+	
+	return a * b + c;
+}
+
+void				AUBufferList::Allocate(const CAStreamBasicDescription &format, UInt32 nFrames)
+{
+	UInt32 nStreams;
+	if (format.IsInterleaved()) {
+		nStreams = 1;
+	} else {
+		nStreams = format.mChannelsPerFrame;
+	}
+
+	// careful -- the I/O thread could be running!
+	if (nStreams > mAllocatedStreams) {
+		mPtrs = (AudioBufferList *)CA_realloc(mPtrs, SafeMultiplyAddUInt32(nStreams, sizeof(AudioBuffer), offsetof(AudioBufferList, mBuffers)));
+		mAllocatedStreams = nStreams;
+	}
+	UInt32 bytesPerStream = SafeMultiplyAddUInt32(nFrames, format.mBytesPerFrame, 0xF) & ~0xF;
+	UInt32 nBytes = SafeMultiplyAddUInt32(nStreams, bytesPerStream, 0);
+	if (nBytes > mAllocatedBytes) {
+		if (mExternalMemory) {
+			mExternalMemory = false;
+			mMemory = NULL;
+		}
+		mMemory = (Byte *)CA_realloc(mMemory, nBytes);
+		mAllocatedBytes = nBytes;
+	}
+	mAllocatedFrames = nFrames;
+	mPtrState = kPtrsInvalid;
+}
+
+void				AUBufferList::Deallocate()
+{
+	mAllocatedStreams = 0;
+	mAllocatedFrames = 0;
+	mAllocatedBytes = 0;
+// this causes a world of hurt if someone upstream disconnects during I/O (SysSoundGraph)
+/*	if (mPtrs) {
+		printf("deallocating bufferlist %08X\n", int(mPtrs));
+		free(mPtrs);
+		mPtrs = NULL;
+	} */
+	if (mMemory) {
+		if (mExternalMemory)
+			mExternalMemory = false;
+		else
+			free(mMemory);
+		mMemory = NULL;
+	}
+	mPtrState = kPtrsInvalid;
+}
+
+AudioBufferList &	AUBufferList::PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames)
+{
+	if (nFrames > mAllocatedFrames)
+		COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess);
+
+	UInt32 nStreams;
+	UInt32 channelsPerStream;
+	if (format.IsInterleaved()) {
+		nStreams = 1;
+		channelsPerStream = format.mChannelsPerFrame;
+	} else {
+		nStreams = format.mChannelsPerFrame;
+		channelsPerStream = 1;
+		if (nStreams > mAllocatedStreams)
+			COMPONENT_THROW(kAudioUnitErr_FormatNotSupported);
+	}
+	
+	AudioBufferList *abl = mPtrs;
+	abl->mNumberBuffers = nStreams;
+	AudioBuffer *buf = abl->mBuffers;
+	Byte *mem = mMemory;
+	UInt32 streamInterval = (mAllocatedFrames * format.mBytesPerFrame + 0xF) & ~0xF;
+	UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame;
+	for ( ; nStreams--; ++buf) {
+		buf->mNumberChannels = channelsPerStream;
+		buf->mData = mem;
+		buf->mDataByteSize = bytesPerBuffer;
+		mem += streamInterval;
+	}
+	if (UInt32(mem - mMemory) > mAllocatedBytes)
+		COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess);
+	mPtrState = kPtrsToMyMemory;
+	return *mPtrs;
+}
+
+AudioBufferList &	AUBufferList::PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames)
+{
+	UInt32 nStreams;
+	UInt32 channelsPerStream;
+	if (format.IsInterleaved()) {
+		nStreams = 1;
+		channelsPerStream = format.mChannelsPerFrame;
+	} else {
+		nStreams = format.mChannelsPerFrame;
+		channelsPerStream = 1;
+		if (nStreams > mAllocatedStreams)
+			COMPONENT_THROW(kAudioUnitErr_FormatNotSupported);
+	}
+	AudioBufferList *abl = mPtrs;
+	abl->mNumberBuffers = nStreams;
+	AudioBuffer *buf = abl->mBuffers;
+	UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame;
+	for ( ; nStreams--; ++buf) {
+		buf->mNumberChannels = channelsPerStream;
+		buf->mData = NULL;
+		buf->mDataByteSize = bytesPerBuffer;
+	}
+	mPtrState = kPtrsToExternalMemory;
+	return *mPtrs;
+}
+
+// this should NOT be called while I/O is in process
+void		AUBufferList::UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf)
+{
+	UInt32 alignedSize = buf.size & ~0xF;
+	if (mMemory != NULL && alignedSize >= mAllocatedBytes) {
+		// don't accept the buffer if we already have one and it's big enough
+		// if we don't already have one, we don't need one
+		Byte *oldMemory = mMemory;
+		mMemory = buf.buffer;
+		mAllocatedBytes = alignedSize;
+		// from Allocate(): nBytes = nStreams * nFrames * format.mBytesPerFrame;	
+		// thus: nFrames = nBytes / (nStreams * format.mBytesPerFrame)
+		mAllocatedFrames = mAllocatedBytes / (format.NumberChannelStreams() * format.mBytesPerFrame);
+		mExternalMemory = true;
+		free(oldMemory);
+	}
+}
+
+#if DEBUG
+void	AUBufferList::PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames, bool asFloats)
+{
+	printf("  %s [%d] 0x%08lX:\n", label, subscript, long(&abl));
+	const AudioBuffer *buf = abl.mBuffers;
+	for (UInt32 i = 0; i < abl.mNumberBuffers; ++buf, ++i) {
+		printf("      [%2d] %5dbytes %dch @ %p: ", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData);
+		if (buf->mData != NULL) {
+			UInt32 nSamples = nFrames * buf->mNumberChannels;
+			for (UInt32 j = 0; j < nSamples; ++j) {
+				if (nSamples > 16 && (j % 16) == 0)
+					printf("\n\t");
+				if (asFloats)
+					printf(" %6.3f", ((float *)buf->mData)[j]);
+				else
+					printf(" %08X", (unsigned)((UInt32 *)buf->mData)[j]);
+			}
+		}
+		printf("\n");
+	}
+}
+#endif
diff --git a/architecture/AU/AUPublic/Utility/AUBuffer.h b/architecture/AU/AUPublic/Utility/AUBuffer.h
new file mode 100644
index 0000000..14106d1
--- /dev/null
+++ b/architecture/AU/AUPublic/Utility/AUBuffer.h
@@ -0,0 +1,267 @@
+/*
+     File: AUBuffer.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUBuffer_h__
+#define __AUBuffer_h__
+
+#include <TargetConditionals.h>
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <AudioUnit/AudioUnit.h>
+#else
+	#include <AudioUnit.h>
+#endif
+
+#include <string.h>
+#include "CAStreamBasicDescription.h"
+#include "CAAutoDisposer.h"
+#include "CADebugMacros.h"
+
+// make this usable outside the stricter context of AudiUnits
+#ifndef COMPONENT_THROW
+	#define COMPONENT_THROW(err) \
+		do { DebugMessage(#err); throw static_cast<OSStatus>(err); } while (0)
+#endif
+
+
+	/*! @class AUBufferList */
+class AUBufferList {
+	enum EPtrState {
+		kPtrsInvalid,
+		kPtrsToMyMemory,
+		kPtrsToExternalMemory
+	};
+public:
+	/*! @ctor AUBufferList */
+	AUBufferList() : mPtrState(kPtrsInvalid), mExternalMemory(false), mPtrs(NULL), mMemory(NULL), 
+		mAllocatedStreams(0), mAllocatedFrames(0), mAllocatedBytes(0) { }
+	/*! @dtor ~AUBufferList */
+	~AUBufferList();
+
+	/*! @method PrepareBuffer */
+	AudioBufferList &	PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames);
+	/*! @method PrepareNullBuffer */
+	AudioBufferList &	PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames);
+
+	/*! @method SetBufferList */
+	AudioBufferList &	SetBufferList(const AudioBufferList &abl) {
+							if (mAllocatedStreams < abl.mNumberBuffers)
+								COMPONENT_THROW(-1);
+							mPtrState = kPtrsToExternalMemory;
+							memcpy(mPtrs, &abl, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl);
+							return *mPtrs;
+						}
+	
+	/*! @method SetBuffer */
+	void				SetBuffer(UInt32 index, const AudioBuffer &ab) {
+							if (mPtrState == kPtrsInvalid || index >= mPtrs->mNumberBuffers)
+								COMPONENT_THROW(-1);
+							mPtrState = kPtrsToExternalMemory;
+							mPtrs->mBuffers[index] = ab;
+						}
+
+	/*! @method InvalidateBufferList */
+	void				InvalidateBufferList() { mPtrState = kPtrsInvalid; }
+
+	/*! @method GetBufferList */
+	AudioBufferList &	GetBufferList() const {
+							if (mPtrState == kPtrsInvalid)
+								COMPONENT_THROW(-1);
+							return *mPtrs;
+						}
+
+	/*! @method CopyBufferListTo */
+	void				CopyBufferListTo(AudioBufferList &abl) const {
+							if (mPtrState == kPtrsInvalid)
+								COMPONENT_THROW(-1);
+							memcpy(&abl, mPtrs, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl);
+						}
+	
+	/*! @method CopyBufferContentsTo */
+	void				CopyBufferContentsTo(AudioBufferList &abl) const {
+							if (mPtrState == kPtrsInvalid)
+								COMPONENT_THROW(-1);
+							const AudioBuffer *srcbuf = mPtrs->mBuffers;
+							AudioBuffer *destbuf = abl.mBuffers;
+
+							for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) {
+								if (i >= mPtrs->mNumberBuffers) // duplicate last source to additional outputs [4341137]
+									--srcbuf;
+								if (destbuf->mData != srcbuf->mData)
+									memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
+								destbuf->mDataByteSize = srcbuf->mDataByteSize;
+							}
+						}
+	
+	/*! @method Allocate */
+	void				Allocate(const CAStreamBasicDescription &format, UInt32 nFrames);
+	/*! @method Deallocate */
+	void				Deallocate();
+	
+	/*! @method UseExternalBuffer */
+	void				UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf);
+
+	// AudioBufferList utilities
+	/*! @method ZeroBuffer */
+	static void			ZeroBuffer(AudioBufferList &abl) {
+							AudioBuffer *buf = abl.mBuffers;
+							for (UInt32 i = abl.mNumberBuffers ; i--; ++buf)
+								memset(buf->mData, 0, buf->mDataByteSize);
+						}
+#if DEBUG
+	/*! @method PrintBuffer */
+	static void			PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames = 8, bool asFloats = true);
+#endif
+
+	/*! @method GetAllocatedFrames */
+	UInt32				GetAllocatedFrames() const { return mAllocatedFrames; }
+	
+private:
+	/*! @ctor AUBufferList */
+	AUBufferList(AUBufferList &) { }	// prohibit copy constructor
+
+	/*! @var mPtrState */
+	EPtrState					mPtrState;
+	/*! @var mExternalMemory */
+	bool						mExternalMemory;
+	/*! @var mPtrs */
+	AudioBufferList *			mPtrs;
+	/*! @var mMemory */
+	Byte *						mMemory;
+	/*! @var mAllocatedStreams */
+	UInt32						mAllocatedStreams;
+	/*! @var mAllocatedFrames */
+	UInt32						mAllocatedFrames;
+	/*! @var mAllocatedBytes */
+	UInt32						mAllocatedBytes;
+};
+
+
+// Allocates an array of samples (type T), to be optimally aligned for the processor
+	/*! @class TAUBuffer */
+template <class T>
+class TAUBuffer {
+public:
+	enum { 
+		kAlignInterval = 0x10,
+		kAlignMask = kAlignInterval - 1
+	};
+	
+	/*! @ctor TAUBuffer.0 */
+	TAUBuffer() :	mMemObject(NULL), mAlignedBuffer(NULL), mBufferSizeBytes(0)
+	{
+	}
+	
+	/*! @ctor TAUBuffer.1 */
+	TAUBuffer(UInt32 numElems, UInt32 numChannels) :	mMemObject(NULL), mAlignedBuffer(NULL),
+														mBufferSizeBytes(0)
+	{
+		Allocate(numElems, numChannels);
+	}
+	
+	/*! @dtor ~TAUBuffer */
+	~TAUBuffer()
+	{
+		Deallocate();
+	}
+		
+	/*! @method Allocate */
+	void	Allocate(UInt32 numElems)			// can also re-allocate
+	{
+		UInt32 reqSize = numElems * sizeof(T);
+		
+		if (mMemObject != NULL && reqSize == mBufferSizeBytes)
+			return;	// already allocated
+
+		mBufferSizeBytes = reqSize;
+		mMemObject = CA_realloc(mMemObject, reqSize);
+		UInt32 misalign = (uintptr_t)mMemObject & kAlignMask;
+		if (misalign) {
+			mMemObject = CA_realloc(mMemObject, reqSize + kAlignMask);
+			mAlignedBuffer = (T *)((char *)mMemObject + kAlignInterval - misalign);
+		} else
+			mAlignedBuffer = (T *)mMemObject;
+	}
+
+	/*! @method Deallocate */
+	void	Deallocate()
+	{
+		if (mMemObject == NULL) return;			// so this method has no effect if we're using
+												// an external buffer
+		
+		free(mMemObject);
+		mMemObject = NULL;
+		mAlignedBuffer = NULL;
+		mBufferSizeBytes = 0;
+	}
+	
+	/*! @method AllocateClear */
+	void	AllocateClear(UInt32 numElems)		// can also re-allocate
+	{
+		Allocate(numElems);
+		Clear();
+	}
+	
+	/*! @method Clear */
+	void	Clear()
+	{
+		memset(mAlignedBuffer, 0, mBufferSizeBytes);
+	}
+	
+	// accessors
+	
+	/*! @method operator T *()@ */
+	operator T *()				{ return mAlignedBuffer; }
+
+private:
+	/*! @var mMemObject */
+	void *		mMemObject;			// null when using an external buffer
+	/*! @var mAlignedBuffer */
+	T *			mAlignedBuffer;		// always valid once allocated
+	/*! @var mBufferSizeBytes */
+	UInt32		mBufferSizeBytes;
+};
+
+#endif // __AUBuffer_h__
diff --git a/architecture/AU/AUPublic/Utility/AUMIDIDefs.h b/architecture/AU/AUPublic/Utility/AUMIDIDefs.h
new file mode 100644
index 0000000..cf0114d
--- /dev/null
+++ b/architecture/AU/AUPublic/Utility/AUMIDIDefs.h
@@ -0,0 +1,136 @@
+/*
+     File: AUMIDIDefs.h
+ Abstract: Part of CoreAudio Utility Classes
+  Version: 1.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+*/
+#ifndef __AUMIDIDefs_h__
+#define __AUMIDIDefs_h__
+
+#if !defined(__TMidiMessage)	/* DAS HACK */
+enum
+{
+	kMidiMessage_NoteOff 			= 0x80,
+	kMidiMessage_NoteOn 			= 0x90,
+	kMidiMessage_PolyPressure 		= 0xA0,
+	kMidiMessage_ControlChange 		= 0xB0,
+	kMidiMessage_ProgramChange 		= 0xC0,
+	kMidiMessage_ChannelPressure 	= 0xD0,
+	kMidiMessage_PitchWheel 		= 0xE0,
+	kMidiMessage_SysEx				= 0xF0,
+	kMidiMessage_SysEx_End			= 0xF7,
+	kMidiMessage_MetaEvent			= 0xFF
+};
+#endif
+
+enum
+{
+	kMidiController_BankSelect				= 0,
+	kMidiController_ModWheel				= 1,
+	kMidiController_Breath					= 2,
+	kMidiController_Foot					= 4,
+	kMidiController_PortamentoTime			= 5,
+	kMidiController_DataEntry				= 6,
+	kMidiController_Volume					= 7,
+	kMidiController_Balance					= 8,
+	kMidiController_Pan						= 10,
+	kMidiController_Expression				= 11,
+	
+	// these controls have a (0-63) == off, (64-127) == on
+	kMidiController_Sustain					= 64, //hold1
+	kMidiController_Portamento				= 65,
+	kMidiController_Sostenuto				= 66,
+	kMidiController_Soft					= 67,
+	kMidiController_LegatoPedal				= 68,
+	kMidiController_Hold2Pedal				= 69,
+	kMidiController_FilterResonance			= 71,
+	kMidiController_ReleaseTime				= 72,
+	kMidiController_AttackTime				= 73,
+	kMidiController_Brightness				= 74,
+	kMidiController_DecayTime				= 75,
+	kMidiController_VibratoRate				= 76,
+	kMidiController_VibratoDepth			= 77,
+	kMidiController_VibratoDelay			= 78,
+	
+	// these controls have a 0-127 range and in MIDI they have no LSB (so fractional values are lost in MIDI)
+	kMidiController_ReverbLevel				= 91,
+	kMidiController_ChorusLevel				= 93,
+
+	kMidiController_RPN_LSB					= 100,
+	kMidiController_RPN_MSB					= 101,
+
+	kMidiController_AllSoundOff				= 120,
+	kMidiController_ResetAllControllers		= 121,
+	kMidiController_AllNotesOff				= 123,
+	kMidiController_OmniModeOff				= 124,
+	kMidiController_OmniModeOn				= 125
+};
+
+// RPN values
+enum 
+{
+	kMidiControllerValue_RPNPitchBendSensitivity	= 0,
+	kMidiControllerValue_RPNChannelFineTuning		= 1,
+	kMidiControllerValue_RPNChannelCoarseTuning		= 2,
+	kMidiControllerValue_RPNModDepthRange			= 5,
+	kMidiControllerValue_RPNNull					= 0x3fff	//! 0x7f/0x7f
+};
+
+// GM2 Sound Bank Constants
+enum 
+{
+	kGM2MelodicBank						= 0x7900,
+	kGM2PercussionBank					= 0x7800,
+	kGSPercussionBank					= 0x7f00,
+	kXGSFXBank							= 0x7E00,
+	kXGPercussionBank					= kGSPercussionBank,
+	kBankMSBMask						= 0xff00
+};
+
+enum 
+{
+	kMSBController_MidPoint			= 0x40
+};
+
+#endif	// __AUMIDIDefs_h__
+
diff --git a/architecture/AU/AUPublic/Utility/AUSilentTimeout.h b/architecture/AU/AUPublic/Utility/AUSilentTimeout.h
new file mode 100644
index 0000000..ed0a4c1
--- /dev/null
+++ b/architecture/AU/AUPublic/Utility/AUSilentTimeout.h
@@ -0,0 +1,93 @@
+/*
+     File: AUSilentTimeout.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __AUSilentTimeout
+#define __AUSilentTimeout
+
+class AUSilentTimeout
+{
+public:
+	AUSilentTimeout()
+		: 	mTimeoutCounter(0),
+			mResetTimer(true)
+				{};
+
+	void				Process(UInt32 inFramesToProcess, UInt32 inTimeoutLimit, bool &ioSilence )
+	{
+		if(ioSilence )
+		{
+			if(mResetTimer )
+			{
+				mTimeoutCounter = inTimeoutLimit;
+				mResetTimer = false;
+			}
+			
+			if(mTimeoutCounter > 0 )
+			{
+				mTimeoutCounter -= inFramesToProcess;
+				ioSilence = false;
+			}
+		}
+		else
+		{
+			// signal to reset the next time we receive silence
+			mResetTimer = true;	
+		}
+	}
+
+	void				Reset()
+	{
+		mResetTimer = true;
+	};
+
+
+
+private:
+	SInt32				mTimeoutCounter;
+	bool				mResetTimer;
+};
+
+#endif // __AUSilentTimeout
diff --git a/architecture/AU/English.lproj/InfoPlist.strings b/architecture/AU/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..d9bf55e
Binary files /dev/null and b/architecture/AU/English.lproj/InfoPlist.strings differ
diff --git a/architecture/AU/FaustAU.exp b/architecture/AU/FaustAU.exp
new file mode 100644
index 0000000..0d81851
--- /dev/null
+++ b/architecture/AU/FaustAU.exp
@@ -0,0 +1,2 @@
+_FaustAUEntry
+_FaustAUFactory
diff --git a/architecture/AU/FaustAU.xcodeproj/project.pbxproj b/architecture/AU/FaustAU.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..cc3c02b
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/project.pbxproj
@@ -0,0 +1,946 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		3E82144E08980DED00D00186 /* CAVectorUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E82144B08980DED00D00186 /* CAVectorUnit.cpp */; };
+		3E82144F08980DED00D00186 /* CAVectorUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E82144C08980DED00D00186 /* CAVectorUnit.h */; };
+		3E82145008980DED00D00186 /* CAVectorUnitTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E82144D08980DED00D00186 /* CAVectorUnitTypes.h */; };
+		4C56E7CB08047C7700DE6468 /* SectionPatternLight.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 4C56E7CA08047C7700DE6468 /* SectionPatternLight.tiff */; };
+		4E98967215DB32DD00CDFBCE /* CAAtomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98965D15DB32DD00CDFBCE /* CAAtomic.h */; };
+		4E98967315DB32DD00CDFBCE /* CAAtomicStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98965E15DB32DD00CDFBCE /* CAAtomicStack.h */; };
+		4E98967415DB32DD00CDFBCE /* CAAutoDisposer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98965F15DB32DD00CDFBCE /* CAAutoDisposer.h */; };
+		4E98967515DB32DD00CDFBCE /* CAByteOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966015DB32DD00CDFBCE /* CAByteOrder.h */; };
+		4E98967615DB32DD00CDFBCE /* CADebugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98966115DB32DD00CDFBCE /* CADebugger.cpp */; };
+		4E98967715DB32DD00CDFBCE /* CADebugger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966215DB32DD00CDFBCE /* CADebugger.h */; };
+		4E98967815DB32DD00CDFBCE /* CADebugMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98966315DB32DD00CDFBCE /* CADebugMacros.cpp */; };
+		4E98967915DB32DD00CDFBCE /* CADebugMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966415DB32DD00CDFBCE /* CADebugMacros.h */; };
+		4E98967A15DB32DD00CDFBCE /* CADebugPrintf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98966515DB32DD00CDFBCE /* CADebugPrintf.cpp */; };
+		4E98967B15DB32DD00CDFBCE /* CADebugPrintf.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966615DB32DD00CDFBCE /* CADebugPrintf.h */; };
+		4E98967C15DB32DD00CDFBCE /* CAException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966715DB32DD00CDFBCE /* CAException.h */; };
+		4E98967D15DB32DD00CDFBCE /* CAGuard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98966815DB32DD00CDFBCE /* CAGuard.cpp */; };
+		4E98967E15DB32DD00CDFBCE /* CAGuard.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966915DB32DD00CDFBCE /* CAGuard.h */; };
+		4E98967F15DB32DD00CDFBCE /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98966A15DB32DD00CDFBCE /* CAHostTimeBase.cpp */; };
+		4E98968015DB32DD00CDFBCE /* CAHostTimeBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966B15DB32DD00CDFBCE /* CAHostTimeBase.h */; };
+		4E98968115DB32DD00CDFBCE /* CALogMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966C15DB32DD00CDFBCE /* CALogMacros.h */; };
+		4E98968215DB32DD00CDFBCE /* CAMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966D15DB32DD00CDFBCE /* CAMath.h */; };
+		4E98968315DB32DD00CDFBCE /* CAReferenceCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966E15DB32DD00CDFBCE /* CAReferenceCounted.h */; };
+		4E98968415DB32DD00CDFBCE /* CAThreadSafeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98966F15DB32DD00CDFBCE /* CAThreadSafeList.h */; };
+		4E98968515DB32DD00CDFBCE /* CAXException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98967015DB32DD00CDFBCE /* CAXException.cpp */; };
+		4E98968615DB32DD00CDFBCE /* CAXException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98967115DB32DD00CDFBCE /* CAXException.h */; };
+		4E98968915DB33EC00CDFBCE /* AUPlugInDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E98968715DB33EC00CDFBCE /* AUPlugInDispatch.cpp */; };
+		4E98968A15DB33EC00CDFBCE /* AUPlugInDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E98968815DB33EC00CDFBCE /* AUPlugInDispatch.h */; };
+		8BA05A6E0720730100365D66 /* FaustAUVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A690720730100365D66 /* FaustAUVersion.h */; };
+		8BA05AAE072073D300365D66 /* AUBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05A7F072073D200365D66 /* AUBase.cpp */; };
+		8BA05AAF072073D300365D66 /* AUBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A80072073D200365D66 /* AUBase.h */; };
+		8BA05AB0072073D300365D66 /* AUDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05A81072073D200365D66 /* AUDispatch.cpp */; };
+		8BA05AB1072073D300365D66 /* AUDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A82072073D200365D66 /* AUDispatch.h */; };
+		8BA05AB2072073D300365D66 /* AUInputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05A83072073D200365D66 /* AUInputElement.cpp */; };
+		8BA05AB3072073D300365D66 /* AUInputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A84072073D200365D66 /* AUInputElement.h */; };
+		8BA05AB4072073D300365D66 /* AUOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05A85072073D200365D66 /* AUOutputElement.cpp */; };
+		8BA05AB5072073D300365D66 /* AUOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A86072073D200365D66 /* AUOutputElement.h */; };
+		8BA05AB7072073D300365D66 /* AUScopeElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05A88072073D200365D66 /* AUScopeElement.cpp */; };
+		8BA05AB8072073D300365D66 /* AUScopeElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A89072073D200365D66 /* AUScopeElement.h */; };
+		8BA05AB9072073D300365D66 /* ComponentBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05A8A072073D200365D66 /* ComponentBase.cpp */; };
+		8BA05ABA072073D300365D66 /* ComponentBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05A8B072073D200365D66 /* ComponentBase.h */; };
+		8BA05AD2072073D300365D66 /* AUBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05AA7072073D200365D66 /* AUBuffer.cpp */; };
+		8BA05AD3072073D300365D66 /* AUBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05AA8072073D200365D66 /* AUBuffer.h */; };
+		8BA05AD7072073D300365D66 /* AUSilentTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05AAC072073D200365D66 /* AUSilentTimeout.h */; };
+		8BA05AE50720742100365D66 /* CAAudioChannelLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05ADF0720742100365D66 /* CAAudioChannelLayout.cpp */; };
+		8BA05AE60720742100365D66 /* CAAudioChannelLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05AE00720742100365D66 /* CAAudioChannelLayout.h */; };
+		8BA05AE70720742100365D66 /* CAMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05AE10720742100365D66 /* CAMutex.cpp */; };
+		8BA05AE80720742100365D66 /* CAMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05AE20720742100365D66 /* CAMutex.h */; };
+		8BA05AE90720742100365D66 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA05AE30720742100365D66 /* CAStreamBasicDescription.cpp */; };
+		8BA05AEA0720742100365D66 /* CAStreamBasicDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA05AE40720742100365D66 /* CAStreamBasicDescription.h */; };
+		8BA05AFC072074E100365D66 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA05AF9072074E100365D66 /* AudioToolbox.framework */; };
+		8BA05AFD072074E100365D66 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA05AFA072074E100365D66 /* AudioUnit.framework */; };
+		8BA05B02072074F900365D66 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA05B01072074F900365D66 /* CoreServices.framework */; };
+		8BA4AE54073EB72300A2709A /* FaustAU_CustomViewFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA4ADCE073EB19800A2709A /* FaustAU_CustomViewFactory.h */; };
+		8BA4AE55073EB72300A2709A /* FaustAU_CustomView.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA4ADD0073EB19800A2709A /* FaustAU_CustomView.h */; };
+		8BA4AE56073EB73300A2709A /* FaustAU_CustomViewFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA4ADCF073EB19800A2709A /* FaustAU_CustomViewFactory.m */; };
+		8BA4AE57073EB73300A2709A /* FaustAU_CustomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA4ADD1073EB19800A2709A /* FaustAU_CustomView.m */; };
+		8BA4AE5C073EB79000A2709A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA4AE5B073EB79000A2709A /* Cocoa.framework */; };
+		8BA4AE5D073EB7C300A2709A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA4AE5B073EB79000A2709A /* Cocoa.framework */; };
+		8BA4AE5E073EB7C500A2709A /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA05AFA072074E100365D66 /* AudioUnit.framework */; };
+		8BA4AE5F073EB7C600A2709A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BA05AF9072074E100365D66 /* AudioToolbox.framework */; };
+		8BA4AE66073EBB2E00A2709A /* FaustAUCustomView.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8BA4AE4E073EB69000A2709A /* FaustAUCustomView.bundle */; };
+		8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
+		F5136D851849688C00752451 /* FaustAU.r in Rez */ = {isa = PBXBuildFile; fileRef = 8BA05A680720730100365D66 /* FaustAU.r */; };
+		F52A44E11848502F004E29CF /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F52A44E01848502F004E29CF /* AppKit.framework */; };
+		F52A44E318485038004E29CF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F52A44E218485038004E29CF /* CoreGraphics.framework */; };
+		F530C7961824BCA800D911C2 /* FaustAU.h in Headers */ = {isa = PBXBuildFile; fileRef = F530C7951824BCA800D911C2 /* FaustAU.h */; };
+		F5956FCB185B69410000940B /* FaustAU_Bargraph.m in Sources */ = {isa = PBXBuildFile; fileRef = F5956FC8185B59950000940B /* FaustAU_Bargraph.m */; };
+		F5956FCC185B69480000940B /* FaustAU_Bargraph.h in Headers */ = {isa = PBXBuildFile; fileRef = F5956FC7185B59950000940B /* FaustAU_Bargraph.h */; };
+		F59F45B41850D9D300D337D4 /* au-output.xml in Resources */ = {isa = PBXBuildFile; fileRef = F59F45B31850D9D300D337D4 /* au-output.xml */; };
+		F5A2F52718494D4600C7EB96 /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5A2F52618494D4600C7EB96 /* CoreMIDI.framework */; };
+		F5A2F52A18494E7500C7EB96 /* AUEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F52818494E7500C7EB96 /* AUEffectBase.cpp */; };
+		F5A2F52B18494E7500C7EB96 /* AUEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F52918494E7500C7EB96 /* AUEffectBase.h */; };
+		F5A2F53C18494EEB00C7EB96 /* AUInstrumentBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F52D18494EEB00C7EB96 /* AUInstrumentBase.cpp */; };
+		F5A2F53D18494EEB00C7EB96 /* AUInstrumentBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F52E18494EEB00C7EB96 /* AUInstrumentBase.h */; };
+		F5A2F53E18494EEB00C7EB96 /* AUMIDIBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F52F18494EEB00C7EB96 /* AUMIDIBase.cpp */; };
+		F5A2F53F18494EEB00C7EB96 /* AUMIDIBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53018494EEB00C7EB96 /* AUMIDIBase.h */; };
+		F5A2F54018494EEB00C7EB96 /* LockFreeFIFO.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53118494EEB00C7EB96 /* LockFreeFIFO.h */; };
+		F5A2F54118494EEB00C7EB96 /* MIDIControlHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53218494EEB00C7EB96 /* MIDIControlHandler.h */; };
+		F5A2F54218494EEB00C7EB96 /* MusicDeviceBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F53318494EEB00C7EB96 /* MusicDeviceBase.cpp */; };
+		F5A2F54318494EEB00C7EB96 /* MusicDeviceBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53418494EEB00C7EB96 /* MusicDeviceBase.h */; };
+		F5A2F54418494EEB00C7EB96 /* SynthElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F53518494EEB00C7EB96 /* SynthElement.cpp */; };
+		F5A2F54518494EEB00C7EB96 /* SynthElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53618494EEB00C7EB96 /* SynthElement.h */; };
+		F5A2F54618494EEB00C7EB96 /* SynthEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53718494EEB00C7EB96 /* SynthEvent.h */; };
+		F5A2F54718494EEB00C7EB96 /* SynthNote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F53818494EEB00C7EB96 /* SynthNote.cpp */; };
+		F5A2F54818494EEB00C7EB96 /* SynthNote.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53918494EEB00C7EB96 /* SynthNote.h */; };
+		F5A2F54918494EEB00C7EB96 /* SynthNoteList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A2F53A18494EEB00C7EB96 /* SynthNoteList.cpp */; };
+		F5A2F54A18494EEB00C7EB96 /* SynthNoteList.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F53B18494EEB00C7EB96 /* SynthNoteList.h */; };
+		F5A2F54C1849505600C7EB96 /* AUMIDIDefs.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A2F54B1849505600C7EB96 /* AUMIDIDefs.h */; };
+		F5B12593184A720600914307 /* FaustAU_Button.m in Sources */ = {isa = PBXBuildFile; fileRef = F5B12588184A70C400914307 /* FaustAU_Button.m */; };
+		F5B12594184A720D00914307 /* FaustAU_Knob.m in Sources */ = {isa = PBXBuildFile; fileRef = F5B1258A184A70C400914307 /* FaustAU_Knob.m */; };
+		F5B12595184A721100914307 /* FaustAU_Knob.h in Sources */ = {isa = PBXBuildFile; fileRef = F5B12589184A70C400914307 /* FaustAU_Knob.h */; };
+		F5B12596184A721500914307 /* FaustAU_Button.h in Sources */ = {isa = PBXBuildFile; fileRef = F5B12587184A70C400914307 /* FaustAU_Button.h */; };
+		F5B12597184A721D00914307 /* FaustAU_Slider.h in Sources */ = {isa = PBXBuildFile; fileRef = F5B1258B184A70C400914307 /* FaustAU_Slider.h */; };
+		F5B12598184A722100914307 /* FaustAU_Slider.m in Sources */ = {isa = PBXBuildFile; fileRef = F5B1258C184A70C400914307 /* FaustAU_Slider.m */; };
+		F5B12599184A725200914307 /* au-output.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5B12585184A640300914307 /* au-output.cpp */; };
+		F77C7D440E254BC700EFE153 /* CABufferList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F77C7D420E254BC700EFE153 /* CABufferList.cpp */; };
+		F77C7D450E254BC700EFE153 /* CABufferList.h in Headers */ = {isa = PBXBuildFile; fileRef = F77C7D430E254BC700EFE153 /* CABufferList.h */; };
+		F77C7D4B0E254C0D00EFE153 /* AUBaseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F77C7D490E254C0D00EFE153 /* AUBaseHelper.cpp */; };
+		F77C7D4C0E254C0D00EFE153 /* AUBaseHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = F77C7D4A0E254C0D00EFE153 /* AUBaseHelper.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		8B707175074BC40400FFC872 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8BA4AE4D073EB69000A2709A;
+			remoteInfo = CocoaUI;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		8BA4AE65073EBB1B00A2709A /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 7;
+			files = (
+				8BA4AE66073EBB2E00A2709A /* FaustAUCustomView.bundle in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		3E82144B08980DED00D00186 /* CAVectorUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAVectorUnit.cpp; sourceTree = "<group>"; };
+		3E82144C08980DED00D00186 /* CAVectorUnit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAVectorUnit.h; sourceTree = "<group>"; };
+		3E82144D08980DED00D00186 /* CAVectorUnitTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAVectorUnitTypes.h; sourceTree = "<group>"; };
+		4C56E7CA08047C7700DE6468 /* SectionPatternLight.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = SectionPatternLight.tiff; sourceTree = "<group>"; };
+		4E98965D15DB32DD00CDFBCE /* CAAtomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAAtomic.h; sourceTree = "<group>"; };
+		4E98965E15DB32DD00CDFBCE /* CAAtomicStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAAtomicStack.h; sourceTree = "<group>"; };
+		4E98965F15DB32DD00CDFBCE /* CAAutoDisposer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAAutoDisposer.h; sourceTree = "<group>"; };
+		4E98966015DB32DD00CDFBCE /* CAByteOrder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAByteOrder.h; sourceTree = "<group>"; };
+		4E98966115DB32DD00CDFBCE /* CADebugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CADebugger.cpp; sourceTree = "<group>"; };
+		4E98966215DB32DD00CDFBCE /* CADebugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugger.h; sourceTree = "<group>"; };
+		4E98966315DB32DD00CDFBCE /* CADebugMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CADebugMacros.cpp; sourceTree = "<group>"; };
+		4E98966415DB32DD00CDFBCE /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = "<group>"; };
+		4E98966515DB32DD00CDFBCE /* CADebugPrintf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CADebugPrintf.cpp; sourceTree = "<group>"; };
+		4E98966615DB32DD00CDFBCE /* CADebugPrintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugPrintf.h; sourceTree = "<group>"; };
+		4E98966715DB32DD00CDFBCE /* CAException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAException.h; sourceTree = "<group>"; };
+		4E98966815DB32DD00CDFBCE /* CAGuard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAGuard.cpp; sourceTree = "<group>"; };
+		4E98966915DB32DD00CDFBCE /* CAGuard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAGuard.h; sourceTree = "<group>"; };
+		4E98966A15DB32DD00CDFBCE /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAHostTimeBase.cpp; sourceTree = "<group>"; };
+		4E98966B15DB32DD00CDFBCE /* CAHostTimeBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAHostTimeBase.h; sourceTree = "<group>"; };
+		4E98966C15DB32DD00CDFBCE /* CALogMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CALogMacros.h; sourceTree = "<group>"; };
+		4E98966D15DB32DD00CDFBCE /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = "<group>"; };
+		4E98966E15DB32DD00CDFBCE /* CAReferenceCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAReferenceCounted.h; sourceTree = "<group>"; };
+		4E98966F15DB32DD00CDFBCE /* CAThreadSafeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAThreadSafeList.h; sourceTree = "<group>"; };
+		4E98967015DB32DD00CDFBCE /* CAXException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAXException.cpp; sourceTree = "<group>"; };
+		4E98967115DB32DD00CDFBCE /* CAXException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAXException.h; sourceTree = "<group>"; };
+		4E98968715DB33EC00CDFBCE /* AUPlugInDispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUPlugInDispatch.cpp; sourceTree = "<group>"; };
+		4E98968815DB33EC00CDFBCE /* AUPlugInDispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUPlugInDispatch.h; sourceTree = "<group>"; };
+		8BA05A670720730100365D66 /* FaustAU.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; path = FaustAU.exp; sourceTree = "<group>"; };
+		8BA05A680720730100365D66 /* FaustAU.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = FaustAU.r; path = Source/AUSource/FaustAU.r; sourceTree = "<group>"; };
+		8BA05A690720730100365D66 /* FaustAUVersion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FaustAUVersion.h; path = Source/AUSource/FaustAUVersion.h; sourceTree = "<group>"; };
+		8BA05A7F072073D200365D66 /* AUBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AUBase.cpp; sourceTree = "<group>"; };
+		8BA05A80072073D200365D66 /* AUBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUBase.h; sourceTree = "<group>"; };
+		8BA05A81072073D200365D66 /* AUDispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AUDispatch.cpp; sourceTree = "<group>"; };
+		8BA05A82072073D200365D66 /* AUDispatch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUDispatch.h; sourceTree = "<group>"; };
+		8BA05A83072073D200365D66 /* AUInputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AUInputElement.cpp; sourceTree = "<group>"; };
+		8BA05A84072073D200365D66 /* AUInputElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUInputElement.h; sourceTree = "<group>"; };
+		8BA05A85072073D200365D66 /* AUOutputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AUOutputElement.cpp; sourceTree = "<group>"; };
+		8BA05A86072073D200365D66 /* AUOutputElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUOutputElement.h; sourceTree = "<group>"; };
+		8BA05A88072073D200365D66 /* AUScopeElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AUScopeElement.cpp; sourceTree = "<group>"; };
+		8BA05A89072073D200365D66 /* AUScopeElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUScopeElement.h; sourceTree = "<group>"; };
+		8BA05A8A072073D200365D66 /* ComponentBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ComponentBase.cpp; sourceTree = "<group>"; };
+		8BA05A8B072073D200365D66 /* ComponentBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ComponentBase.h; sourceTree = "<group>"; };
+		8BA05AA7072073D200365D66 /* AUBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AUBuffer.cpp; sourceTree = "<group>"; };
+		8BA05AA8072073D200365D66 /* AUBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUBuffer.h; sourceTree = "<group>"; };
+		8BA05AAC072073D200365D66 /* AUSilentTimeout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUSilentTimeout.h; sourceTree = "<group>"; };
+		8BA05ADF0720742100365D66 /* CAAudioChannelLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAAudioChannelLayout.cpp; sourceTree = "<group>"; };
+		8BA05AE00720742100365D66 /* CAAudioChannelLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAAudioChannelLayout.h; sourceTree = "<group>"; };
+		8BA05AE10720742100365D66 /* CAMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAMutex.cpp; sourceTree = "<group>"; };
+		8BA05AE20720742100365D66 /* CAMutex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAMutex.h; sourceTree = "<group>"; };
+		8BA05AE30720742100365D66 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = "<group>"; };
+		8BA05AE40720742100365D66 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = "<group>"; };
+		8BA05AF9072074E100365D66 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
+		8BA05AFA072074E100365D66 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
+		8BA05AFB072074E100365D66 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
+		8BA05B01072074F900365D66 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
+		8BA4ADCE073EB19800A2709A /* FaustAU_CustomViewFactory.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = FaustAU_CustomViewFactory.h; path = Source/CocoaUI/FaustAU_CustomViewFactory.h; sourceTree = "<group>"; };
+		8BA4ADCF073EB19800A2709A /* FaustAU_CustomViewFactory.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = FaustAU_CustomViewFactory.m; path = Source/CocoaUI/FaustAU_CustomViewFactory.m; sourceTree = "<group>"; };
+		8BA4ADD0073EB19800A2709A /* FaustAU_CustomView.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = FaustAU_CustomView.h; path = Source/CocoaUI/FaustAU_CustomView.h; sourceTree = "<group>"; };
+		8BA4ADD1073EB19800A2709A /* FaustAU_CustomView.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = FaustAU_CustomView.m; path = Source/CocoaUI/FaustAU_CustomView.m; sourceTree = "<group>"; };
+		8BA4AE4E073EB69000A2709A /* FaustAUCustomView.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FaustAUCustomView.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+		8BA4AE4F073EB69000A2709A /* FaustAUCustomView.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = FaustAUCustomView.plist; sourceTree = "<group>"; };
+		8BA4AE5B073EB79000A2709A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		8D01CCD10486CAD60068D4B7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		8D01CCD20486CAD60068D4B7 /* FaustAU.component */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FaustAU.component; sourceTree = BUILT_PRODUCTS_DIR; };
+		F52A44E01848502F004E29CF /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+		F52A44E218485038004E29CF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+		F530C7951824BCA800D911C2 /* FaustAU.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU.h; path = Source/AUSource/FaustAU.h; sourceTree = "<group>"; };
+		F5956FC7185B59950000940B /* FaustAU_Bargraph.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Bargraph.h; path = Source/CocoaUI/FaustAU_Bargraph.h; sourceTree = "<group>"; };
+		F5956FC8185B59950000940B /* FaustAU_Bargraph.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Bargraph.m; path = Source/CocoaUI/FaustAU_Bargraph.m; sourceTree = "<group>"; };
+		F59F45B31850D9D300D337D4 /* au-output.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = "au-output.xml"; path = "Source/au-output.xml"; sourceTree = "<group>"; };
+		F5A2F52618494D4600C7EB96 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
+		F5A2F52818494E7500C7EB96 /* AUEffectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AUEffectBase.cpp; path = AUPublic/AUEffectBase/AUEffectBase.cpp; sourceTree = SOURCE_ROOT; };
+		F5A2F52918494E7500C7EB96 /* AUEffectBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AUEffectBase.h; path = AUPublic/AUEffectBase/AUEffectBase.h; sourceTree = SOURCE_ROOT; };
+		F5A2F52D18494EEB00C7EB96 /* AUInstrumentBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUInstrumentBase.cpp; sourceTree = "<group>"; };
+		F5A2F52E18494EEB00C7EB96 /* AUInstrumentBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUInstrumentBase.h; sourceTree = "<group>"; };
+		F5A2F52F18494EEB00C7EB96 /* AUMIDIBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUMIDIBase.cpp; sourceTree = "<group>"; };
+		F5A2F53018494EEB00C7EB96 /* AUMIDIBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUMIDIBase.h; sourceTree = "<group>"; };
+		F5A2F53118494EEB00C7EB96 /* LockFreeFIFO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LockFreeFIFO.h; sourceTree = "<group>"; };
+		F5A2F53218494EEB00C7EB96 /* MIDIControlHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIControlHandler.h; sourceTree = "<group>"; };
+		F5A2F53318494EEB00C7EB96 /* MusicDeviceBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicDeviceBase.cpp; sourceTree = "<group>"; };
+		F5A2F53418494EEB00C7EB96 /* MusicDeviceBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicDeviceBase.h; sourceTree = "<group>"; };
+		F5A2F53518494EEB00C7EB96 /* SynthElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SynthElement.cpp; sourceTree = "<group>"; };
+		F5A2F53618494EEB00C7EB96 /* SynthElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SynthElement.h; sourceTree = "<group>"; };
+		F5A2F53718494EEB00C7EB96 /* SynthEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SynthEvent.h; sourceTree = "<group>"; };
+		F5A2F53818494EEB00C7EB96 /* SynthNote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SynthNote.cpp; sourceTree = "<group>"; };
+		F5A2F53918494EEB00C7EB96 /* SynthNote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SynthNote.h; sourceTree = "<group>"; };
+		F5A2F53A18494EEB00C7EB96 /* SynthNoteList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SynthNoteList.cpp; sourceTree = "<group>"; };
+		F5A2F53B18494EEB00C7EB96 /* SynthNoteList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SynthNoteList.h; sourceTree = "<group>"; };
+		F5A2F54B1849505600C7EB96 /* AUMIDIDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUMIDIDefs.h; sourceTree = "<group>"; };
+		F5B12585184A640300914307 /* au-output.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = "au-output.cpp"; path = "Source/au-output.cpp"; sourceTree = "<group>"; };
+		F5B12587184A70C400914307 /* FaustAU_Button.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Button.h; path = Source/CocoaUI/FaustAU_Button.h; sourceTree = "<group>"; };
+		F5B12588184A70C400914307 /* FaustAU_Button.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Button.m; path = Source/CocoaUI/FaustAU_Button.m; sourceTree = "<group>"; };
+		F5B12589184A70C400914307 /* FaustAU_Knob.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Knob.h; path = Source/CocoaUI/FaustAU_Knob.h; sourceTree = "<group>"; };
+		F5B1258A184A70C400914307 /* FaustAU_Knob.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Knob.m; path = Source/CocoaUI/FaustAU_Knob.m; sourceTree = "<group>"; };
+		F5B1258B184A70C400914307 /* FaustAU_Slider.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Slider.h; path = Source/CocoaUI/FaustAU_Slider.h; sourceTree = "<group>"; };
+		F5B1258C184A70C400914307 /* FaustAU_Slider.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = FaustAU_Slider.m; path = Source/CocoaUI/FaustAU_Slider.m; sourceTree = "<group>"; };
+		F77C7D420E254BC700EFE153 /* CABufferList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CABufferList.cpp; sourceTree = "<group>"; };
+		F77C7D430E254BC700EFE153 /* CABufferList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CABufferList.h; sourceTree = "<group>"; };
+		F77C7D490E254C0D00EFE153 /* AUBaseHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUBaseHelper.cpp; sourceTree = "<group>"; };
+		F77C7D4A0E254C0D00EFE153 /* AUBaseHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUBaseHelper.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8BA4AE4C073EB69000A2709A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F52A44E318485038004E29CF /* CoreGraphics.framework in Frameworks */,
+				F52A44E11848502F004E29CF /* AppKit.framework in Frameworks */,
+				8BA4AE5D073EB7C300A2709A /* Cocoa.framework in Frameworks */,
+				8BA4AE5E073EB7C500A2709A /* AudioUnit.framework in Frameworks */,
+				8BA4AE5F073EB7C600A2709A /* AudioToolbox.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D01CCCD0486CAD60068D4B7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F5A2F52718494D4600C7EB96 /* CoreMIDI.framework in Frameworks */,
+				8BA05AFC072074E100365D66 /* AudioToolbox.framework in Frameworks */,
+				8BA05AFD072074E100365D66 /* AudioUnit.framework in Frameworks */,
+				8BA05B02072074F900365D66 /* CoreServices.framework in Frameworks */,
+				8BA4AE5C073EB79000A2709A /* Cocoa.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		089C166AFE841209C02AAC07 /* FilterDemo */ = {
+			isa = PBXGroup;
+			children = (
+				08FB77ADFE841716C02AAC07 /* Source */,
+				089C167CFE841241C02AAC07 /* Resources */,
+				089C1671FE841209C02AAC07 /* Libraries */,
+				19C28FB4FE9D528D11CA2CBB /* Products */,
+			);
+			name = FilterDemo;
+			sourceTree = "<group>";
+		};
+		089C1671FE841209C02AAC07 /* Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				F5A2F52618494D4600C7EB96 /* CoreMIDI.framework */,
+				F52A44E218485038004E29CF /* CoreGraphics.framework */,
+				F52A44E01848502F004E29CF /* AppKit.framework */,
+				8BA4AE5B073EB79000A2709A /* Cocoa.framework */,
+				8BA05B01072074F900365D66 /* CoreServices.framework */,
+				8BA05AF9072074E100365D66 /* AudioToolbox.framework */,
+				8BA05AFA072074E100365D66 /* AudioUnit.framework */,
+				8BA05AFB072074E100365D66 /* CoreAudio.framework */,
+			);
+			name = Libraries;
+			sourceTree = "<group>";
+		};
+		089C167CFE841241C02AAC07 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				4C56E7CA08047C7700DE6468 /* SectionPatternLight.tiff */,
+				8BA4AE4F073EB69000A2709A /* FaustAUCustomView.plist */,
+				8D01CCD10486CAD60068D4B7 /* Info.plist */,
+				089C167DFE841241C02AAC07 /* InfoPlist.strings */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		08FB77ADFE841716C02AAC07 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				8BA05A7D072073D200365D66 /* AUPublic */,
+				8BA05A56072072A900365D66 /* AUSource */,
+				8BA4ADCB073EB14C00A2709A /* CustomView */,
+				8BA05AEB0720742700365D66 /* PublicUtility */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		19C28FB4FE9D528D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D01CCD20486CAD60068D4B7 /* FaustAU.component */,
+				8BA4AE4E073EB69000A2709A /* FaustAUCustomView.bundle */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		8BA05A56072072A900365D66 /* AUSource */ = {
+			isa = PBXGroup;
+			children = (
+				F5B12585184A640300914307 /* au-output.cpp */,
+				F530C7951824BCA800D911C2 /* FaustAU.h */,
+				F59F45B31850D9D300D337D4 /* au-output.xml */,
+				8BA05A670720730100365D66 /* FaustAU.exp */,
+				8BA05A680720730100365D66 /* FaustAU.r */,
+				8BA05A690720730100365D66 /* FaustAUVersion.h */,
+			);
+			name = AUSource;
+			sourceTree = "<group>";
+		};
+		8BA05A7D072073D200365D66 /* AUPublic */ = {
+			isa = PBXGroup;
+			children = (
+				F5A2F52C18494EEB00C7EB96 /* AUInstrumentBase */,
+				8BA05A7E072073D200365D66 /* AUBase */,
+				8BA05A99072073D200365D66 /* AUEffectBase */,
+				8BA05AA6072073D200365D66 /* Utility */,
+			);
+			path = AUPublic;
+			sourceTree = "<group>";
+		};
+		8BA05A7E072073D200365D66 /* AUBase */ = {
+			isa = PBXGroup;
+			children = (
+				4E98968715DB33EC00CDFBCE /* AUPlugInDispatch.cpp */,
+				4E98968815DB33EC00CDFBCE /* AUPlugInDispatch.h */,
+				8BA05A7F072073D200365D66 /* AUBase.cpp */,
+				8BA05A80072073D200365D66 /* AUBase.h */,
+				8BA05A81072073D200365D66 /* AUDispatch.cpp */,
+				8BA05A82072073D200365D66 /* AUDispatch.h */,
+				8BA05A83072073D200365D66 /* AUInputElement.cpp */,
+				8BA05A84072073D200365D66 /* AUInputElement.h */,
+				8BA05A85072073D200365D66 /* AUOutputElement.cpp */,
+				8BA05A86072073D200365D66 /* AUOutputElement.h */,
+				8BA05A88072073D200365D66 /* AUScopeElement.cpp */,
+				8BA05A89072073D200365D66 /* AUScopeElement.h */,
+				8BA05A8A072073D200365D66 /* ComponentBase.cpp */,
+				8BA05A8B072073D200365D66 /* ComponentBase.h */,
+			);
+			path = AUBase;
+			sourceTree = "<group>";
+		};
+		8BA05A99072073D200365D66 /* AUEffectBase */ = {
+			isa = PBXGroup;
+			children = (
+				F5A2F52818494E7500C7EB96 /* AUEffectBase.cpp */,
+				F5A2F52918494E7500C7EB96 /* AUEffectBase.h */,
+			);
+			name = AUEffectBase;
+			path = OtherBases;
+			sourceTree = "<group>";
+		};
+		8BA05AA6072073D200365D66 /* Utility */ = {
+			isa = PBXGroup;
+			children = (
+				F77C7D490E254C0D00EFE153 /* AUBaseHelper.cpp */,
+				F5A2F54B1849505600C7EB96 /* AUMIDIDefs.h */,
+				F77C7D4A0E254C0D00EFE153 /* AUBaseHelper.h */,
+				8BA05AA7072073D200365D66 /* AUBuffer.cpp */,
+				8BA05AA8072073D200365D66 /* AUBuffer.h */,
+				8BA05AAC072073D200365D66 /* AUSilentTimeout.h */,
+			);
+			path = Utility;
+			sourceTree = "<group>";
+		};
+		8BA05AEB0720742700365D66 /* PublicUtility */ = {
+			isa = PBXGroup;
+			children = (
+				4E98965D15DB32DD00CDFBCE /* CAAtomic.h */,
+				4E98965E15DB32DD00CDFBCE /* CAAtomicStack.h */,
+				4E98965F15DB32DD00CDFBCE /* CAAutoDisposer.h */,
+				4E98966015DB32DD00CDFBCE /* CAByteOrder.h */,
+				4E98966115DB32DD00CDFBCE /* CADebugger.cpp */,
+				4E98966215DB32DD00CDFBCE /* CADebugger.h */,
+				4E98966315DB32DD00CDFBCE /* CADebugMacros.cpp */,
+				4E98966415DB32DD00CDFBCE /* CADebugMacros.h */,
+				4E98966515DB32DD00CDFBCE /* CADebugPrintf.cpp */,
+				4E98966615DB32DD00CDFBCE /* CADebugPrintf.h */,
+				4E98966715DB32DD00CDFBCE /* CAException.h */,
+				4E98966815DB32DD00CDFBCE /* CAGuard.cpp */,
+				4E98966915DB32DD00CDFBCE /* CAGuard.h */,
+				4E98966A15DB32DD00CDFBCE /* CAHostTimeBase.cpp */,
+				4E98966B15DB32DD00CDFBCE /* CAHostTimeBase.h */,
+				4E98966C15DB32DD00CDFBCE /* CALogMacros.h */,
+				4E98966D15DB32DD00CDFBCE /* CAMath.h */,
+				4E98966E15DB32DD00CDFBCE /* CAReferenceCounted.h */,
+				4E98966F15DB32DD00CDFBCE /* CAThreadSafeList.h */,
+				4E98967015DB32DD00CDFBCE /* CAXException.cpp */,
+				4E98967115DB32DD00CDFBCE /* CAXException.h */,
+				F77C7D420E254BC700EFE153 /* CABufferList.cpp */,
+				F77C7D430E254BC700EFE153 /* CABufferList.h */,
+				3E82144D08980DED00D00186 /* CAVectorUnitTypes.h */,
+				3E82144B08980DED00D00186 /* CAVectorUnit.cpp */,
+				3E82144C08980DED00D00186 /* CAVectorUnit.h */,
+				8BA05ADF0720742100365D66 /* CAAudioChannelLayout.cpp */,
+				8BA05AE00720742100365D66 /* CAAudioChannelLayout.h */,
+				8BA05AE10720742100365D66 /* CAMutex.cpp */,
+				8BA05AE20720742100365D66 /* CAMutex.h */,
+				8BA05AE30720742100365D66 /* CAStreamBasicDescription.cpp */,
+				8BA05AE40720742100365D66 /* CAStreamBasicDescription.h */,
+			);
+			path = PublicUtility;
+			sourceTree = "<group>";
+		};
+		8BA4ADCB073EB14C00A2709A /* CustomView */ = {
+			isa = PBXGroup;
+			children = (
+				F5956FC7185B59950000940B /* FaustAU_Bargraph.h */,
+				F5956FC8185B59950000940B /* FaustAU_Bargraph.m */,
+				F5B12587184A70C400914307 /* FaustAU_Button.h */,
+				F5B12588184A70C400914307 /* FaustAU_Button.m */,
+				F5B12589184A70C400914307 /* FaustAU_Knob.h */,
+				F5B1258A184A70C400914307 /* FaustAU_Knob.m */,
+				F5B1258B184A70C400914307 /* FaustAU_Slider.h */,
+				F5B1258C184A70C400914307 /* FaustAU_Slider.m */,
+				8BA4ADCE073EB19800A2709A /* FaustAU_CustomViewFactory.h */,
+				8BA4ADCF073EB19800A2709A /* FaustAU_CustomViewFactory.m */,
+				8BA4ADD0073EB19800A2709A /* FaustAU_CustomView.h */,
+				8BA4ADD1073EB19800A2709A /* FaustAU_CustomView.m */,
+			);
+			name = CustomView;
+			sourceTree = "<group>";
+		};
+		F5A2F52C18494EEB00C7EB96 /* AUInstrumentBase */ = {
+			isa = PBXGroup;
+			children = (
+				F5A2F52D18494EEB00C7EB96 /* AUInstrumentBase.cpp */,
+				F5A2F52E18494EEB00C7EB96 /* AUInstrumentBase.h */,
+				F5A2F52F18494EEB00C7EB96 /* AUMIDIBase.cpp */,
+				F5A2F53018494EEB00C7EB96 /* AUMIDIBase.h */,
+				F5A2F53118494EEB00C7EB96 /* LockFreeFIFO.h */,
+				F5A2F53218494EEB00C7EB96 /* MIDIControlHandler.h */,
+				F5A2F53318494EEB00C7EB96 /* MusicDeviceBase.cpp */,
+				F5A2F53418494EEB00C7EB96 /* MusicDeviceBase.h */,
+				F5A2F53518494EEB00C7EB96 /* SynthElement.cpp */,
+				F5A2F53618494EEB00C7EB96 /* SynthElement.h */,
+				F5A2F53718494EEB00C7EB96 /* SynthEvent.h */,
+				F5A2F53818494EEB00C7EB96 /* SynthNote.cpp */,
+				F5A2F53918494EEB00C7EB96 /* SynthNote.h */,
+				F5A2F53A18494EEB00C7EB96 /* SynthNoteList.cpp */,
+				F5A2F53B18494EEB00C7EB96 /* SynthNoteList.h */,
+			);
+			path = AUInstrumentBase;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		8BA4AE52073EB70000A2709A /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F5956FCC185B69480000940B /* FaustAU_Bargraph.h in Headers */,
+				8BA4AE54073EB72300A2709A /* FaustAU_CustomViewFactory.h in Headers */,
+				8BA4AE55073EB72300A2709A /* FaustAU_CustomView.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D01CCC70486CAD60068D4B7 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F5A2F54018494EEB00C7EB96 /* LockFreeFIFO.h in Headers */,
+				F530C7961824BCA800D911C2 /* FaustAU.h in Headers */,
+				8BA05A6E0720730100365D66 /* FaustAUVersion.h in Headers */,
+				F5A2F54818494EEB00C7EB96 /* SynthNote.h in Headers */,
+				8BA05AAF072073D300365D66 /* AUBase.h in Headers */,
+				8BA05AB1072073D300365D66 /* AUDispatch.h in Headers */,
+				8BA05AB3072073D300365D66 /* AUInputElement.h in Headers */,
+				8BA05AB5072073D300365D66 /* AUOutputElement.h in Headers */,
+				8BA05AB8072073D300365D66 /* AUScopeElement.h in Headers */,
+				8BA05ABA072073D300365D66 /* ComponentBase.h in Headers */,
+				8BA05AD3072073D300365D66 /* AUBuffer.h in Headers */,
+				8BA05AD7072073D300365D66 /* AUSilentTimeout.h in Headers */,
+				F5A2F53F18494EEB00C7EB96 /* AUMIDIBase.h in Headers */,
+				F5A2F54C1849505600C7EB96 /* AUMIDIDefs.h in Headers */,
+				F5A2F54118494EEB00C7EB96 /* MIDIControlHandler.h in Headers */,
+				8BA05AE60720742100365D66 /* CAAudioChannelLayout.h in Headers */,
+				8BA05AE80720742100365D66 /* CAMutex.h in Headers */,
+				8BA05AEA0720742100365D66 /* CAStreamBasicDescription.h in Headers */,
+				3E82144F08980DED00D00186 /* CAVectorUnit.h in Headers */,
+				3E82145008980DED00D00186 /* CAVectorUnitTypes.h in Headers */,
+				F77C7D450E254BC700EFE153 /* CABufferList.h in Headers */,
+				F77C7D4C0E254C0D00EFE153 /* AUBaseHelper.h in Headers */,
+				F5A2F54318494EEB00C7EB96 /* MusicDeviceBase.h in Headers */,
+				4E98967215DB32DD00CDFBCE /* CAAtomic.h in Headers */,
+				4E98967315DB32DD00CDFBCE /* CAAtomicStack.h in Headers */,
+				F5A2F54A18494EEB00C7EB96 /* SynthNoteList.h in Headers */,
+				F5A2F53D18494EEB00C7EB96 /* AUInstrumentBase.h in Headers */,
+				4E98967415DB32DD00CDFBCE /* CAAutoDisposer.h in Headers */,
+				4E98967515DB32DD00CDFBCE /* CAByteOrder.h in Headers */,
+				4E98967715DB32DD00CDFBCE /* CADebugger.h in Headers */,
+				4E98967915DB32DD00CDFBCE /* CADebugMacros.h in Headers */,
+				4E98967B15DB32DD00CDFBCE /* CADebugPrintf.h in Headers */,
+				4E98967C15DB32DD00CDFBCE /* CAException.h in Headers */,
+				4E98967E15DB32DD00CDFBCE /* CAGuard.h in Headers */,
+				4E98968015DB32DD00CDFBCE /* CAHostTimeBase.h in Headers */,
+				4E98968115DB32DD00CDFBCE /* CALogMacros.h in Headers */,
+				F5A2F54618494EEB00C7EB96 /* SynthEvent.h in Headers */,
+				4E98968215DB32DD00CDFBCE /* CAMath.h in Headers */,
+				4E98968315DB32DD00CDFBCE /* CAReferenceCounted.h in Headers */,
+				4E98968415DB32DD00CDFBCE /* CAThreadSafeList.h in Headers */,
+				F5A2F54518494EEB00C7EB96 /* SynthElement.h in Headers */,
+				4E98968615DB32DD00CDFBCE /* CAXException.h in Headers */,
+				F5A2F52B18494E7500C7EB96 /* AUEffectBase.h in Headers */,
+				4E98968A15DB33EC00CDFBCE /* AUPlugInDispatch.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		8BA4AE4D073EB69000A2709A /* CocoaUI */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 3EED0941089806170095A620 /* Build configuration list for PBXNativeTarget "CocoaUI" */;
+			buildPhases = (
+				8BA4AE52073EB70000A2709A /* Headers */,
+				8BA4AE4A073EB69000A2709A /* Resources */,
+				8BA4AE4B073EB69000A2709A /* Sources */,
+				8BA4AE4C073EB69000A2709A /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = CocoaUI;
+			productName = CocoaUI;
+			productReference = 8BA4AE4E073EB69000A2709A /* FaustAUCustomView.bundle */;
+			productType = "com.apple.product-type.bundle";
+		};
+		8D01CCC60486CAD60068D4B7 /* FaustAU */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 3EED0945089806170095A620 /* Build configuration list for PBXNativeTarget "FaustAU" */;
+			buildPhases = (
+				8D01CCC70486CAD60068D4B7 /* Headers */,
+				8D01CCC90486CAD60068D4B7 /* Resources */,
+				8D01CCCB0486CAD60068D4B7 /* Sources */,
+				8D01CCCD0486CAD60068D4B7 /* Frameworks */,
+				8D01CCCF0486CAD60068D4B7 /* Rez */,
+				8BA4AE65073EBB1B00A2709A /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				8B707176074BC40400FFC872 /* PBXTargetDependency */,
+			);
+			name = FaustAU;
+			productInstallPath = "$(HOME)/Library/Bundles";
+			productName = FilterDemo;
+			productReference = 8D01CCD20486CAD60068D4B7 /* FaustAU.component */;
+			productType = "com.apple.product-type.bundle";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		089C1669FE841209C02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0440;
+			};
+			buildConfigurationList = 3EED0949089806170095A620 /* Build configuration list for PBXProject "FaustAU" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 089C166AFE841209C02AAC07 /* FilterDemo */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8D01CCC60486CAD60068D4B7 /* FaustAU */,
+				8BA4AE4D073EB69000A2709A /* CocoaUI */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8BA4AE4A073EB69000A2709A /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4C56E7CB08047C7700DE6468 /* SectionPatternLight.tiff in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D01CCC90486CAD60068D4B7 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F59F45B41850D9D300D337D4 /* au-output.xml in Resources */,
+				8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+		8D01CCCF0486CAD60068D4B7 /* Rez */ = {
+			isa = PBXRezBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F5136D851849688C00752451 /* FaustAU.r in Rez */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8BA4AE4B073EB69000A2709A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F5B12595184A721100914307 /* FaustAU_Knob.h in Sources */,
+				F5B12597184A721D00914307 /* FaustAU_Slider.h in Sources */,
+				8BA4AE56073EB73300A2709A /* FaustAU_CustomViewFactory.m in Sources */,
+				8BA4AE57073EB73300A2709A /* FaustAU_CustomView.m in Sources */,
+				F5956FCB185B69410000940B /* FaustAU_Bargraph.m in Sources */,
+				F5B12594184A720D00914307 /* FaustAU_Knob.m in Sources */,
+				F5B12593184A720600914307 /* FaustAU_Button.m in Sources */,
+				F5B12596184A721500914307 /* FaustAU_Button.h in Sources */,
+				F5B12598184A722100914307 /* FaustAU_Slider.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D01CCCB0486CAD60068D4B7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F5A2F53C18494EEB00C7EB96 /* AUInstrumentBase.cpp in Sources */,
+				8BA05AAE072073D300365D66 /* AUBase.cpp in Sources */,
+				F5A2F54218494EEB00C7EB96 /* MusicDeviceBase.cpp in Sources */,
+				8BA05AB0072073D300365D66 /* AUDispatch.cpp in Sources */,
+				8BA05AB2072073D300365D66 /* AUInputElement.cpp in Sources */,
+				8BA05AB4072073D300365D66 /* AUOutputElement.cpp in Sources */,
+				8BA05AB7072073D300365D66 /* AUScopeElement.cpp in Sources */,
+				8BA05AB9072073D300365D66 /* ComponentBase.cpp in Sources */,
+				8BA05AD2072073D300365D66 /* AUBuffer.cpp in Sources */,
+				8BA05AE50720742100365D66 /* CAAudioChannelLayout.cpp in Sources */,
+				F5A2F54418494EEB00C7EB96 /* SynthElement.cpp in Sources */,
+				8BA05AE70720742100365D66 /* CAMutex.cpp in Sources */,
+				F5A2F53E18494EEB00C7EB96 /* AUMIDIBase.cpp in Sources */,
+				8BA05AE90720742100365D66 /* CAStreamBasicDescription.cpp in Sources */,
+				F5A2F52A18494E7500C7EB96 /* AUEffectBase.cpp in Sources */,
+				3E82144E08980DED00D00186 /* CAVectorUnit.cpp in Sources */,
+				F77C7D440E254BC700EFE153 /* CABufferList.cpp in Sources */,
+				F77C7D4B0E254C0D00EFE153 /* AUBaseHelper.cpp in Sources */,
+				4E98967615DB32DD00CDFBCE /* CADebugger.cpp in Sources */,
+				F5A2F54718494EEB00C7EB96 /* SynthNote.cpp in Sources */,
+				4E98967815DB32DD00CDFBCE /* CADebugMacros.cpp in Sources */,
+				4E98967A15DB32DD00CDFBCE /* CADebugPrintf.cpp in Sources */,
+				F5B12599184A725200914307 /* au-output.cpp in Sources */,
+				4E98967D15DB32DD00CDFBCE /* CAGuard.cpp in Sources */,
+				4E98967F15DB32DD00CDFBCE /* CAHostTimeBase.cpp in Sources */,
+				4E98968515DB32DD00CDFBCE /* CAXException.cpp in Sources */,
+				F5A2F54918494EEB00C7EB96 /* SynthNoteList.cpp in Sources */,
+				4E98968915DB33EC00CDFBCE /* AUPlugInDispatch.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		8B707176074BC40400FFC872 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8BA4AE4D073EB69000A2709A /* CocoaUI */;
+			targetProxy = 8B707175074BC40400FFC872 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				089C167EFE841241C02AAC07 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		3EED0942089806170095A620 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUGGING_SYMBOLS = YES;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+				INFOPLIST_FILE = FaustAUCustomView.plist;
+				INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = FaustAUCustomView;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				ZERO_LINK = YES;
+			};
+			name = Development;
+		};
+		3EED0943089806170095A620 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				COPY_PHASE_STRIP = YES;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+				INFOPLIST_FILE = FaustAUCustomView.plist;
+				INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = FaustAUCustomView;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				ZERO_LINK = NO;
+			};
+			name = Deployment;
+		};
+		3EED0944089806170095A620 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+				INFOPLIST_FILE = FaustAUCustomView.plist;
+				INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = FaustAUCustomView;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+			};
+			name = Default;
+		};
+		3EED0946089806170095A620 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				DEBUGGING_SYMBOLS = YES;
+				EXPORTED_SYMBOLS_FILE = FaustAU.exp;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				GENERATE_PKGINFO_FILE = YES;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/";
+				LIBRARY_STYLE = Bundle;
+				OTHER_LDFLAGS = "-bundle";
+				OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase";
+				PRODUCT_NAME = FaustAU;
+				REZ_SEARCH_PATHS = (
+					/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers,
+					/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase,
+				);
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = component;
+			};
+			name = Development;
+		};
+		3EED0947089806170095A620 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				EXPORTED_SYMBOLS_FILE = FaustAU.exp;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				GENERATE_PKGINFO_FILE = YES;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/";
+				LIBRARY_STYLE = Bundle;
+				OTHER_LDFLAGS = "-bundle";
+				OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase";
+				PRODUCT_NAME = FaustAU;
+				REZ_SEARCH_PATHS = (
+					/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers,
+					/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase,
+				);
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = component;
+			};
+			name = Deployment;
+		};
+		3EED0948089806170095A620 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				EXPORTED_SYMBOLS_FILE = FaustAU.exp;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				GENERATE_PKGINFO_FILE = YES;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/";
+				LIBRARY_STYLE = Bundle;
+				OTHER_LDFLAGS = "-bundle";
+				OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase";
+				PRODUCT_NAME = FaustAU;
+				REZ_SEARCH_PATHS = (
+					/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers,
+					/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase,
+				);
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = component;
+			};
+			name = Default;
+		};
+		3EED094A089806170095A620 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CLANG_ENABLE_OBJC_ARC = NO;
+				HEADER_SEARCH_PATHS = /usr/local/include;
+				MACOSX_DEPLOYMENT_TARGET = "";
+				SDKROOT = macosx;
+			};
+			name = Development;
+		};
+		3EED094B089806170095A620 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CLANG_ENABLE_OBJC_ARC = NO;
+				HEADER_SEARCH_PATHS = /usr/local/include;
+				MACOSX_DEPLOYMENT_TARGET = "";
+				SDKROOT = macosx;
+			};
+			name = Deployment;
+		};
+		3EED094C089806170095A620 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CLANG_ENABLE_OBJC_ARC = NO;
+				HEADER_SEARCH_PATHS = /usr/local/include;
+				MACOSX_DEPLOYMENT_TARGET = "";
+				SDKROOT = macosx;
+			};
+			name = Default;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		3EED0941089806170095A620 /* Build configuration list for PBXNativeTarget "CocoaUI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3EED0942089806170095A620 /* Development */,
+				3EED0943089806170095A620 /* Deployment */,
+				3EED0944089806170095A620 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+		3EED0945089806170095A620 /* Build configuration list for PBXNativeTarget "FaustAU" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3EED0946089806170095A620 /* Development */,
+				3EED0947089806170095A620 /* Deployment */,
+				3EED0948089806170095A620 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+		3EED0949089806170095A620 /* Build configuration list for PBXProject "FaustAU" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3EED094A089806170095A620 /* Development */,
+				3EED094B089806170095A620 /* Deployment */,
+				3EED094C089806170095A620 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
diff --git a/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..c03bd52
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:FaustAU.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/xcuserdata/reza.xcuserdatad/UserInterfaceState.xcuserstate b/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/xcuserdata/reza.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..f81cc7c
Binary files /dev/null and b/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/xcuserdata/reza.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/xcuserdata/reza.xcuserdatad/WorkspaceSettings.xcsettings b/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/xcuserdata/reza.xcuserdatad/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..659c876
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/xcuserdata/reza.xcuserdatad/WorkspaceSettings.xcsettings
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
+	<true/>
+	<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
+	<true/>
+</dict>
+</plist>
diff --git a/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
new file mode 100644
index 0000000..fe2b454
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+   type = "1"
+   version = "2.0">
+</Bucket>
diff --git a/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/CocoaUI.xcscheme b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/CocoaUI.xcscheme
new file mode 100644
index 0000000..640ca96
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/CocoaUI.xcscheme
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0460"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "8BA4AE4D073EB69000A2709A"
+               BuildableName = "FaustAUCustomView.bundle"
+               BlueprintName = "CocoaUI"
+               ReferencedContainer = "container:FaustAU.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Development">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Development"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Deployment"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Development">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Deployment"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/FaustAU.xcscheme b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/FaustAU.xcscheme
new file mode 100644
index 0000000..4a643bc
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/FaustAU.xcscheme
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0460"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "8D01CCC60486CAD60068D4B7"
+               BuildableName = "FaustAU.component"
+               BlueprintName = "FaustAU"
+               ReferencedContainer = "container:FaustAU.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Development">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Development"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <PathRunnable
+         FilePath = "/Applications/Utilities/AU Lab.app">
+      </PathRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Deployment"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Development">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Deployment"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/xcschememanagement.plist b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..2337539
--- /dev/null
+++ b/architecture/AU/FaustAU.xcodeproj/xcuserdata/reza.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>SchemeUserState</key>
+	<dict>
+		<key>CocoaUI.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>1</integer>
+		</dict>
+		<key>FaustAU.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>0</integer>
+		</dict>
+	</dict>
+	<key>SuppressBuildableAutocreation</key>
+	<dict>
+		<key>8BA4AE4D073EB69000A2709A</key>
+		<dict>
+			<key>primary</key>
+			<true/>
+		</dict>
+		<key>8D01CCC60486CAD60068D4B7</key>
+		<dict>
+			<key>primary</key>
+			<true/>
+		</dict>
+	</dict>
+</dict>
+</plist>
diff --git a/architecture/AU/FaustAUCustomView.plist b/architecture/AU/FaustAUCustomView.plist
new file mode 100644
index 0000000..def4350
--- /dev/null
+++ b/architecture/AU/FaustAUCustomView.plist
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleExecutable</key>
+	<string>FaustAUCustomView</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.grame.audiounit.FaustAU</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>NSPrincipalClass</key>
+	<string>FaustAU_CustomViewFactory</string>
+</dict>
+</plist>
diff --git a/architecture/AU/Info.plist b/architecture/AU/Info.plist
new file mode 100644
index 0000000..d203169
--- /dev/null
+++ b/architecture/AU/Info.plist
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>AudioComponents</key>
+	<array>
+		<dict>
+			<key>description</key>
+			<string>_DESC_</string>
+			<key>factoryFunction</key>
+			<string>FaustAUFactory</string>
+			<key>manufacturer</key>
+			<string>_MANF_</string>
+			<key>name</key>
+			<string>_NAME_</string>
+			<key>sandboxSafe</key>
+			<true/>
+			<key>subtype</key>
+			<string>_STYP_</string>
+			<key>type</key>
+			<string>_TYPE_</string>
+			<key>version</key>
+			<integer>65536</integer>
+		</dict>
+	</array>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>FaustAU</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.grame.audiounit.FaustAU</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.2</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.2</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+</dict>
+</plist>
diff --git a/architecture/AU/PublicUtility/CAAtomic.h b/architecture/AU/PublicUtility/CAAtomic.h
new file mode 100644
index 0000000..a9be8b5
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAAtomic.h
@@ -0,0 +1,305 @@
+/*
+     File: CAAtomic.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+/*
+	This file implements all Atomic operations using Interlocked functions specified in
+	Winbase.h
+NOTE: According to Microsoft documentation, all Interlocked functions generates a
+full barrier. 
+	On Windows:
+	As the Interlocked functions returns the Old value, Extra checks and operations 
+	are made after the atomic operation to return value consistent with OSX counterparts.
+*/
+#ifndef __CAAtomic_h__
+#define __CAAtomic_h__
+
+#if TARGET_OS_WIN32
+	#include <windows.h>
+	#include <intrin.h>
+	#pragma intrinsic(_InterlockedOr)
+	#pragma intrinsic(_InterlockedAnd)
+#else
+	#include <CoreFoundation/CFBase.h>
+	#include <libkern/OSAtomic.h>
+#endif
+
+inline void CAMemoryBarrier() 
+{
+#if TARGET_OS_WIN32
+	MemoryBarrier();
+#else
+	OSMemoryBarrier();
+#endif
+}
+
+inline SInt32 CAAtomicAdd32Barrier(SInt32 theAmt, volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+	long lRetVal = InterlockedExchangeAdd((volatile long*)theValue, theAmt);
+	// InterlockedExchangeAdd returns the original value which differs from OSX version. 
+	// At this point the addition would have occured and hence returning the new value
+	// to keep it sync with OSX.
+	return lRetVal + theAmt;
+#else
+	return OSAtomicAdd32Barrier(theAmt, (volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicOr32Barrier(UInt32 theMask, volatile UInt32* theValue)
+{
+#if TARGET_OS_WIN32
+	// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
+	// function instead.
+	long j = _InterlockedOr((volatile long*)theValue, theMask);
+	// _InterlockedOr returns the original value which differs from OSX version.
+	// Returning the new value similar to OSX
+	return (SInt32)(j | theMask);
+#else
+	return OSAtomicOr32Barrier(theMask, (volatile uint32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicAnd32Barrier(UInt32 theMask, volatile UInt32* theValue)
+{
+#if TARGET_OS_WIN32
+// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
+// function instead.
+	long j = _InterlockedAnd((volatile long*)theValue, theMask);
+	// _InterlockedAnd returns the original value which differs from OSX version.
+	// Returning the new value similar to OSX
+	return (SInt32)(j & theMask);
+#else
+	return OSAtomicAnd32Barrier(theMask, (volatile uint32_t *)theValue);
+#endif
+}
+
+inline bool CAAtomicCompareAndSwap32Barrier(SInt32 oldValue, SInt32 newValue, volatile SInt32 *theValue)
+{
+#if TARGET_OS_WIN32
+	// InterlockedCompareExchange returns the old value. But we need to return bool value.
+	long lRetVal = InterlockedCompareExchange((volatile long*)theValue, newValue, oldValue);
+// Hence we check if the new value is set and if it is we return true else false.
+// If theValue is equal to oldValue then the swap happens. Otherwise swap doesn't happen.
+	return (oldValue == lRetVal);
+#else
+	return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile int32_t *)theValue);
+#endif
+}
+
+
+inline SInt32 CAAtomicIncrement32(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+	return (SInt32)InterlockedIncrement((volatile long*)theValue);
+#else
+	return OSAtomicIncrement32((volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicDecrement32(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+	return (SInt32)InterlockedDecrement((volatile long*)theValue);
+#else
+	return OSAtomicDecrement32((volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicIncrement32Barrier(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+	return CAAtomicIncrement32(theValue);
+#else
+	return OSAtomicIncrement32Barrier((volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicDecrement32Barrier(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+	return CAAtomicDecrement32(theValue);
+#else
+	return OSAtomicDecrement32Barrier((volatile int32_t *)theValue);
+#endif
+}
+
+inline bool CAAtomicTestAndClearBarrier(int bitToClear, void* theAddress)
+{
+#if TARGET_OS_WIN32
+	BOOL bOldVal = InterlockedBitTestAndReset((long*)theAddress, bitToClear);
+	return (bOldVal ? true : false);
+#else
+	return OSAtomicTestAndClearBarrier(bitToClear, (volatile void *)theAddress);
+#endif
+}
+
+inline bool CAAtomicTestAndClear(int bitToClear, void* theAddress)
+{
+#if TARGET_OS_WIN32
+	BOOL bOldVal = CAAtomicTestAndClearBarrier(bitToClear, (long*)theAddress);
+	return (bOldVal ? true : false);
+#else
+	return OSAtomicTestAndClear(bitToClear, (volatile void *)theAddress);
+#endif
+}
+
+inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
+{
+#if TARGET_OS_WIN32
+	BOOL bOldVal = InterlockedBitTestAndSet((long*)theAddress, bitToSet);
+	return (bOldVal ? true : false);
+#else
+	return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress);
+#endif
+}
+
+// int32_t flavors -- for C++ only since we can't overload in C
+// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
+// this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where
+// SInt32 is defined as signed long so this would work there.
+// So in order to fix the redefinition errors, we define these functions only if MacTypes.h is included.
+#if defined(__cplusplus) && defined(__MACTYPES__) && !__LP64__
+inline int32_t CAAtomicAdd32Barrier(int32_t theAmt, volatile int32_t* theValue)
+{
+	return CAAtomicAdd32Barrier(theAmt, (volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicOr32Barrier(uint32_t theMask, volatile uint32_t* theValue)
+{
+	return CAAtomicOr32Barrier(theMask, (volatile UInt32 *)theValue);
+}
+
+inline int32_t CAAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t* theValue)
+{
+	return CAAtomicAnd32Barrier(theMask, (volatile UInt32 *)theValue);
+}
+
+inline bool CAAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue)
+{
+	return CAAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicIncrement32(volatile int32_t* theValue)
+{
+	return CAAtomicIncrement32((volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicDecrement32(volatile int32_t* theValue)
+{
+	return CAAtomicDecrement32((volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicIncrement32Barrier(volatile int32_t* theValue)
+{
+	return CAAtomicIncrement32Barrier((volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
+{
+	return CAAtomicDecrement32Barrier((volatile SInt32 *)theValue);
+}
+#endif // __cplusplus && !__LP64__
+
+#if __LP64__
+inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
+{
+	return OSAtomicCompareAndSwap64Barrier(__oldValue, __newValue, __theValue);
+}
+#endif
+
+inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, volatile void ** __theValue)
+{
+#if __LP64__
+	return CAAtomicCompareAndSwap64Barrier((int64_t)__oldValue, (int64_t)__newValue, (int64_t *)__theValue);
+#else
+	return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue);
+#endif
+}
+
+/* Spinlocks.  These use memory barriers as required to synchronize access to shared
+ * memory protected by the lock.  The lock operation spins, but employs various strategies
+ * to back off if the lock is held, making it immune to most priority-inversion livelocks.
+ * The try operation immediately returns false if the lock was held, true if it took the
+ * lock.  The convention is that unlocked is zero, locked is nonzero.
+ */
+#define	CA_SPINLOCK_INIT    0
+
+typedef int32_t CASpinLock;
+
+bool    CASpinLockTry( volatile CASpinLock *__lock );
+void    CASpinLockLock( volatile CASpinLock *__lock );
+void    CASpinLockUnlock( volatile CASpinLock *__lock );
+
+inline void    CASpinLockLock( volatile CASpinLock *__lock )
+{
+#if TARGET_OS_MAC
+	OSSpinLockLock(__lock);
+#else
+	while (CAAtomicTestAndSetBarrier(0, (void*)__lock))
+		usleep(1000); // ???
+#endif
+}
+
+inline void    CASpinLockUnlock( volatile CASpinLock *__lock )
+{
+#if TARGET_OS_MAC
+	OSSpinLockUnlock(__lock);
+#else
+	CAAtomicTestAndClearBarrier(0, (void*)__lock);
+#endif
+}
+
+inline bool    CASpinLockTry( volatile CASpinLock *__lock )
+{
+#if TARGET_OS_MAC
+	return OSSpinLockTry(__lock);
+#else
+	return (CAAtomicTestAndSetBarrier(0, (void*)__lock) == 0);
+#endif
+}
+
+
+#endif // __CAAtomic_h__
diff --git a/architecture/AU/PublicUtility/CAAtomicStack.h b/architecture/AU/PublicUtility/CAAtomicStack.h
new file mode 100644
index 0000000..691185b
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAAtomicStack.h
@@ -0,0 +1,239 @@
+/*
+     File: CAAtomicStack.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAAtomicStack_h__
+#define __CAAtomicStack_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <libkern/OSAtomic.h>
+#else
+	#include <CAAtomic.h>
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
+	#include <CoreServices/CoreServices.h>
+#endif
+
+//  linked list LIFO or FIFO (pop_all_reversed) stack, elements are pushed and popped atomically
+//  class T must implement T *& next().
+template <class T>
+class TAtomicStack {
+public:
+	TAtomicStack() : mHead(NULL) { }
+	
+	// non-atomic routines, for use when initializing/deinitializing, operate NON-atomically
+	void	push_NA(T *item)
+	{
+		item->next() = mHead;
+		mHead = item;
+	}
+	
+	T *		pop_NA()
+	{
+		T *result = mHead;
+		if (result)
+			mHead = result->next();
+		return result;
+	}
+	
+	bool	empty() { return mHead == NULL; }
+	
+	T *		head() { return mHead; }
+	
+	// atomic routines
+	void	push_atomic(T *item)
+	{
+		T *head_;
+		do {
+			head_ = mHead;
+			item->next() = head_;
+		} while (!compare_and_swap(head_, item, &mHead));
+	}
+	
+	void	push_multiple_atomic(T *item)
+		// pushes entire linked list headed by item
+	{
+		T *head_, *p = item, *tail;
+		// find the last one -- when done, it will be linked to head
+		do {
+			tail = p;
+			p = p->next();
+		} while (p);
+		do {
+			head_ = mHead;
+			tail->next() = head_;
+		} while (!compare_and_swap(head_, item, &mHead));
+	}
+	
+	T *		pop_atomic_single_reader()
+		// this may only be used when only one thread may potentially pop from the stack.
+		// if multiple threads may pop, this suffers from the ABA problem.
+		// <rdar://problem/4606346> TAtomicStack suffers from the ABA problem
+	{
+		T *result;
+		do {
+			if ((result = mHead) == NULL)
+				break;
+		} while (!compare_and_swap(result, result->next(), &mHead));
+		return result;
+	}
+	
+	T *		pop_atomic()
+		// This is inefficient for large linked lists.
+		// prefer pop_all() to a series of calls to pop_atomic.
+		// push_multiple_atomic has to traverse the entire list.
+	{
+		T *result = pop_all();
+		if (result) {
+			T *next = result->next();
+			if (next)
+				// push all the remaining items back onto the stack
+				push_multiple_atomic(next);
+		}
+		return result;
+	}
+	
+	T *		pop_all()
+	{
+		T *result;
+		do {
+			if ((result = mHead) == NULL)
+				break;
+		} while (!compare_and_swap(result, NULL, &mHead));
+		return result;
+	}
+	
+	T*		pop_all_reversed()
+	{
+		TAtomicStack<T> reversed;
+		T *p = pop_all(), *next;
+		while (p != NULL) {
+			next = p->next();
+			reversed.push_NA(p);
+			p = next;
+		}
+		return reversed.mHead;
+	}
+	
+	static bool	compare_and_swap(T *oldvalue, T *newvalue, T **pvalue)
+	{
+#if TARGET_OS_MAC
+	#if __LP64__
+			return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue);
+	#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+			return ::OSAtomicCompareAndSwap32Barrier(int32_t(oldvalue), int32_t(newvalue), (int32_t *)pvalue);
+	#else
+			return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
+	#endif
+#else
+			//return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
+			return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue);
+#endif
+	}
+	
+protected:
+	T *		mHead;
+};
+
+#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) && !TARGET_OS_WIN32)
+#include <libkern/OSAtomic.h>
+
+class CAAtomicStack {
+public:
+	CAAtomicStack(size_t nextPtrOffset) : mNextPtrOffset(nextPtrOffset) {
+		/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
+		mHead.opaque1 = 0; mHead.opaque2 = 0;
+	}
+	// a subset of the above
+	void	push_atomic(void *p) { OSAtomicEnqueue(&mHead, p, mNextPtrOffset); }
+	void	push_NA(void *p) { push_atomic(p); }
+
+	void *	pop_atomic() { return OSAtomicDequeue(&mHead, mNextPtrOffset); }
+	void *	pop_atomic_single_reader() { return pop_atomic(); }
+	void *	pop_NA() { return pop_atomic(); }
+	
+private:
+	OSQueueHead		mHead;
+	size_t			mNextPtrOffset;
+};
+
+// a more efficient subset of TAtomicStack using OSQueue.
+template <class T>
+class TAtomicStack2 {
+public:
+	TAtomicStack2() {
+		/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
+		mHead.opaque1 = 0; mHead.opaque2 = 0;
+		mNextPtrOffset = -1;
+	}
+	void	push_atomic(T *item) {
+		if (mNextPtrOffset < 0) {
+			T **pnext = &item->next();	// hack around offsetof not working with C++
+			mNextPtrOffset = (Byte *)pnext - (Byte *)item;
+		}
+		OSAtomicEnqueue(&mHead, item, mNextPtrOffset);
+	}
+	void	push_NA(T *item) { push_atomic(item); }
+
+	T *		pop_atomic() { return (T *)OSAtomicDequeue(&mHead, mNextPtrOffset); }
+	T *		pop_atomic_single_reader() { return pop_atomic(); }
+	T *		pop_NA() { return pop_atomic(); }
+	
+	// caution: do not try to implement pop_all_reversed here. the writer could add new elements
+	// while the reader is trying to pop old ones!
+	
+private:
+	OSQueueHead		mHead;
+	ssize_t			mNextPtrOffset;
+};
+
+#else
+
+#define TAtomicStack2 TAtomicStack
+
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED && !TARGET_OS_WIN32
+
+#endif // __CAAtomicStack_h__
diff --git a/architecture/AU/PublicUtility/CAAudioChannelLayout.cpp b/architecture/AU/PublicUtility/CAAudioChannelLayout.cpp
new file mode 100644
index 0000000..d961036
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAAudioChannelLayout.cpp
@@ -0,0 +1,153 @@
+/*
+     File: CAAudioChannelLayout.cpp 
+ Abstract:  CAAudioChannelLayout.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+//=============================================================================
+//	Includes
+//=============================================================================
+
+//	Self Include
+#include "CAAudioChannelLayout.h"
+#include "CAAutoDisposer.h"
+#include <stdlib.h>
+#include <string.h>
+
+//=============================================================================
+//	CAAudioChannelLayout
+//=============================================================================
+
+AudioChannelLayout*	CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
+{
+	UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
+	AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(CA_calloc(1, theSize));
+	if(theAnswer != NULL)
+	{
+		SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
+	}
+	return theAnswer;
+}
+
+void	CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
+{
+	free(inChannelLayout);
+}
+
+void	CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
+{
+	outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+	outChannelLayout.mChannelBitmap = 0;
+	outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
+	for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
+	{
+		outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
+		outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
+		outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
+		outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
+		outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
+	}
+}
+
+bool	operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
+{
+	// compare based on the number of channel descriptions present
+	// (this may be too strict a comparison if all you care about are matching layout tags)
+	UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
+	UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
+	
+	if (theSize1 != theSize2)
+		return false;
+		
+	return !memcmp (&x, &y, theSize1);
+}
+
+bool	operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y)
+{
+	return !(x == y);
+}
+
+// counting the one bits in a word
+inline UInt32 CountOnes(UInt32 x)
+{
+	// secret magic algorithm for counting bits in a word.
+	UInt32 t;
+	x = x - ((x >> 1) & 0x55555555);
+	t = ((x >> 2) & 0x33333333);
+	x = (x & 0x33333333) + t;
+	x = (x + (x >> 4)) & 0x0F0F0F0F;
+	x = x + (x << 8);
+	x = x + (x << 16);
+	return x >> 24;
+}
+
+UInt32	CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
+{
+	if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+		return inLayout.mNumberChannelDescriptions;
+	
+	if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+		return CountOnes (inLayout.mChannelBitmap);
+
+	return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
+}
+
+void 	CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
+{
+	if (layout == NULL) 
+	{
+		fprintf (file, "\tNULL layout\n");
+		return;
+	}
+	fprintf (file, "\tTag=0x%X, ", (int)layout->mChannelLayoutTag);
+	if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+		fprintf (file, "Using Bitmap:0x%X\n", (int)layout->mChannelBitmap);
+	else {
+		fprintf (file, "Num Chan Descs=%d\n", (int)layout->mNumberChannelDescriptions);
+		const AudioChannelDescription *desc = layout->mChannelDescriptions;
+		for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
+			fprintf (file, "\t\tLabel=%d, Flags=0x%X, ", (int)desc->mChannelLabel, (int)desc->mChannelFlags);
+			fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
+		}
+	}
+}
diff --git a/architecture/AU/PublicUtility/CAAudioChannelLayout.h b/architecture/AU/PublicUtility/CAAudioChannelLayout.h
new file mode 100644
index 0000000..e8ba246
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAAudioChannelLayout.h
@@ -0,0 +1,199 @@
+/*
+     File: CAAudioChannelLayout.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CAAudioChannelLayout_h__)
+#define __CAAudioChannelLayout_h__
+
+//=============================================================================
+//	Includes
+//=============================================================================
+
+//	System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+	#include <CoreFoundation/CoreFoundation.h>
+#else
+	#include <CoreAudioTypes.h>
+	#include <CoreFoundation.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CADebugMacros.h"
+#include "CAAutoDisposer.h"
+
+#if !HAL_Build
+	#include "CAReferenceCounted.h"
+#endif
+
+//=============================================================================
+//	CAAudioChannelLayout
+//=============================================================================
+
+bool	operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
+bool	operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y);
+
+extern "C" void 	CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
+
+class CAAudioChannelLayout
+{
+//	static Construction/Destruction
+public:
+	static AudioChannelLayout*	Create(UInt32 inNumberChannelDescriptions);
+	static void					Destroy(AudioChannelLayout* inChannelLayout);
+	static UInt32				CalculateByteSize(UInt32 inNumberChannelDescriptions) { 
+									return OffsetOf32(AudioChannelLayout, mChannelDescriptions) + inNumberChannelDescriptions * SizeOf32(AudioChannelDescription);
+								}
+	static void					SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
+	static UInt32				NumberChannels(const AudioChannelLayout& inLayout);
+	
+#if !HAL_Build
+// object methods	
+public:
+								CAAudioChannelLayout ();
+
+								CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
+									// if inChooseSurround is false, then symmetrical speaker arrangements
+									// are chosen in place of surround layouts if there is a choice
+									// This call chooses layouts based on the expected defaults in 
+									// AudioUnit usage
+								CAAudioChannelLayout (AudioChannelLayoutTag inTag);
+								CAAudioChannelLayout (const CAAudioChannelLayout &c);
+								CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
+								~CAAudioChannelLayout();
+	
+	CAAudioChannelLayout&		operator= (const AudioChannelLayout* inChannelLayout);
+	CAAudioChannelLayout&		operator= (const CAAudioChannelLayout& c);
+	bool						operator== (const CAAudioChannelLayout &c) const;
+	bool						operator!= (const CAAudioChannelLayout &c) const;
+
+	void						SetWithTag(AudioChannelLayoutTag inTag);
+
+	bool						IsValid() const { return NumberChannels() > 0; }
+	UInt32						Size() const { return mLayout ? mLayout->Size() : 0; }
+	
+	UInt32						NumberChannels() const { return mLayout ? mLayout->NumberChannels() : 0; }
+	
+	AudioChannelLayoutTag		Tag() const { return Layout().mChannelLayoutTag; }
+	const AudioChannelLayout&	Layout() const { return mLayout->Layout(); }
+	operator const AudioChannelLayout *() const { return &Layout(); }
+	
+	void						Print () const { Print (stdout); }
+	void						Print (FILE* file) const;
+
+	OSStatus					Save (CFPropertyListRef *outData) const;
+	OSStatus					Restore (CFPropertyListRef &inData);
+	
+private:
+	class RefCountedLayout : public CAReferenceCounted {
+		void *	operator new(size_t /* size */, size_t aclSize)
+		{
+			return CA_malloc(sizeof(RefCountedLayout) - sizeof(AudioChannelLayout) + aclSize);
+		}
+		
+		void	operator delete(void *mem)
+		{
+			free(mem);
+		}
+		
+		
+		RefCountedLayout(UInt32 inDataSize) :
+			mByteSize(inDataSize)
+		{ 
+			memset(&mACL, 0, inDataSize);
+		}
+		
+	public:
+		static RefCountedLayout *CreateWithNumberChannelDescriptions(unsigned nChannels) {
+								size_t size = CAAudioChannelLayout::CalculateByteSize(nChannels);
+								return new(size) RefCountedLayout(size);
+							}
+
+		static RefCountedLayout *CreateWithLayout(const AudioChannelLayout *layout) {
+								size_t size = CAAudioChannelLayout::CalculateByteSize(layout->mNumberChannelDescriptions);
+								RefCountedLayout *acl = new(size) RefCountedLayout(size);
+								memcpy(&acl->mACL, layout, size);
+								return acl;
+							}
+		static RefCountedLayout *CreateWithLayoutTag(AudioChannelLayoutTag layoutTag) {
+								RefCountedLayout *acl = CreateWithNumberChannelDescriptions(0);
+								acl->mACL.mChannelLayoutTag = layoutTag;
+								return acl;
+							}
+	
+		const AudioChannelLayout & 	Layout() const { return mACL; }
+		
+		UInt32						Size () const { return mByteSize; }
+		
+		UInt32						NumberChannels() { return CAAudioChannelLayout::NumberChannels(Layout()); }
+		
+	private:
+		const UInt32		mByteSize;
+		AudioChannelLayout 	mACL;
+		// * * * mACL is variable length and thus must be last * * *
+		
+			// only the constructors can change the actual state of the layout
+		friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
+		friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
+		friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
+		friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
+		
+		AudioChannelLayout * 	GetLayout() { return &mACL; }
+	
+	private:
+		// prohibited methods: private and unimplemented.
+		RefCountedLayout();
+		RefCountedLayout(const RefCountedLayout& c);
+		RefCountedLayout& operator=(const RefCountedLayout& c);
+	};
+	
+	RefCountedLayout		*mLayout;
+#endif	//	HAL_Build
+
+};
+
+#endif
diff --git a/architecture/AU/PublicUtility/CAAutoDisposer.h b/architecture/AU/PublicUtility/CAAutoDisposer.h
new file mode 100644
index 0000000..2cd48b2
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAAutoDisposer.h
@@ -0,0 +1,508 @@
+/*
+     File: CAAutoDisposer.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CAPtr_h__)
+#define __CAPtr_h__
+
+#include <stdlib.h>		// for malloc
+#include <new>			// for bad_alloc
+#include <string.h>		// for memset
+
+inline void* CA_malloc(size_t size)
+{
+	void* p = malloc(size);
+	if (!p && size) throw std::bad_alloc();
+	return p;
+}
+
+inline void* CA_realloc(void* old, size_t size)
+{
+#if TARGET_OS_WIN32
+	void* p = realloc(old, size);
+#else
+	void* p = reallocf(old, size); // reallocf ensures the old pointer is freed if memory is full (p is NULL).
+#endif
+	if (!p && size) throw std::bad_alloc();
+	return p;
+}
+
+#ifndef UINTPTR_MAX
+#if __LP64__
+#define UINTPTR_MAX	  18446744073709551615ULL
+#else
+#define UINTPTR_MAX	  4294967295U
+#endif
+#endif
+
+inline void* CA_calloc(size_t n, size_t size)
+{	
+	// ensure that multiplication will not overflow
+	if (n && UINTPTR_MAX / n < size) throw std::bad_alloc();
+	
+	size_t nsize = n*size;
+	void* p = malloc(nsize);
+	if (!p && nsize) throw std::bad_alloc();
+
+	memset(p, 0, nsize);
+	return p;
+}
+
+
+// helper class for automatic conversions
+template <typename T>
+struct CAPtrRef
+{
+	T* ptr_;
+
+	explicit CAPtrRef(T* ptr) : ptr_(ptr) {}
+};
+
+template <typename T>
+class CAAutoFree
+{
+private:
+	T* ptr_;
+
+public:
+	
+	CAAutoFree() : ptr_(0) {}
+	
+	explicit CAAutoFree(T* ptr) : ptr_(ptr) {}
+	
+	template<typename U>
+	CAAutoFree(CAAutoFree<U>& that) : ptr_(that.release()) {} // take ownership
+
+	// C++ std says: a template constructor is never a copy constructor
+	CAAutoFree(CAAutoFree<T>& that) : ptr_(that.release()) {} // take ownership
+
+	CAAutoFree(size_t n, bool clear = false) 
+		// this becomes an ambiguous call if n == 0
+		: ptr_(0) 
+		{
+			size_t maxItems = ~size_t(0) / sizeof(T);
+			if (n > maxItems) 
+				throw std::bad_alloc();
+
+			ptr_ = static_cast<T*>(clear ? CA_calloc(n, sizeof(T)) : CA_malloc(n * sizeof(T)));
+		}
+	
+	~CAAutoFree() { free(); }
+	
+	void alloc(size_t numItems, bool clear = false) 
+	{
+		size_t maxItems = ~size_t(0) / sizeof(T);
+		if (numItems > maxItems) throw std::bad_alloc();
+		
+		free();
+		ptr_ = static_cast<T*>(clear ? CA_calloc(numItems, sizeof(T)) : CA_malloc(numItems * sizeof(T)));
+	}
+	
+	void allocBytes(size_t numBytes, bool clear = false) 
+	{
+		free();
+		ptr_ = static_cast<T*>(clear ? CA_calloc(1, numBytes) : CA_malloc(numBytes));
+	}
+	
+	void reallocBytes(size_t numBytes) 
+	{
+		ptr_ = static_cast<T*>(CA_realloc(ptr_, numBytes));
+	}
+
+	void reallocItems(size_t numItems) 
+	{
+		size_t maxItems = ~size_t(0) / sizeof(T);
+		if (numItems > maxItems) throw std::bad_alloc();
+		
+		ptr_ = static_cast<T*>(CA_realloc(ptr_, numItems * sizeof(T)));
+	}
+	
+	template <typename U>
+	CAAutoFree& operator=(CAAutoFree<U>& that) 
+	{ 
+		set(that.release());	// take ownership
+		return *this;
+	}
+	
+	CAAutoFree& operator=(CAAutoFree& that) 
+	{ 
+		set(that.release());	// take ownership
+		return *this;
+	}
+	
+	CAAutoFree& operator=(T* ptr) 
+	{
+		set(ptr); 
+		return *this;
+	}
+	
+	template <typename U>
+	CAAutoFree& operator=(U* ptr) 
+	{
+		set(ptr); 
+		return *this;
+	}
+		
+	T& operator*() const { return *ptr_; }
+	T* operator->() const { return ptr_; }
+	
+	T* operator()() const { return ptr_; }
+	T* get() const { return ptr_; }
+	operator T*() const { return ptr_; }
+
+	bool operator==(CAAutoFree const& that) const { return ptr_ == that.ptr_; }
+	bool operator!=(CAAutoFree const& that) const { return ptr_ != that.ptr_; }
+	bool operator==(T* ptr) const { return ptr_ == ptr; }
+	bool operator!=(T* ptr) const { return ptr_ != ptr; }
+		
+	T* release() 
+	{
+		// release ownership
+		T* result = ptr_;
+		ptr_ = 0;
+		return result;
+	}
+	
+	void set(T* ptr)
+	{
+		if (ptr != ptr_)
+		{
+			::free(ptr_);
+			ptr_ = ptr;
+		}
+	}
+	
+	void free() 
+	{
+		set(0);
+	}
+
+
+	// automatic conversions to allow assignment from results of functions.
+	// hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+	CAAutoFree(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+	CAAutoFree& operator=(CAPtrRef<T> ref)
+	{
+		set(ref.ptr_);
+		return *this;
+	}
+
+	template<typename U>
+	operator CAPtrRef<U>()
+		{ return CAPtrRef<U>(release()); }
+
+	template<typename U>
+	operator CAAutoFree<U>()
+		{ return CAAutoFree<U>(release()); }
+	
+};
+
+
+template <typename T>
+class CAAutoDelete
+{
+private:
+	T* ptr_;
+
+public:
+	CAAutoDelete() : ptr_(0) {}
+
+	explicit CAAutoDelete(T* ptr) : ptr_(ptr) {}
+	
+	template<typename U>
+	CAAutoDelete(CAAutoDelete<U>& that) : ptr_(that.release()) {} // take ownership
+
+	// C++ std says: a template constructor is never a copy constructor
+	CAAutoDelete(CAAutoDelete<T>& that) : ptr_(that.release()) {} // take ownership
+	
+	~CAAutoDelete() { free(); }
+	
+	template <typename U>
+	CAAutoDelete& operator=(CAAutoDelete<U>& that) 
+	{ 
+		set(that.release());	// take ownership
+		return *this;
+	}
+	
+	CAAutoDelete& operator=(CAAutoDelete& that) 
+	{ 
+		set(that.release());	// take ownership
+		return *this;
+	}
+	
+	CAAutoDelete& operator=(T* ptr) 
+	{
+		set(ptr); 
+		return *this;
+	}
+	
+	template <typename U>
+	CAAutoDelete& operator=(U* ptr) 
+	{
+		set(ptr); 
+		return *this;
+	}
+		
+	T& operator*() const { return *ptr_; }
+	T* operator->() const { return ptr_; }
+	
+	T* operator()() const { return ptr_; }
+	T* get() const { return ptr_; }
+	operator T*() const { return ptr_; }
+	
+	bool operator==(CAAutoDelete const& that) const { return ptr_ == that.ptr_; }
+	bool operator!=(CAAutoDelete const& that) const { return ptr_ != that.ptr_; }
+	bool operator==(T* ptr) const { return ptr_ == ptr; }
+	bool operator!=(T* ptr) const { return ptr_ != ptr; }
+		
+	T* release() 
+	{
+		// release ownership
+		T* result = ptr_;
+		ptr_ = 0;
+		return result;
+	}
+	
+	void set(T* ptr)
+	{
+		if (ptr != ptr_)
+		{
+			delete ptr_;
+			ptr_ = ptr;
+		}
+	}
+	
+	void free() 
+	{
+		set(0);
+	}
+
+
+	// automatic conversions to allow assignment from results of functions.
+	// hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+	CAAutoDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+	CAAutoDelete& operator=(CAPtrRef<T> ref)
+	{
+		set(ref.ptr_);
+		return *this;
+	}
+
+	template<typename U>
+	operator CAPtrRef<U>()
+		{ return CAPtrRef<U>(release()); }
+
+	template<typename U>
+	operator CAAutoFree<U>()
+		{ return CAAutoFree<U>(release()); }
+	
+};
+
+
+template <typename T>
+class CAAutoArrayDelete
+{
+private:
+	T* ptr_;
+
+public:
+	CAAutoArrayDelete() : ptr_(0) {}
+
+	explicit CAAutoArrayDelete(T* ptr) : ptr_(ptr) {}
+	
+	template<typename U>
+	CAAutoArrayDelete(CAAutoArrayDelete<U>& that) : ptr_(that.release()) {} // take ownership
+
+	// C++ std says: a template constructor is never a copy constructor
+	CAAutoArrayDelete(CAAutoArrayDelete<T>& that) : ptr_(that.release()) {} // take ownership
+	
+	// this becomes an ambiguous call if n == 0
+	CAAutoArrayDelete(size_t n) : ptr_(new T[n]) {}
+	
+	~CAAutoArrayDelete() { free(); }
+	
+	void alloc(size_t numItems) 
+	{
+		free();
+		ptr_ = new T [numItems];
+	}
+	
+	template <typename U>
+	CAAutoArrayDelete& operator=(CAAutoArrayDelete<U>& that) 
+	{ 
+		set(that.release());	// take ownership
+		return *this;
+	}
+	
+	CAAutoArrayDelete& operator=(CAAutoArrayDelete& that) 
+	{ 
+		set(that.release());	// take ownership
+		return *this;
+	}
+	
+	CAAutoArrayDelete& operator=(T* ptr) 
+	{
+		set(ptr); 
+		return *this;
+	}
+	
+	template <typename U>
+	CAAutoArrayDelete& operator=(U* ptr) 
+	{
+		set(ptr); 
+		return *this;
+	}
+		
+	T& operator*() const { return *ptr_; }
+	T* operator->() const { return ptr_; }
+	
+	T* operator()() const { return ptr_; }
+	T* get() const { return ptr_; }
+	operator T*() const { return ptr_; }
+
+	bool operator==(CAAutoArrayDelete const& that) const { return ptr_ == that.ptr_; }
+	bool operator!=(CAAutoArrayDelete const& that) const { return ptr_ != that.ptr_; }
+	bool operator==(T* ptr) const { return ptr_ == ptr; }
+	bool operator!=(T* ptr) const { return ptr_ != ptr; }
+		
+	T* release() 
+	{
+		// release ownership
+		T* result = ptr_;
+		ptr_ = 0;
+		return result;
+	}
+	
+	void set(T* ptr)
+	{
+		if (ptr != ptr_)
+		{
+			delete [] ptr_;
+			ptr_ = ptr;
+		}
+	}
+	
+	void free() 
+	{
+		set(0);
+	}
+
+
+	// automatic conversions to allow assignment from results of functions.
+	// hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+	CAAutoArrayDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+	CAAutoArrayDelete& operator=(CAPtrRef<T> ref)
+	{
+		set(ref.ptr_);
+		return *this;
+	}
+
+	template<typename U>
+	operator CAPtrRef<U>()
+		{ return CAPtrRef<U>(release()); }
+
+	template<typename U>
+	operator CAAutoArrayDelete<U>()
+		{ return CAAutoFree<U>(release()); }
+	
+};
+
+
+
+
+
+// convenience function
+template <typename T>
+void free(CAAutoFree<T>& p)
+{
+	p.free();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if 0
+// example program showing ownership transfer
+
+CAAutoFree<char> source()
+{
+	// source allocates and returns ownership to the caller.
+	const char* str = "this is a test";
+	size_t size = strlen(str) + 1;
+	CAAutoFree<char> captr(size, false);
+	strlcpy(captr(), str, size);
+	printf("source %08X %08X '%s'\n", &captr, captr(), captr());
+	return captr;
+}
+
+void user(CAAutoFree<char> const& captr)
+{
+	// passed by const reference. user can access the pointer but does not take ownership.
+	printf("user: %08X %08X '%s'\n", &captr, captr(), captr());
+}
+
+void sink(CAAutoFree<char> captr)
+{
+	// passed by value. sink takes ownership and frees the pointer on return.
+	printf("sink: %08X %08X '%s'\n", &captr, captr(), captr());
+}
+
+
+int main (int argc, char * const argv[]) 
+{
+
+	CAAutoFree<char> captr(source());
+	printf("main captr A %08X %08X\n", &captr, captr());
+	user(captr);
+	sink(captr);
+	printf("main captr B %08X %08X\n", &captr, captr());
+    return 0;
+}
+#endif
+
+#endif
diff --git a/architecture/AU/PublicUtility/CABufferList.cpp b/architecture/AU/PublicUtility/CABufferList.cpp
new file mode 100644
index 0000000..841d8e6
--- /dev/null
+++ b/architecture/AU/PublicUtility/CABufferList.cpp
@@ -0,0 +1,264 @@
+/*
+     File: CABufferList.cpp 
+ Abstract:  CABufferList.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "CABufferList.h"
+#include "CAByteOrder.h"
+
+void		CABufferList::AllocateBuffers(UInt32 nBytes)
+{
+	if (nBytes <= GetNumBytes()) return;
+
+	if (mABL.mNumberBuffers > 1)
+		// align successive buffers for Altivec and to take alternating
+		// cache line hits by spacing them by odd multiples of 16
+		nBytes = ((nBytes + 15) & ~15) | 16;
+	UInt32 memorySize = nBytes * mABL.mNumberBuffers;
+	Byte *newMemory = new Byte[memorySize], *p = newMemory;
+	memset(newMemory, 0, memorySize);	// get page faults now, not later
+	
+	AudioBuffer *buf = mABL.mBuffers;
+	for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+		if (buf->mData != NULL && buf->mDataByteSize > 0)
+			// preserve existing buffer contents
+			memcpy(p, buf->mData, buf->mDataByteSize);
+		buf->mDataByteSize = nBytes;
+		buf->mData = p;
+		p += nBytes;
+	}
+	Byte *oldMemory = mBufferMemory;
+	mBufferMemory = newMemory;
+	mBufferCapacity = nBytes;
+	delete[] oldMemory;
+}
+
+void		CABufferList::AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inSrcList, CABufferList *inSetPtrList)
+{
+	if (mABL.mNumberBuffers != inSrcList->mABL.mNumberBuffers) return;
+	if (mABL.mNumberBuffers != inSetPtrList->mABL.mNumberBuffers) return;
+	if (nBytes <= GetNumBytes()) {
+		CopyAllFrom(inSrcList, inSetPtrList);
+		return;
+	}
+	inSetPtrList->VerifyNotTrashingOwnedBuffer();
+	UInt32 fromByteSize = inSrcList->GetNumBytes();
+	
+	if (mABL.mNumberBuffers > 1)
+		// align successive buffers for Altivec and to take alternating
+		// cache line hits by spacing them by odd multiples of 16
+		nBytes = ((nBytes + 15) & ~15) | 16;
+	UInt32 memorySize = nBytes * mABL.mNumberBuffers;
+	Byte *newMemory = new Byte[memorySize], *p = newMemory;
+	memset(newMemory, 0, memorySize);	// make buffer "hot"
+	
+	AudioBuffer *buf = mABL.mBuffers;
+	AudioBuffer *ptrBuf = inSetPtrList->mABL.mBuffers;
+	AudioBuffer *srcBuf = inSrcList->mABL.mBuffers;
+	for (UInt32 i = mABL.mNumberBuffers; i--; ++buf, ++ptrBuf, ++srcBuf) {
+		if (srcBuf->mData != NULL && srcBuf->mDataByteSize > 0)
+			// preserve existing buffer contents
+			memmove(p, srcBuf->mData, srcBuf->mDataByteSize);
+		buf->mDataByteSize = nBytes;
+		buf->mData = p;
+		ptrBuf->mDataByteSize = srcBuf->mDataByteSize;
+		ptrBuf->mData = p;
+		p += nBytes;
+	}
+	Byte *oldMemory = mBufferMemory;
+	mBufferMemory = newMemory;
+	mBufferCapacity = nBytes;
+	if (inSrcList != inSetPtrList)
+		inSrcList->BytesConsumed(fromByteSize);
+	delete[] oldMemory;
+}
+
+void		CABufferList::DeallocateBuffers()
+{
+	AudioBuffer *buf = mABL.mBuffers;
+	for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+		buf->mData = NULL;
+		buf->mDataByteSize = 0;
+	}
+	if (mBufferMemory != NULL) {
+		delete[] mBufferMemory;
+		mBufferMemory = NULL;
+		mBufferCapacity = 0;
+	}
+    
+}
+
+static void show(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label, const char *fmtstr=NULL)
+{
+	printf("%s %p (%d fr%s):\n", label ? label : "AudioBufferList", &abl, framesToPrint, fmtstr ? fmtstr : "");
+	const AudioBuffer *buf = abl.mBuffers;
+	for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++buf) {
+		printf("    [%2d] %5dbytes %dch @ %p", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData);
+		if (framesToPrint && buf->mData != NULL) {
+			printf(":");
+			Byte *p = (Byte *)buf->mData;
+			for (int j = framesToPrint * buf->mNumberChannels; --j >= 0; )
+				switch (wordSize) {
+				case 0:	// native float
+					printf(" %6.3f", *(Float32 *)p);
+					p += sizeof(Float32);
+					break;
+				// positive: big endian
+				case 1:
+				case -1:
+					printf(" %02X", *p);
+					p += 1;
+					break;
+				case 2:
+					printf(" %04X", CFSwapInt16BigToHost(*(UInt16 *)p));
+					p += 2;
+					break;
+				case 3:
+					printf(" %06X", (p[0] << 16) | (p[1] << 8) | p[2]);
+					p += 3;
+					break;
+				case 4:
+					printf(" %08X", (unsigned int)CFSwapInt32BigToHost(*(UInt32 *)p));
+					p += 4;
+					break;
+				case 10:
+					printf(" %6.3f", CASwapFloat32BigToHost(*(Float32 *)p));
+					p += sizeof(Float32);
+					break;
+				case -2:
+					printf(" %04X", CFSwapInt16LittleToHost(*(UInt16 *)p));
+					p += 2;
+					break;
+				case -3:
+					printf(" %06X", (p[2] << 16) | (p[1] << 8) | p[0]);
+					p += 3;
+					break;
+				case -4:
+					printf(" %08X", (unsigned int)CFSwapInt32LittleToHost(*(UInt32 *)p));
+					p += 4;
+					break;
+				case -10:
+					printf(" %6.3f", CASwapFloat32LittleToHost(*(Float32 *)p));
+					p += sizeof(Float32);
+					break;
+				}
+		}
+		printf("\n");
+	}
+}
+
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, const AudioStreamBasicDescription &asbd, const char *label)
+{
+	CAStreamBasicDescription fmt(asbd);
+	int wordSize = 1;
+	char fmtstr[80] = { 0 };
+	
+	if (fmt.mFormatID == kAudioFormatLinearPCM) {
+		if (fmt.mFormatFlags & kLinearPCMFormatFlagIsFloat) {
+			if (fmt.mBitsPerChannel == 32) {
+				if (fmt.mFormatFlags & kLinearPCMFormatFlagIsBigEndian) {
+					wordSize = 10;
+					strcpy(fmtstr, ", BEF");
+				} else {
+					wordSize = -10;
+					strcpy(fmtstr, ", LEF");
+				}
+			}
+		} else {
+			wordSize = fmt.SampleWordSize();
+			if (wordSize > 0) {
+				int fracbits = (asbd.mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
+				if (fracbits > 0)
+					sprintf(fmtstr, ", %d.%d-bit", (int)asbd.mBitsPerChannel - fracbits, fracbits);
+				else
+					sprintf(fmtstr, ", %d-bit", (int)asbd.mBitsPerChannel);
+
+				if (!(fmt.mFormatFlags & kLinearPCMFormatFlagIsBigEndian)) {
+					wordSize = -wordSize;
+					strcat(fmtstr, " LEI");
+				} else {
+					strcat(fmtstr, " BEI");
+				}
+			}
+		}
+	}
+	show(abl, framesToPrint, wordSize, label, fmtstr);
+}
+
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label)
+{
+	show(abl, framesToPrint, wordSize, label);
+}
+
+extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize)
+{
+	show(*abl, framesToPrint, wordSize, NULL);
+}
+
+// if the return result is odd, there was a null buffer.
+extern "C" int CrashIfClientProvidedBogusAudioBufferList(const AudioBufferList *abl, bool nullok)
+{
+	const AudioBuffer *buf = abl->mBuffers, *bufend = buf + abl->mNumberBuffers;
+	int sum = 0;	// defeat attempts by the compiler to optimize away the code that touches the buffers
+	int anyNull = 0;
+	for ( ; buf < bufend; ++buf) {
+		const int *p = (const int *)buf->mData;
+		if (p == NULL) {
+			anyNull = 1;
+			if (nullok) continue;
+		}
+        
+        // if client provided a bogus ABL, we want to crash here
+		unsigned datasize = buf->mDataByteSize;
+		if (datasize >= sizeof(int)) {
+            // turn off the analyzer warning in this case since crash if any, is intended            
+#ifndef __clang_analyzer__
+			sum += p[0];
+			sum += p[datasize / sizeof(int) - 1];
+#endif            
+		}
+	}
+	return anyNull | (sum & ~1);
+}
+
diff --git a/architecture/AU/PublicUtility/CABufferList.h b/architecture/AU/PublicUtility/CABufferList.h
new file mode 100644
index 0000000..ef5a1f3
--- /dev/null
+++ b/architecture/AU/PublicUtility/CABufferList.h
@@ -0,0 +1,319 @@
+/*
+     File: CABufferList.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CABufferList_h__
+#define __CABufferList_h__
+
+#include <stddef.h>
+#include "CAStreamBasicDescription.h"
+#include "CAXException.h"
+
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, const AudioStreamBasicDescription &fmt, const char *label=NULL);
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label=NULL);
+extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize);
+extern "C" int CrashIfClientProvidedBogusAudioBufferList(const AudioBufferList *abl, bool nullOK=false);
+
+/* ____________________________________________________________________________
+//	CABufferList - variable length buffer list
+
+	This class is designed for use in non-simplistic cases. For AudioUnits, AUBufferList
+	is preferred.
+	
+	CABufferList can be used in one of two ways:
+		- as mutable pointers into non-owned memory
+		- as an immutable array of buffers (owns its own memory).
+
+ 	All buffers are assumed to have the same format (number of channels, word size), so that
+		we can assume their mDataByteSizes are all the same.
+____________________________________________________________________________ */
+class CABufferList {
+public:
+	void *	operator new(size_t /*size*/, int nBuffers) {
+				return ::operator new(sizeof(CABufferList) + (nBuffers-1) * sizeof(AudioBuffer));
+			}
+	static CABufferList *	New(const char *name, const CAStreamBasicDescription &format)
+	{
+		UInt32 numBuffers = format.NumberChannelStreams(), channelsPerBuffer = format.NumberInterleavedChannels();
+		return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
+	}
+	static CABufferList *	New(const CAStreamBasicDescription &format) { return New("", format); }
+
+	static CABufferList *	New(UInt32 numBuffers, UInt32 channelsPerBuffer, const char *name="") {
+		return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
+	}
+
+protected:
+	CABufferList(const char *name, UInt32 numBuffers, UInt32 channelsPerBuffer) :
+		mName(name),
+		mBufferMemory(NULL),
+		mBufferCapacity(0)
+	{
+		//XAssert(numBuffers > 0 /*&& channelsPerBuffer > 0*/);
+		mABL.mNumberBuffers = numBuffers;
+		AudioBuffer *buf = mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+			buf->mNumberChannels = channelsPerBuffer;
+			buf->mDataByteSize = 0;
+			buf->mData = NULL;
+		}
+	}
+
+public:
+	~CABufferList()
+	{
+		if (mBufferMemory)
+			delete[] mBufferMemory;
+	}
+	
+	const char *				Name() { return mName; }
+	
+	const AudioBufferList &		GetBufferList() const { return mABL; }
+	
+	AudioBufferList &			GetModifiableBufferList() { return _GetBufferList(); }
+	
+	UInt32		GetNumberBuffers() const { return mABL.mNumberBuffers; }
+	
+	UInt32		GetNumBytes() const
+	{
+		return mABL.mBuffers[0].mDataByteSize;
+	}
+	
+	void		SetBytes(UInt32 nBytes, void *data)
+	{
+		VerifyNotTrashingOwnedBuffer();
+		XAssert(mABL.mNumberBuffers == 1);
+		mABL.mBuffers[0].mDataByteSize = nBytes;
+		mABL.mBuffers[0].mData = data;
+	}
+	
+	void		CopyAllFrom(CABufferList *srcbl, CABufferList *ptrbl)
+					// copies bytes from srcbl
+					// make ptrbl reflect the length copied
+					// note that srcbl may be same as ptrbl!
+	{
+		// Note that this buffer *can* own memory and its pointers/lengths are not
+		// altered; only its buffer contents, which are copied from srcbl.
+		// The pointers/lengths in ptrbl are updated to reflect the addresses/lengths
+		// of the copied data, and srcbl's contents are consumed.
+		ptrbl->VerifyNotTrashingOwnedBuffer();
+		UInt32 nBytes = srcbl->GetNumBytes();
+		AudioBuffer *mybuf = mABL.mBuffers, *srcbuf = srcbl->mABL.mBuffers,
+					*ptrbuf = ptrbl->mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf, ++ptrbuf) {
+			memmove(mybuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
+			ptrbuf->mData = mybuf->mData;
+			ptrbuf->mDataByteSize = srcbuf->mDataByteSize;
+		}
+		if (srcbl != ptrbl)
+			srcbl->BytesConsumed(nBytes);
+	}
+	
+	// copies data from another buffer list.
+	void		CopyDataFrom(const AudioBufferList &other)
+	{
+		for (unsigned i = 0; i < other.mNumberBuffers; ++i) {
+			XAssert(mBufferCapacity == 0 || other.mBuffers[i].mDataByteSize <= mBufferCapacity);
+			memcpy(mABL.mBuffers[i].mData, other.mBuffers[i].mData, 
+				mABL.mBuffers[i].mDataByteSize = other.mBuffers[i].mDataByteSize);
+		}
+	}
+	
+	void		AppendFrom(CABufferList *blp, UInt32 nBytes)
+	{
+		// this may mutate a buffer that owns memory.
+		AudioBuffer *mybuf = mABL.mBuffers, *srcbuf = blp->mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf) {
+			XAssert(nBytes <= srcbuf->mDataByteSize);
+			XAssert(mBufferCapacity == 0 || mybuf->mDataByteSize + nBytes <= mBufferCapacity);
+			memcpy((Byte *)mybuf->mData + mybuf->mDataByteSize, srcbuf->mData, nBytes);
+			mybuf->mDataByteSize += nBytes;
+		}
+		blp->BytesConsumed(nBytes);
+	}
+	
+	void		PadWithZeroes(UInt32 desiredBufferSize)
+					// for cases where an algorithm (e.g. SRC) requires some
+					// padding to create silence following end-of-file
+	{
+		XAssert(mBufferCapacity == 0 || desiredBufferSize <= mBufferCapacity);
+		if (GetNumBytes() > desiredBufferSize) return;
+		AudioBuffer *buf = mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+			memset((Byte *)buf->mData + buf->mDataByteSize, 0, desiredBufferSize - buf->mDataByteSize);
+			buf->mDataByteSize = desiredBufferSize;
+		}
+	}
+	
+	void		SetToZeroes(UInt32 nBytes)
+	{
+		XAssert(mBufferCapacity == 0 || nBytes <= mBufferCapacity);
+		AudioBuffer *buf = mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+			memset((Byte *)buf->mData, 0, nBytes);
+			buf->mDataByteSize = nBytes;
+		}
+	}
+	
+	void		Reset()
+	{
+		DeallocateBuffers();
+	}
+	
+	Boolean		SameDataAs(const CABufferList* anotherBufferList)
+	{
+		// check to see if two buffer lists point to the same memory.
+		if (mABL.mNumberBuffers != anotherBufferList->mABL.mNumberBuffers) return false;
+		
+		for (UInt32 i = 0; i < mABL.mNumberBuffers; ++i) {
+			if (mABL.mBuffers[i].mData != anotherBufferList->mABL.mBuffers[i].mData) return false;
+		}
+		return true;
+	}
+	
+	void		BytesConsumed(UInt32 nBytes)
+					// advance buffer pointers, decrease buffer sizes
+	{
+		VerifyNotTrashingOwnedBuffer();
+		AudioBuffer *buf = mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+			XAssert(nBytes <= buf->mDataByteSize);
+			buf->mData = (Byte *)buf->mData + nBytes;
+			buf->mDataByteSize -= nBytes;
+		}
+	}
+	
+	void		SetFrom(const AudioBufferList *abl)
+	{
+		VerifyNotTrashingOwnedBuffer();
+		memcpy(&_GetBufferList(), abl, (char *)&abl->mBuffers[abl->mNumberBuffers] - (char *)abl);
+	}
+	
+	void		SetFrom(const CABufferList *blp)
+	{
+		SetFrom(&blp->GetBufferList());
+	}
+	
+	void		SetFrom(const AudioBufferList *abl, UInt32 nBytes)
+	{
+		VerifyNotTrashingOwnedBuffer();
+		AudioBuffer *mybuf = mABL.mBuffers;
+		const AudioBuffer *srcbuf = abl->mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf) {
+			mybuf->mNumberChannels = srcbuf->mNumberChannels;
+			mybuf->mDataByteSize = nBytes;
+			mybuf->mData = srcbuf->mData;
+		}
+	}
+	
+	void		SetFrom(const CABufferList *blp, UInt32 nBytes)
+	{
+		SetFrom(&blp->GetBufferList(), nBytes);
+	}
+	
+	AudioBufferList *	ToAudioBufferList(AudioBufferList *abl) const
+	{
+		memcpy(abl, &GetBufferList(), (char *)&abl->mBuffers[mABL.mNumberBuffers] - (char *)abl);
+		return abl;
+	}
+	
+	void		AllocateBuffers(UInt32 nBytes);
+	void		AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inCopyFromList, CABufferList *inSetPtrList);
+	
+	void		DeallocateBuffers();
+	
+	void		UseExternalBuffer(Byte *ptr, UInt32 nBytes);
+    
+	void		AdvanceBufferPointers(UInt32 nBytes) // $$$ ReducingSize
+					// this is for bufferlists that function simply as
+					// an array of pointers into another bufferlist, being advanced,
+					// as in RenderOutput implementations
+	{
+		VerifyNotTrashingOwnedBuffer();
+		AudioBuffer *buf = mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+			buf->mData = (Byte *)buf->mData + nBytes;
+			buf->mDataByteSize -= nBytes;
+		}
+	}
+	
+	void		SetNumBytes(UInt32 nBytes)
+	{
+		XAssert(mBufferCapacity == 0 || nBytes <= mBufferCapacity);
+		AudioBuffer *buf = mABL.mBuffers;
+		for (UInt32 i = mABL.mNumberBuffers; i--; ++buf)
+			buf->mDataByteSize = nBytes;
+	}
+
+	void		Print(const char *label=NULL, int nframes=0, int wordSize=0) const
+	{
+		if (label == NULL)
+			label = mName;
+		printf("%s - ", label);
+		CAShowAudioBufferList(&GetBufferList(), nframes, wordSize);
+		if (mBufferMemory)
+			printf("  owned memory @ 0x%p:\n", mBufferMemory);
+	}
+	
+	UInt32		GetCapacityBytes() const { return mBufferCapacity; }
+
+protected:
+	AudioBufferList &	_GetBufferList() { return mABL; }	// use with care
+							// if we make this public, then we lose ability to call VerifyNotTrashingOwnedBuffer
+	void				VerifyNotTrashingOwnedBuffer()
+	{
+		// This needs to be called from places where we are modifying the buffer pointers.
+		// It's an error to modify the buffer pointers or lengths if we own the buffer memory.
+		XAssert(mBufferMemory == NULL);
+	}
+
+	const char *						mName;	// for debugging
+	Byte *								mBufferMemory;
+	UInt32								mBufferCapacity;	// max mDataByteSize of each buffer
+	AudioBufferList						mABL;
+	// don't add anything here
+};
+
+#endif // __CABufferList_h__
diff --git a/architecture/AU/PublicUtility/CAByteOrder.h b/architecture/AU/PublicUtility/CAByteOrder.h
new file mode 100644
index 0000000..bddf648
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAByteOrder.h
@@ -0,0 +1,161 @@
+/*
+     File: CAByteOrder.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CAByteOrder_h__)
+#define __CAByteOrder_h__
+
+//=============================================================================
+//	Includes
+//=============================================================================
+
+//	System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreFoundation/CoreFoundation.h>
+#else
+	#include "CoreFoundation.h"
+#endif
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+CF_INLINE Float32 CASwapFloat32 (Float32 arg) {
+	union {
+		Float32 f;
+		UInt32 i;
+	} flip;
+
+	flip.f = arg;
+	flip.i = CFSwapInt32 (flip.i);
+	
+	return flip.f;
+}
+
+CF_INLINE Float64 CASwapFloat64 (Float64 arg) {
+	union {
+		Float64 f;
+		UInt64 i;
+	} flip;
+
+	flip.f = arg;
+	flip.i = CFSwapInt64 (flip.i);
+	
+	return flip.f;
+}
+
+#pragma mark -Flippers
+
+CF_INLINE Float32 CASwapFloat32BigToHost(Float32 arg) {
+#if defined(__BIG_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64BigToHost(Float64 arg) {
+#if defined(__BIG_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat64(arg);
+#endif
+}
+
+CF_INLINE Float32 CASwapFloat32HostToBig(Float32 arg) {
+#if defined(__BIG_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64HostToBig(Float64 arg) {
+#if defined(__BIG_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat64(arg);
+#endif
+}
+
+CF_INLINE Float32 CASwapFloat32LittleToHost(Float32 arg) {
+#if defined(__LITTLE_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64LittleToHost(Float64 arg) {
+#if defined(__LITTLE_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat64(arg);
+#endif
+}
+
+CF_INLINE Float32 CASwapFloat32HostToLittle(Float32 arg) {
+#if defined(__LITTLE_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64HostToLittle(Float64 arg) {
+#if defined(__LITTLE_ENDIAN__)
+    return arg;
+#else
+	return CASwapFloat64(arg);
+#endif
+}
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/architecture/AU/PublicUtility/CADebugMacros.cpp b/architecture/AU/PublicUtility/CADebugMacros.cpp
new file mode 100644
index 0000000..a5466c1
--- /dev/null
+++ b/architecture/AU/PublicUtility/CADebugMacros.cpp
@@ -0,0 +1,88 @@
+/*
+     File: CADebugMacros.cpp 
+ Abstract:  CADebugMacros.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "CADebugMacros.h"
+#include <stdio.h>
+#include <stdarg.h>
+#if TARGET_API_MAC_OSX
+	#include <syslog.h>
+#endif
+
+#if DEBUG
+#include <stdio.h>
+
+void	DebugPrint(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+}
+#endif // DEBUG
+
+#if TARGET_API_MAC_OSX
+void	LogError(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+#if DEBUG
+	vprintf(fmt, args);
+#endif
+	vsyslog(LOG_ERR, fmt, args);
+	va_end(args);
+}
+
+void	LogWarning(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+#if DEBUG
+	vprintf(fmt, args);
+#endif
+	vsyslog(LOG_WARNING, fmt, args);
+	va_end(args);
+}
+#endif
diff --git a/architecture/AU/PublicUtility/CADebugMacros.h b/architecture/AU/PublicUtility/CADebugMacros.h
new file mode 100644
index 0000000..8d3c030
--- /dev/null
+++ b/architecture/AU/PublicUtility/CADebugMacros.h
@@ -0,0 +1,580 @@
+/*
+     File: CADebugMacros.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CADebugMacros_h__)
+#define __CADebugMacros_h__
+
+//=============================================================================
+//	Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include "CoreAudioTypes.h"
+#endif
+
+//=============================================================================
+//	CADebugMacros
+//=============================================================================
+
+//#define	CoreAudio_StopOnFailure			1
+//#define	CoreAudio_TimeStampMessages		1
+//#define	CoreAudio_ThreadStampMessages	1
+//#define	CoreAudio_FlushDebugMessages	1
+
+#if TARGET_RT_BIG_ENDIAN
+	#define	CA4CCToCString(the4CC)					{ ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 }
+	#define CACopy4CCToCString(theCString, the4CC)	{ theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; }
+#else
+	#define	CA4CCToCString(the4CC)					{ ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 }
+	#define CACopy4CCToCString(theCString, the4CC)	{ theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; }
+#endif
+
+//	This is a macro that does a sizeof and casts the result to a UInt32. This is useful for all the
+//	places where -wshorten64-32 catches assigning a sizeof expression to a UInt32.
+//	For want of a better place to park this, we'll park it here.
+#define	SizeOf32(X)	((UInt32)sizeof(X))
+
+//	This is a macro that does a offsetof and casts the result to a UInt32. This is useful for all the
+//	places where -wshorten64-32 catches assigning an offsetof expression to a UInt32.
+//	For want of a better place to park this, we'll park it here.
+#define	OffsetOf32(X, Y)	((UInt32)offsetof(X, Y))
+
+//	This macro casts the expression to a UInt32. It is called out specially to allow us to track casts
+//	that have been added purely to avert -wshorten64-32 warnings on 64 bit platforms.
+//	For want of a better place to park this, we'll park it here.
+#define	ToUInt32(X)	((UInt32)(X))
+
+#pragma mark	Basic Definitions
+
+#if	DEBUG || CoreAudio_Debug
+	// can be used to break into debugger immediately, also see CADebugger
+	#define BusError()		{ long* p=NULL; *p=0; }
+	
+	//	basic debugging print routines
+	#if	TARGET_OS_MAC && !TARGET_API_MAC_CARBON
+		extern void DebugStr(const unsigned char* debuggerMsg);
+		#define	DebugMessage(msg)	DebugStr("\p"msg)
+		#define DebugMessageN1(msg, N1)
+		#define DebugMessageN2(msg, N1, N2)
+		#define DebugMessageN3(msg, N1, N2, N3)
+	#else
+		#include "CADebugPrintf.h"
+		
+		#if	(CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile)
+			#define	FlushRtn	,fflush(DebugPrintfFile)
+		#else
+			#define	FlushRtn
+		#endif
+		
+		#if		CoreAudio_ThreadStampMessages
+			#include <pthread.h>
+			#include "CAHostTimeBase.h"
+			#if TARGET_RT_64_BIT
+				#define	DebugPrintfThreadIDFormat	"%16p"
+			#else
+				#define	DebugPrintfThreadIDFormat	"%8p"
+			#endif
+			#define	DebugMsg(inFormat, ...)	DebugPrintf("%17qd: " DebugPrintfThreadIDFormat " " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), pthread_self(), ## __VA_ARGS__) FlushRtn
+		#elif	CoreAudio_TimeStampMessages
+			#include "CAHostTimeBase.h"
+			#define	DebugMsg(inFormat, ...)	DebugPrintf("%17qd: " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), ## __VA_ARGS__) FlushRtn
+		#else
+			#define	DebugMsg(inFormat, ...)	DebugPrintf(inFormat, ## __VA_ARGS__) FlushRtn
+		#endif
+	#endif
+	void	DebugPrint(const char *fmt, ...);	// can be used like printf
+	#ifndef DEBUGPRINT
+		#define DEBUGPRINT(msg) DebugPrint msg		// have to double-parenthesize arglist (see Debugging.h)
+	#endif
+	#if VERBOSE
+		#define vprint(msg) DEBUGPRINT(msg)
+	#else
+		#define vprint(msg)
+	#endif
+	
+	// Original macro keeps its function of turning on and off use of CADebuggerStop() for both asserts and throws.
+	// For backwards compat, it overrides any setting of the two sub-macros.
+	#if	CoreAudio_StopOnFailure
+		#include "CADebugger.h"
+		#undef CoreAudio_StopOnAssert
+		#define CoreAudio_StopOnAssert 1
+		#undef CoreAudio_StopOnThrow
+		#define CoreAudio_StopOnThrow 1
+		#define STOP	CADebuggerStop()
+	#else
+		#define STOP
+	#endif
+
+	#if CoreAudio_StopOnAssert
+		#if !CoreAudio_StopOnFailure
+			#include "CADebugger.h"
+			#define STOP
+		#endif
+		#define __ASSERT_STOP CADebuggerStop()
+	#else
+		#define __ASSERT_STOP
+	#endif
+
+	#if CoreAudio_StopOnThrow
+		#if !CoreAudio_StopOnFailure
+			#include "CADebugger.h"
+			#define STOP
+		#endif
+		#define __THROW_STOP CADebuggerStop()
+	#else
+		#define __THROW_STOP
+	#endif
+
+#else
+	#define	DebugMsg(inFormat, ...)
+	#ifndef DEBUGPRINT
+		#define DEBUGPRINT(msg)
+	#endif
+	#define vprint(msg)
+	#define	STOP
+	#define __ASSERT_STOP
+	#define __THROW_STOP
+#endif
+
+//	Old-style numbered DebugMessage calls are implemented in terms of DebugMsg() now
+#define	DebugMessage(msg)										DebugMsg(msg)
+#define DebugMessageN1(msg, N1)									DebugMsg(msg, N1)
+#define DebugMessageN2(msg, N1, N2)								DebugMsg(msg, N1, N2)
+#define DebugMessageN3(msg, N1, N2, N3)							DebugMsg(msg, N1, N2, N3)
+#define DebugMessageN4(msg, N1, N2, N3, N4)						DebugMsg(msg, N1, N2, N3, N4)
+#define DebugMessageN5(msg, N1, N2, N3, N4, N5)					DebugMsg(msg, N1, N2, N3, N4, N5)
+#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6)				DebugMsg(msg, N1, N2, N3, N4, N5, N6)
+#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7)			DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7)
+#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8)		DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8)
+#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)	DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)
+
+void	LogError(const char *fmt, ...);			// writes to syslog (and stderr if debugging)
+void	LogWarning(const char *fmt, ...);		// writes to syslog (and stderr if debugging)
+
+#define	NO_ACTION	(void)0
+
+#if	DEBUG || CoreAudio_Debug
+
+#pragma mark	Debug Macros
+
+#define	Assert(inCondition, inMessage)													\
+			if(!(inCondition))															\
+			{																			\
+				DebugMessage(inMessage);												\
+				__ASSERT_STOP;																	\
+			}
+
+#define	AssertFileLine(inCondition, inMessage)											\
+			if(!(inCondition))															\
+			{																			\
+				DebugMessageN3("%s, line %d: %s", __FILE__, __LINE__, inMessage);		\
+				__ASSERT_STOP;															\
+			}
+
+#define	AssertNoError(inError, inMessage)												\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					char __4CC[5] = CA4CCToCString(__Err);								\
+					DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC);		\
+					__ASSERT_STOP;														\
+				}																		\
+			}
+
+#define	AssertNoKernelError(inError, inMessage)											\
+			{																			\
+				unsigned int __Err = (unsigned int)(inError);							\
+				if(__Err != 0)															\
+				{																		\
+					DebugMessageN1(inMessage ", Error: 0x%X", __Err);					\
+					__ASSERT_STOP;														\
+				}																		\
+			}
+
+#define	AssertNotNULL(inPtr, inMessage)													\
+			{																			\
+				if((inPtr) == NULL)														\
+				{																		\
+					DebugMessage(inMessage);											\
+					__ASSERT_STOP;														\
+				}																		\
+			}
+
+#define	FailIf(inCondition, inHandler, inMessage)										\
+			if(inCondition)																\
+			{																			\
+				DebugMessage(inMessage);												\
+				STOP;																	\
+				goto inHandler;															\
+			}
+
+#define	FailWithAction(inCondition, inAction, inHandler, inMessage)						\
+			if(inCondition)																\
+			{																			\
+				DebugMessage(inMessage);												\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfNULL(inPointer, inAction, inHandler, inMessage)							\
+			if((inPointer) == NULL)														\
+			{																			\
+				DebugMessage(inMessage);												\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfKernelError(inKernelError, inAction, inHandler, inMessage)				\
+			{																			\
+				unsigned int __Err = (inKernelError);									\
+				if(__Err != 0)															\
+				{																		\
+					DebugMessageN1(inMessage ", Error: 0x%X", __Err);					\
+					STOP;																\
+					{ inAction; }														\
+					goto inHandler;														\
+				}																		\
+			}
+
+#define	FailIfError(inError, inAction, inHandler, inMessage)							\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					char __4CC[5] = CA4CCToCString(__Err);								\
+					DebugMessageN2(inMessage ", Error: %ld (%s)", (long int)__Err, __4CC);	\
+					STOP;																\
+					{ inAction; }														\
+					goto inHandler;														\
+				}																		\
+			}
+
+#define	FailIfNoMessage(inCondition, inHandler, inMessage)								\
+			if(inCondition)																\
+			{																			\
+				STOP;																	\
+				goto inHandler;															\
+			}
+
+#define	FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage)			\
+			if(inCondition)																\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage)					\
+			if((inPointer) == NULL)														\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage)		\
+			{																			\
+				unsigned int __Err = (inKernelError);									\
+				if(__Err != 0)															\
+				{																		\
+					STOP;																\
+					{ inAction; }														\
+					goto inHandler;														\
+				}																		\
+			}
+
+#define	FailIfErrorNoMessage(inError, inAction, inHandler, inMessage)					\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					STOP;																\
+					{ inAction; }														\
+					goto inHandler;														\
+				}																		\
+			}
+
+#if defined(__cplusplus)
+
+#define Throw(inException)  __THROW_STOP; throw (inException)
+
+#define	ThrowIf(inCondition, inException, inMessage)									\
+			if(inCondition)																\
+			{																			\
+				DebugMessage(inMessage);												\
+				Throw(inException);														\
+			}
+
+#define	ThrowIfNULL(inPointer, inException, inMessage)									\
+			if((inPointer) == NULL)														\
+			{																			\
+				DebugMessage(inMessage);												\
+				Throw(inException);														\
+			}
+
+#define	ThrowIfKernelError(inKernelError, inException, inMessage)						\
+			{																			\
+				unsigned int __Err = (inKernelError);									\
+				if(__Err != 0)															\
+				{																		\
+					DebugMessageN1(inMessage ", Error: 0x%X", __Err);					\
+					Throw(inException);													\
+				}																		\
+			}
+
+#define	ThrowIfError(inError, inException, inMessage)									\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					char __4CC[5] = CA4CCToCString(__Err);								\
+					DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC);		\
+					Throw(inException);													\
+				}																		\
+			}
+
+#if TARGET_OS_WIN32
+#define	ThrowIfWinError(inError, inException, inMessage)								\
+			{																			\
+				HRESULT __Err = (inError);												\
+				if(FAILED(__Err))														\
+				{																		\
+					DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err));			\
+					Throw(inException);													\
+				}																		\
+			}
+#endif
+
+#define	SubclassResponsibility(inMethodName, inException)								\
+			{																			\
+				DebugMessage(inMethodName": Subclasses must implement this method");	\
+				Throw(inException);														\
+			}
+
+#endif	//	defined(__cplusplus)
+
+#else
+
+#pragma mark	Release Macros
+
+#define	Assert(inCondition, inMessage)													\
+			if(!(inCondition))															\
+			{																			\
+				__ASSERT_STOP;															\
+			}
+
+#define AssertFileLine(inCondition, inMessage) Assert(inCondition, inMessage)
+
+#define	AssertNoError(inError, inMessage)												\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					__ASSERT_STOP;														\
+				}																		\
+			}
+
+#define	AssertNoKernelError(inError, inMessage)											\
+			{																			\
+				unsigned int __Err = (unsigned int)(inError);							\
+				if(__Err != 0)															\
+				{																		\
+					__ASSERT_STOP;														\
+				}																		\
+			}
+
+#define	AssertNotNULL(inPtr, inMessage)													\
+			{																			\
+				if((inPtr) == NULL)														\
+				{																		\
+					__ASSERT_STOP;														\
+				}																		\
+			}
+
+#define	FailIf(inCondition, inHandler, inMessage)										\
+			if(inCondition)																\
+			{																			\
+				STOP;																	\
+				goto inHandler;															\
+			}
+
+#define	FailWithAction(inCondition, inAction, inHandler, inMessage)						\
+			if(inCondition)																\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfNULL(inPointer, inAction, inHandler, inMessage)							\
+			if((inPointer) == NULL)														\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfKernelError(inKernelError, inAction, inHandler, inMessage)				\
+			if((inKernelError) != 0)													\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfError(inError, inAction, inHandler, inMessage)							\
+			if((inError) != 0)															\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfNoMessage(inCondition, inHandler, inMessage)								\
+			if(inCondition)																\
+			{																			\
+				STOP;																	\
+				goto inHandler;															\
+			}
+
+#define	FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage)			\
+			if(inCondition)																\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage)					\
+			if((inPointer) == NULL)														\
+			{																			\
+				STOP;																	\
+				{ inAction; }															\
+				goto inHandler;															\
+			}
+
+#define	FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage)		\
+			{																			\
+				unsigned int __Err = (inKernelError);									\
+				if(__Err != 0)															\
+				{																		\
+					STOP;																\
+					{ inAction; }														\
+					goto inHandler;														\
+				}																		\
+			}
+
+#define	FailIfErrorNoMessage(inError, inAction, inHandler, inMessage)					\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					STOP;																\
+					{ inAction; }														\
+					goto inHandler;														\
+				}																		\
+			}
+
+#if defined(__cplusplus)
+
+#define Throw(inException)  __THROW_STOP; throw (inException)
+
+#define	ThrowIf(inCondition, inException, inMessage)									\
+			if(inCondition)																\
+			{																			\
+				Throw(inException);														\
+			}
+
+#define	ThrowIfNULL(inPointer, inException, inMessage)									\
+			if((inPointer) == NULL)														\
+			{																			\
+				Throw(inException);														\
+			}
+
+#define	ThrowIfKernelError(inKernelError, inException, inMessage)						\
+			{																			\
+				unsigned int __Err = (inKernelError);									\
+				if(__Err != 0)															\
+				{																		\
+					Throw(inException);													\
+				}																		\
+			}
+
+#define	ThrowIfError(inError, inException, inMessage)									\
+			{																			\
+				SInt32 __Err = (inError);												\
+				if(__Err != 0)															\
+				{																		\
+					Throw(inException);													\
+				}																		\
+			}
+
+#if TARGET_OS_WIN32
+#define	ThrowIfWinError(inError, inException, inMessage)								\
+			{																			\
+				HRESULT __Err = (inError);												\
+				if(FAILED(__Err))														\
+				{																		\
+					Throw(inException);													\
+				}																		\
+			}
+#endif
+
+#define	SubclassResponsibility(inMethodName, inException)								\
+			{																			\
+				Throw(inException);														\
+			}
+
+#endif	//	defined(__cplusplus)
+
+#endif  //  DEBUG || CoreAudio_Debug
+
+#endif
diff --git a/architecture/AU/PublicUtility/CADebugPrintf.cpp b/architecture/AU/PublicUtility/CADebugPrintf.cpp
new file mode 100644
index 0000000..e69955f
--- /dev/null
+++ b/architecture/AU/PublicUtility/CADebugPrintf.cpp
@@ -0,0 +1,89 @@
+/*
+     File: CADebugPrintf.cpp 
+ Abstract:  CADebugPrintf.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+//==================================================================================================
+//	Includes
+//==================================================================================================
+
+//	Self Include
+#include "CADebugPrintf.h"
+
+#if	DEBUG || CoreAudio_Debug
+
+	#if	TARGET_OS_WIN32
+		#include <stdarg.h>
+		#include <stdio.h>
+		#include <Windows.h>
+		extern "C"
+		int	CAWin32DebugPrintf(char* inFormat, ...)
+		{
+			char theMessage[1024];
+			va_list theArguments;
+			va_start(theArguments, inFormat);
+			_vsnprintf(theMessage, 1024, inFormat, theArguments);
+			va_end(theArguments);
+			OutputDebugString(theMessage);
+			return 0;
+		}
+	#endif
+	
+	#if defined(CoreAudio_UseSideFile)
+		#include <unistd.h>
+		FILE* sDebugPrintfSideFile = NULL;
+		extern "C"
+		void OpenDebugPrintfSideFile()
+		{
+			if(sDebugPrintfSideFile == NULL)
+			{
+				char theFileName[1024];
+				snprintf(theFileName, sizeof(theFileName), CoreAudio_UseSideFile, getpid());
+				sDebugPrintfSideFile = fopen(theFileName, "a+");
+				DebugPrintfRtn(DebugPrintfFileComma "\n------------------------------\n");
+			}
+		}
+	#endif
+
+#endif
diff --git a/architecture/AU/PublicUtility/CADebugPrintf.h b/architecture/AU/PublicUtility/CADebugPrintf.h
new file mode 100644
index 0000000..9a79508
--- /dev/null
+++ b/architecture/AU/PublicUtility/CADebugPrintf.h
@@ -0,0 +1,115 @@
+/*
+     File: CADebugPrintf.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CADebugPrintf_h__)
+#define __CADebugPrintf_h__
+
+//=============================================================================
+//	Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include "CoreAudioTypes.h"
+#endif
+
+//=============================================================================
+//	Macros to redirect debugging output to various logging services
+//=============================================================================
+
+//#define	CoreAudio_UseSysLog		1
+//#define	CoreAudio_UseSideFile	"/CoreAudio-%d.txt"
+
+#if	DEBUG || CoreAudio_Debug
+	
+	#if	TARGET_OS_WIN32
+		#if defined(__cplusplus)
+		extern "C"
+		#endif
+		extern int CAWin32DebugPrintf(char* inFormat, ...);
+		#define	DebugPrintfRtn			CAWin32DebugPrintf
+		#define	DebugPrintfFile			
+		#define	DebugPrintfLineEnding	"\n"
+		#define	DebugPrintfFileComma
+	#else
+		#if	CoreAudio_UseSysLog
+			#include <sys/syslog.h>
+			#define	DebugPrintfRtn	syslog
+			#define	DebugPrintfFile	LOG_NOTICE
+			#define	DebugPrintfLineEnding	""
+			#define	DebugPrintfFileComma	DebugPrintfFile,
+		#elif defined(CoreAudio_UseSideFile)
+			#include <stdio.h>
+			#if defined(__cplusplus)
+			extern "C"
+			#endif
+			void OpenDebugPrintfSideFile();
+			extern FILE* sDebugPrintfSideFile;
+			#define	DebugPrintfRtn	fprintf
+			#define	DebugPrintfFile	((sDebugPrintfSideFile != NULL) ? sDebugPrintfSideFile : stderr)
+			#define	DebugPrintfLineEnding	"\n"
+			#define	DebugPrintfFileComma	DebugPrintfFile,
+		#else
+			#include <stdio.h>
+			#define	DebugPrintfRtn	fprintf
+			#define	DebugPrintfFile	stderr
+			#define	DebugPrintfLineEnding	"\n"
+			#define	DebugPrintfFileComma	DebugPrintfFile,
+		#endif
+	#endif
+
+	#define	DebugPrintf(inFormat, ...)	DebugPrintfRtn(DebugPrintfFileComma inFormat DebugPrintfLineEnding, ## __VA_ARGS__)
+#else
+	#define	DebugPrintfRtn	
+	#define	DebugPrintfFile	
+	#define	DebugPrintfLineEnding	
+	#define	DebugPrintfFileComma
+	#define	DebugPrintf(inFormat, ...)
+#endif
+
+
+#endif
diff --git a/architecture/AU/PublicUtility/CADebugger.cpp b/architecture/AU/PublicUtility/CADebugger.cpp
new file mode 100644
index 0000000..cee21c1
--- /dev/null
+++ b/architecture/AU/PublicUtility/CADebugger.cpp
@@ -0,0 +1,77 @@
+/*
+     File: CADebugger.cpp 
+ Abstract:  CADebugger.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+//=============================================================================
+//	Includes
+//=============================================================================
+
+#include "CADebugger.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include <CoreAudioTypes.h>
+#endif
+
+//	on X, use the Unix routine, otherwise use Debugger()
+#if TARGET_API_MAC_OSX
+	#include <signal.h>
+#endif
+
+//=============================================================================
+//	CADebugger
+//=============================================================================
+
+void	CADebuggerStop()
+{
+	#if	CoreAudio_Debug
+		#if	TARGET_API_MAC_OSX
+			raise(SIGINT);
+		#else
+			__debugbreak();
+		#endif
+	#endif
+}
diff --git a/architecture/AU/PublicUtility/CADebugger.h b/architecture/AU/PublicUtility/CADebugger.h
new file mode 100644
index 0000000..11f18f2
--- /dev/null
+++ b/architecture/AU/PublicUtility/CADebugger.h
@@ -0,0 +1,56 @@
+/*
+     File: CADebugger.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CADebugger_h__)
+#define __CADebugger_h__
+
+//=============================================================================
+//	CADebugger
+//=============================================================================
+
+extern void	CADebuggerStop();
+
+#endif
diff --git a/architecture/AU/PublicUtility/CAException.h b/architecture/AU/PublicUtility/CAException.h
new file mode 100644
index 0000000..be28a44
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAException.h
@@ -0,0 +1,83 @@
+/*
+     File: CAException.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CAException_h__)
+#define __CAException_h__
+
+//=============================================================================
+//	Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include "CoreAudioTypes.h"
+#endif
+
+//=============================================================================
+//	CAException
+//=============================================================================
+
+class CAException
+{
+
+public:
+					CAException(OSStatus inError) : mError(inError) {}
+					CAException(const CAException& inException) : mError(inException.mError) {}
+	CAException&	operator=(const CAException& inException) { mError = inException.mError; return *this; }
+					~CAException() {}
+
+	OSStatus		GetError() const { return mError; }
+	
+protected:
+	OSStatus		mError;
+};
+
+#define	CATry								try{
+#define CACatch								} catch(...) {}
+#define	CASwallowException(inExpression)	try { inExpression; } catch(...) {}
+
+#endif
diff --git a/architecture/AU/PublicUtility/CAGuard.cpp b/architecture/AU/PublicUtility/CAGuard.cpp
new file mode 100644
index 0000000..b070a29
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAGuard.cpp
@@ -0,0 +1,339 @@
+/*
+     File: CAGuard.cpp 
+ Abstract:  CAGuard.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+//==================================================================================================
+//	Includes
+//==================================================================================================
+
+//	Self Include
+#include "CAGuard.h"
+
+#if TARGET_OS_MAC
+	#include <errno.h>
+#endif
+
+//	PublicUtility Inludes
+#include "CADebugMacros.h"
+#include "CAException.h"
+#include "CAHostTimeBase.h"
+
+//==================================================================================================
+//	Logging
+//==================================================================================================
+
+#if CoreAudio_Debug
+//	#define	Log_Ownership		1
+//	#define	Log_WaitOwnership	1
+//	#define	Log_TimedWaits		1
+//	#define Log_Latency			1
+//	#define	Log_Errors			1
+#endif
+
+//#warning		Need a try-based Locker too
+//==================================================================================================
+//	CAGuard
+//==================================================================================================
+
+CAGuard::CAGuard(const char* inName)
+:
+	CAMutex(inName)
+#if	Log_Average_Latency
+	,mAverageLatencyAccumulator(0.0),
+	mAverageLatencyCount(0)
+#endif
+{
+#if TARGET_OS_MAC
+	OSStatus theError = pthread_cond_init(&mCondVar, NULL);
+	ThrowIf(theError != 0, CAException(theError), "CAGuard::CAGuard: Could not init the cond var");
+#elif TARGET_OS_WIN32
+	mEvent = CreateEvent(NULL, true, false, NULL);
+	ThrowIfNULL(mEvent, CAException(GetLastError()), "CAGuard::CAGuard: Could not create the event");
+#endif
+}
+
+CAGuard::~CAGuard()
+{
+#if TARGET_OS_MAC
+	pthread_cond_destroy(&mCondVar);
+#elif TARGET_OS_WIN32
+	if(mEvent != NULL)
+	{
+		CloseHandle(mEvent);
+	}
+#endif
+}
+
+void	CAGuard::Wait()
+{
+#if TARGET_OS_MAC
+	ThrowIf(!pthread_equal(pthread_self(), mOwner), CAException(1), "CAGuard::Wait: A thread has to have locked a guard before it can wait");
+
+	mOwner = 0;
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::Wait: thread %p is waiting on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+	#endif
+
+	OSStatus theError = pthread_cond_wait(&mCondVar, &mMutex);
+	ThrowIf(theError != 0, CAException(theError), "CAGuard::Wait: Could not wait for a signal");
+	mOwner = pthread_self();
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::Wait: thread %p waited on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+	#endif
+#elif TARGET_OS_WIN32
+	ThrowIf(GetCurrentThreadId() != mOwner, CAException(1), "CAGuard::Wait: A thread has to have locked a guard before it can wait");
+
+	mOwner = 0;
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::Wait: thread %lu is waiting on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+	#endif
+
+	ReleaseMutex(mMutex);
+	HANDLE theHandles[] = { mMutex, mEvent };
+	OSStatus theError = WaitForMultipleObjects(2, theHandles, true, INFINITE);
+	ThrowIfError(theError, CAException(GetLastError()), "CAGuard::Wait: Could not wait for the signal");
+	mOwner = GetCurrentThreadId();
+	ResetEvent(mEvent);
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::Wait: thread %lu waited on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+	#endif
+#endif
+}
+
+bool	CAGuard::WaitFor(UInt64 inNanos)
+{
+	bool theAnswer = false;
+
+#if TARGET_OS_MAC
+	ThrowIf(!pthread_equal(pthread_self(), mOwner), CAException(1), "CAGuard::WaitFor: A thread has to have locked a guard be for it can wait");
+
+	#if	Log_TimedWaits
+		DebugMessageN1("CAGuard::WaitFor: waiting %.0f", (Float64)inNanos);
+	#endif
+
+	struct timespec	theTimeSpec;
+	static const UInt64	kNanosPerSecond = 1000000000ULL;
+	if(inNanos >= kNanosPerSecond)
+	{
+		theTimeSpec.tv_sec = static_cast<UInt32>(inNanos / kNanosPerSecond);
+		theTimeSpec.tv_nsec = static_cast<UInt32>(inNanos % kNanosPerSecond);
+	}
+	else
+	{
+		theTimeSpec.tv_sec = 0;
+		theTimeSpec.tv_nsec = static_cast<UInt32>(inNanos);
+	}
+	
+	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
+		UInt64	theStartNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+	#endif
+
+	mOwner = 0;
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::WaitFor: thread %p is waiting on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+	#endif
+
+	OSStatus theError = pthread_cond_timedwait_relative_np(&mCondVar, &mMutex, &theTimeSpec);
+	ThrowIf((theError != 0) && (theError != ETIMEDOUT), CAException(theError), "CAGuard::WaitFor: Wait got an error");
+	mOwner = pthread_self();
+	
+	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
+		UInt64	theEndNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+	#endif
+	
+	#if	Log_TimedWaits
+		DebugMessageN1("CAGuard::WaitFor: waited  %.0f", (Float64)(theEndNanos - theStartNanos));
+	#endif
+	
+	#if	Log_Latency
+		DebugMessageN1("CAGuard::WaitFor: latency  %.0f", (Float64)((theEndNanos - theStartNanos) - inNanos));
+	#endif
+	
+	#if	Log_Average_Latency
+		++mAverageLatencyCount;
+		mAverageLatencyAccumulator += (theEndNanos - theStartNanos) - inNanos;
+		if(mAverageLatencyCount >= 50)
+		{
+			DebugMessageN2("CAGuard::WaitFor: average latency  %.3f ns over %ld waits", mAverageLatencyAccumulator / mAverageLatencyCount, mAverageLatencyCount);
+			mAverageLatencyCount = 0;
+			mAverageLatencyAccumulator = 0.0;
+		}
+	#endif
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::WaitFor: thread %p waited on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+	#endif
+
+	theAnswer = theError == ETIMEDOUT;
+#elif TARGET_OS_WIN32
+	ThrowIf(GetCurrentThreadId() != mOwner, CAException(1), "CAGuard::WaitFor: A thread has to have locked a guard be for it can wait");
+
+	#if	Log_TimedWaits
+		DebugMessageN1("CAGuard::WaitFor: waiting %.0f", (Float64)inNanos);
+	#endif
+
+	//	the time out is specified in milliseconds(!)
+	UInt32 theWaitTime = static_cast<UInt32>(inNanos / 1000000ULL);
+
+	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
+		UInt64	theStartNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+	#endif
+
+	mOwner = 0;
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::WaitFor: thread %lu is waiting on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+	#endif
+	
+	ReleaseMutex(mMutex);
+	HANDLE theHandles[] = { mMutex, mEvent };
+	OSStatus theError = WaitForMultipleObjects(2, theHandles, true, theWaitTime);
+	ThrowIf((theError != WAIT_OBJECT_0) && (theError != WAIT_TIMEOUT), CAException(GetLastError()), "CAGuard::WaitFor: Wait got an error");
+	mOwner = GetCurrentThreadId();
+	ResetEvent(mEvent);
+	
+	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
+		UInt64	theEndNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+	#endif
+	
+	#if	Log_TimedWaits
+		DebugMessageN1("CAGuard::WaitFor: waited  %.0f", (Float64)(theEndNanos - theStartNanos));
+	#endif
+	
+	#if	Log_Latency
+		DebugMessageN1("CAGuard::WaitFor: latency  %.0f", (Float64)((theEndNanos - theStartNanos) - inNanos));
+	#endif
+	
+	#if	Log_Average_Latency
+		++mAverageLatencyCount;
+		mAverageLatencyAccumulator += (theEndNanos - theStartNanos) - inNanos;
+		if(mAverageLatencyCount >= 50)
+		{
+			DebugMessageN2("CAGuard::WaitFor: average latency  %.3f ns over %ld waits", mAverageLatencyAccumulator / mAverageLatencyCount, mAverageLatencyCount);
+			mAverageLatencyCount = 0;
+			mAverageLatencyAccumulator = 0.0;
+		}
+	#endif
+
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::WaitFor: thread %lu waited on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+	#endif
+
+	theAnswer = theError == WAIT_TIMEOUT;
+#endif
+
+	return theAnswer;
+}
+
+bool	CAGuard::WaitUntil(UInt64 inNanos)
+{
+	bool	theAnswer = false;
+	UInt64	theCurrentNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+	
+#if	Log_TimedWaits
+	DebugMessageN2("CAGuard::WaitUntil: now: %.0f, requested: %.0f", (double)theCurrentNanos, (double)inNanos);
+#endif
+	
+	if(inNanos > theCurrentNanos)
+	{
+#if Log_Errors
+		if((inNanos - theCurrentNanos) > 1000000000ULL)
+		{
+			DebugMessage("CAGuard::WaitUntil: about to wait for more than a second");
+		}
+#endif
+		theAnswer = WaitFor(inNanos - theCurrentNanos);
+	}
+	else
+	{
+#if	Log_Errors
+		DebugMessageN2("CAGuard::WaitUntil: Time has expired before waiting, now: %.0f, requested: %.0f", (double)theCurrentNanos, (double)inNanos);
+#endif
+		theAnswer = true;
+	}
+
+	return theAnswer;
+}
+
+void	CAGuard::Notify()
+{
+#if TARGET_OS_MAC
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::Notify: thread %p is notifying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+	#endif
+
+	OSStatus theError = pthread_cond_signal(&mCondVar);
+	ThrowIf(theError != 0, CAException(theError), "CAGuard::Notify: failed");
+#elif TARGET_OS_WIN32
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::Notify: thread %lu is notifying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+	#endif
+	
+	SetEvent(mEvent);
+#endif
+}
+
+void	CAGuard::NotifyAll()
+{
+#if TARGET_OS_MAC
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::NotifyAll: thread %p is notifying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+	#endif
+
+	OSStatus theError = pthread_cond_broadcast(&mCondVar);
+	ThrowIf(theError != 0, CAException(theError), "CAGuard::NotifyAll: failed");
+#elif TARGET_OS_WIN32
+	#if	Log_WaitOwnership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::NotifyAll: thread %lu is notifying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+	#endif
+	
+	SetEvent(mEvent);
+#endif
+}
diff --git a/architecture/AU/PublicUtility/CAGuard.h b/architecture/AU/PublicUtility/CAGuard.h
new file mode 100644
index 0000000..b49dcb4
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAGuard.h
@@ -0,0 +1,133 @@
+/*
+     File: CAGuard.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CAGuard_h__)
+#define __CAGuard_h__
+
+//==================================================================================================
+//	Includes
+//=============================================================================
+
+//	Super Class Includes
+#include "CAMutex.h"
+
+#if CoreAudio_Debug
+//	#define	Log_Average_Latency	1
+#endif
+
+//==================================================================================================
+//	CAGuard
+//
+//	This is your typical mutex with signalling implemented via pthreads.
+//	Lock() will return true if and only if the guard is locked on that call.
+//	A thread that already has the guard will receive 'false' if it locks it
+//	again. Use of the stack-based CAGuard::Locker class is highly recommended
+//	to properly manage the recursive nesting. The Wait calls with timeouts
+//	will return true if and only if the timeout period expired. They will
+//	return false if they receive notification any other way.
+//==================================================================================================
+
+class	CAGuard : public CAMutex
+{
+
+//	Construction/Destruction
+public:
+					CAGuard(const char* inName);
+	virtual			~CAGuard();
+
+//	Actions
+public:
+	virtual void	Wait();
+	virtual bool	WaitFor(UInt64 inNanos);
+	virtual bool	WaitUntil(UInt64 inNanos);
+	
+	virtual void	Notify();
+	virtual void	NotifyAll();
+
+//	Implementation
+protected:
+#if TARGET_OS_MAC
+	pthread_cond_t	mCondVar;
+#else
+	HANDLE			mEvent;
+#endif
+#if	Log_Average_Latency
+	Float64			mAverageLatencyAccumulator;
+	UInt32			mAverageLatencyCount;
+#endif
+	
+//	Helper class to manage taking and releasing recursively
+public:
+	class			Locker
+	{
+	
+	//	Construction/Destruction
+	public:
+					Locker(CAGuard& inGuard) : mGuard(inGuard), mNeedsRelease(false) { mNeedsRelease = mGuard.Lock(); }
+					~Locker() { if(mNeedsRelease) { mGuard.Unlock(); } }
+	
+	private:
+					Locker(const Locker&);
+		Locker&		operator=(const Locker&);
+	
+	//	Actions
+	public:
+		void		Wait() { mGuard.Wait(); }
+		bool		WaitFor(UInt64 inNanos) { return mGuard.WaitFor(inNanos); }
+		bool		WaitUntil(UInt64 inNanos) { return mGuard.WaitUntil(inNanos); }
+		
+		void		Notify() { mGuard.Notify(); }
+		void		NotifyAll() { mGuard.NotifyAll(); }
+
+	//	Implementation
+	private:
+		CAGuard&	mGuard;
+		bool		mNeedsRelease;	
+	};
+
+};
+
+#endif
diff --git a/architecture/AU/PublicUtility/CAHostTimeBase.cpp b/architecture/AU/PublicUtility/CAHostTimeBase.cpp
new file mode 100644
index 0000000..a7a8777
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAHostTimeBase.cpp
@@ -0,0 +1,110 @@
+/*
+     File: CAHostTimeBase.cpp 
+ Abstract:  CAHostTimeBase.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+//=============================================================================
+//	Includes
+//=============================================================================
+
+#include "CAHostTimeBase.h"
+
+Float64	CAHostTimeBase::sFrequency = 0;
+Float64	CAHostTimeBase::sInverseFrequency = 0;
+UInt32	CAHostTimeBase::sMinDelta = 0;
+UInt32	CAHostTimeBase::sToNanosNumerator = 0;
+UInt32	CAHostTimeBase::sToNanosDenominator = 0;
+UInt32	CAHostTimeBase::sFromNanosNumerator = 0;
+UInt32	CAHostTimeBase::sFromNanosDenominator = 0;
+bool	CAHostTimeBase::sUseMicroseconds = false;
+bool	CAHostTimeBase::sIsInited = false;
+#if Track_Host_TimeBase
+UInt64	CAHostTimeBase::sLastTime = 0;
+#endif
+
+//=============================================================================
+//	CAHostTimeBase
+//
+//	This class provides platform independent access to the host's time base.
+//=============================================================================
+
+void	CAHostTimeBase::Initialize()
+{
+	//	get the info about Absolute time
+	#if TARGET_OS_MAC
+		struct mach_timebase_info	theTimeBaseInfo;
+		mach_timebase_info(&theTimeBaseInfo);
+		sMinDelta = 1;
+		sToNanosNumerator = theTimeBaseInfo.numer;
+		sToNanosDenominator = theTimeBaseInfo.denom;
+		sFromNanosNumerator = sToNanosDenominator;
+		sFromNanosDenominator = sToNanosNumerator;
+
+		//	the frequency of that clock is: (sToNanosDenominator / sToNanosNumerator) * 10^9
+		sFrequency = static_cast<Float64>(sToNanosDenominator) / static_cast<Float64>(sToNanosNumerator);
+		sFrequency *= 1000000000.0;
+	#elif TARGET_OS_WIN32
+		LARGE_INTEGER theFrequency;
+		QueryPerformanceFrequency(&theFrequency);
+		sMinDelta = 1;
+		sToNanosNumerator = 1000000000ULL;
+		sToNanosDenominator = *((UInt64*)&theFrequency);
+		sFromNanosNumerator = sToNanosDenominator;
+		sFromNanosDenominator = sToNanosNumerator;
+		sFrequency = static_cast<Float64>(*((UInt64*)&theFrequency));
+	#endif
+	sInverseFrequency = 1.0 / sFrequency;
+	
+	#if	Log_Host_Time_Base_Parameters
+		DebugMessage(  "Host Time Base Parameters");
+		DebugMessageN1(" Minimum Delta:          %lu", sMinDelta);
+		DebugMessageN1(" Frequency:              %f", sFrequency);
+		DebugMessageN1(" To Nanos Numerator:     %lu", sToNanosNumerator);
+		DebugMessageN1(" To Nanos Denominator:   %lu", sToNanosDenominator);
+		DebugMessageN1(" From Nanos Numerator:   %lu", sFromNanosNumerator);
+		DebugMessageN1(" From Nanos Denominator: %lu", sFromNanosDenominator);
+	#endif
+
+	sIsInited = true;
+}
diff --git a/architecture/AU/PublicUtility/CAHostTimeBase.h b/architecture/AU/PublicUtility/CAHostTimeBase.h
new file mode 100644
index 0000000..2a32106
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAHostTimeBase.h
@@ -0,0 +1,231 @@
+/*
+     File: CAHostTimeBase.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CAHostTimeBase_h__)
+#define __CAHostTimeBase_h__
+
+//=============================================================================
+//	Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include <CoreAudioTypes.h>
+#endif
+
+#if TARGET_OS_MAC
+	#include <mach/mach_time.h>
+#elif TARGET_OS_WIN32
+	#include <windows.h>
+#else
+	#error	Unsupported operating system
+#endif
+
+#include "CADebugMacros.h"
+
+//=============================================================================
+//	CAHostTimeBase
+//
+//	This class provides platform independent access to the host's time base.
+//=============================================================================
+
+#if CoreAudio_Debug
+//	#define Log_Host_Time_Base_Parameters	1
+//	#define Track_Host_TimeBase				1
+#endif
+
+class	CAHostTimeBase
+{
+
+public:
+	static UInt64	ConvertToNanos(UInt64 inHostTime);
+	static UInt64	ConvertFromNanos(UInt64 inNanos);
+
+	static UInt64	GetTheCurrentTime();
+#if TARGET_OS_MAC
+	static UInt64	GetCurrentTime() { return GetTheCurrentTime(); }
+#endif
+	static UInt64	GetCurrentTimeInNanos();
+
+	static Float64	GetFrequency() { if(!sIsInited) { Initialize(); } return sFrequency; }
+	static Float64	GetInverseFrequency() { if(!sIsInited) { Initialize(); } return sInverseFrequency; }
+	static UInt32	GetMinimumDelta() { if(!sIsInited) { Initialize(); } return sMinDelta; }
+
+	static UInt64	AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
+	static SInt64	HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
+
+private:
+	static void		Initialize();
+	
+	static bool		sIsInited;
+	
+	static Float64	sFrequency;
+	static Float64	sInverseFrequency;
+	static UInt32	sMinDelta;
+	static UInt32	sToNanosNumerator;
+	static UInt32	sToNanosDenominator;
+	static UInt32	sFromNanosNumerator;
+	static UInt32	sFromNanosDenominator;
+	static bool		sUseMicroseconds;
+#if Track_Host_TimeBase
+	static UInt64	sLastTime;
+#endif
+};
+
+inline UInt64	CAHostTimeBase::GetTheCurrentTime()
+{
+	UInt64 theTime = 0;
+
+	#if TARGET_OS_MAC
+		theTime = mach_absolute_time();
+	#elif TARGET_OS_WIN32
+		LARGE_INTEGER theValue;
+		QueryPerformanceCounter(&theValue);
+		theTime = *((UInt64*)&theValue);
+	#endif
+	
+	#if	Track_Host_TimeBase
+		if(sLastTime != 0)
+		{
+			if(theTime <= sLastTime)
+			{
+				DebugMessageN2("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime);
+			}
+			sLastTime = theTime;
+		}
+		else
+		{
+			sLastTime = theTime;
+		}
+	#endif
+
+	return theTime;
+}
+
+inline UInt64	CAHostTimeBase::ConvertToNanos(UInt64 inHostTime)
+{
+	if(!sIsInited)
+	{
+		Initialize();
+	}
+	
+	Float64 theNumerator = static_cast<Float64>(sToNanosNumerator);
+	Float64 theDenominator = static_cast<Float64>(sToNanosDenominator);
+	Float64 theHostTime = static_cast<Float64>(inHostTime);
+
+	Float64 thePartialAnswer = theHostTime / theDenominator;
+	Float64 theFloatAnswer = thePartialAnswer * theNumerator;
+	UInt64 theAnswer = static_cast<UInt64>(theFloatAnswer);
+
+	//Assert(!((theNumerator > theDenominator) && (theAnswer < inHostTime)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped");
+	//Assert(!((theDenominator > theNumerator) && (theAnswer > inHostTime)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped");
+
+	return theAnswer;
+}
+
+inline UInt64	CAHostTimeBase::ConvertFromNanos(UInt64 inNanos)
+{
+	if(!sIsInited)
+	{
+		Initialize();
+	}
+
+	Float64 theNumerator = static_cast<Float64>(sToNanosNumerator);
+	Float64 theDenominator = static_cast<Float64>(sToNanosDenominator);
+	Float64 theNanos = static_cast<Float64>(inNanos);
+
+	Float64 thePartialAnswer = theNanos / theNumerator;
+	Float64 theFloatAnswer = thePartialAnswer * theDenominator;
+	UInt64 theAnswer = static_cast<UInt64>(theFloatAnswer);
+
+	//Assert(!((theDenominator > theNumerator) && (theAnswer < inNanos)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped");
+	//Assert(!((theNumerator > theDenominator) && (theAnswer > inNanos)), "CAHostTimeBase::ConvertToNanos: The conversion wrapped");
+
+	return theAnswer;
+}
+
+
+inline UInt64	CAHostTimeBase::GetCurrentTimeInNanos()
+{
+	return ConvertToNanos(GetTheCurrentTime());
+}
+
+inline UInt64	CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
+{
+	UInt64 theAnswer;
+	
+	if(inStartTime <= inEndTime)
+	{
+		theAnswer = inEndTime - inStartTime;
+	}
+	else
+	{
+		theAnswer = inStartTime - inEndTime;
+	}
+	
+	return ConvertToNanos(theAnswer);
+}
+
+inline SInt64	CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
+{
+	SInt64 theAnswer;
+	SInt64 theSign = 1;
+	
+	if(inStartTime <= inEndTime)
+	{
+		theAnswer = inEndTime - inStartTime;
+	}
+	else
+	{
+		theAnswer = inStartTime - inEndTime;
+		theSign = -1;
+	}
+	
+	return theSign * ConvertToNanos(theAnswer);
+}
+
+#endif
diff --git a/architecture/AU/PublicUtility/CALogMacros.h b/architecture/AU/PublicUtility/CALogMacros.h
new file mode 100644
index 0000000..f021b08
--- /dev/null
+++ b/architecture/AU/PublicUtility/CALogMacros.h
@@ -0,0 +1,140 @@
+/*
+     File: CALogMacros.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#if !defined(__CALogMacros_h__)
+#define __CALogMacros_h__
+
+//=============================================================================
+//	Log Macros
+//=============================================================================
+
+#if	CoreAudio_Debug
+
+	#include "CADebugMacros.h"
+	#include "CADebugPrintf.h"
+	#include <stdio.h>
+	#include <string.h>
+	
+	#define	PrintLine(msg)						DebugPrintfRtn(DebugPrintfFileComma "%s\n", (msg))
+	
+	#define PrintBool(msg, b)					DebugPrintfRtn(DebugPrintfFileComma "%s%s\n", (msg), (b) ? "true" : "false")
+	#define PrintIndexedBool(msg, i, b)			DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: %s\n", (msg), (long)(i), (b) ? "true" : "false")
+	
+	#define PrintToggle(msg, b)					DebugPrintfRtn(DebugPrintfFileComma "%s%s\n", (msg), (b) ? "on" : "off")
+	#define PrintIndexedToggle(msg, i, b)		DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: %s\n", (msg), (long)(i), (b) ? "on" : "off")
+	
+	#define PrintInt(msg, n)					DebugPrintfRtn(DebugPrintfFileComma "%s%ld\n", (msg), (long)(n))
+	#define PrintIndexedInt(msg, i, n)			DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: %ld\n", (msg), (long)(i), (long)(n))
+	
+	#define PrintHex(msg, n)					DebugPrintfRtn(DebugPrintfFileComma "%s0x%lX\n", (msg), (unsigned long)(n))
+	#define PrintIndexedHex(msg, i, n)			DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: 0x%lX\n", (msg), (long)(i), (unsigned long)(n))
+	
+	#define PrintFloat(msg, f)					DebugPrintfRtn(DebugPrintfFileComma "%s%.6f\n", (msg), (f))
+	#define PrintIndexedFloat(msg, i, f)		DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: %.6f\n", (msg), (long)(i), (f))
+	#define PrintFloatIndexedFloat(msg, i, f)	DebugPrintfRtn(DebugPrintfFileComma "  %s %.6f: %.6f\n", (msg), (i), (f))
+	
+	#define	PrintString(msg, s)					DebugPrintfRtn(DebugPrintfFileComma "%s%s\n", (msg), (s))
+	#define PrintIndexedString(msg, i, s)		DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: %s\n", (msg), (long)(i), (s))
+	
+	#define PrintPointer(msg, p)				DebugPrintfRtn(DebugPrintfFileComma "%s%p\n", (msg), (p))
+	#define PrintIndexedPointer(msg, i, p)		DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: %p\n", (msg), (long)(i), (p))
+	
+	#define	Print4CharCode(msg, c)				{																								\
+													UInt32 __4CC_number = (c);																	\
+													char __4CC_string[5] = CA4CCToCString(__4CC_number);										\
+													DebugPrintfRtn(DebugPrintfFileComma "%s'%s'\n", (msg), __4CC_string);							\
+												}
+	#define PrintIndexed4CharCode(msg, i, c)	{																								\
+													UInt32 __4CC_number = (c);																	\
+													char __4CC_string[5] = CA4CCToCString(__4CC_number);										\
+													DebugPrintfRtn(DebugPrintfFileComma "  %s %ld: '%s'\n", (msg), (long)(i), __4CC_string);		\
+												}
+	
+	#define	ErrorLine(s)						DebugPrintfRtn(DebugPrintfFileComma "%s\n", (s))
+	#define	OSErrorLine(s, e)					{																								\
+													OSStatus __err_number = (e);																\
+													char __err_string[5] = CA4CCToCString(__err_number);										\
+													DebugPrintfRtn(DebugPrintfFileComma "%s, OSStatus code: %s\n", (s), __err_string);				\
+												}
+	
+	#define	MessageIfOSError(e, s)				if((e) != 0) { OSErrorLine(s, e); }
+	#define	MessageIfNULL(p, s)					if((p) == 0) { ErrorLine(s); }
+
+#else
+
+	#define	PrintLine(msg)					
+	
+	#define PrintBool(msg, b)					(b)
+	#define PrintIndexedBool(msg, i, b)			(b)
+	
+	#define PrintInt(msg, n)					(n)
+	#define PrintIndexedInt(msg, i, n)			(n)
+	
+	#define PrintHex(msg, n)					(n)
+	#define PrintIndexedHex(msg, i, n)			(n)
+	
+	#define PrintFloat(msg, f)					(f)
+	#define PrintIndexedFloat(msg, i, f)		(f)
+	#define PrintFloatIndexedFloat(msg, i, f)	(f)
+	
+	#define	PrintString(msg, s)					(s)
+	#define PrintIndexedString(msg, i, s)		(s)
+	
+	#define PrintPointer(msg, p)				(p)
+	#define PrintIndexedPointer(msg, i, p)		(p)
+	
+	#define	Print4CharCode(msg, c)				(c)
+	#define PrintIndexed4CharCode(msg, i, c)	(c)
+	
+	#define	ErrorLine(s)						(s)
+	#define	OSErrorLine(s, e)					(e)
+	
+	#define	MessageIfOSError(e, s)				(e)
+	#define	MessageIfNULL(p, s)					(p)
+
+#endif	//	CoreAudio_Debug
+
+#endif
diff --git a/architecture/AU/PublicUtility/CAMath.h b/architecture/AU/PublicUtility/CAMath.h
new file mode 100644
index 0000000..3f3001e
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAMath.h
@@ -0,0 +1,68 @@
+/*
+     File: CAMath.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAMath_h__
+#define __CAMath_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include <CoreAudioTypes.h>
+#endif
+
+inline bool fiszero(Float64 f) { return (f == 0.); }
+inline bool fiszero(Float32 f) { return (f == 0.f); }
+
+inline bool fnonzero(Float64 f) { return !fiszero(f); }
+inline bool fnonzero(Float32 f) { return !fiszero(f); }
+
+inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
+inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
+
+inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
+inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
+
+#endif // __CAMath_h__
diff --git a/architecture/AU/PublicUtility/CAMutex.cpp b/architecture/AU/PublicUtility/CAMutex.cpp
new file mode 100644
index 0000000..faf8912
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAMutex.cpp
@@ -0,0 +1,345 @@
+/*
+     File: CAMutex.cpp 
+ Abstract:  CAMutex.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+//==================================================================================================
+//	Includes
+//==================================================================================================
+
+//	Self Include
+#include "CAMutex.h"
+
+#if TARGET_OS_MAC
+	#include <errno.h>
+#endif
+
+//	PublicUtility Includes
+#include "CADebugMacros.h"
+#include "CAException.h"
+#include "CAHostTimeBase.h"
+
+//==================================================================================================
+//	Logging
+//==================================================================================================
+
+#if CoreAudio_Debug
+//	#define	Log_Ownership		1
+//	#define	Log_Errors			1
+//	#define Log_LongLatencies	1
+//	#define LongLatencyThreshholdNS	1000000ULL	// nanoseconds
+#endif
+
+//==================================================================================================
+//	CAMutex
+//==================================================================================================
+
+CAMutex::CAMutex(const char* inName)
+:
+	mName(inName),
+	mOwner(0)
+{
+#if TARGET_OS_MAC
+	OSStatus theError = pthread_mutex_init(&mMutex, NULL);
+	ThrowIf(theError != 0, CAException(theError), "CAMutex::CAMutex: Could not init the mutex");
+	
+	#if	Log_Ownership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+	#endif
+#elif TARGET_OS_WIN32
+	mMutex = CreateMutex(NULL, false, NULL);
+	ThrowIfNULL(mMutex, CAException(GetLastError()), "CAMutex::CAMutex: could not create the mutex.");
+	
+	#if	Log_Ownership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+	#endif
+#endif
+}
+
+CAMutex::~CAMutex()
+{
+#if TARGET_OS_MAC
+	#if	Log_Ownership
+		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+	#endif
+	pthread_mutex_destroy(&mMutex);
+#elif TARGET_OS_WIN32
+	#if	Log_Ownership
+		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+	#endif
+	if(mMutex != NULL)
+	{
+		CloseHandle(mMutex);
+	}
+#endif
+}
+
+bool	CAMutex::Lock()
+{
+	bool theAnswer = false;
+	
+#if TARGET_OS_MAC
+	pthread_t theCurrentThread = pthread_self();
+	if(!pthread_equal(theCurrentThread, mOwner))
+	{
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+		#endif
+		
+		#if Log_LongLatencies
+			UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos();
+		#endif
+		
+		OSStatus theError = pthread_mutex_lock(&mMutex);
+		ThrowIf(theError != 0, CAException(theError), "CAMutex::Lock: Could not lock the mutex");
+		mOwner = theCurrentThread;
+		theAnswer = true;
+	
+		#if Log_LongLatencies
+			UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos();
+			if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS)
+				DebugPrintfRtn(DebugPrintfFileComma "Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 /* nanos to seconds */, mName);
+		#endif
+		
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+		#endif
+	}
+#elif TARGET_OS_WIN32
+	if(mOwner != GetCurrentThreadId())
+	{
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+		#endif
+
+		OSStatus theError = WaitForSingleObject(mMutex, INFINITE);
+		ThrowIfError(theError, CAException(theError), "CAMutex::Lock: could not lock the mutex");
+		mOwner = GetCurrentThreadId();
+		theAnswer = true;
+	
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+		#endif
+	}
+#endif
+
+	return theAnswer;
+}
+
+void	CAMutex::Unlock()
+{
+#if TARGET_OS_MAC
+	if(pthread_equal(pthread_self(), mOwner))
+	{
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+		#endif
+
+		mOwner = 0;
+		OSStatus theError = pthread_mutex_unlock(&mMutex);
+		ThrowIf(theError != 0, CAException(theError), "CAMutex::Unlock: Could not unlock the mutex");
+	
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+		#endif
+	}
+	else
+	{
+		DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
+	}
+#elif TARGET_OS_WIN32
+	if(mOwner == GetCurrentThreadId())
+	{
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+		#endif
+
+		mOwner = 0;
+		bool wasReleased = ReleaseMutex(mMutex);
+		ThrowIf(!wasReleased, CAException(GetLastError()), "CAMutex::Unlock: Could not unlock the mutex");
+	
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+		#endif
+	}
+	else
+	{
+		DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
+	}
+#endif
+}
+
+bool	CAMutex::Try(bool& outWasLocked)
+{
+	bool theAnswer = false;
+	outWasLocked = false;
+
+#if TARGET_OS_MAC
+	pthread_t theCurrentThread = pthread_self();
+	if(!pthread_equal(theCurrentThread, mOwner))
+	{
+		//	this means the current thread doesn't already own the lock
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+		#endif
+
+		//	go ahead and call trylock to see if we can lock it.
+		int theError = pthread_mutex_trylock(&mMutex);
+		if(theError == 0)
+		{
+			//	return value of 0 means we successfully locked the lock
+			mOwner = theCurrentThread;
+			theAnswer = true;
+			outWasLocked = true;
+	
+			#if	Log_Ownership
+				DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+			#endif
+		}
+		else if(theError == EBUSY)
+		{
+			//	return value of EBUSY means that the lock was already locked by another thread
+			theAnswer = false;
+			outWasLocked = false;
+	
+			#if	Log_Ownership
+				DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+			#endif
+		}
+		else
+		{
+			//	any other return value means something really bad happenned
+			ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed");
+		}
+	}
+	else
+	{
+		//	this means the current thread already owns the lock
+		theAnswer = true;
+		outWasLocked = false;
+	}
+#elif TARGET_OS_WIN32
+	if(mOwner != GetCurrentThreadId())
+	{
+		//	this means the current thread doesn't own the lock
+		#if	Log_Ownership
+			DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+		#endif
+		
+		//	try to acquire the mutex
+		OSStatus theError = WaitForSingleObject(mMutex, 0);
+		if(theError == WAIT_OBJECT_0)
+		{
+			//	this means we successfully locked the lock
+			mOwner = GetCurrentThreadId();
+			theAnswer = true;
+			outWasLocked = true;
+	
+			#if	Log_Ownership
+				DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+			#endif
+		}
+		else if(theError == WAIT_TIMEOUT)
+		{
+			//	this means that the lock was already locked by another thread
+			theAnswer = false;
+			outWasLocked = false;
+	
+			#if	Log_Ownership
+				DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+			#endif
+		}
+		else
+		{
+			//	any other return value means something really bad happenned
+			ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed");
+		}
+	}
+	else
+	{
+		//	this means the current thread already owns the lock
+		theAnswer = true;
+		outWasLocked = false;
+	}
+#endif
+	
+	return theAnswer;
+}
+
+bool	CAMutex::IsFree() const
+{
+	return mOwner == 0;
+}
+
+bool	CAMutex::IsOwnedByCurrentThread() const
+{
+	bool theAnswer = true;
+	
+#if TARGET_OS_MAC
+	theAnswer = pthread_equal(pthread_self(), mOwner);
+#elif TARGET_OS_WIN32
+	theAnswer = (mOwner == GetCurrentThreadId());
+#endif
+
+	return theAnswer;
+}
+
+
+CAMutex::Unlocker::Unlocker(CAMutex& inMutex)
+:	mMutex(inMutex),
+	mNeedsLock(false)
+{
+	Assert(mMutex.IsOwnedByCurrentThread(), "Major problem: Unlocker attempted to unlock a mutex not owned by the current thread!");
+
+	mMutex.Unlock();
+	mNeedsLock = true;
+}
+
+CAMutex::Unlocker::~Unlocker()
+{
+	if(mNeedsLock)
+	{
+		mMutex.Lock();
+	}
+}
diff --git a/architecture/AU/PublicUtility/CAMutex.h b/architecture/AU/PublicUtility/CAMutex.h
new file mode 100644
index 0000000..7e072fe
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAMutex.h
@@ -0,0 +1,163 @@
+/*
+     File: CAMutex.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAMutex_h__
+#define __CAMutex_h__
+
+//==================================================================================================
+//	Includes
+//==================================================================================================
+
+//	System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+#else
+	#include <CoreAudioTypes.h>
+#endif
+
+#if TARGET_OS_MAC
+	#include <pthread.h>
+#elif TARGET_OS_WIN32
+	#include <windows.h>
+#else
+	#error	Unsupported operating system
+#endif
+
+//==================================================================================================
+//	A recursive mutex.
+//==================================================================================================
+
+class	CAMutex
+{
+//	Construction/Destruction
+public:
+					CAMutex(const char* inName);
+	virtual			~CAMutex();
+
+//	Actions
+public:
+	virtual bool	Lock();
+	virtual void	Unlock();
+	virtual bool	Try(bool& outWasLocked);	// returns true if lock is free, false if not
+	
+	virtual bool	IsFree() const;
+	virtual bool	IsOwnedByCurrentThread() const;
+		
+//	Implementation
+protected:
+	const char*		mName;
+#if TARGET_OS_MAC
+	pthread_t		mOwner;
+	pthread_mutex_t	mMutex;
+#elif TARGET_OS_WIN32
+	UInt32			mOwner;
+	HANDLE			mMutex;
+#endif
+
+//	Helper class to manage taking and releasing recursively
+public:
+	class			Locker
+	{
+	
+	//	Construction/Destruction
+	public:
+					Locker(CAMutex& inMutex) : mMutex(&inMutex), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); }
+					Locker(CAMutex* inMutex) : mMutex(inMutex), mNeedsRelease(false) { mNeedsRelease = (mMutex != NULL && mMutex->Lock()); }
+						// in this case the mutex can be null
+					~Locker() { if(mNeedsRelease) { mMutex->Unlock(); } }
+	
+	
+	private:
+					Locker(const Locker&);
+		Locker&		operator=(const Locker&);
+	
+	//	Implementation
+	private:
+		CAMutex*	mMutex;
+		bool		mNeedsRelease;
+	
+	};
+
+// Unlocker
+	class Unlocker
+	{
+	public:
+						Unlocker(CAMutex& inMutex);
+						~Unlocker();
+		
+	private:
+		CAMutex&	mMutex;
+		bool		mNeedsLock;
+		
+		// Hidden definitions of copy ctor, assignment operator
+		Unlocker(const Unlocker& copy);				// Not implemented
+		Unlocker& operator=(const Unlocker& copy);	// Not implemented
+	};
+	
+// you can use this with Try - if you take the lock in try, pass in the outWasLocked var
+	class Tryer {
+	
+	//	Construction/Destruction
+	public:
+		Tryer (CAMutex &mutex) : mMutex(mutex), mNeedsRelease(false), mHasLock(false) { mHasLock = mMutex.Try (mNeedsRelease); }
+		~Tryer () { if (mNeedsRelease) mMutex.Unlock(); }
+		
+		bool HasLock () const { return mHasLock; }
+
+	private:
+					Tryer(const Tryer&);
+		Tryer&		operator=(const Tryer&);
+
+	//	Implementation
+	private:
+		CAMutex &		mMutex;
+		bool			mNeedsRelease;
+		bool			mHasLock;
+	};
+};
+
+
+#endif // __CAMutex_h__
diff --git a/architecture/AU/PublicUtility/CAReferenceCounted.h b/architecture/AU/PublicUtility/CAReferenceCounted.h
new file mode 100644
index 0000000..7b74dfe
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAReferenceCounted.h
@@ -0,0 +1,87 @@
+/*
+     File: CAReferenceCounted.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAReferenceCounted_h__
+#define __CAReferenceCounted_h__
+
+#include "CAAtomic.h"
+
+// base class for reference-counted objects
+class CAReferenceCounted {
+public:
+	CAReferenceCounted() : mRefCount(1) {}
+	
+	void	retain() { CAAtomicIncrement32(&mRefCount); }
+	
+	void	release() 
+			{ 
+				SInt32 rc = CAAtomicDecrement32 (&mRefCount);
+				if (rc == 0) {
+					releaseObject();
+				}
+			}
+
+protected:
+    virtual	~CAReferenceCounted() { }
+	
+	virtual void releaseObject () 
+			{ 
+				delete this; 
+			}
+
+#if DEBUG
+public:
+#endif
+	SInt32	GetReferenceCount() const { return mRefCount; }
+private:
+	SInt32		mRefCount;
+
+	CAReferenceCounted(const CAReferenceCounted &a);
+	CAReferenceCounted &operator=(const CAReferenceCounted &a);
+};
+
+
+#endif // __CAReferenceCounted_h__
diff --git a/architecture/AU/PublicUtility/CAStreamBasicDescription.cpp b/architecture/AU/PublicUtility/CAStreamBasicDescription.cpp
new file mode 100644
index 0000000..c5b1d65
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAStreamBasicDescription.cpp
@@ -0,0 +1,795 @@
+/*
+     File: CAStreamBasicDescription.cpp 
+ Abstract:  CAStreamBasicDescription.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "CAStreamBasicDescription.h"
+#include "CAMath.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreFoundation/CFByteOrder.h>
+#else
+	#include <CFByteOrder.h>
+#endif
+
+#pragma mark	This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it
+
+char *CAStringForOSType (OSType t, char *writeLocation)
+{
+	char *p = writeLocation;
+    unsigned char str[4] = {0}, *q = str;
+	*(UInt32 *)str = CFSwapInt32HostToBig(t);
+
+	bool hasNonPrint = false;
+	for (int i = 0; i < 4; ++i) {
+		if (!(isprint(*q) && *q != '\\')) {
+			hasNonPrint = true;
+			break;
+		}
+        q++;
+	}
+    q = str;
+	
+	if (hasNonPrint)
+		p += sprintf (p, "0x");
+	else
+		*p++ = '\'';
+		
+	for (int i = 0; i < 4; ++i) {
+		if (hasNonPrint) {
+			p += sprintf(p, "%02X", *q++);
+		} else {
+			*p++ = *q++;
+		}
+	}
+	if (!hasNonPrint)
+		*p++ = '\'';
+	*p = '\0';
+	return writeLocation;
+}
+
+
+const AudioStreamBasicDescription	CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+CAStreamBasicDescription::CAStreamBasicDescription() 
+{ 
+	memset (this, 0, sizeof(AudioStreamBasicDescription)); 
+}
+	
+CAStreamBasicDescription::CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
+{
+	SetFrom(desc);
+}
+
+
+CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate,		UInt32 inFormatID,
+									UInt32 inBytesPerPacket,	UInt32 inFramesPerPacket,
+									UInt32 inBytesPerFrame,		UInt32 inChannelsPerFrame,
+									UInt32 inBitsPerChannel,	UInt32 inFormatFlags)
+{
+	mSampleRate = inSampleRate;
+	mFormatID = inFormatID;
+	mBytesPerPacket = inBytesPerPacket;
+	mFramesPerPacket = inFramesPerPacket;
+	mBytesPerFrame = inBytesPerFrame;
+	mChannelsPerFrame = inChannelsPerFrame;
+	mBitsPerChannel = inBitsPerChannel;
+	mFormatFlags = inFormatFlags;
+	mReserved = 0;
+}
+
+char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize) const
+{
+	int bufsize = (int)_bufsize;	// must be signed to protect against overflow
+	char *theBuffer = buf;
+	int nc;
+	char formatID[24];
+	CAStringForOSType (mFormatID, formatID);
+	nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags);
+	buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+	if (mFormatID == kAudioFormatLinearPCM) {
+		bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
+		int wordSize = SampleWordSize();
+		const char *endian = (wordSize > 1) ? 
+			((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
+		const char *sign = isInt ? 
+			((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
+		const char *floatInt = isInt ? "integer" : "float";
+		char packed[32];
+		if (wordSize > 0 && PackednessIsSignificant()) {
+			if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
+				snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize);
+			else
+				snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize);
+		} else
+			packed[0] = '\0';
+		const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
+			((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
+		const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
+		const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
+		char bitdepth[20];
+
+		int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
+		if (fracbits > 0)
+			snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits);
+		else
+			snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel);
+		
+		/* nc =*/ snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s",
+			bitdepth, endian, sign, floatInt, 
+			commaSpace, packed, align, deinter);
+		// buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+	} else if (mFormatID == 'alac') {	//	kAudioFormatAppleLossless
+		int sourceBits = 0;
+		switch (mFormatFlags)
+		{
+			case 1:	//	kAppleLosslessFormatFlag_16BitSourceData
+				sourceBits = 16;
+				break;
+    		case 2:	//	kAppleLosslessFormatFlag_20BitSourceData
+    			sourceBits = 20;
+    			break;
+    		case 3:	//	kAppleLosslessFormatFlag_24BitSourceData
+    			sourceBits = 24;
+    			break;
+    		case 4:	//	kAppleLosslessFormatFlag_32BitSourceData
+    			sourceBits = 32;
+    			break;
+		}
+		if (sourceBits)
+			nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits);
+		else
+			nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, ");
+		buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+		/* nc =*/ snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket);
+		//	buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+	}
+	else
+		/* nc =*/ snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame",
+			(int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame);
+exit:
+	return theBuffer;
+}
+
+void	CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription)
+{
+	//  the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
+	if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
+	{
+		//  the canonical linear PCM format
+		ioDescription.mFormatFlags = kAudioFormatFlagsCanonical;
+		ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+		ioDescription.mFramesPerPacket = 1;
+		ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+		ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType);
+	}
+}
+
+void	CAStreamBasicDescription::NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription)
+{
+	//  the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
+	if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
+	{
+		//  the canonical linear PCM format
+		ioDescription.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
+		if(inNativeEndian)
+		{
+#if TARGET_RT_BIG_ENDIAN
+			ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+		}
+		else
+		{
+#if TARGET_RT_LITTLE_ENDIAN
+			ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+		}
+		ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+		ioDescription.mFramesPerPacket = 1;
+		ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+		ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType);
+	}
+}
+
+void	CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription)
+{
+	ioDescription.mSampleRate = 0;
+	ioDescription.mFormatID = 0;
+	ioDescription.mBytesPerPacket = 0;
+	ioDescription.mFramesPerPacket = 0;
+	ioDescription.mBytesPerFrame = 0;
+	ioDescription.mChannelsPerFrame = 0;
+	ioDescription.mBitsPerChannel = 0;
+	ioDescription.mFormatFlags = 0;
+}
+
+void	CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription)
+{
+	if(fiszero(ioDescription.mSampleRate))
+	{
+		ioDescription.mSampleRate = inTemplateDescription.mSampleRate;
+	}
+	if(ioDescription.mFormatID == 0)
+	{
+		ioDescription.mFormatID = inTemplateDescription.mFormatID;
+	}
+	if(ioDescription.mFormatFlags == 0)
+	{
+		ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags;
+	}
+	if(ioDescription.mBytesPerPacket == 0)
+	{
+		ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket;
+	}
+	if(ioDescription.mFramesPerPacket == 0)
+	{
+		ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket;
+	}
+	if(ioDescription.mBytesPerFrame == 0)
+	{
+		ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame;
+	}
+	if(ioDescription.mChannelsPerFrame == 0)
+	{
+		ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame;
+	}
+	if(ioDescription.mBitsPerChannel == 0)
+	{
+		ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel;
+	}
+}
+
+void	CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate)
+{
+	if(inIncludeSampleRate)
+	{
+		int theCharactersWritten = snprintf(outName, inMaxNameLength, "%.0f ", inDescription.mSampleRate);
+		outName += theCharactersWritten;
+		inMaxNameLength -= theCharactersWritten;
+	}
+	
+	switch(inDescription.mFormatID)
+	{
+		case kAudioFormatLinearPCM:
+			{
+				const char* theEndianString = NULL;
+				if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0)
+				{
+					#if	TARGET_RT_LITTLE_ENDIAN
+						theEndianString = "Big Endian";
+					#endif
+				}
+				else
+				{
+					#if	TARGET_RT_BIG_ENDIAN
+						theEndianString = "Little Endian";
+					#endif
+				}
+				
+				const char* theKindString = NULL;
+				if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
+				{
+					theKindString = (inAbbreviate ? "Float" : "Floating Point");
+				}
+				else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
+				{
+					theKindString = (inAbbreviate ? "SInt" : "Signed Integer");
+				}
+				else
+				{
+					theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer");
+				}
+				
+				const char* thePackingString = NULL;
+				if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0)
+				{
+					if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0)
+					{
+						thePackingString = "High";
+					}
+					else
+					{
+						thePackingString = "Low";
+					}
+				}
+				
+				const char* theMixabilityString = NULL;
+				if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0)
+				{
+					theMixabilityString = "Mixable";
+				}
+				else
+				{
+					theMixabilityString = "Unmixable";
+				}
+				
+				if(inAbbreviate)
+				{
+					if(theEndianString != NULL)
+					{
+						if(thePackingString != NULL)
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+						}
+						else
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
+						}
+					}
+					else
+					{
+						if(thePackingString != NULL)
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8));
+						}
+						else
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
+						}
+					}
+				}
+				else
+				{
+					if(theEndianString != NULL)
+					{
+						if(thePackingString != NULL)
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+						}
+						else
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
+						}
+					}
+					else
+					{
+						if(thePackingString != NULL)
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+						}
+						else
+						{
+							snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
+						}
+					}
+				}
+			}
+			break;
+		
+		case kAudioFormatAC3:
+			strlcpy(outName, "AC-3", sizeof(outName));
+			break;
+		
+		case kAudioFormat60958AC3:
+			strlcpy(outName, "AC-3 for SPDIF", sizeof(outName));
+			break;
+		
+		default:
+			CACopy4CCToCString(outName, inDescription.mFormatID);
+			break;
+	};
+}
+
+#if CoreAudio_Debug
+#include "CALogMacros.h"
+
+void	CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc)
+{
+	PrintFloat		("  Sample Rate:        ", inDesc.mSampleRate);
+	Print4CharCode	("  Format ID:          ", inDesc.mFormatID);
+	PrintHex		("  Format Flags:       ", inDesc.mFormatFlags);
+	PrintInt		("  Bytes per Packet:   ", inDesc.mBytesPerPacket);
+	PrintInt		("  Frames per Packet:  ", inDesc.mFramesPerPacket);
+	PrintInt		("  Bytes per Frame:    ", inDesc.mBytesPerFrame);
+	PrintInt		("  Channels per Frame: ", inDesc.mChannelsPerFrame);
+	PrintInt		("  Bits per Channel:   ", inDesc.mBitsPerChannel);
+}
+#endif
+
+bool	operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+	bool theAnswer = false;
+	bool isDone = false;
+	
+	//	note that if either side is 0, that field is skipped
+	
+	//	format ID is the first order sort
+	if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0)))
+	{
+		if(x.mFormatID != y.mFormatID)
+		{
+			//	formats are sorted numerically except that linear
+			//	PCM is always first
+			if(x.mFormatID == kAudioFormatLinearPCM)
+			{
+				theAnswer = true;
+			}
+			else if(y.mFormatID == kAudioFormatLinearPCM)
+			{
+				theAnswer = false;
+			}
+			else
+			{
+				theAnswer = x.mFormatID < y.mFormatID;
+			}
+			isDone = true;
+		}
+	}
+	
+	
+	//  mixable is always better than non-mixable for linear PCM and should be the second order sort item
+	if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
+	{
+		if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0))
+		{
+			theAnswer = true;
+			isDone = true;
+		}
+		else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0))
+		{
+			theAnswer = false;
+			isDone = true;
+		}
+	}
+	
+	//	floating point vs integer for linear PCM only
+	if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
+	{
+		if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat))
+		{
+			//	floating point is better than integer
+			theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat;
+			isDone = true;
+		}
+	}
+	
+	//	bit depth
+	if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0)))
+	{
+		if(x.mBitsPerChannel != y.mBitsPerChannel)
+		{
+			//	deeper bit depths are higher quality
+			theAnswer = x.mBitsPerChannel < y.mBitsPerChannel;
+			isDone = true;
+		}
+	}
+	
+	//	sample rate
+	if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate))
+	{
+		if(fnotequal(x.mSampleRate, y.mSampleRate))
+		{
+			//	higher sample rates are higher quality
+			theAnswer = x.mSampleRate < y.mSampleRate;
+			isDone = true;
+		}
+	}
+	
+	//	number of channels
+	if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0)))
+	{
+		if(x.mChannelsPerFrame != y.mChannelsPerFrame)
+		{
+			//	more channels is higher quality
+			theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame;
+			//isDone = true;
+		}
+	}
+	
+	return theAnswer;
+}
+
+static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+	UInt32 xFlags = x.mFormatFlags;
+	UInt32 yFlags = y.mFormatFlags;
+	
+	// match wildcards
+	if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) 
+		return true;
+	
+	if (x.mFormatID == kAudioFormatLinearPCM)
+	{		 		
+		// knock off the all clear flag
+		xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
+		yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
+	
+		// if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
+		if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
+			xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh;
+			yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
+		}
+		
+		// if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
+		if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
+			xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
+			yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger;
+		}
+		
+		//	if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
+		if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
+		{
+			xFlags = xFlags & ~kAudioFormatFlagIsBigEndian;
+		}
+		if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
+		{
+			yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
+		}
+		
+		//	if the number of channels is 1, we don't care about non-interleavedness
+		if (x.mChannelsPerFrame == 1 && y.mChannelsPerFrame == 1) {
+			xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
+			yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
+		}
+	}
+	return xFlags == yFlags;
+}
+
+bool	operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+	//	the semantics for equality are:
+	//		1) Values must match exactly -- except for PCM format flags, see above.
+	//		2) wildcard's are ignored in the comparison
+	
+#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
+	
+	return 
+			//	check the sample rate
+		(fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
+		
+			//	check the format ids
+		&& MATCH(mFormatID)
+		
+			//	check the format flags
+		&& MatchFormatFlags(x, y)  
+			
+			//	check the bytes per packet
+		&& MATCH(mBytesPerPacket) 
+		
+			//	check the frames per packet
+		&& MATCH(mFramesPerPacket) 
+		
+			//	check the bytes per frame
+		&& MATCH(mBytesPerFrame) 
+		
+			//	check the channels per frame
+		&& MATCH(mChannelsPerFrame) 
+		
+			//	check the channels per frame
+		&& MATCH(mBitsPerChannel) ;
+}
+
+bool	CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const
+{
+	if (interpretingWildcards)
+		return *this == other;
+	return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0;
+}
+
+bool SanityCheck(const AudioStreamBasicDescription& x)
+{
+	// This function returns false if there are sufficiently insane values in any field.
+	// It is very conservative so even some very unlikely values will pass.
+	// This is just meant to catch the case where the data from a file is corrupted.
+	
+	return 
+		(x.mSampleRate >= 0.)	
+		&& (x.mSampleRate < 3e6)	// SACD sample rate is 2.8224 MHz
+		&& (x.mBytesPerPacket < 1000000)
+		&& (x.mFramesPerPacket < 1000000)
+		&& (x.mBytesPerFrame < 1000000)
+		&& (x.mChannelsPerFrame <= 1024)
+		&& (x.mBitsPerChannel <= 1024)
+		&& (x.mFormatID != 0)
+		&& !(x.mFormatID == kAudioFormatLinearPCM && (x.mFramesPerPacket != 1 || x.mBytesPerPacket != x.mBytesPerFrame));
+}
+
+bool CAStreamBasicDescription::FromText(const char *inTextDesc, AudioStreamBasicDescription &fmt)
+{
+	const char *p = inTextDesc;
+	
+	memset(&fmt, 0, sizeof(fmt));
+
+	bool isPCM = true;	// until proven otherwise
+	UInt32 pcmFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
+
+	if (p[0] == '-')	// previously we required a leading dash on PCM formats
+		++p;
+
+	if (p[0] == 'B' && p[1] == 'E') {
+		pcmFlags |= kLinearPCMFormatFlagIsBigEndian;
+		p += 2;
+	} else if (p[0] == 'L' && p[1] == 'E') {
+		p += 2;
+	} else {
+		// default is native-endian
+#if TARGET_RT_BIG_ENDIAN
+		pcmFlags |= kLinearPCMFormatFlagIsBigEndian;
+#endif
+	}
+	if (p[0] == 'F') {
+		pcmFlags = (pcmFlags & ~kAudioFormatFlagIsSignedInteger) | kAudioFormatFlagIsFloat;
+		++p;
+	} else {
+		if (p[0] == 'U') {
+			pcmFlags &= ~kAudioFormatFlagIsSignedInteger;
+			++p;
+		}
+		if (p[0] == 'I')
+			++p;
+		else {
+			// it's not PCM; presumably some other format (NOT VALIDATED; use AudioFormat for that)
+			isPCM = false;
+			p = inTextDesc;	// go back to the beginning
+			char buf[4] = { ' ',' ',' ',' ' };
+			for (int i = 0; i < 4; ++i) {
+				if (*p != '\\') {
+					if ((buf[i] = *p++) == '\0') {
+						// special-case for 'aac'
+						if (i != 3) return false;
+						--p;	// keep pointing at the terminating null
+						buf[i] = ' ';
+						break;
+					}
+				} else {
+					// "\xNN" is a hex byte
+					if (*++p != 'x') return false;
+					int x;
+					if (sscanf(++p, "%02X", &x) != 1) return false;
+					buf[i] = x;
+					p += 2;
+				}
+			}
+			
+			if (strchr("-@/#", buf[3])) {
+				// further special-casing for 'aac'
+				buf[3] = ' ';
+				--p;
+			}
+			
+			fmt.mFormatID = CFSwapInt32BigToHost(*(UInt32 *)buf);
+		}
+	}
+	
+	if (isPCM) {
+		fmt.mFormatID = kAudioFormatLinearPCM;
+		fmt.mFormatFlags = pcmFlags;
+		fmt.mFramesPerPacket = 1;
+		fmt.mChannelsPerFrame = 1;
+		int bitdepth = 0, fracbits = 0;
+		while (isdigit(*p))
+			bitdepth = 10 * bitdepth + *p++ - '0';
+		if (*p == '.') {
+			++p;
+			if (!isdigit(*p)) {
+				fprintf(stderr, "Expected fractional bits following '.'\n");
+				goto Bail;
+			}
+			while (isdigit(*p))
+				fracbits = 10 * fracbits + *p++ - '0';
+			bitdepth += fracbits;
+			fmt.mFormatFlags |= (fracbits << kLinearPCMFormatFlagsSampleFractionShift);
+		}
+		fmt.mBitsPerChannel = bitdepth;
+		fmt.mBytesPerPacket = fmt.mBytesPerFrame = (bitdepth + 7) / 8;
+		if (bitdepth & 7) {
+			// assume unpacked. (packed odd bit depths are describable but not supported in AudioConverter.)
+			fmt.mFormatFlags &= ~kLinearPCMFormatFlagIsPacked;
+			// alignment matters; default to high-aligned. use ':L_' for low.
+			fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
+		}
+	}
+	if (*p == '@') {
+		++p;
+		while (isdigit(*p))
+			fmt.mSampleRate = 10 * fmt.mSampleRate + (*p++ - '0');
+	}
+	if (*p == '/') {
+		UInt32 flags = 0;
+		while (true) {
+			char c = *++p;
+			if (c >= '0' && c <= '9')
+				flags = (flags << 4) | (c - '0');
+			else if (c >= 'A' && c <= 'F')
+				flags = (flags << 4) | (c - 'A' + 10);
+			else if (c >= 'a' && c <= 'f')
+				flags = (flags << 4) | (c - 'a' + 10);
+			else break;
+		}
+		fmt.mFormatFlags = flags;
+	}
+	if (*p == '#') {
+		++p;
+		while (isdigit(*p))
+			fmt.mFramesPerPacket = 10 * fmt.mFramesPerPacket + (*p++ - '0');
+	}
+	if (*p == ':') {
+		++p;
+		fmt.mFormatFlags &= ~kLinearPCMFormatFlagIsPacked;
+		if (*p == 'L')
+			fmt.mFormatFlags &= ~kLinearPCMFormatFlagIsAlignedHigh;
+		else if (*p == 'H')
+			fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
+		else
+			goto Bail;
+		++p;
+		int bytesPerFrame = 0;
+		while (isdigit(*p))
+			bytesPerFrame = 10 * bytesPerFrame + (*p++ - '0');
+		fmt.mBytesPerFrame = fmt.mBytesPerPacket = bytesPerFrame;
+	}
+	if (*p == ',') {
+		++p;
+		int ch = 0;
+		while (isdigit(*p))
+			ch = 10 * ch + (*p++ - '0');
+		fmt.mChannelsPerFrame = ch;
+		if (*p == 'D') {
+			++p;
+			if (fmt.mFormatID != kAudioFormatLinearPCM) {
+				fprintf(stderr, "non-interleaved flag invalid for non-PCM formats\n");
+				goto Bail;
+			}
+			fmt.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+		} else {
+			if (*p == 'I') ++p;	// default
+			if (fmt.mFormatID == kAudioFormatLinearPCM)
+				fmt.mBytesPerPacket = fmt.mBytesPerFrame *= ch;
+		}
+	}
+	if (*p != '\0') {
+		fprintf(stderr, "extra characters at end of format string: %s\n", p);
+		goto Bail;
+	}
+	return true;
+
+Bail:
+	fprintf(stderr, "Invalid format string: %s\n", inTextDesc);
+	fprintf(stderr, "Syntax of format strings is: \n");
+	return false;
+}
+
+const char *CAStreamBasicDescription::sTextParsingUsageString = 
+	"format[@sample_rate_hz][/format_flags][#frames_per_packet][:LHbytesPerFrame][,channelsDI].\n"
+	"Format for PCM is [-][BE|LE]{F|I|UI}{bitdepth}; else a 4-char format code (e.g. aac, alac).\n";
diff --git a/architecture/AU/PublicUtility/CAStreamBasicDescription.h b/architecture/AU/PublicUtility/CAStreamBasicDescription.h
new file mode 100644
index 0000000..367cc19
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAStreamBasicDescription.h
@@ -0,0 +1,409 @@
+/*
+     File: CAStreamBasicDescription.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAStreamBasicDescription_h__
+#define __CAStreamBasicDescription_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreAudio/CoreAudioTypes.h>
+	#include <CoreFoundation/CoreFoundation.h>
+#else
+	#include "CoreAudioTypes.h"
+	#include "CoreFoundation.h"
+#endif
+
+#include "CADebugMacros.h"
+#include <string.h>	// for memset, memcpy
+#include <stdio.h>	// for FILE *
+
+#pragma mark	This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
+
+extern char *CAStringForOSType (OSType t, char *writeLocation);
+
+// define Leopard specific symbols for backward compatibility if applicable
+#if COREAUDIOTYPES_VERSION < 1050
+typedef Float32 AudioSampleType;
+enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked };
+#endif
+#if COREAUDIOTYPES_VERSION < 1051
+typedef Float32 AudioUnitSampleType;
+enum {
+	kLinearPCMFormatFlagsSampleFractionShift    = 7,
+	kLinearPCMFormatFlagsSampleFractionMask     = (0x3F << kLinearPCMFormatFlagsSampleFractionShift),
+};
+#endif
+
+//	define the IsMixable format flag for all versions of the system
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
+	enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
+#else
+	enum { kIsNonMixableFlag = (1L << 6) };
+#endif
+
+//=============================================================================
+//	CAStreamBasicDescription
+//
+//	This is a wrapper class for the AudioStreamBasicDescription struct.
+//	It adds a number of convenience routines, but otherwise adds nothing
+//	to the footprint of the original struct.
+//=============================================================================
+class CAStreamBasicDescription : 
+	public AudioStreamBasicDescription
+{
+
+//	Constants
+public:
+	static const AudioStreamBasicDescription	sEmpty;
+	
+	enum CommonPCMFormat {
+		kPCMFormatOther		= 0,
+		kPCMFormatFloat32	= 1,
+		kPCMFormatInt16		= 2,
+		kPCMFormatFixed824	= 3
+	};
+	
+//	Construction/Destruction
+public:
+	CAStreamBasicDescription();
+	
+	CAStreamBasicDescription(const AudioStreamBasicDescription &desc);
+	
+	CAStreamBasicDescription(		double inSampleRate,		UInt32 inFormatID,
+									UInt32 inBytesPerPacket,	UInt32 inFramesPerPacket,
+									UInt32 inBytesPerFrame,		UInt32 inChannelsPerFrame,
+									UInt32 inBitsPerChannel,	UInt32 inFormatFlags);
+
+	CAStreamBasicDescription(	double inSampleRate, UInt32 inNumChannels, CommonPCMFormat pcmf, bool inIsInterleaved) {
+		unsigned wordsize;
+
+		mSampleRate = inSampleRate;
+		mFormatID = kAudioFormatLinearPCM;
+		mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
+		mFramesPerPacket = 1;
+		mChannelsPerFrame = inNumChannels;
+		mBytesPerFrame = mBytesPerPacket = 0;
+		mReserved = 0;
+
+		switch (pcmf) {
+		default:
+			return;
+		case kPCMFormatFloat32:
+			wordsize = 4;
+			mFormatFlags |= kAudioFormatFlagIsFloat;
+			break;
+		case kPCMFormatInt16:
+			wordsize = 2;
+			mFormatFlags |= kAudioFormatFlagIsSignedInteger;
+			break;
+		case kPCMFormatFixed824:
+			wordsize = 4;
+			mFormatFlags |= kAudioFormatFlagIsSignedInteger | (24 << kLinearPCMFormatFlagsSampleFractionShift);
+			break;
+		}
+		mBitsPerChannel = wordsize * 8;
+		if (inIsInterleaved)
+			mBytesPerFrame = mBytesPerPacket = wordsize * inNumChannels;
+		else {
+			mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+			mBytesPerFrame = mBytesPerPacket = wordsize;
+		}
+	}
+
+//	Assignment
+	CAStreamBasicDescription&	operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
+
+	void	SetFrom(const AudioStreamBasicDescription &desc)
+	{
+		memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
+	}
+	
+	bool		FromText(const char *inTextDesc) { return FromText(inTextDesc, *this); }
+	static bool	FromText(const char *inTextDesc, AudioStreamBasicDescription &outDesc);
+					// return true if parsing was successful
+	
+	static const char *sTextParsingUsageString;
+	
+	// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+	//
+	// interrogation
+	
+	bool	IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
+	
+	bool	PackednessIsSignificant() const
+	{
+		Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
+		return (SampleWordSize() << 3) != mBitsPerChannel;
+	}
+	
+	bool	AlignmentIsSignificant() const
+	{
+		return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
+	}
+	
+	bool	IsInterleaved() const
+	{
+		return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
+	}
+	
+	bool	IsSignedInteger() const
+	{
+		return IsPCM() && (mFormatFlags & kAudioFormatFlagIsSignedInteger);
+	}
+	
+	bool	IsFloat() const
+	{
+		return IsPCM() && (mFormatFlags & kAudioFormatFlagIsFloat);
+	}
+	
+	bool	IsNativeEndian() const
+	{
+		return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian;
+	}
+	
+	// for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
+	UInt32	NumberInterleavedChannels() const	{ return IsInterleaved() ? mChannelsPerFrame : 1; }	
+	UInt32	NumberChannelStreams() const		{ return IsInterleaved() ? 1 : mChannelsPerFrame; }
+	UInt32	NumberChannels() const				{ return mChannelsPerFrame; }
+	UInt32	SampleWordSize() const				{ 
+			return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() :  0;
+	}
+
+	UInt32	FramesToBytes(UInt32 nframes) const	{ return nframes * mBytesPerFrame; }
+	UInt32	BytesToFrames(UInt32 nbytes) const	{
+		Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
+		return nbytes / mBytesPerFrame;
+	}
+	
+	bool	SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
+	{
+		return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
+	}
+	
+	bool	IdentifyCommonPCMFormat(CommonPCMFormat &outFormat, bool *outIsInterleaved=NULL) const
+	{	// return true if it's a valid PCM format.
+	
+		outFormat = kPCMFormatOther;
+		// trap out patently invalid formats.
+		if (mFormatID != kAudioFormatLinearPCM || mFramesPerPacket != 1 || mBytesPerFrame != mBytesPerPacket || mBitsPerChannel/8 > mBytesPerFrame || mChannelsPerFrame == 0)
+			return false;
+		bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
+		if (outIsInterleaved != NULL) *outIsInterleaved = interleaved;
+		unsigned wordsize = mBytesPerFrame;
+		if (interleaved) {
+			if (wordsize % mChannelsPerFrame != 0) return false;
+			wordsize /= mChannelsPerFrame;
+		}
+		
+		if ((mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian
+		&& wordsize * 8 == mBitsPerChannel) {
+			// packed and native endian, good
+			if (mFormatFlags & kLinearPCMFormatFlagIsFloat) {
+				// float: reject nonsense bits
+				if (mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask))
+					return false;
+				if (wordsize == 4)
+					outFormat = kPCMFormatFloat32;
+			} else if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) {
+				// signed int
+				unsigned fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
+				if (wordsize == 4 && fracbits == 24)
+					outFormat = kPCMFormatFixed824;
+				else if (wordsize == 2 && fracbits == 0)
+					outFormat = kPCMFormatInt16;
+			}
+		}
+		return true;
+	}
+
+	bool IsCommonFloat32(bool *outIsInterleaved=NULL) const {
+		CommonPCMFormat fmt;
+		return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat32;
+	}
+	bool IsCommonFixed824(bool *outIsInterleaved=NULL) const {
+		CommonPCMFormat fmt;
+		return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFixed824;
+	}
+	bool IsCommonInt16(bool *outIsInterleaved=NULL) const {
+		CommonPCMFormat fmt;
+		return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatInt16;
+	}
+	
+	// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+	//
+	//	manipulation
+	
+	void	SetCanonical(UInt32 nChannels, bool interleaved)
+				// note: leaves sample rate untouched
+	{
+		mFormatID = kAudioFormatLinearPCM;
+		int sampleSize = SizeOf32(AudioSampleType);
+		mFormatFlags = kAudioFormatFlagsCanonical;
+		mBitsPerChannel = 8 * sampleSize;
+		mChannelsPerFrame = nChannels;
+		mFramesPerPacket = 1;
+		if (interleaved)
+			mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
+		else {
+			mBytesPerPacket = mBytesPerFrame = sampleSize;
+			mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+		}
+	}
+	
+	bool	IsCanonical() const
+	{
+		if (mFormatID != kAudioFormatLinearPCM) return false;
+		UInt32 reqFormatFlags;
+		UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagsSampleFractionMask);
+		bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
+		unsigned sampleSize = SizeOf32(AudioSampleType);
+		reqFormatFlags = kAudioFormatFlagsCanonical;
+		UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize;
+
+		return ((mFormatFlags & flagsMask) == reqFormatFlags
+			&& mBitsPerChannel == 8 * sampleSize
+			&& mFramesPerPacket == 1
+			&& mBytesPerFrame == reqFrameSize
+			&& mBytesPerPacket == reqFrameSize);
+	}
+	
+	void	SetAUCanonical(UInt32 nChannels, bool interleaved)
+	{
+		mFormatID = kAudioFormatLinearPCM;
+#if CA_PREFER_FIXED_POINT
+		mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
+#else
+		mFormatFlags = kAudioFormatFlagsCanonical;
+#endif
+		mChannelsPerFrame = nChannels;
+		mFramesPerPacket = 1;
+		mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType);
+		if (interleaved)
+			mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType);
+		else {
+			mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType);
+			mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+		}
+	}
+	
+	void	ChangeNumberChannels(UInt32 nChannels, bool interleaved)
+				// alter an existing format
+	{
+		Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
+		UInt32 wordSize = SampleWordSize();	// get this before changing ANYTHING
+		if (wordSize == 0)
+			wordSize = (mBitsPerChannel + 7) / 8;
+		mChannelsPerFrame = nChannels;
+		mFramesPerPacket = 1;
+		if (interleaved) {
+			mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
+			mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved;
+		} else {
+			mBytesPerPacket = mBytesPerFrame = wordSize;
+			mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+		}
+	}
+	
+	// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+	//
+	//	other
+	
+	bool	IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const;
+	
+	void	Print() const {
+		Print (stdout);
+	}
+
+	void	Print(FILE* file) const {
+		PrintFormat (file, "", "AudioStreamBasicDescription:");	
+	}
+
+	void	PrintFormat(FILE *f, const char *indent, const char *name) const {
+		char buf[256];
+		fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf)));
+	}
+	
+	void	PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline
+		char buf[256];
+		fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf)));
+	}
+
+	char *	AsString(char *buf, size_t bufsize) const;
+
+	static void Print (const AudioStreamBasicDescription &inDesc) 
+	{ 
+		CAStreamBasicDescription desc(inDesc);
+		desc.Print ();
+	}
+	
+	OSStatus			Save(CFPropertyListRef *outData) const;
+		
+	OSStatus			Restore(CFPropertyListRef &inData);
+
+//	Operations
+	static bool			IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
+	static void			NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
+	static void			NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription);
+	static void			ResetFormat(AudioStreamBasicDescription& ioDescription);
+	static void			FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
+	static void			GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate = false);
+#if CoreAudio_Debug
+	static void			PrintToLog(const AudioStreamBasicDescription& inDesc);
+#endif
+};
+
+bool		operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
+bool		operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
+#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
+inline bool	operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
+inline bool	operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
+inline bool	operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
+inline bool	operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
+#endif
+
+bool SanityCheck(const AudioStreamBasicDescription& x);
+
+
+#endif // __CAStreamBasicDescription_h__
diff --git a/architecture/AU/PublicUtility/CAThreadSafeList.h b/architecture/AU/PublicUtility/CAThreadSafeList.h
new file mode 100644
index 0000000..c6f0486
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAThreadSafeList.h
@@ -0,0 +1,255 @@
+/*
+     File: CAThreadSafeList.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAThreadSafeList_h__
+#define __CAThreadSafeList_h__
+
+#include "CAAtomicStack.h"
+
+//  linked list of T's
+//	T must define operator ==
+template <class T>
+class TThreadSafeList {
+private:
+	enum EEventType { kAdd, kRemove, kClear };
+	class Node {
+	public:
+		Node *		mNext;
+		EEventType	mEventType;
+		T			mObject;
+		
+		Node *&	next() { return mNext; }
+	};
+
+public:
+	class iterator {
+	public:
+		iterator() { }
+		iterator(Node *n) : mNode(n) { }
+		
+		bool operator == (const iterator &other) const { return this->mNode == other.mNode; }
+		bool operator != (const iterator &other) const { return this->mNode != other.mNode; }
+		
+		T & operator * () const { return mNode->mObject; }
+		
+		iterator & operator ++ () { mNode = mNode->next(); return *this; }	// preincrement
+		iterator operator ++ (int) { iterator tmp = *this; mNode = mNode->next(); return tmp; } // postincrement
+		
+	private:
+		Node *		mNode;
+	};
+	
+	TThreadSafeList() { }
+	~TThreadSafeList()
+	{
+		mActiveList.free_all();
+		mPendingList.free_all();
+		mFreeList.free_all();
+	}
+	
+	// These may be called on any thread
+	
+	void	deferred_add(const T &obj)	// can be called on any thread
+	{
+		Node *node = AllocNode();
+		node->mEventType = kAdd;
+		node->mObject = obj;
+		mPendingList.push_atomic(node);
+		//mPendingList.dump("pending after add");
+	}
+	
+	void	deferred_remove(const T &obj)	// can be called on any thread
+	{
+		Node *node = AllocNode();
+		node->mEventType = kRemove;
+		node->mObject = obj;
+		mPendingList.push_atomic(node);
+		//mPendingList.dump("pending after remove");
+	}
+	
+	void	deferred_clear()					// can be called on any thread
+	{
+		Node *node = AllocNode();
+		node->mEventType = kClear;
+		mPendingList.push_atomic(node);
+	}
+	
+	// These must be called from only one thread
+	
+	void	update()		// must only be called from one thread
+	{
+		NodeStack reversed;
+		Node *event, *node, *next;
+		bool workDone = false;
+		
+		// reverse the events so they are in order
+		event = mPendingList.pop_all();
+		while (event != NULL) {
+			next = event->mNext;
+			reversed.push_NA(event);
+			event = next;
+			workDone = true;
+		}
+		if (workDone) {
+			//reversed.dump("pending popped");
+			//mActiveList.dump("active before update");
+			
+			// now process them
+			while ((event = reversed.pop_NA()) != NULL) {
+				switch (event->mEventType) {
+				case kAdd:
+					{
+						Node **pnode;
+						bool needToInsert = true;
+						for (pnode = mActiveList.phead(); *pnode != NULL; pnode = &node->mNext) {
+							node = *pnode;
+							if (node->mObject == event->mObject) {
+								//printf("already active!!!\n");
+								FreeNode(event);
+								needToInsert = false;
+								break;
+							}
+						}
+						if (needToInsert) {
+							// link the new event in at the end of the active list
+							*pnode = event;
+							event->mNext = NULL;
+						}
+					}
+					break;
+				case kRemove:
+					// find matching node in the active list, remove it
+					for (Node **pnode = mActiveList.phead(); *pnode != NULL; ) {
+						node = *pnode;
+						if (node->mObject == event->mObject) {
+							*pnode = node->mNext;	// remove from linked list
+							FreeNode(node);
+							break;
+						}
+						pnode = &node->mNext;
+					}
+					// dispose the request node
+					FreeNode(event);
+					break;
+				case kClear:
+					for (node = mActiveList.head(); node != NULL; ) {
+						next = node->mNext;
+						FreeNode(node);
+						node = next;
+					}
+					FreeNode(event);
+					break;
+				default:
+					//printf("invalid node type %d!\n", event->mEventType);
+					break;
+				}
+			}
+			//mActiveList.dump("active after update");
+		}
+	}
+	
+	iterator begin() const {
+		//mActiveList.dump("active at begin");
+		return iterator(mActiveList.head());
+	}
+	iterator end() const { return iterator(NULL); }
+
+	
+private:
+	Node *	AllocNode()
+	{
+		Node *node = mFreeList.pop_atomic();
+		if (node == NULL)
+			node = (Node *)CA_malloc(sizeof(Node));
+		return node;
+	}
+	
+	void	FreeNode(Node *node)
+	{
+		mFreeList.push_atomic(node);
+	}
+
+private:
+	class NodeStack : public TAtomicStack<Node> {
+	public:
+		void free_all() {
+			Node *node;
+			while ((node = this->pop_NA()) != NULL)
+				free(node);
+		}
+		
+		Node **	phead() { return &this->mHead; }
+		Node *	head() const { return this->mHead; }
+		
+		/*void	dump(char *label) const
+		{
+			char buf[1024];
+			int count = 0;
+			Node *node = mHead;
+			sprintf(buf, "%s:", label);
+			while (node != NULL) {
+				sprintf(buf+strlen(buf), " %p/%d", node, node->mEventType);
+				if (++count == 5) { sprintf(buf+strlen(buf), "..."); break; }
+				node = node->mNext;
+			}
+			puts(buf);
+		}*/
+		
+		/*int size() const
+		{
+			int count = 0;
+			for (Node *node = mHead; node != NULL; node = node->mNext)
+				++count;
+			return count;
+		}*/
+	};
+
+	NodeStack	mActiveList;	// what's actually in the container - only accessed on one thread
+	NodeStack	mPendingList;	// add or remove requests - threadsafe
+	NodeStack	mFreeList;		// free nodes for reuse - threadsafe
+};
+
+#endif // __CAThreadSafeList_h__
diff --git a/architecture/AU/PublicUtility/CAVectorUnit.cpp b/architecture/AU/PublicUtility/CAVectorUnit.cpp
new file mode 100644
index 0000000..5b6b5d6
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAVectorUnit.cpp
@@ -0,0 +1,191 @@
+/*
+     File: CAVectorUnit.cpp 
+ Abstract:  CAVectorUnit.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "CAVectorUnit.h"
+
+#if !TARGET_OS_WIN32
+	#include <sys/sysctl.h>
+#elif HAS_IPP
+	#include "ippdefs.h"
+	#include "ippcore.h"
+#endif
+
+int gCAVectorUnitType = kVecUninitialized;
+
+#if TARGET_OS_WIN32
+// Use cpuid to check if SSE2 is available.
+// Before calling this function make sure cpuid is available
+static SInt32 IsSSE2Available()
+{
+	int return_value;
+
+	{
+		int r_edx;
+		_asm
+		{
+			mov eax, 0x01
+			cpuid
+			mov r_edx, edx
+		}
+		return_value = (r_edx >> 26) & 0x1;
+	}
+	return return_value;
+}
+
+// Use cpuid to check if SSE3 is available.
+// Before calling this function make sure cpuid is available
+static SInt32 IsSSE3Available()
+{
+	SInt32 return_value;
+
+	{
+		SInt32 r_ecx;
+		_asm
+		{
+			mov eax, 0x01
+			cpuid
+			mov r_ecx, ecx
+		}
+		return_value = r_ecx & 0x1;
+	}
+	return return_value;
+}
+
+// Return true if the cpuid instruction is available.
+// The cpuid instruction is available if bit 21 in the EFLAGS register can be changed
+// This function may not work on Intel CPUs prior to Pentium (didn't test)
+static bool IsCpuidAvailable()
+{
+	SInt32 return_value = 0x0;
+	_asm{
+		pushfd    ;			//push original EFLAGS 
+		pop eax   ;			//get original EFLAGS 
+		mov ecx, eax   ;	//save original EFLAGS 
+		xor eax, 200000h  ; //flip ID bit in EFLAGS 
+		push eax   ;		//save new EFLAGS value on stack 
+		popfd    ;			//replace current EFLAGS value 
+		pushfd    ;			//get new EFLAGS 
+		pop eax   ;			//store new EFLAGS in EAX 
+		xor eax, ecx   ;	 
+		je end_cpuid_identify  ; //can't toggle ID bit
+		mov return_value, 0x1;	
+end_cpuid_identify:
+		nop;
+		}
+		return return_value;
+}
+
+#endif
+
+SInt32	CAVectorUnit_Examine()
+{
+	int result = kVecNone;
+	
+#if TARGET_OS_WIN32
+#if HAS_IPP	
+	// Initialize the static IPP library! This needs to be done before
+	// any IPP function calls, otherwise we may have a performance penalty
+	int status = ippStaticInit();
+	if ( status == ippStsNonIntelCpu )
+	{
+		IppCpuType cpuType = ippGetCpuType();
+		if ( cpuType >= ippCpuSSE || cpuType <= ippCpuSSE42 )
+			ippStaticInitCpu( cpuType );
+	}
+#endif
+	{
+		// On Windows we use cpuid to detect the vector unit because it works on Intel and AMD.
+		// The IPP library does not detect SSE on AMD processors.
+		if (IsCpuidAvailable())
+		{
+			if(IsSSE3Available())
+			{
+				result = kVecSSE3;
+			}
+			else if(IsSSE2Available())
+			{
+				result = kVecSSE2;
+			}
+		}
+	}
+#elif TARGET_OS_MAC
+#if DEBUG
+	if (getenv("CA_NoVector")) {
+		fprintf(stderr, "CA_NoVector set; Vector unit optimized routines will be bypassed\n");
+		return result;
+	} 
+	else
+#endif
+	{
+	#if (TARGET_CPU_PPC || TARGET_CPU_PPC64)
+		int sels[2] = { CTL_HW, HW_VECTORUNIT };
+		int vType = 0; //0 == scalar only
+		size_t length = sizeof(vType);
+		int error = sysctl(sels, 2, &vType, &length, NULL, 0);
+		if (!error && vType > 0)
+			result = kVecAltivec;
+	#elif (TARGET_CPU_X86 || TARGET_CPU_X86_64)
+		int answer = 0;
+		size_t length = sizeof(answer);
+		int error = sysctlbyname("hw.optional.sse3", &answer, &length, NULL, 0);
+		if (!error && answer)
+			result = kVecSSE3;
+		else {
+			answer = 0;
+			length = sizeof(answer);
+			error = sysctlbyname("hw.optional.sse2", &answer, &length, NULL, 0);
+			if (!error && answer)
+				result = kVecSSE2;
+		}
+	#elif (TARGET_CPU_ARM) && defined(_ARM_ARCH_7)
+		result = kVecNeon;
+	#endif
+	}
+#endif
+	gCAVectorUnitType = result;
+	return result;
+}
+
diff --git a/architecture/AU/PublicUtility/CAVectorUnit.h b/architecture/AU/PublicUtility/CAVectorUnit.h
new file mode 100644
index 0000000..9e8e8c8
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAVectorUnit.h
@@ -0,0 +1,100 @@
+/*
+     File: CAVectorUnit.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAVectorUnit_h__
+#define __CAVectorUnit_h__
+
+#include <TargetConditionals.h>
+#include "CAVectorUnitTypes.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreFoundation/CFBase.h>
+#else
+	#include "CFBase.h"
+#endif
+
+// Unify checks for vector units.
+// Allow setting an environment variable "CA_NoVector" to turn off vectorized code at runtime (very useful for performance testing).
+
+extern int gCAVectorUnitType;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern SInt32 CAVectorUnit_Examine();	// expensive. use GetType() for lazy initialization and caching.
+
+static inline SInt32 CAVectorUnit_GetType()
+{
+	int x = gCAVectorUnitType;
+	return (x != kVecUninitialized) ? x : CAVectorUnit_Examine();
+}
+
+static inline Boolean CAVectorUnit_HasVectorUnit()
+{
+	return CAVectorUnit_GetType() > kVecNone;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+class CAVectorUnit {
+public:
+	static SInt32		GetVectorUnitType() { return CAVectorUnit_GetType(); }
+	static bool			HasVectorUnit() { return GetVectorUnitType() > kVecNone; }
+	static bool			HasAltivec() { return GetVectorUnitType() == kVecAltivec; }
+	static bool			HasSSE2() { return GetVectorUnitType() >= kVecSSE2; }
+	static bool			HasSSE3() { return GetVectorUnitType() == kVecSSE3; }
+	static bool			HasNeon() { return GetVectorUnitType() == kVecNeon; }
+};
+#endif
+
+#endif // __CAVectorUnit_h__
diff --git a/architecture/AU/PublicUtility/CAVectorUnitTypes.h b/architecture/AU/PublicUtility/CAVectorUnitTypes.h
new file mode 100644
index 0000000..055d1f8
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAVectorUnitTypes.h
@@ -0,0 +1,59 @@
+/*
+     File: CAVectorUnitTypes.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAVectorUnitTypes_h__
+#define __CAVectorUnitTypes_h__
+
+enum {
+	kVecUninitialized = -1,
+	kVecNone = 0,
+	kVecAltivec = 1,
+	kVecSSE2 = 100,
+	kVecSSE3 = 101,
+	kVecNeon = 200
+};
+
+#endif
diff --git a/architecture/AU/PublicUtility/CAXException.cpp b/architecture/AU/PublicUtility/CAXException.cpp
new file mode 100644
index 0000000..18b7601
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAXException.cpp
@@ -0,0 +1,49 @@
+/*
+     File: CAXException.cpp 
+ Abstract:  CAXException.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#include "CAXException.h"
+
+CAXException::WarningHandler CAXException::sWarningHandler = NULL;
diff --git a/architecture/AU/PublicUtility/CAXException.h b/architecture/AU/PublicUtility/CAXException.h
new file mode 100644
index 0000000..369d93d
--- /dev/null
+++ b/architecture/AU/PublicUtility/CAXException.h
@@ -0,0 +1,338 @@
+/*
+     File: CAXException.h 
+ Abstract:  Part of CoreAudio Utility Classes  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __CAXException_h__
+#define __CAXException_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+	#include <CoreFoundation/CoreFoundation.h>
+#else
+	#include <ConditionalMacros.h>
+	#include <CoreFoundation.h>
+#endif
+#include "CADebugMacros.h"
+#include <ctype.h>
+//#include <stdio.h>
+#include <string.h>
+
+
+class CAX4CCString {
+public:
+	CAX4CCString(OSStatus error) {
+		// see if it appears to be a 4-char-code
+		char *str = mStr;
+		*(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error);
+		if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
+			str[0] = str[5] = '\'';
+			str[6] = '\0';
+		} else if (error > -200000 && error < 200000)
+			// no, format it as an integer
+			sprintf(str, "%d", (int)error);
+		else
+			sprintf(str, "0x%x", (int)error);
+	}
+	const char *get() const { return mStr; }
+	operator const char *() const { return mStr; }
+private:
+	char mStr[16];
+};
+
+// An extended exception class that includes the name of the failed operation
+class CAXException {
+public:
+	CAXException(const char *operation, OSStatus err) :
+		mError(err)
+		{
+			if (operation == NULL)
+				mOperation[0] = '\0';
+			else if (strlen(operation) >= sizeof(mOperation)) {
+				memcpy(mOperation, operation, sizeof(mOperation) - 1);
+				mOperation[sizeof(mOperation) - 1] = '\0';
+			} else
+
+			strlcpy(mOperation, operation, sizeof(mOperation));
+		}
+	
+	char *FormatError(char *str) const
+	{
+		return FormatError(str, mError);
+	}
+	
+	char				mOperation[256];
+	const OSStatus		mError;
+	
+	// -------------------------------------------------
+	
+	typedef void (*WarningHandler)(const char *msg, OSStatus err);
+	
+	static char *FormatError(char *str, OSStatus error)
+	{
+		strcpy(str, CAX4CCString(error));
+		return str;
+	}
+	
+	static void Warning(const char *s, OSStatus error)
+	{
+		if (sWarningHandler)
+			(*sWarningHandler)(s, error);
+	}
+	
+	static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; }
+private:
+	static WarningHandler	sWarningHandler;
+};
+
+#if	DEBUG || CoreAudio_Debug
+	#define XThrowIfError(error, operation)										\
+		do {																	\
+			OSStatus __err = error;												\
+			if (__err) {														\
+				DebugMessageN2("about to throw %s: %s", CAX4CCString(__err).get(), operation);\
+				__THROW_STOP;															\
+				throw CAXException(operation, __err);							\
+			}																	\
+		} while (0)
+
+	#define XThrowIf(condition, error, operation)								\
+		do {																	\
+			if (condition) {													\
+				OSStatus __err = error;											\
+				DebugMessageN2("about to throw %s: %s", CAX4CCString(__err).get(), operation);\
+				__THROW_STOP;															\
+				throw CAXException(operation, __err);							\
+			}																	\
+		} while (0)
+
+	#define XRequireNoError(error, label)										\
+		do {																	\
+			OSStatus __err = error;												\
+			if (__err) {														\
+				DebugMessageN2("about to throw %s: %s", CAX4CCString(__err).get(), #error);\
+				STOP;															\
+				goto label;														\
+			}																	\
+		} while (0)
+	
+	#define XAssert(assertion)													\
+		do {																	\
+			if (!(assertion)) {													\
+				DebugMessageN3("[%s, %d] error: failed assertion: %s", __FILE__, __LINE__, #assertion);		\
+				__ASSERT_STOP;															\
+			}																	\
+		} while (0)
+	
+	#define XAssertNoError(error)												\
+		do {																	\
+			OSStatus __err = error;												\
+			if (__err) {														\
+				DebugMessageN2("error %s: %s", CAX4CCString(__err).get(), #error);\
+				STOP;															\
+			}																	\
+		} while (0)
+
+	#define ca_require_noerr(errorCode, exceptionLabel)							\
+		do																		\
+		{																		\
+			int evalOnceErrorCode = (errorCode);								\
+			if ( __builtin_expect(0 != evalOnceErrorCode, 0) )					\
+			{																	\
+				DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d",	\
+					#errorCode,	evalOnceErrorCode,		 						\
+					#exceptionLabel,											\
+					__FILE__,													\
+					__LINE__);													\
+				goto exceptionLabel;											\
+			}																	\
+		} while ( 0 )
+
+	#define ca_verify_noerr(errorCode)											\
+		do																		\
+		{																		\
+			int evalOnceErrorCode = (errorCode);								\
+			if ( __builtin_expect(0 != evalOnceErrorCode, 0) )					\
+			{																	\
+				DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d",				\
+					#errorCode,	evalOnceErrorCode,								\
+					__FILE__,													\
+					__LINE__);													\
+			}																	\
+		} while ( 0 )
+
+	#define ca_debug_string(message)											\
+		do																		\
+		{																		\
+			DebugMessageN3("ca_debug_string: %s %s:%d",							\
+				message,														\
+				__FILE__,														\
+				__LINE__);														\
+		} while ( 0 )
+
+
+	#define ca_verify(assertion)												\
+		do																		\
+		{																		\
+			if ( __builtin_expect(!(assertion), 0) )							\
+			{																	\
+				DebugMessageN3("ca_verify: %s %s:%d",							\
+					#assertion,													\
+					__FILE__,													\
+					__LINE__);													\
+			}																	\
+		} while ( 0 )
+
+	#define ca_require(assertion, exceptionLabel)								\
+		do																		\
+		{																		\
+			if ( __builtin_expect(!(assertion), 0) )							\
+			{																	\
+				DebugMessageN4("ca_require: %s %s %s:%d",						\
+					#assertion,													\
+					#exceptionLabel,											\
+					__FILE__,													\
+					__LINE__);													\
+				goto exceptionLabel;											\
+			}																	\
+		} while ( 0 )
+
+   #define ca_check(assertion)													\
+      do																		\
+      {																			\
+          if ( __builtin_expect(!(assertion), 0) )								\
+          {																		\
+              DebugMessageN3("ca_check: %s %s:%d",							\
+                  #assertion,													\
+                  __FILE__,														\
+                  __LINE__);													\
+          }																		\
+      } while ( 0 )
+		
+#else
+	#define XThrowIfError(error, operation)										\
+		do {																	\
+			OSStatus __err = error;												\
+			if (__err) {														\
+				throw CAXException(operation, __err);							\
+			}																	\
+		} while (0)
+
+	#define XThrowIf(condition, error, operation)								\
+		do {																	\
+			if (condition) {													\
+				OSStatus __err = error;											\
+				throw CAXException(operation, __err);							\
+			}																	\
+		} while (0)
+
+	#define XRequireNoError(error, label)										\
+		do {																	\
+			OSStatus __err = error;												\
+			if (__err) {														\
+				goto label;														\
+			}																	\
+		} while (0)
+
+	#define XAssert(assertion)													\
+		do {																	\
+			if (!(assertion)) {													\
+			}																	\
+		} while (0)
+
+	#define XAssertNoError(error)												\
+		do {																	\
+			/*OSStatus __err =*/ error;											\
+		} while (0)
+
+	#define ca_require_noerr(errorCode, exceptionLabel)							\
+		do																		\
+		{																		\
+			if ( __builtin_expect(0 != (errorCode), 0) )						\
+			{																	\
+				goto exceptionLabel;											\
+			}																	\
+		} while ( 0 )
+
+	#define ca_verify_noerr(errorCode)											\
+		do																		\
+		{																		\
+			if ( 0 != (errorCode) )												\
+			{																	\
+			}																	\
+		} while ( 0 )
+
+	#define ca_debug_string(message)
+
+	#define ca_verify(assertion)												\
+		do																		\
+		{																		\
+			if ( !(assertion) )													\
+			{																	\
+			}																	\
+		} while ( 0 )
+
+	#define ca_require(assertion, exceptionLabel)								\
+		do																		\
+		{																		\
+			if ( __builtin_expect(!(assertion), 0) )							\
+			{																	\
+				goto exceptionLabel;											\
+			}																	\
+		} while ( 0 )
+
+   #define ca_check(assertion)													\
+		do																		\
+		{																		\
+			if ( !(assertion) )													\
+			{																	\
+			}																	\
+		} while ( 0 )
+
+
+#endif
+
+#define XThrow(error, operation) XThrowIf(true, error, operation)
+#define XThrowIfErr(error) XThrowIfError(error, #error)
+
+#endif // __CAXException_h__
diff --git a/architecture/AU/SectionPatternLight.tiff b/architecture/AU/SectionPatternLight.tiff
new file mode 100644
index 0000000..5025ccb
Binary files /dev/null and b/architecture/AU/SectionPatternLight.tiff differ
diff --git a/architecture/AU/Source/AUSource/FaustAU.h b/architecture/AU/Source/AUSource/FaustAU.h
new file mode 100644
index 0000000..2f31ff1
--- /dev/null
+++ b/architecture/AU/Source/AUSource/FaustAU.h
@@ -0,0 +1,28 @@
+//
+//  FaustAUEffect.h
+//  FaustAU
+//
+//  Created by Reza Payami on 11/1/13.
+//
+//
+
+#ifndef FaustAU_FaustAU_h
+#define FaustAU_FaustAU_h
+
+#include <string>
+#include <vector>
+
+#include "faust/audio/dsp.h"
+#include "faust/au/AUUI.h"
+
+#define FaustAU _FaustAUClass_
+
+enum
+{
+    kAudioUnitCustomProperty_dspUI = 65536
+};
+
+#define CUSTOM_VIEW_BUNDLE_ID "FaustAUCustomView"
+#define CUSTOM_VIEW_BUNDLE_NAME "com.grame.audiounit.FaustAU"
+
+#endif
diff --git a/architecture/AU/Source/AUSource/FaustAU.r b/architecture/AU/Source/AUSource/FaustAU.r
new file mode 100644
index 0000000..daa42c2
--- /dev/null
+++ b/architecture/AU/Source/AUSource/FaustAU.r
@@ -0,0 +1,153 @@
+/*
+ File: FaustAU.r
+ Abstract:  FaustAU.r
+ Version: 1.01
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ 
+ */
+#include <AudioUnit/AudioUnit.r>
+
+#include "FaustAUVersion.h"
+
+#define UseExtendedThingResource 1
+
+#include <CoreServices/CoreServices.r>
+
+// Note that resource IDs must be spaced 2 apart for the 'STR ' name and description
+#define kAudioUnitResID_FaustAU				1000
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FaustAU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#define RES_ID			kAudioUnitResID_FaustAU
+
+//#define COMP_TYPE   kAudioUnitType_Effect
+//#define COMP_TYPE		kAudioUnitType_MusicDevice
+
+#define COMP_TYPE		_COMPTYPE_
+
+#define COMP_SUBTYPE	FaustAU_COMP_SUBTYPE
+#define COMP_MANUF		FaustAU_COMP_MANF
+
+#define VERSION			kFaustAUVersion
+#define NAME			"_NAME_"
+#define DESCRIPTION		"_DESC_"
+#define ENTRY_POINT		"FaustAUEntry"
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+// this is a define used to indicate that a component has no static data that would mean
+// that no more than one instance could be open at a time - never been true for AUs
+#ifndef cmpThreadSafeOnMac
+#define cmpThreadSafeOnMac	0x10000000
+#endif
+
+resource 'STR ' (RES_ID, purgeable) {
+	NAME
+};
+
+resource 'STR ' (RES_ID + 1, purgeable) {
+	DESCRIPTION
+};
+
+resource 'dlle' (RES_ID) {
+	ENTRY_POINT
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+resource 'thng' (RES_ID, NAME) {
+	COMP_TYPE,
+	COMP_SUBTYPE,
+	COMP_MANUF,
+	0, 0, 0, 0,								//	no 68K
+	'STR ',	RES_ID,
+	'STR ',	RES_ID + 1,
+	0,	0,			/* icon */
+	VERSION,
+	componentHasMultiplePlatforms | componentDoAutoVersion,
+	0,
+	{
+        #if defined(ppc_YES)
+        cmpThreadSafeOnMac,
+        'dlle', RES_ID, platformPowerPCNativeEntryPoint
+        #define NeedLeadingComma 1
+        #endif
+        #if defined(ppc64_YES)
+		#if defined(NeedLeadingComma)
+        ,
+		#endif
+        cmpThreadSafeOnMac,
+        'dlle', RES_ID, platformPowerPC64NativeEntryPoint
+        #define NeedLeadingComma 1
+        #endif
+        #if defined(i386_YES)
+		#if defined(NeedLeadingComma)
+        ,
+		#endif
+        cmpThreadSafeOnMac,
+        'dlle', RES_ID, platformIA32NativeEntryPoint
+        #define NeedLeadingComma 1
+        #endif
+        #if defined(x86_64_YES)
+		#if defined(NeedLeadingComma)
+        ,
+		#endif
+        cmpThreadSafeOnMac,
+        'dlle', RES_ID, 8
+        #define NeedLeadingComma 1
+        #endif
+	}
+};
+
+
+#undef RES_ID
+#undef COMP_TYPE
+#undef COMP_SUBTYPE
+#undef COMP_MANUF
+#undef VERSION
+#undef NAME
+#undef DESCRIPTION
+#undef ENTRY_POINT
+#undef NeedLeadingComma
+
diff --git a/architecture/AU/Source/AUSource/FaustAUVersion.h b/architecture/AU/Source/AUSource/FaustAUVersion.h
new file mode 100644
index 0000000..3c9877a
--- /dev/null
+++ b/architecture/AU/Source/AUSource/FaustAUVersion.h
@@ -0,0 +1,64 @@
+/*
+     File: FaustAUVersion.h
+ Abstract: FaustAUVersion.h
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+#ifndef __FaustAUVersion_h__
+#define __FaustAUVersion_h__
+
+
+#ifdef DEBUG
+	#define kFaustAUVersion 0xFFFFFFFF
+#else
+	#define kFaustAUVersion 0x00010000	
+#endif
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
+#define FaustAU_TYPE            kAudioUnitType_Effect
+#define FaustAU_COMP_SUBTYPE	'_STYP_'
+#define FaustAU_COMP_MANF		'_MANF_'
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
+
+#endif
+
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.h b/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.h
new file mode 100644
index 0000000..8e4a5f5
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.h
@@ -0,0 +1,18 @@
+#import <Foundation/Foundation.h>
+
+#include "FaustAU.h"
+
+ at interface FaustAU_Bargraph : NSSlider
+{
+    NSTextField* _labelTextField;
+    NSTextField* _valueTextField;
+}
+
+- (FaustAU_Bargraph*)init :(NSRect) frame :(auBargraph*)fBargraph :(int)controlId;
+
+ at property (nonatomic, strong) NSTextField* labelTextField;
+ at property (nonatomic, strong) NSTextField* valueTextField;
+
+- (void)setDoubleValue:(double)aDouble;
+
+ at end
\ No newline at end of file
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.m b/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.m
new file mode 100644
index 0000000..a2a128c
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.m
@@ -0,0 +1,21 @@
+#import "FaustAU_Bargraph.h"
+
+ at implementation FaustAU_Bargraph
+
+ at synthesize labelTextField =_labelTextField;
+ at synthesize valueTextField =_valueTextField;
+
+
+- (FaustAU_Bargraph*)init :(NSRect)frame :(auBargraph*)fBargraph :(int)controlId {
+    return self;
+}
+
+- (void)setDoubleValue:(double)aDouble
+{
+    [super setDoubleValue: aDouble];
+    NSString *stringValue = [NSString stringWithFormat:@"%9.2f", aDouble];
+    [_valueTextField setStringValue:stringValue];
+}
+
+ at end
+
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Button.h b/architecture/AU/Source/CocoaUI/FaustAU_Button.h
new file mode 100644
index 0000000..2b2b4d1
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Button.h
@@ -0,0 +1,20 @@
+#import <Foundation/Foundation.h>
+
+#include "FaustAU.h"
+
+ at protocol FaustAU_ButtonProtocol <NSObject>
+- (void)buttonPushed:(id)sender;
+ at end
+
+
+ at interface FaustAU_Button : NSButton
+{
+ at public
+    bool buttonState;
+    id <FaustAU_ButtonProtocol> delegate;
+}
+
+- (FaustAU_Button*)init :(NSRect) frame :(auButton*)fButton :(int)controlId;
+- (void)mouseDown:(NSEvent *)theEvent;
+- (void)mouseUp:(NSEvent *)theEvent;
+ at end
\ No newline at end of file
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Button.m b/architecture/AU/Source/CocoaUI/FaustAU_Button.m
new file mode 100644
index 0000000..53ec48b
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Button.m
@@ -0,0 +1,56 @@
+#import "FaustAU_Button.h"
+
+ at implementation FaustAU_Button
+
+- (FaustAU_Button*)init :(NSRect)frame :(auButton*)fButton :(int)controlId {
+    
+    [self initWithFrame:frame];
+    
+    buttonState = 1;
+    
+    [self setTitle:[[NSString alloc] initWithCString:fButton->fLabel.c_str() encoding:NSUTF8StringEncoding]]; //TODO
+    
+    [self setButtonType:NSMomentaryPushInButton];
+    [self setBezelStyle:NSRoundedBezelStyle];
+    
+    NSString *identifier = [NSString stringWithFormat:@"%d",controlId]; 
+    [self setIdentifier: identifier];
+    
+    return self;
+}
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+    [self setNeedsDisplay:YES];
+    buttonState = 0;
+    [self setNeedsDisplay:TRUE];
+    [delegate buttonPushed: self];
+    
+}
+
+- (void)drawRect:(NSRect)rect {
+    if (buttonState)
+    {
+        [[NSColor lightGrayColor] set];
+    }
+    else
+    {
+        [[NSColor darkGrayColor] set];
+    }
+    
+    NSRectFill(rect);
+    [super drawRect: rect];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+    buttonState = 1;
+    [delegate buttonPushed: self];
+    [self setNeedsDisplay:TRUE];
+}
+ at end
+
+
+
+
+
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_CustomView.h b/architecture/AU/Source/CocoaUI/FaustAU_CustomView.h
new file mode 100644
index 0000000..733c2de
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_CustomView.h
@@ -0,0 +1,87 @@
+/*
+     File: FaustAU_CustomView.h 
+ Abstract: FaustAU_CustomView.h  
+  Version: 1.01 
+  
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple 
+ Inc. ("Apple") in consideration of your agreement to the following 
+ terms, and your use, installation, modification or redistribution of 
+ this Apple software constitutes acceptance of these terms.  If you do 
+ not agree with these terms, please do not use, install, modify or 
+ redistribute this Apple software. 
+  
+ In consideration of your agreement to abide by the following terms, and 
+ subject to these terms, Apple grants you a personal, non-exclusive 
+ license, under Apple's copyrights in this original Apple software (the 
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple 
+ Software, with or without modifications, in source and/or binary forms; 
+ provided that if you redistribute the Apple Software in its entirety and 
+ without modifications, you must retain this notice and the following 
+ text and disclaimers in all such redistributions of the Apple Software. 
+ Neither the name, trademarks, service marks or logos of Apple Inc. may 
+ be used to endorse or promote products derived from the Apple Software 
+ without specific prior written permission from Apple.  Except as 
+ expressly stated in this notice, no other rights or licenses, express or 
+ implied, are granted by Apple herein, including but not limited to any 
+ patent rights that may be infringed by your derivative works or by other 
+ works in which the Apple Software may be incorporated. 
+  
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE 
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
+  
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 
+ POSSIBILITY OF SUCH DAMAGE. 
+  
+ Copyright (C) 2012 Apple Inc. All Rights Reserved. 
+  
+*/
+
+#import <Cocoa/Cocoa.h>
+#import <AudioUnit/AudioUnit.h>
+#import <AudioToolbox/AudioToolbox.h>
+
+#import <FaustAU_Slider.h>
+#import <FaustAU_Knob.h>
+#import <FaustAU_Button.h>
+#import <FaustAU_Bargraph.h>
+
+//TODO
+#define MAX_CONTROLS 1000
+
+#include <map>
+
+
+ at interface FaustAU_CustomView : NSView <FaustAU_KnobProtocol, FaustAU_ButtonProtocol>
+{	
+    AudioUnit mAU;
+    NSTimer* timer;
+    bool monitor;
+    bool usesBargraphs;
+    NSTextField* paramValues[MAX_CONTROLS];
+    AUEventListenerRef mAUEventListener;
+    std::map <int, NSView*> viewMap;
+    std::map <NSButton*, NSBox*> showHideMap;
+}
+
+- (void)setAU:(AudioUnit)inAU;
+- (void)paramChanged:(id)sender;
+
+- (void)update;
+
+- (void)buttonPushed:(id)sender;
+- (void)knobUpdatedWithIndex:(int)index
+                   withValue:(double)aDouble
+                   withObject:(id)object;
+- (void)xmlButtonPushed:(id)sender;
+- (void)monitorButtonPushed:(id)sender;
+
+ at end
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_CustomView.m b/architecture/AU/Source/CocoaUI/FaustAU_CustomView.m
new file mode 100644
index 0000000..4259bb6
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_CustomView.m
@@ -0,0 +1,883 @@
+
+#import "FaustAU_CustomView.h"
+
+#include "FaustAU.h"
+
+ at implementation FaustAU_CustomView
+
+// This listener responds to parameter changes, gestures, and property notifications
+void eventListenerDispatcher (void *inRefCon, void *inObject, const AudioUnitEvent *inEvent, UInt64 inHostTime, Float32 inValue)
+{
+	FaustAU_CustomView *SELF = (FaustAU_CustomView *)inRefCon;
+	[SELF eventListener:inObject event: inEvent value: inValue];
+}
+
+void addParamListener (AUEventListenerRef listener, void* refCon, AudioUnitEvent *inEvent)
+{
+	inEvent->mEventType = kAudioUnitEvent_BeginParameterChangeGesture;
+	verify_noerr ( AUEventListenerAddEventType(	listener, refCon, inEvent));
+	
+	inEvent->mEventType = kAudioUnitEvent_EndParameterChangeGesture;
+	verify_noerr ( AUEventListenerAddEventType(	listener, refCon, inEvent));
+	
+	inEvent->mEventType = kAudioUnitEvent_ParameterValueChange;
+	verify_noerr ( AUEventListenerAddEventType(	listener, refCon, inEvent));
+}
+
+- (void)addListeners
+{
+    auUI* dspUI;
+    
+    if (mAU) {
+		verify_noerr( AUEventListenerCreate(eventListenerDispatcher, self,
+											CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0.05, 0.05,
+											&mAUEventListener));
+        dspUI = [self dspUI];
+        
+		//add listeners
+        AudioUnitEvent auEvent;
+        for (int i = 0; i < dspUI->fUITable.size(); i++)
+            if (dspUI->fUITable[i] && dspUI->fUITable[i]->fZone)
+            {
+                if (dynamic_cast<auButton*>(dspUI->fUITable[i])) {
+                }
+                else if (dynamic_cast<auToggleButton*>(dspUI->fUITable[i])) {
+                }
+                else if (dynamic_cast<auCheckButton*>(dspUI->fUITable[i])) {
+                }
+                else {
+                    AudioUnitParameter parameter =
+                    {
+                        mAU,
+                        i,
+                        kAudioUnitScope_Global,
+                        0 // mElement
+                    };
+                    auEvent.mArgument.mParameter = parameter;
+                    addParamListener (mAUEventListener, self, &auEvent);                }
+            }
+        
+		/* Add a listener for the changes in our custom property */
+		/* The Audio unit will send a property change when the unit is intialized */
+		auEvent.mEventType = kAudioUnitEvent_PropertyChange;
+		auEvent.mArgument.mProperty.mAudioUnit = mAU;
+		auEvent.mArgument.mProperty.mPropertyID = kAudioUnitCustomProperty_dspUI;
+		auEvent.mArgument.mProperty.mScope = kAudioUnitScope_Global;
+		auEvent.mArgument.mProperty.mElement = 0;
+		verify_noerr (AUEventListenerAddEventType (mAUEventListener, self, &auEvent));
+	}
+	
+}
+
+- (void)removeListeners
+{
+	if (mAUEventListener) verify_noerr (AUListenerDispose(mAUEventListener));
+	mAUEventListener = NULL;
+	mAU = NULL;
+}
+
+- (auUI*) dspUI
+{
+    auUI* dspUI;
+    
+    UInt32 dataSize = sizeof(auUI*);
+    
+    ComponentResult result = AudioUnitGetProperty(mAU,
+                                                  (AudioUnitPropertyID)kAudioUnitCustomProperty_dspUI,
+                                                  kAudioUnitScope_Global,
+                                                  (AudioUnitElement)0, //inElement
+                                                  (void*)&dspUI,
+                                                  &dataSize);
+    return dspUI;
+}
+
+/*
+ - (BOOL)isFlipped {
+     return YES;
+ }
+*/
+
+- (void)dealloc {
+    
+     [self unsetTimer];
+     
+     [self removeListeners];
+     
+     [[NSNotificationCenter defaultCenter] removeObserver: self];
+    
+     [super dealloc];
+}
+
+- (NSButton*)addButton:(NSBox*) nsBox :(auButton*)fButton :(int)controlId :(NSPoint&) origin :(NSSize&) size :(bool)isVerticalBox
+{
+    int width = 100;
+    int height = 35;
+    
+    FaustAU_Button* button = [[FaustAU_Button alloc] init :NSMakeRect(origin.x, origin.y, width, height) :fButton :controlId];
+    
+    button->delegate = self;
+    
+    [nsBox addSubview:button];
+    
+    if (isVerticalBox)
+    {
+        origin.y += height;
+        size.height += height;
+        if (size.width < width)
+            size.width = width;
+    }
+    else
+    {
+        origin.x += width;
+        size.width += width;
+        if (size.height < height)
+            size.height = height;
+    }
+    
+    return button;
+    
+}
+
+- (NSButton*)addCheckButton:(NSBox*) nsBox :(auCheckButton*)fButton :(int)controlId :(NSPoint&) origin :(NSSize&) size :(bool)isVerticalBox
+{
+    int width = 100;
+    int height = 35;
+    
+    NSRect frame = NSMakeRect(origin.x, origin.y, width, height);
+    
+    NSButton* button = [[NSButton alloc] initWithFrame:frame ];
+    
+    [button setTitle:[[NSString alloc] initWithCString:fButton->fLabel.c_str() encoding:NSUTF8StringEncoding]];
+    
+    [button setButtonType:NSSwitchButton];
+    [button setBezelStyle:NSRoundedBezelStyle];
+    
+    NSString *identifier = [NSString stringWithFormat:@"%d",controlId];
+    [button setIdentifier: identifier];
+    
+    [button setTarget:self];
+    [button setAction:@selector(paramChanged:)];
+    
+    [nsBox addSubview:button];
+    
+    if (isVerticalBox)
+    {
+        origin.y += height;
+        size.height += height;
+        if (size.width < width)
+            size.width = width;
+    }
+    else
+    {
+        origin.x += width;
+        size.width += width;
+        if (size.height < height)
+            size.height = height;
+    }
+    
+    return button;
+    
+}
+
+
+- (NSTextField*)addTextField:(NSBox*) nsBox :(const char*)label :(int)controlId :(NSPoint&) origin :(bool)isVerticalBox
+{
+    int width = 100;
+    int height = 35;
+    
+    NSTextField* textField;
+    
+    textField = [[NSTextField alloc] initWithFrame:NSMakeRect(origin.x, origin.y + 2 , width, height)];
+    
+    [textField setBezeled:NO];
+    [textField setDrawsBackground:NO];
+    [textField setEditable:NO];
+    [textField setSelectable:NO];
+    [textField setIdentifier: @"200"]; //TODO
+    [textField setStringValue:[[NSString alloc] initWithCString:label encoding:NSUTF8StringEncoding]];
+    
+    [nsBox addSubview:textField];
+    
+    return textField;
+    
+}
+
+
+- (FaustAU_Slider*)addSlider:(NSBox*) nsBox :(auSlider*)fSlider :(int)controlId :(NSPoint&) origin :(NSSize&) size :(bool)isVerticalBox
+{
+    int labelWidth = 0;
+    
+    NSTextField* labelTextField = NULL;
+    
+    if (strcmp(fSlider->fLabel.c_str(), "")) {
+    
+        labelTextField = [self addTextField :nsBox :fSlider->fLabel.c_str() :200 :origin :isVerticalBox];
+        [labelTextField setAlignment: NSRightTextAlignment];
+    
+        labelWidth = 100;
+    }
+    
+    int width;
+    int height;
+    float value;
+    
+    if (fSlider->fIsVertical) {
+        width = 15;
+        height = 100;
+    }
+    else{
+        width = 300;
+        height = 45;
+    }
+    
+    
+    FaustAU_Slider* slider;
+    slider = [[FaustAU_Slider alloc] initWithFrame:NSMakeRect(origin.x + labelWidth, origin.y, width, height)];
+    [slider setMinValue:fSlider->fMin];
+    [slider setMaxValue:fSlider->fMax];
+    
+    AudioUnitGetParameter(mAU, controlId, kAudioUnitScope_Global, 0, &value);
+    [slider setDoubleValue:value];
+    
+    //TODO [slider setNumberOfTickMarks: (fSlider->fMax - fSlider->fMin) / fSlider->fStep];
+    NSString *identifier = [NSString stringWithFormat:@"%d",controlId];
+    [slider setIdentifier: identifier];
+    
+    [slider setContinuous:YES];
+    
+    [slider setAction:@selector(paramChanged:)];
+    [slider setTarget:self];
+    
+    [nsBox addSubview:slider];
+    
+    AudioUnitGetParameter(mAU, controlId, kAudioUnitScope_Global, 0, &value);
+    char valueString[100];
+    sprintf(valueString, "%9.2f", value);
+    
+    NSPoint org;
+    org.x = origin.x + labelWidth + width - 12;
+    org.y = origin.y;
+    NSTextField* valueTextField = [self addTextField :nsBox :valueString :-1 :org :isVerticalBox];
+    [valueTextField setAlignment: NSLeftTextAlignment];
+    
+    if (isVerticalBox)
+    {
+        origin.y += height;
+        size.height += height;
+        if (size.width < width+labelWidth+100)
+            size.width = width+labelWidth+100;
+    }
+    else
+    {
+        origin.x += width+labelWidth+100;
+        size.width += width+labelWidth+100;
+        if (size.height < height)
+            size.height = height;
+    }
+    
+    paramValues[controlId] = valueTextField;
+    
+    if (labelTextField)
+        [slider setLabelTextField: labelTextField];
+    
+    [slider setValueTextField: valueTextField];
+    
+    return slider;
+    
+}
+
+
+- (NSArray*)generateArrayFrom:(float)start to:(float)stop step:(float)step
+{
+    NSMutableArray *a = [[NSMutableArray alloc] init];
+    float v = start;
+    
+    while (v <= stop)
+    {
+        [a addObject:@(v)];
+        v += step;
+        
+    }
+    return a;
+}
+
+
+- (FaustAU_Knob*)addKnob:(NSBox*) nsBox :(auSlider*)fSlider :(int)controlId :(NSPoint&) origin :(NSSize&) size :(bool)isVerticalBox
+{
+    
+    NSTextField* labelTextField;
+    int labelWidth = 0;
+    
+    if (strcmp(fSlider->fLabel.c_str(), "")) {
+        
+        labelTextField = [self addTextField :nsBox :fSlider->fLabel.c_str() :200 :origin :isVerticalBox];
+        [labelTextField setAlignment: NSRightTextAlignment];
+        
+        labelWidth = 100;
+    }
+    
+    labelTextField = [self addTextField :nsBox :fSlider->fLabel.c_str() :200 :origin :isVerticalBox];
+    [labelTextField setAlignment: NSRightTextAlignment];
+    
+    int width = 50;
+    int height = 50;
+    float value;
+    
+    AudioUnitGetParameter(mAU, controlId, kAudioUnitScope_Global, 0, &value);
+    
+    int initAngle =  225.0 - 270.0 * (value - fSlider->fMin) / (fSlider->fMax - fSlider->fMin);
+    
+    FaustAU_Knob *knob = [[FaustAU_Knob alloc] initWithFrame:NSMakeRect(origin.x + labelWidth, origin.y, width, height)
+                                                  withInsets:10
+                                    withControlPointDiameter:2
+                                       withControlPointColor:[NSColor darkGrayColor]
+                                               withKnobColor:[NSColor whiteColor]
+                                         withBackgroundColor:[NSColor clearColor]
+                                            withCurrentAngle:initAngle];
+    
+    
+    knob->control = controlId;
+    
+    knob->controlPoint->delegate = self;
+    
+    knob->controlPoint->data = [self generateArrayFrom:fSlider->fMin to:fSlider->fMax step:fSlider->fStep]; //TODO step
+    
+    NSString *identifier = [NSString stringWithFormat:@"%d",controlId];
+    [knob setIdentifier: identifier];
+    
+    [nsBox addSubview:knob];
+    
+    
+    AudioUnitGetParameter(mAU, controlId, kAudioUnitScope_Global, 0, &value);
+    char valueString[100];
+    sprintf(valueString, "%9.2f", value);
+    
+    
+    NSPoint org;
+    org.x = origin.x + labelWidth + 28;
+    org.y = origin.y;
+    NSTextField* valueTextField = [self addTextField :nsBox :valueString :-1 :org :isVerticalBox];
+    [valueTextField setAlignment: NSLeftTextAlignment];
+    
+    if (isVerticalBox)
+    {
+        origin.y += height;
+        size.height += height;
+        if (size.width < width+labelWidth + 30)
+            size.width = width+labelWidth + 30;
+    }
+    else
+    {
+        origin.x += width+labelWidth + 30;
+        size.width += width + labelWidth + 30;
+        if (size.height < height)
+            size.height = height;
+    }
+    
+    paramValues[controlId] = valueTextField;
+    
+    if (labelTextField)
+        [knob setLabelTextField: labelTextField];
+    
+    [knob setValueTextField: valueTextField];
+    
+    return knob;
+    
+}
+
+
+- (FaustAU_Bargraph*)addBargraph:(NSBox*) nsBox :(auBargraph*)fBargraph :(int)controlId :(NSPoint&) origin :(NSSize&) size :(bool)isVerticalBox
+{
+    NSTextField* labelTextField = NULL;
+    int labelWidth = 0;
+    
+    if (strcmp(fBargraph->fLabel.c_str(), "")) {
+        
+        labelTextField = [self addTextField :nsBox :fBargraph->fLabel.c_str() :200 :origin :isVerticalBox];
+        [labelTextField setAlignment: NSRightTextAlignment];
+        
+        labelWidth = 100;
+    }
+    
+    
+    int width;
+    int height;
+    float value;
+    
+    if (fBargraph->fIsVertical) {
+        width = 35;
+        height = 100;
+    }
+    else {
+        width = 300;
+        height = 55;
+    }
+    
+    FaustAU_Bargraph* bargraph;
+    bargraph = [[FaustAU_Bargraph alloc] initWithFrame:NSMakeRect(origin.x + labelWidth, origin.y, width, height)];
+    [bargraph setMinValue:fBargraph->fMin];
+    [bargraph setMaxValue:fBargraph->fMax];
+    
+    AudioUnitGetParameter(mAU, controlId, kAudioUnitScope_Global, 0, &value);
+    [bargraph setDoubleValue:value];
+    
+    //TODO [barGraph setNumberOfTickMarks: (fBargraph->fMax - fBargraph->fMin) / fBargraph->fStep];
+    NSString *identifier = [NSString stringWithFormat:@"%d",controlId];
+    [bargraph setIdentifier: identifier];
+    
+    [bargraph setContinuous:YES];
+    
+    [bargraph setAction:@selector(paramChanged:)];
+    [bargraph setTarget:self];
+    
+    [nsBox addSubview:bargraph];
+    
+    AudioUnitGetParameter(mAU, controlId, kAudioUnitScope_Global, 0, &value);
+    char valueString[100];
+    sprintf(valueString, "%9.2f", value);
+    
+    NSPoint org;
+    org.x = origin.x + labelWidth + width - 12;
+    org.y = origin.y;
+    NSTextField* valueTextField = [self addTextField :nsBox :valueString :-1 :org :isVerticalBox];
+    [valueTextField setAlignment: NSLeftTextAlignment];
+    
+    if (isVerticalBox)
+    {
+        origin.y += height;
+        size.height += height;
+        if (size.width < width+labelWidth+100)
+            size.width = width+labelWidth+100;
+    }
+    else
+    {
+        origin.x += width+labelWidth+100;
+        size.width += width+labelWidth+100;
+        if (size.height < height)
+            size.height = height;
+    }
+    
+    paramValues[controlId] = valueTextField;
+    
+    if (labelTextField)
+        [bargraph setLabelTextField: labelTextField];
+    
+    [bargraph setValueTextField: valueTextField];
+    
+    return bargraph;
+}
+
+- (NSBox*)addBox:(NSBox*) nsParentBox :(auBox*)fThisBox :(NSPoint&) parentBoxOrigin :(NSSize&) parentBoxSize :(bool)isParentVerticalBox {
+    
+    auUIObject* childUIObject;
+    
+    NSBox* nsThisBox = [[NSBox alloc] init];
+    NSPoint thisBoxOrigin;
+    NSSize thisBoxSize;
+    
+    thisBoxOrigin.x = thisBoxOrigin.y = 0;
+    thisBoxSize.width = thisBoxSize.height = 0;
+    
+    [nsThisBox setTitle:[[NSString alloc] initWithCString:fThisBox->fLabel.c_str() encoding:NSUTF8StringEncoding]];
+    
+    auUI* dspUI = [self dspUI];
+    
+    int controlId;
+    NSView* childView = NULL;
+    
+    bool hasChildView = false;
+    
+      for (int i = 0; i < fThisBox->children.size(); i++) {
+        if (fThisBox->isVertical)
+            childUIObject = fThisBox->children[fThisBox->children.size() - i - 1]; //not isFlipped
+        else
+            childUIObject = fThisBox->children[i];
+
+        for (int j = 0; j < dspUI->fUITable.size(); j++)
+        {
+            if (dspUI->fUITable[j] == childUIObject)
+                controlId = j;
+        }
+        
+        if (dynamic_cast<auBox*>(childUIObject)) {
+            [self addBox :nsThisBox :(auBox*)childUIObject :thisBoxOrigin :thisBoxSize :fThisBox->isVertical];
+        }
+        else
+        {
+            if (dynamic_cast<auButton*>(childUIObject)) {
+                childView = [self addButton :nsThisBox :(auButton*)childUIObject :controlId :thisBoxOrigin :thisBoxSize :fThisBox->isVertical];
+            }
+            else if (dynamic_cast<auCheckButton*>(childUIObject)) {
+                childView = [self addCheckButton :nsThisBox :(auCheckButton*)childUIObject :controlId :thisBoxOrigin :thisBoxSize :fThisBox->isVertical];
+            }
+            
+            else if (dynamic_cast<auSlider*>(childUIObject)) {
+                if (dspUI->knobSet.count(childUIObject->fZone)) { //isKnob
+                    childView = [self addKnob :nsThisBox :(auSlider*)childUIObject :controlId :thisBoxOrigin :thisBoxSize :fThisBox->isVertical];
+                }
+                else {
+                    childView = [self addSlider :nsThisBox :(auSlider*)childUIObject :controlId :thisBoxOrigin :thisBoxSize :fThisBox->isVertical];
+                }
+            }
+            else if (dynamic_cast<auBargraph*>(childUIObject)) {
+                childView = [self addBargraph :nsThisBox :(auBargraph*)childUIObject :controlId :thisBoxOrigin :thisBoxSize :fThisBox->isVertical];
+            }
+            
+            hasChildView = true;
+            
+            if (childView)
+                viewMap[controlId] = childView;
+            
+        }
+    }
+    
+    /* if (hasChildView)
+     {
+     
+     auButton showHideAUButton(fThisBox->fLabel.c_str(), NULL);
+     
+     NSButton* showHideButton = [self addButton :nsThisBox :&showHideAUButton :-100 :thisBoxOrigin :thisBoxSize :fThisBox->isVertical]; //TODO -100
+     /*
+     
+     // NSButton* showHideBtton = [[NSButton alloc] initWithFrame:NSMakeRect(0 //*thisBoxOrigin.x//, frame.size.//height - 30,  35, 70 )];
+     
+     [showHideButton setTarget:self];
+     [showHideButton setAction:@selector(showHide:)];
+     
+     [nsThisBox addSubview:showHideButton];
+     showHideMap[showHideButton] = nsThisBox;
+     }*/
+    
+    
+    NSRect frame;
+    frame.origin.x = parentBoxOrigin.x;
+    frame.origin.y = parentBoxOrigin.y;
+    frame.size.width  = thisBoxSize.width + 25;
+    frame.size.height = thisBoxSize.height + 25;
+    [nsThisBox setFrame:frame];
+    
+    [nsThisBox setNeedsDisplay:YES];
+    
+    [nsParentBox addSubview:nsThisBox];
+    
+    if (isParentVerticalBox)
+    {
+        parentBoxOrigin.x = 0;
+        parentBoxOrigin.y += thisBoxSize.height + 25;
+        
+        parentBoxSize.height += thisBoxSize.height + 25;
+        if (parentBoxSize.width < thisBoxSize.width)
+            parentBoxSize.width = thisBoxSize.width;
+    }
+    else
+    {
+        parentBoxOrigin.x += thisBoxSize.width + 25;
+        parentBoxSize.width += thisBoxSize.width + 25;
+
+        if (parentBoxSize.height < thisBoxSize.height)
+            parentBoxSize.height = thisBoxSize.height;
+        parentBoxOrigin.y = 0;
+    }
+    
+    return nsThisBox;
+    
+}
+
+-(void)repaint
+{
+    auUI* dspUI = [self dspUI];
+    NSRect frame;
+    
+    NSPoint origin;
+    origin.x = origin.y = 0;
+    
+    NSSize size;
+    size.width = size.height = 0;
+    
+    NSBox* nsCustomViewBox = [[NSBox alloc] init];
+    [nsCustomViewBox setTitle:@"FaustAU CustomView"];
+    [self addBox :nsCustomViewBox :dspUI->boundingBox :origin :size :true];
+    
+    frame.origin.x  = 0;
+    frame.origin.y = 0;
+    frame.size.width  = size.width + 25;
+    frame.size.height = size.height + 25;
+    [nsCustomViewBox setFrame:frame];
+    [nsCustomViewBox setNeedsDisplay:YES];
+    [self addSubview:nsCustomViewBox];
+    
+    //xml button
+    NSButton* button;
+    NSRect monitorFrame = NSMakeRect(size.width - 32, 6, 55, 24);
+    button = [[NSButton alloc] initWithFrame:monitorFrame ];
+    [button setTitle:@"XML"];
+    [button setButtonType:NSMomentaryPushInButton];
+    [button setBezelStyle:NSRoundedBezelStyle];
+    [button setTarget:self];
+    [button setAction:@selector(xmlButtonPushed:)];
+    [button setState:TRUE];
+    [self addSubview:button];
+    
+    if (usesBargraphs)
+    {
+        NSRect monitorFrame = NSMakeRect(10, 10, 60, 15);
+        button = [[NSButton alloc] initWithFrame:monitorFrame ];
+        [button setTitle:@"MON"];
+        [button setButtonType:NSSwitchButton];
+        [button setBezelStyle:NSRoundedBezelStyle];
+        [button setTarget:self];
+        [button setAction:@selector(monitorButtonPushed:)];
+        [button setState:TRUE];
+        [self addSubview:button];
+    }
+    
+    
+    [self setFrame:frame];
+    [self setNeedsDisplay:YES];
+}
+
+- (void)setAU:(AudioUnit)inAU {
+	if (mAU)
+		[self removeListeners];
+    
+    mAU = inAU;
+    [self addListeners];
+    [self synchronizeUIWithParameterValues];
+    
+    auUI* dspUI = [self dspUI];
+    
+    usesBargraphs = false;
+    for (int i = 0; i < dspUI->fUITable.size(); i++)
+    {
+        if (dspUI->fUITable[i] && dspUI->fUITable[i]->fZone)
+        {
+            if (dynamic_cast<auBargraph*>(dspUI->fUITable[i]))
+                usesBargraphs = true;
+            break;
+        }
+    }
+    
+    if (usesBargraphs)
+    {
+        monitor = true;
+        [self setTimer];
+    }
+    
+    [self repaint];
+}
+
+-(void)setTimer
+{
+    if (!timer)
+    {
+        timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(update) userInfo:nil repeats:YES];
+    }
+}
+
+-(void)unsetTimer
+{
+    if (timer)
+    {
+        [timer invalidate];
+        timer = nil;
+    }
+}
+
+- (void)update
+{
+    [self synchronizeUIWithParameterValues];
+    
+    [self setNeedsDisplay:YES];
+}
+
+// Called upon a knob update
+- (void)knobUpdatedWithIndex:(int)index
+                   withValue:(double)value
+                  withObject:(id)object
+{
+    [ (FaustAU_Knob*)object setDoubleValue :value ];
+    
+    int paramId = [[object identifier] intValue];
+    
+    ComponentResult result = AudioUnitSetParameter(mAU,
+                                                   paramId, //AudioUnitParameterID
+                                                   kAudioUnitScope_Global,
+                                                   (AudioUnitElement)0, //inElement
+                                                   value, //inValue
+                                                   0); //inBufferOffsetInFrames
+    
+    NSString *string = [NSString stringWithFormat:@"%9.2f", value];
+    [paramValues[paramId] setStringValue: string];
+    
+	AudioUnitParameter parameter = {mAU,
+        paramId, //paramId
+        kAudioUnitScope_Global,
+        0 }; //mElement
+	
+	NSAssert(	AUParameterSet(mAUEventListener, object, &parameter, (Float32)value, 0) == noErr,
+             @"[FaustAU_CustomView paramChanged:] AUParameterSet()");
+    
+    [object setNeedsDisplay:TRUE];
+}
+
+
+- (void)showHide:(id)sender
+{
+   	
+    int intValue = [sender intValue];
+    
+    if (intValue)
+    {
+        [sender setTitle: @"-"];
+        [sender setIntValue: 1];
+        
+        NSBox* box = showHideMap[sender];
+        
+        [box setHidden:FALSE];
+        [box setNeedsDisplay:YES];
+    }
+    else
+    {
+        [sender setTitle: @"+"];
+        [sender setIntValue: 0];
+        
+        NSBox* box = showHideMap[sender];
+        
+        [box setHidden:TRUE];
+        [box setNeedsDisplay:YES];
+    }
+    
+    //[self repaint];
+}
+
+
+- (void)buttonPushed:(id)sender
+{
+    int state =  ((FaustAU_Button*)sender)->buttonState;
+    int paramId = [[sender identifier] intValue];
+    
+    ComponentResult result = AudioUnitSetParameter(mAU,
+                                                   paramId, //AudioUnitParameterID
+                                                   kAudioUnitScope_Global,
+                                                   (AudioUnitElement)0, //inElement
+                                                   state, //inValue
+                                                   0); //inBufferOffsetInFrames
+    
+	AudioUnitParameter parameter = {mAU,
+        paramId, //paramId
+        kAudioUnitScope_Global,
+        0 }; //mElement
+	
+	NSAssert(	AUParameterSet(mAUEventListener, sender, &parameter, (Float32)state, 0) == noErr,
+             @"[FaustAU_CustomView paramChanged:] AUParameterSet()");
+    
+}
+
+- (void)xmlButtonPushed:(id)sender
+{
+    NSData *data;
+    NSString* dataString;
+    NSString *oldString, *newString;
+    
+    auUI* dspUI = [self dspUI];
+    NSFileManager *filemgr = [NSFileManager defaultManager];
+    
+    NSString* path = [NSHomeDirectory() stringByAppendingString: @"/Library/Audio/Plug-Ins/Components/_FILENAME_.component/Contents/Resources/au-output.xml"];
+    
+    NSSavePanel *savePanel = [NSSavePanel savePanel];
+    NSString *outputFileName = NULL;
+    int result = [savePanel runModal];
+    
+    if (result == NSOKButton){
+        outputFileName = [[savePanel URL] path];
+    }
+    
+    data = [filemgr contentsAtPath: path ];
+    
+    dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+    
+    for (int i = 0; i < dspUI->fUITable.size(); i++)
+    {
+        if (dspUI->fUITable[i] && dspUI->fUITable[i]->fZone)
+        {
+            oldString = [NSString stringWithFormat:@"id=\"%i\"", i + 1];
+            newString = [NSString stringWithFormat:@"id=\"%i\" value=\"%f\"", i + 1, *dspUI->fUITable[i]->fZone];
+            
+            dataString = [dataString stringByReplacingOccurrencesOfString: oldString withString:newString];
+        }
+    }
+    
+    data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
+    [filemgr createFileAtPath: outputFileName contents: data attributes: nil];
+    
+}
+
+- (void)monitorButtonPushed:(id)sender
+{
+    monitor = [(NSButton*)sender state];
+    
+    if (monitor)
+        [self setTimer];
+    else
+        [self unsetTimer];
+}
+
+- (void)paramChanged:(id)sender
+{
+   	
+    float value =  [sender doubleValue]; //TODO
+    int paramId = [[sender identifier] intValue];
+    
+    ComponentResult result = AudioUnitSetParameter(mAU,
+                                                   paramId, //AudioUnitParameterID
+                                                   kAudioUnitScope_Global,
+                                                   (AudioUnitElement)0, //inElement
+                                                   value, //inValue
+                                                   0); //inBufferOffsetInFrames
+    
+    NSString *string = [NSString stringWithFormat:@"%9.2f", value];
+    [paramValues[paramId] setStringValue: string];
+    
+	AudioUnitParameter parameter = {mAU,
+        paramId, //paramId
+        kAudioUnitScope_Global,
+        0 }; //mElement
+	
+	NSAssert(	AUParameterSet(mAUEventListener, sender, &parameter, (Float32)value, 0) == noErr,
+             @"[FaustAU_CustomView paramChanged:] AUParameterSet()");
+    
+}
+
+- (void)synchronizeUIWithParameterValues {
+    auUI* dspUI = [self dspUI];
+    
+    NSView* subView = NULL;
+    int paramId;
+    Float32 value;
+    
+    for (int i = 0; i < dspUI->fUITable.size(); i++)
+    {
+        if (dspUI->fUITable[i] && dspUI->fUITable[i]->fZone)
+        {
+            subView = viewMap[i]; //TODO can be used for other cases
+            
+            if (subView)
+            {
+                if (dynamic_cast<auBargraph*>(dspUI->fUITable[i])
+                    ) {
+                    
+                    value = *(dspUI->fUITable[i]->fZone);
+                    
+                    [subView setDoubleValue:value];
+                    
+                }
+            }
+        }
+    }
+}
+
+- (void)eventListener:(void *) inObject event:(const AudioUnitEvent *)inEvent value:(Float32)inValue {
+}
+
+
+ at end
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.h b/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.h
new file mode 100644
index 0000000..ea50a91
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.h
@@ -0,0 +1,13 @@
+#import <Cocoa/Cocoa.h>
+#import <AudioUnit/AUCocoaUIView.h>
+
+ at class FaustAU_CustomView;
+
+ at interface FaustAU_CustomViewFactory : NSObject <AUCocoaUIBase>
+{
+    IBOutlet FaustAU_CustomView *uiFreshlyLoadedView;	// This class is the File's Owner of the CocoaView 
+}															// This data member needs to be the same class as the view class the factory will return
+
+- (NSString *) description;	
+
+ at end
\ No newline at end of file
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.m b/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.m
new file mode 100644
index 0000000..f06352d
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.m
@@ -0,0 +1,22 @@
+#import "FaustAU_CustomViewFactory.h"
+#import "FaustAU_CustomView.h"
+
+ at implementation FaustAU_CustomViewFactory
+
+- (unsigned) interfaceVersion {
+	return 0;
+}
+
+// string description of the Cocoa UI
+- (NSString *) description {
+	return @"Grame: FaustAU";
+}
+
+- (NSView *)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize {
+    FaustAU_CustomView *view = [[FaustAU_CustomView alloc] init];
+    [view setAU:inAU];
+    return [view autorelease];
+}
+
+
+ at end
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Knob.h b/architecture/AU/Source/CocoaUI/FaustAU_Knob.h
new file mode 100644
index 0000000..02db0d9
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Knob.h
@@ -0,0 +1,81 @@
+//  Based on Paolo Boschini's FlatKnob.
+
+#import <Cocoa/Cocoa.h>
+
+static const int INSETS = 10;
+static const int CONTROL_POINT_DIAMETER = 12;
+
+ at protocol FaustAU_KnobProtocol <NSObject>
+- (void)knobUpdatedWithIndex:(int)index withValue:(double)value withObject:(id)knob;
+
+ at end
+
+/**********************************************************************************/
+
+ at interface FaustAU_ControlPoint : NSView {
+    float currentDraggedAngle;
+    int currentAngle;
+    int mouseDownPosition;
+    float previousValue;
+    int insets;
+    int controlPointDiameter;
+    NSColor *controlPointColor;
+    
+ at public
+    float value;
+    
+    NSArray *data;
+    id <FaustAU_KnobProtocol> delegate;
+}
+
+- (id)initWithFrame:(NSRect)frame withInsets:(int)insets
+    withControlPointDiameter:(int)controlPointDiameter
+    withControlPointColor:(NSColor*)controlPointColor
+    withCurrentAngle:(int)_currentAngle;
+
+
+ at end
+
+
+/**********************************************************************************/
+
+
+ at interface FaustAU_FlatKnob : NSView {
+    int insets;
+    NSColor *backgroundColor;
+    NSColor *knobColor;
+ at public
+    int control;
+    FaustAU_ControlPoint *controlPoint;
+}
+
+- (id)initWithFrame:(NSRect)frame
+        withInsets:(int)insets
+        withControlPointDiameter:(int)controlPointDiameter
+        withControlPointColor:(NSColor*)controlPointColor
+        withKnobColor:(NSColor*)knobColor
+        withBackgroundColor:(NSColor*)backgroundColor
+        withCurrentAngle:(int)currentAngle;
+ at end
+
+
+/**********************************************************************************/
+
+
+ at interface FaustAU_Knob : FaustAU_FlatKnob
+{
+    NSTextField* _labelTextField;
+    NSTextField* _valueTextField;
+}
+
+- (double)doubleValue;
+- (void)setDoubleValue:(double)aDouble;
+
+ at property (nonatomic, strong) NSTextField* labelTextField;
+ at property (nonatomic, strong) NSTextField* valueTextField;
+
+
+ at end
+
+
+
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Knob.m b/architecture/AU/Source/CocoaUI/FaustAU_Knob.m
new file mode 100644
index 0000000..bb4d789
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Knob.m
@@ -0,0 +1,199 @@
+//  Based on Paolo Boschini's FlatKnob.
+
+#import "FaustAU_Knob.h"
+
+#import <QuartzCore/QuartzCore.h>
+
+ at implementation FaustAU_FlatKnob
+
+- (id)initWithFrame:(NSRect)frame
+{
+    return [self initWithFrame:(NSRect)frame
+                withInsets:INSETS
+                withControlPointDiameter:CONTROL_POINT_DIAMETER
+                withControlPointColor:[NSColor redColor]
+                withKnobColor:[NSColor colorWithSRGBRed:0 green:0.4 blue:1 alpha:1]
+                withBackgroundColor:[NSColor blackColor]
+                withCurrentAngle:225];
+}
+
+- (id)initWithFrame:(NSRect)frame withInsets:(int)_insets
+        withControlPointDiameter:(int)_controlPointDiameter
+        withControlPointColor:(NSColor*)_controlPointColor
+        withKnobColor:(NSColor*)_knobColor
+        withBackgroundColor:(NSColor*)_backgroundColor
+        withCurrentAngle:(int)_currentAngle;
+
+{
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+        backgroundColor = _backgroundColor;
+        knobColor = _knobColor;
+        insets = _insets;
+        
+        [self setWantsLayer:YES];
+        self.layer.backgroundColor = backgroundColor.CGColor;
+        self.layer.cornerRadius = 15;
+        
+        NSRect rect = NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height);
+        self->controlPoint = [[FaustAU_ControlPoint alloc] initWithFrame:rect
+                                                    withInsets:insets
+                                                    withControlPointDiameter:_controlPointDiameter
+                                                    withControlPointColor:_controlPointColor
+                                                    withCurrentAngle:_currentAngle];
+        [self addSubview:self->controlPoint];
+    }
+    return self;
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+    NSBezierPath *fillCircle;
+    NSRect rect;
+    
+    int i;
+    for (i = 0; i < 5; ++i)
+    {
+        rect = NSMakeRect(insets+i,
+                          insets+i,
+                          self.bounds.size.width - (insets*2 + i*2),
+                          self.bounds.size.height - (insets*2 + i*2));
+        fillCircle = [NSBezierPath bezierPathWithOvalInRect:rect];
+        [[knobColor colorWithAlphaComponent:i * 0.1 + 0.3] setFill];
+        [fillCircle fill];
+    }
+    
+    rect = NSMakeRect(insets+i,
+                      insets+i,
+                      self.bounds.size.width - (insets*2 + i*2),
+                      self.bounds.size.height - (insets*2 + i*2));
+    fillCircle = [NSBezierPath bezierPathWithOvalInRect:rect];
+    [[knobColor colorWithAlphaComponent:1] setFill];
+    [fillCircle fill];
+}
+
+ at end
+
+/**********************************************************************************/
+
+ at implementation FaustAU_ControlPoint
+
+- (id)initWithFrame:(NSRect)frame withInsets:(int)_insets
+    withControlPointDiameter:(int)_controlPointDiameter
+    withControlPointColor:(NSColor*)_controlPointColor
+    withCurrentAngle:(int)_currentAngle;
+
+{
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+        insets = _insets;
+        controlPointDiameter = _controlPointDiameter;
+        controlPointColor = _controlPointColor;
+        currentDraggedAngle = currentAngle = _currentAngle;
+        previousValue = 0;
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+    NSBezierPath *indicator;
+    [[controlPointColor colorWithAlphaComponent:1] set];
+    indicator = [NSBezierPath bezierPathWithOvalInRect:[self makeRectWithWidth:controlPointDiameter]];
+    [indicator fill];
+    
+    [[controlPointColor colorWithAlphaComponent:0.5] set];
+    indicator = [NSBezierPath bezierPathWithOvalInRect:[self makeRectWithWidth:controlPointDiameter+2]];
+    [indicator fill];
+    
+    [[controlPointColor colorWithAlphaComponent:0.3] set];
+    indicator = [NSBezierPath bezierPathWithOvalInRect:[self makeRectWithWidth:controlPointDiameter+4]];
+    [indicator fill];
+}
+
+- (NSRect)makeRectWithWidth:(int)width
+{
+    double radians = currentDraggedAngle * M_PI / 180.0;
+    int radius = (self.bounds.size.width/2 - insets);
+    return NSMakeRect(cos(radians)*radius + self.bounds.size.width/2 - width/2,
+                      sin(radians)*radius + self.bounds.size.height/2 - width/2,
+                      width,
+                      width);
+}
+
+#pragma mark Control
+- (void)mouseDown:(NSEvent *)theEvent
+{
+    NSPoint event_location = [theEvent locationInWindow];
+    NSPoint local_point = [self convertPoint:event_location fromView:nil];
+    mouseDownPosition = (int)local_point.y;
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+    currentAngle = currentDraggedAngle;
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+    [self updateWithYcoord:theEvent];
+}
+
+- (void)updateWithYcoord:(NSEvent *)theEvent
+{
+    NSPoint event_location = [theEvent locationInWindow];
+    NSPoint local_point = [self convertPoint:event_location fromView:nil];
+    currentDraggedAngle = mouseDownPosition - (int)local_point.y + currentAngle;
+    
+    if (currentDraggedAngle > 225) currentDraggedAngle = 225;
+    if (currentDraggedAngle < -45) currentDraggedAngle = -45;
+    
+    float currentValuePosition = (225.0 - currentDraggedAngle);
+    value = (currentValuePosition / 270.0) * (self->data.count-1);
+    
+    if (value != previousValue)
+    {
+        previousValue = value;
+        
+        double val = [[self->data objectAtIndex:value] doubleValue]; //TODO
+        [self->delegate knobUpdatedWithIndex:value
+                                   withValue:val
+                                  withObject:[self superview]];
+        
+        currentDraggedAngle = 225.0 - ((270.0 / (self->data.count-1)) * value);
+        [self setNeedsDisplay:YES];
+    }
+}
+
+- (BOOL)mouseDownCanMoveWindow
+{
+    return NO;
+}
+
+ at end
+
+/**********************************************************************************/
+
+
+ at implementation FaustAU_Knob
+
+ at synthesize labelTextField =_labelTextField;
+ at synthesize valueTextField =_valueTextField;
+
+- (void)setDoubleValue:(double)aDouble //TODO
+{
+    //TODO controlPoint->value = aDouble;
+    NSString *stringValue = [NSString stringWithFormat:@"%9.2f", aDouble]; //TODO
+    [_valueTextField setStringValue:stringValue]; //TODO
+}
+
+- (double)doubleValue
+{
+    return [[self->controlPoint->data objectAtIndex:self->controlPoint->value] doubleValue]; //TODO
+}
+
+
+ at end
\ No newline at end of file
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Slider.h b/architecture/AU/Source/CocoaUI/FaustAU_Slider.h
new file mode 100644
index 0000000..90ff522
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Slider.h
@@ -0,0 +1,18 @@
+#import <Foundation/Foundation.h>
+
+#include "FaustAU.h"
+
+ at interface FaustAU_Slider : NSSlider
+{
+    NSTextField* _labelTextField;
+    NSTextField* _valueTextField;
+}
+
+- (FaustAU_Slider*)init :(NSRect) frame :(auSlider*)fButton :(int)controlId;
+
+ at property (nonatomic, strong) NSTextField* labelTextField;
+ at property (nonatomic, strong) NSTextField* valueTextField;
+
+- (void)setDoubleValue:(double)aDouble;
+
+ at end
\ No newline at end of file
diff --git a/architecture/AU/Source/CocoaUI/FaustAU_Slider.m b/architecture/AU/Source/CocoaUI/FaustAU_Slider.m
new file mode 100644
index 0000000..9e8d61c
--- /dev/null
+++ b/architecture/AU/Source/CocoaUI/FaustAU_Slider.m
@@ -0,0 +1,21 @@
+#import "FaustAU_Slider.h"
+
+ at implementation FaustAU_Slider
+
+ at synthesize labelTextField =_labelTextField;
+ at synthesize valueTextField =_valueTextField;
+
+
+- (FaustAU_Slider*)init :(NSRect)frame :(auSlider*)fSlider :(int)controlId {
+    return self;
+}
+
+- (void)setDoubleValue:(double)aDouble
+{
+    [super setDoubleValue: aDouble];
+    NSString *stringValue = [NSString stringWithFormat:@"%9.2f", aDouble];
+    [_valueTextField setStringValue:stringValue];
+}
+
+ at end
+
diff --git a/architecture/AU/version.plist b/architecture/AU/version.plist
new file mode 100644
index 0000000..594a144
--- /dev/null
+++ b/architecture/AU/version.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildVersion</key>
+	<string>3</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.2</string>
+	<key>CFBundleVersion</key>
+	<string>1.2</string>
+	<key>ProjectName</key>
+	<string>CoreAudioExamples</string>
+	<key>SourceVersion</key>
+	<string>550000</string>
+</dict>
+</plist>
diff --git a/architecture/VST/PkgInfo b/architecture/VST/PkgInfo
old mode 100755
new mode 100644
diff --git a/architecture/alchemy-as.cpp b/architecture/alchemy-as.cpp
index 339cb0e..4713a95 100644
--- a/architecture/alchemy-as.cpp
+++ b/architecture/alchemy-as.cpp
@@ -44,8 +44,6 @@
 
 #ifdef __GNUC__
 
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
 
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
diff --git a/architecture/alsa-console.cpp b/architecture/alsa-console.cpp
new file mode 100644
index 0000000..63d0a0d
--- /dev/null
+++ b/architecture/alsa-console.cpp
@@ -0,0 +1,141 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections : 
+	the ARCHITECTURE section (in two parts) and the USER section. Each section 
+	is governed by its own copyright and license. Please check individually 
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work 
+	that contains this FAUST architecture section and distribute  
+	that work under terms of your choice, so long as this FAUST 
+	architecture section is not modified. 
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <iostream>
+#include <list>
+
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/GUI.h"
+#include "faust/gui/console.h"
+#include "faust/audio/alsa-dsp.h"
+
+#ifdef OSCCTRL
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+
+/**************************BEGIN USER SECTION **************************/
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+					
+mydsp*	DSP;
+
+std::list<GUI*>               GUI::fGuiList;
+
+//-------------------------------------------------------------------------
+// 									MAIN
+//-------------------------------------------------------------------------
+int main(int argc, char *argv[] )
+{
+	char* appname = basename (argv [0]);
+    char  rcfilename[256];
+	char* home = getenv("HOME");
+	snprintf(rcfilename, 255, "%s/.%src", home, appname);
+	
+	DSP = new mydsp();
+	if (DSP==0) {
+        std::cerr << "Unable to allocate Faust DSP object" << std::endl;
+		exit(1);
+	}
+
+	CMDUI* interface = new CMDUI(argc, argv);
+	FUI* finterface	= new FUI();
+	DSP->buildUserInterface(interface);
+	DSP->buildUserInterface(finterface);
+
+#ifdef HTTPCTRL
+	httpdUI* httpdinterface = new httpdUI(appname, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
+	DSP->buildUserInterface(httpdinterface);
+    std::cout << "HTTPD is on" << std::endl;
+#endif
+
+#ifdef OSCCTRL
+	GUI* oscinterface = new OSCUI(appname, argc, argv);
+	DSP->buildUserInterface(oscinterface);
+#endif
+
+	alsaaudio audio (argc, argv, DSP);
+	audio.init(appname, DSP);
+	finterface->recallState(rcfilename);	
+	audio.start();
+	
+#ifdef HTTPCTRL
+	httpdinterface->run();
+#endif
+	
+#ifdef OSCCTRL
+	oscinterface->run();
+#endif
+	interface->run();
+	
+	audio.stop();
+	finterface->saveState(rcfilename);
+    
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
+  	return 0;
+}
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/alsa-gtk.cpp b/architecture/alsa-gtk.cpp
index cbbd2b3..45e873a 100644
--- a/architecture/alsa-gtk.cpp
+++ b/architecture/alsa-gtk.cpp
@@ -37,16 +37,22 @@
 #include <libgen.h>
 #include <stdlib.h>
 #include <iostream>
+#include <list>
 
-#include "gui/FUI.h"
-#include "misc.h"
-#include "gui/faustgtk.h"
-#include "audio/alsa-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/faustgtk.h"
+#include "faust/audio/alsa-dsp.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
 #endif
 
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+
 /**************************BEGIN USER SECTION **************************/
 
 /******************************************************************************
@@ -66,9 +72,9 @@
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 					
-mydsp	DSP;
+mydsp*	DSP;
 
-list<GUI*>               GUI::fGuiList;
+std::list<GUI*>               GUI::fGuiList;
 
 //-------------------------------------------------------------------------
 // 									MAIN
@@ -81,22 +87,38 @@ int main(int argc, char *argv[])
 	
 	snprintf(appname, 255, "%s", basename(argv[0]));
 	snprintf(rcfilename, 255, "%s/.%src", home, appname);
+	
+	DSP = new mydsp();
+	if (DSP==0) {
+        std::cerr << "Unable to allocate Faust DSP object" << std::endl;
+		exit(1);
+	}
 
 	GUI* interface 	= new GTKUI (appname, &argc, &argv);
 	FUI* finterface	= new FUI();
-	DSP.buildUserInterface(interface);
-	DSP.buildUserInterface(finterface);
+	DSP->buildUserInterface(interface);
+	DSP->buildUserInterface(finterface);
+
+#ifdef HTTPCTRL
+	httpdUI* httpdinterface = new httpdUI(appname, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
+	DSP->buildUserInterface(httpdinterface);
+    std::cout << "HTTPD is on" << std::endl;
+#endif
 
 #ifdef OSCCTRL
 	GUI* oscinterface = new OSCUI(appname, argc, argv);
-	DSP.buildUserInterface(oscinterface);
+	DSP->buildUserInterface(oscinterface);
 #endif
 
-	alsaaudio audio (argc, argv, &DSP);
-	audio.init(appname, &DSP);
+	alsaaudio audio (argc, argv, DSP);
+	audio.init(appname, DSP);
 	finterface->recallState(rcfilename);	
 	audio.start();
 	
+#ifdef HTTPCTRL
+	httpdinterface->run();
+#endif
+	
 #ifdef OSCCTRL
 	oscinterface->run();
 #endif
@@ -104,6 +126,17 @@ int main(int argc, char *argv[])
 	
 	audio.stop();
 	finterface->saveState(rcfilename);
+    
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
   	return 0;
 }
 
diff --git a/architecture/alsa-qt.cpp b/architecture/alsa-qt.cpp
index 1196f08..1c7c98f 100644
--- a/architecture/alsa-qt.cpp
+++ b/architecture/alsa-qt.cpp
@@ -37,14 +37,19 @@
 #include <libgen.h>
 #include <stdlib.h>
 #include <iostream>
+#include <list>
 
-#include "gui/FUI.h"
-#include "misc.h"
-#include "gui/faustqt.h"
-#include "audio/alsa-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/faustqt.h"
+#include "faust/audio/alsa-dsp.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
 #endif
 
 
@@ -66,9 +71,9 @@
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 					
-mydsp	DSP;
+mydsp*	DSP;
 
-list<GUI*>               GUI::fGuiList;
+std::list<GUI*>               GUI::fGuiList;
 
 //-------------------------------------------------------------------------
 // 									MAIN
@@ -79,29 +84,62 @@ int main(int argc, char *argv[] )
     char  rcfilename[256];
 	char* home = getenv("HOME");
 	snprintf(rcfilename, 255, "%s/.%src", home, appname);
-
-	GUI* interface = new QTGUI(argc, argv);
+	
+	DSP = new mydsp();
+	if (DSP==0) {
+        std::cerr << "Unable to allocate Faust DSP object" << std::endl;
+		exit(1);
+	}
+    
+    QApplication myApp(argc, argv);
+
+	QTGUI* interface = new QTGUI();
 	FUI* finterface	= new FUI();
-	DSP.buildUserInterface(interface);
-	DSP.buildUserInterface(finterface);
+	DSP->buildUserInterface(interface);
+	DSP->buildUserInterface(finterface);
+
+#ifdef HTTPCTRL
+	httpdUI* httpdinterface = new httpdUI(appname, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
+	DSP->buildUserInterface(httpdinterface);
+     std::cout << "HTTPD is on" << std::endl;
+#endif
 
 #ifdef OSCCTRL
 	GUI* oscinterface = new OSCUI(appname, argc, argv);
-	DSP.buildUserInterface(oscinterface);
+	DSP->buildUserInterface(oscinterface);
 #endif
 
-	alsaaudio audio (argc, argv, &DSP);
-	audio.init(appname, &DSP);
+	alsaaudio audio (argc, argv, DSP);
+	audio.init(appname, DSP);
 	finterface->recallState(rcfilename);	
 	audio.start();
 	
+#ifdef HTTPCTRL
+	httpdinterface->run();
+#endif
+	
 #ifdef OSCCTRL
 	oscinterface->run();
 #endif
 	interface->run();
 	
+    myApp.setStyleSheet(interface->styleSheet());
+    myApp.exec();
+    interface->stop();
+    
 	audio.stop();
 	finterface->saveState(rcfilename);
+    
+   // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
   	return 0;
 }
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
diff --git a/architecture/android-sp.cpp b/architecture/android-sp.cpp
new file mode 100644
index 0000000..2b244ed
--- /dev/null
+++ b/architecture/android-sp.cpp
@@ -0,0 +1,454 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File for Android
+ Copyright (C) 2013 GRAME, Romain Michon, CCRMA - Stanford University
+ Copyright (C) 2003-2015 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/*
+ * README:
+ * The file only implements the native part of faust2android applications.
+ * The native C API is documented at the end of this file in the "Native Faust
+ * API" section.
+ */
+
+#include <math.h>
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/meta.h"
+#include "faust/gui/jsonfaustui.h"
+#include "faust/gui/JSONUI.h"
+//#include "faust/gui/APIUI.h"
+
+//**************************************************************
+// DSP class
+//**************************************************************
+
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+//**************************************************************
+// Polyphony
+//**************************************************************
+
+#include "faust/dsp/poly-dsp.h"
+
+//**************************************************************
+// Android Audio
+//**************************************************************
+
+#define FAUSTFLOAT float
+
+#include "faust/audio/android-dsp.h"
+
+#include "faust/gui/APIUI.h"
+
+//**************************************************************
+// Native Faust API
+//**************************************************************
+
+#include <android/log.h>
+#include "dsp_faust.h"
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+struct AndroidEngine {
+
+    androidaudio* fDriver;    // the audio engine
+    mydsp fMonoDSP;           // the monophonic Faust object
+    mydsp_poly* fPolyDSP;     // the polyphonic Faust object
+    APIUI fAPIUI;             // the UI description
+    JSONUI fJSON;
+    string fJSONString;
+    bool fRunning;
+
+    int fSampleRate, fBufferSize, fPolyMax;
+    
+    AndroidEngine(int sampling_rate, int buffer_size):fJSON(fMonoDSP.getNumInputs(), fMonoDSP.getNumOutputs())
+    {
+        fPolyDSP = NULL;
+        fDriver = NULL;
+        fSampleRate = sampling_rate;
+        fBufferSize = buffer_size;
+        fRunning = false;
+        
+        // configuring the UI
+        fMonoDSP.buildUserInterface(&fAPIUI);
+        fMonoDSP.buildUserInterface(&fJSON);
+        
+        fJSONString = fJSON.JSON();
+        
+        if (fJSONString.find("keyboard") != std::string::npos ||
+            fJSONString.find("poly") != std::string::npos){
+            fPolyMax = 6;
+            fPolyDSP = new mydsp_poly(fBufferSize, fPolyMax);
+            fPolyDSP->init(fSampleRate);
+        } else {
+            fPolyMax = 0;
+        }
+        
+        // allocating audio
+        fDriver = new androidaudio(fSampleRate, fBufferSize);
+    }
+    
+    virtual ~AndroidEngine()
+    {
+        delete fDriver;
+        delete fPolyDSP;
+    }
+    
+    bool init()
+    {
+        return fDriver->init("Dummy", (fPolyMax == 0) ? &fMonoDSP : (dsp*)fPolyDSP);
+    }
+    
+    bool start()
+    {
+        if (!fRunning) {
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "REAL start");
+            fRunning = fDriver->start();
+        }
+        return fRunning;
+    }
+    
+    void stop()
+    {
+        if (fRunning) {
+            fRunning = false;
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "REAL stop");
+            fDriver->stop();
+        }
+    }
+    
+    int keyOn(int pitch, int velocity)
+    {
+        if (fPolyMax > 0) {
+            fPolyDSP->keyOn(0, pitch, velocity);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    int keyOff(int pitch)
+    {
+        if (fPolyMax > 0) {
+            fPolyDSP->keyOff(0, pitch);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    int pitchBend(int refPitch, float pitch)
+    {
+        if (fPolyMax > 0) {
+            fPolyDSP->pitchBend(0, refPitch, pitch);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    const char* getJSON()
+    {
+        return fJSONString.c_str();
+    }
+    
+    int getParamsCount()
+    {
+        return fAPIUI.getParamsCount();
+    }
+    
+    float getParam(const char* address)
+    {
+        if (fPolyMax == 0) {
+            return fAPIUI.getParamValue(fAPIUI.getParamIndex(address));
+        } else {
+            return fPolyDSP->getValue(address);
+        }
+    }
+    
+    void setParam(const char* address, float value)
+    {
+        if (fPolyMax == 0) {
+            fAPIUI.setParamValue(fAPIUI.getParamIndex(address), value);
+        } else {
+            fPolyDSP->setValue(address, value);
+        }
+    }
+    
+    int setVoiceParam(const char* address, int pitch, float value)
+    {
+        if (fPolyMax > 0) {
+            fPolyDSP->setValue(address, pitch, value);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    int setVoiceGain(int pitch, float gain) {
+        if (fPolyMax > 0) {
+            fPolyDSP->setVoiceGain(pitch, gain);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    const char* getParamAddress(int id) {
+        return fAPIUI.getParamName(id);
+    }
+    
+    void propagateAcc(int acc, float v)
+    {
+        fAPIUI.propagateAcc(acc, v);
+    }
+    
+    void setAccConverter(int p, int acc, int curve, float amin, float amid, float amax)
+    {
+        __android_log_print(ANDROID_LOG_ERROR, "Faust", "setAccConverter %d %d %d %f %f %f", p, acc, curve, amin, amid, amax);
+        fAPIUI.setAccConverter(p, acc, curve, amin, amid, amax);
+    }
+    
+    void propagateGyr(int gyr, float v)
+    {
+        fAPIUI.propagateGyr(gyr, v);
+    }
+    
+    void setGyrConverter(int p, int gyr, int curve, float amin, float amid, float amax)
+    {
+        __android_log_print(ANDROID_LOG_ERROR, "Faust", "setGyrConverter %d %d %d %f %f %f", p, gyr, curve, amin, amid, amax);
+        fAPIUI.setGyrConverter(p, gyr, curve, amin, amid, amax);
+    }
+};
+
+static AndroidEngine* gGlobal = NULL;
+
+/*
+ * init(samplingRate, bufferFrames)
+ * Initializes the Audio engine and the DSP code
+ * with samplingRate and bufferFrames.
+ * This method also looks for the [style:poly]
+ * metadata in the Faust code and initializes a
+ * polyphonic object or not based on that. init
+ * should be called before start.
+ */
+bool init(int sample_rate, int buffer_size)
+{
+    __android_log_print(ANDROID_LOG_ERROR, "Faust", "JNI init");
+    gGlobal = new AndroidEngine(sample_rate, buffer_size);
+    return gGlobal->init();
+}
+
+/*
+ * start()
+ * Begins the processing and return 1 if the connection
+ * with the audio device was successful and 0 if not.
+ * On Android it also creates the native thread where the
+ * DSP tasks will be computed.
+ */
+bool start()
+{
+    __android_log_print(ANDROID_LOG_ERROR, "Faust", "JNI start");
+    return gGlobal->start();
+}
+
+/*
+ * stop()
+ * Stops the processing.
+ */
+void stop()
+{
+    __android_log_print(ANDROID_LOG_ERROR, "Faust", "JNI stop");
+	 return gGlobal->stop();
+}
+        
+/*
+ * destroy()
+ * Destroy the audio engine and related ressources.
+ * the native thread on Android.
+ */
+void destroy()
+{
+    __android_log_print(ANDROID_LOG_ERROR, "Faust", "JNI destroy");
+    delete gGlobal;
+    gGlobal = NULL;
+}
+
+/*
+ * isRunning()
+ * returns true if the DSP frames are being computed and
+ * false if not.
+ */
+bool isRunning()
+{
+	return (gGlobal != NULL);
+}
+
+/*
+ * keyOn(pitch, velocity)
+ * Instantiates a new polyphonic voice where velocity
+ * and pitch are MIDI numbers (0-127). keyOn can only
+ * be used if the [style:poly] metadata is used in the
+ * Faust code. keyOn will return 0 if the object is not
+ * polyphonic and 1 otherwise.
+ */
+int keyOn(int pitch, int velocity)
+{
+    return gGlobal->keyOn(pitch, velocity);
+}
+
+/*
+ * keyOff(pitch)
+ * De-instantiates a polyphonic voice where pitch is the
+ * MIDI number of the note (0-127). keyOff can only be
+ * used if the [style:poly] metadata is used in the Faust
+ * code. keyOn will return 0 if the object is not polyphonic
+ * and 1 otherwise.
+ */
+int keyOff(int pitch)
+{
+	return gGlobal->keyOff(pitch);
+}
+
+/*
+ * pitchBend(refPitch, pitch)
+ * Replaces refPitch in the voice associated with it with pitch.
+ * pitch is a MIDI number expressed as a decimal number.
+ * pitchBend can only be used if the [style:poly] metadata
+ * is used in the Faust code. pitchBend will return 0
+ * if the object is not polyphonic and 1 otherwise.
+ */
+int pitchBend(int refPitch, float pitch)
+{
+    return gGlobal->pitchBend(refPitch, pitch);
+}
+
+/*
+ * getJSON()
+ * Returns a string containing a JSON description of the
+ * UI of the Faust object.
+ */
+const char* getJSON()
+{
+    return gGlobal->getJSON();
+}
+
+/*
+ * getParamsCount()
+ * Returns the number of parameters of the Faust object.
+ */
+int getParamsCount()
+{
+    return gGlobal->getParamsCount();
+}
+
+/*
+ * getParam(address)
+ * Takes the address of a parameter and returns its current
+ * value.
+ */
+float getParam(const char* address)
+{
+    return gGlobal->getParam(address);
+}
+
+/*
+ * setParam(address,value)
+ * Sets the value of the parameter associated with address.
+ */
+void setParam(const char* address, float value)
+{
+    return gGlobal->setParam(address, value);
+}
+
+/*
+ * setVoiceParam(address,pitch,value)
+ * Sets the value of the parameter associated with address for
+ * the voice associated with pitch. setVoiceParam can only be
+ * used if the [style:poly] metadata is used in the Faust code.
+ * setVoiceParam will return 0 if the object is not polyphonic
+ * and 1 otherwise.
+ */
+int setVoiceParam(const char* address, int pitch, float value)
+{
+    return gGlobal->setVoiceParam(address, pitch, value);
+}
+
+/*
+ * setVoiceGain(pitch,gain)
+ * Sets the gain (0-1) of the voice associated with pitch.
+ * setVoiceGain can only be used if the [style:poly] metadata
+ * is used in the Faust code. setVoiceGain will return 0 if the
+ * object is not polyphonic and 1 otherwise.
+ */
+int setVoiceGain(int pitch, float gain)
+{
+    return gGlobal->setVoiceGain(pitch, gain);
+}
+
+/*
+ * getParamAddress(id)
+ * Returns the address of a parameter in function of its "id".
+ */
+const char* getParamAddress(int id)
+{
+    return gGlobal->getParamAddress(id);
+}
+
+/*
+ * propagateAcc(int acc, float v)
+ * Propage accelerometer value to the curve conversion layer.
+ */
+void propagateAcc(int acc, float v)
+{
+    gGlobal->propagateAcc(acc, v);
+}
+
+/*
+ * setAccConverter(int p, int acc, int curve, float amin, float amid, float amax)
+ * Change accelerometer curve mapping.
+ */
+void setAccConverter(int p, int acc, int curve, float amin, float amid, float amax)
+{
+    //__android_log_print(ANDROID_LOG_ERROR, "Faust", "setAccConverter %d %d %d %f %f %f", p, acc, curve, amin, amid, amax);
+    gGlobal->setAccConverter(p, acc, curve, amin, amid, amax);
+}
+
+/*
+ * propagateGyr(int gyr, float v)
+ * Propage gyroscope value to the curve conversion layer.
+ */
+void propagateGyr(int gyr, float v)
+{
+    gGlobal->propagateGyr(gyr, v);
+}
+
+/*
+ * setGyrConverter(int p, int acc, int curve, float amin, float amid, float amax)
+ * Change gyroscope curve mapping.
+ */
+void setGyrConverter(int p, int gyr, int curve, float amin, float amid, float amax)
+{
+    //__android_log_print(ANDROID_LOG_ERROR, "Faust", "setAccConverter %d %d %d %f %f %f", p, acc, curve, amin, amid, amax);
+    gGlobal->setGyrConverter(p, gyr, curve, amin, amid, amax);
+}
+
diff --git a/architecture/android.cpp b/architecture/android.cpp
new file mode 100644
index 0000000..6ae404f
--- /dev/null
+++ b/architecture/android.cpp
@@ -0,0 +1,332 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File for Android
+ Copyright (C) 2013 GRAME, Romain Michon, CCRMA - Stanford University
+ Copyright (C) 2003-2013 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/*
+ * README:
+ * The file only implements the native part of faust2android applications.
+ * It uses a modified version of Victor Lazzarini's opensl_io (available at:
+ * https://bitbucket.org/victorlazzarini/android-audiotest) adapted to Faust
+ * to minimize latency.
+ * The native C API is documented at the end of this file in the "Native Faust
+ * API" section.
+ */
+
+#include <math.h>
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/meta.h"
+#include "faust/gui/jsonfaustui.h"
+#include "faust/gui/JSONUI.h"
+#include "faust/gui/MapUI.h"
+
+//**************************************************************
+// DSP class
+//**************************************************************
+
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+//**************************************************************
+// Polyphony
+//**************************************************************
+
+#include "faust/dsp/poly-dsp.h"
+
+//**************************************************************
+// Android Audio (modified opensl_io)
+//**************************************************************
+
+#define FAUSTFLOAT float
+
+#include "faust/audio/opensles-android-dsp.h"
+
+//**************************************************************
+// Native Faust API
+//**************************************************************
+
+#include <android/log.h>
+#include "dsp_faust.h"
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+OPENSL_STREAM *p;           // the audio engine
+mydsp DSP;                  // the monophonic Faust object
+mydsp_poly *DSPpoly = NULL; // the polyphonic Faust object
+MapUI mapUI;                // the UI description
+pthread_t audioThread;      // native thread for audio
+JSONUI json(DSP.getNumInputs(), DSP.getNumOutputs());
+string jsonString;
+
+// Global variables
+int SR, bufferSize, polyMax, inChanNumb, outChanNumb;
+float **bufferout, **bufferin;
+bool on;
+
+/*
+ * init(samplingRate, bufferFrames)
+ * Initializes the Audio engine and the DSP code
+ * with samplingRate and bufferFrames.
+ * This method also looks for the [style:poly]
+ * metadata in the Faust code and initializes a
+ * polyphonic object or not based on that. init
+ * should be called before start.
+ */
+void init(int samplingRate, int bufferFrames) {
+	// configuring global variables
+	SR = samplingRate;
+	bufferSize = bufferFrames;
+	DSP.init(SR);
+	inChanNumb = DSP.getNumInputs();
+	outChanNumb = DSP.getNumOutputs();
+
+	// configuring the UI
+	DSP.buildUserInterface(&mapUI);
+	DSP.buildUserInterface(&json);
+
+	jsonString = json.JSON();
+
+    if (jsonString.find("keyboard") != std::string::npos ||
+        jsonString.find("poly") != std::string::npos){
+        polyMax = 6;
+        DSPpoly = new mydsp_poly(bufferSize, polyMax);
+        DSPpoly->init(SR);
+    } else {
+        polyMax = 0;
+    }
+
+	// Allocating memory for output channels. Only the first two channels
+	// are played. Additional output channels are ignored.
+	bufferout = new float *[outChanNumb];
+	for (int i = 0; i < outChanNumb; i++) {
+		bufferout[i] = new float[bufferSize];
+	}
+
+	// Allocating memory for input channel. We assume no more than
+	// one physical input channel. Additional input channels will 
+	// share the content of input channel 0.
+	if (inChanNumb >= 1) {
+		bufferin = new float *[inChanNumb];
+		bufferin[0] = new float[bufferSize];
+		for (int i = 1; i < inChanNumb; i++) {
+			bufferin[i] = bufferin[0];
+		}
+	}
+}
+
+/*
+ * processDSP(threadID)
+ * Compute the DSP frames of the Faust object.
+ */
+void *processDSP(void *threadID) {
+	while (on) {
+		// getting input signal
+		if (inChanNumb >= 1) {
+			android_AudioIn(p, bufferin[0], bufferSize);
+        }
+
+		// computing...
+		if (polyMax == 0) {
+			DSP.compute(bufferSize, bufferin, bufferout);
+		} else {
+			DSPpoly->compute(bufferSize, bufferin, bufferout);
+        }
+
+		// sending output signal
+		android_AudioOut(p, bufferout, bufferSize);
+	}
+}
+
+/*
+ * start()
+ * Begins the processing and return 1 if the connection
+ * with the audio device was successful and 0 if not.
+ * On Android it also creates the native thread where the
+ * DSP tasks will be computed.
+ */
+bool start() {
+	on = true;
+	p = android_OpenAudioDevice(SR, min(1, inChanNumb), min(2, outChanNumb), bufferSize);
+	pthread_create(&audioThread, NULL, processDSP, NULL);
+	return (p != NULL);
+}
+
+/*
+ * stop()
+ * Stops the processing, closes the audio engine and terminates
+ * the native thread on Android.
+ */
+void stop() {
+	on = false;
+	pthread_join(audioThread, 0);
+	android_CloseAudioDevice(p);
+	for (int i = 0; i < outChanNumb; i++) {
+		delete[] bufferout[i];
+	}
+	delete[] bufferout;
+	if (inChanNumb >= 1) {
+		for (int i = 0; i < inChanNumb; i++) {
+			delete[] bufferin[i];
+		}
+		delete[] bufferin;
+	}
+	delete DSPpoly;
+}
+
+/*
+ * isRunning()
+ * returns true if the DSP frames are being computed and
+ * false if not.
+ */
+bool isRunning() {
+	return on;
+}
+
+/*
+ * keyOn(pitch, velocity)
+ * Instantiates a new polyphonic voice where velocity
+ * and pitch are MIDI numbers (0-127). keyOn can only
+ * be used if the [style:poly] metadata is used in the
+ * Faust code. keyOn will return 0 if the object is not
+ * polyphonic and 1 otherwise.
+ */
+int keyOn(int pitch, int velocity) {
+	if (polyMax > 0) {
+		DSPpoly->keyOn(0, pitch, velocity);
+		return 1;
+	} else {
+		return 0;
+    }
+}
+
+/*
+ * keyOff(pitch)
+ * De-instantiates a polyphonic voice where pitch is the
+ * MIDI number of the note (0-127). keyOff can only be
+ * used if the [style:poly] metadata is used in the Faust
+ * code. keyOn will return 0 if the object is not polyphonic
+ * and 1 otherwise.
+ */
+int keyOff(int pitch) {
+	if (polyMax > 0) {
+		DSPpoly->keyOff(0, pitch);
+		return 1;
+	} else {
+		return 0;
+    }
+}
+
+/*
+ * pitchBend(refPitch, pitch)
+ * Replaces refPitch in the voice associated with it with pitch.
+ * pitch is a MIDI number expressed as a decimal number.
+ * pitchBend can only be used if the [style:poly] metadata
+ * is used in the Faust code. pitchBend will return 0
+ * if the object is not polyphonic and 1 otherwise.
+ */
+int pitchBend(int refPitch, float pitch){
+	if (polyMax > 0) {
+		DSPpoly->pitchBend(0, refPitch, pitch);
+		return 1;
+	} else {
+		return 0;
+    }
+}
+
+/*
+ * getJSON()
+ * Returns a string containing a JSON description of the
+ * UI of the Faust object.
+ */
+const char *getJSON() {
+	return jsonString.c_str();
+}
+
+/*
+ * getParamsCount()
+ * Returns the number of parameters of the Faust object.
+ */
+int getParamsCount() {
+	return mapUI.getParamsCount();
+}
+
+/*
+ * getParam(address)
+ * Takes the address of a parameter and returns its current
+ * value.
+ */
+float getParam(const char* address) {
+	 return (polyMax == 0) ? mapUI.getValue(address) : DSPpoly->getValue(address);
+}
+
+/*
+ * setParam(address,value)
+ * Sets the value of the parameter associated with address.
+ */
+void setParam(const char* address, float value) {
+	if (polyMax == 0) {
+		mapUI.setValue(address, value);
+	} else {
+		DSPpoly->setValue(address, value);
+    }
+}
+
+/*
+ * setVoiceParam(address,pitch,value)
+ * Sets the value of the parameter associated with address for
+ * the voice associated with pitch. setVoiceParam can only be
+ * used if the [style:poly] metadata is used in the Faust code.
+ * setVoiceParam will return 0 if the object is not polyphonic
+ * and 1 otherwise.
+ */
+int setVoiceParam(const char* address, int pitch, float value) {
+	if (polyMax > 0) {
+		DSPpoly->setValue(address, pitch, value);
+		return 1;
+	} else {
+        return 0;
+    }
+}
+
+/*
+ * setVoiceGain(pitch,gain)
+ * Sets the gain (0-1) of the voice associated with pitch.
+ * setVoiceGain can only be used if the [style:poly] metadata
+ * is used in the Faust code. setVoiceGain will return 0 if the
+ * object is not polyphonic and 1 otherwise.
+ */
+int setVoiceGain(int pitch, float gain) {
+	if (polyMax > 0) {
+		DSPpoly->setVoiceGain(pitch, gain);
+		return 1;
+	} else {
+        return 0;
+    }
+}
+
+/*
+ * getParamAddress(id)
+ * Returns the address of a parameter in function of its "id".
+ */
+const char *getParamAddress(int id) {
+	return mapUI.getParamPath(id).c_str();
+}
diff --git a/architecture/android/Faust.iml b/architecture/android/Faust.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/architecture/android/Faust.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/classes/main" />
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/architecture/android/app/app.iml b/architecture/android/app/app.iml
new file mode 100644
index 0000000..c4921dc
--- /dev/null
+++ b/architecture/android/app/app.iml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":app" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
+    <orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
+  </component>
+</module>
+
diff --git a/architecture/android/app/build.gradle b/architecture/android/app/build.gradle
new file mode 100644
index 0000000..ccc45d8
--- /dev/null
+++ b/architecture/android/app/build.gradle
@@ -0,0 +1,42 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "22.0.1"
+
+    defaultConfig {
+        applicationId "com.faust"
+        minSdkVersion 16
+        targetSdkVersion 21
+
+        ndk {
+            moduleName "dsp_faust"
+            cFlags "-O3 -fexceptions -frtti"
+            ldLibs "OpenSLES"
+            ldLibs "log"
+            stl "gnustl_static"
+            abiFilters "armeabi-v7a"
+        }
+    }
+
+    signingConfigs {
+        release {
+            storeFile file("tools/faust2android.keystore")
+            storePassword "mephisto"
+            keyAlias "faust2an"
+            keyPassword "mephisto"
+        }
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+            signingConfig signingConfigs.release
+        }
+    }
+}
+
+dependencies {
+    compile 'com.android.support:support-v4:22.1.1'
+}
diff --git a/architecture/android/app/src/main/AndroidManifest.xml b/architecture/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..0c6e9c2
--- /dev/null
+++ b/architecture/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,62 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.faust"
+    android:versionCode="6"
+    android:versionName="1.5" >
+    
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+
+    <application
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name" >
+        <activity
+            android:name="com.faust.FaustActivity"
+            android:label="@string/app_name" 
+            android:windowSoftInputMode="stateHidden" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name="com.faust.PianoActivity"
+            android:label="@string/keyboard_activity"
+            android:parentActivityName="com.faust.FaustActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="orientation|keyboardHidden"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+            <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="com.faust.FaustActivity" />
+        </activity>
+        <activity
+            android:name="com.faust.MultiActivity"
+            android:label="@string/multi_activity"
+            android:parentActivityName="com.faust.FaustActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="orientation|keyboardHidden"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+            <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="com.faust.FaustActivity" />
+        </activity>
+        <activity
+            android:name="com.faust.MultiKeyboardActivity"
+            android:label="@string/multi_keyboard_activity"
+            android:parentActivityName="com.faust.FaustActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="orientation|keyboardHidden"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+            <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="com.faust.FaustActivity" />
+        </activity>
+     </application>
+
+</manifest>
diff --git a/architecture/android/app/src/main/java/android/widget/VerticalSeekBar.java b/architecture/android/app/src/main/java/android/widget/VerticalSeekBar.java
new file mode 100644
index 0000000..2207851
--- /dev/null
+++ b/architecture/android/app/src/main/java/android/widget/VerticalSeekBar.java
@@ -0,0 +1,67 @@
+package android.widget;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+public class VerticalSeekBar extends SeekBar {
+
+    public VerticalSeekBar(Context context) {
+        super(context);
+    }
+
+    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public VerticalSeekBar(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(h, w, oldh, oldw);
+    }
+
+    @Override
+    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
+        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
+    }
+
+    protected void onDraw(Canvas c) {
+        c.rotate(-90);
+        c.translate(-getHeight(),0);
+
+        super.onDraw(c);
+    }
+    
+    /*
+    public void setProgress(int progress){
+    	super.setProgress(progress+5000);
+    }
+    */
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (!isEnabled()) {
+            return false;
+        }
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+            case MotionEvent.ACTION_UP:
+             int i=0;
+             i=getMax() - (int) (getMax() * event.getY() / getHeight());
+                setProgress(i);
+                onSizeChanged(getWidth(), getHeight(), 0, 0);
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+                break;
+        }
+        return true;
+    }
+    
+}
\ No newline at end of file
diff --git a/architecture/android/app/src/main/java/com/dsp_faust/dsp_faust.java b/architecture/android/app/src/main/java/com/dsp_faust/dsp_faust.java
new file mode 100644
index 0000000..e568d43
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/dsp_faust/dsp_faust.java
@@ -0,0 +1,93 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.11
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package com.dsp_faust;
+import android.util.Log;
+
+public class dsp_faust {
+  public static void init(int arg0, int arg1) {
+    Log.d("FaustJava", "JNI init");
+    dsp_faustJNI.init(arg0, arg1);
+  }
+
+  public static int start() {
+    Log.d("FaustJava", "JNI start");
+    return dsp_faustJNI.start();
+  }
+
+  public static void stop() {
+    Log.d("FaustJava", "JNI stop");
+    dsp_faustJNI.stop();
+  }
+    
+  public static void destroy() {
+    Log.d("FaustJava", "JNI destroy");
+    dsp_faustJNI.destroy();
+  }
+
+  public static boolean isRunning() {
+    return dsp_faustJNI.isRunning();
+  }
+
+  public static int keyOn(int arg0, int arg1) {
+    return dsp_faustJNI.keyOn(arg0, arg1);
+  }
+
+  public static int keyOff(int arg0) {
+    return dsp_faustJNI.keyOff(arg0);
+  }
+
+  public static int pitchBend(int arg0, float arg1) {
+    return dsp_faustJNI.pitchBend(arg0, arg1);
+  }
+
+  public static String getJSON() {
+    return dsp_faustJNI.getJSON();
+  }
+
+  public static int getParamsCount() {
+    return dsp_faustJNI.getParamsCount();
+  }
+
+  public static float getParam(String arg0) {
+    return dsp_faustJNI.getParam(arg0);
+  }
+
+  public static void setParam(String arg0, float arg1) {
+    dsp_faustJNI.setParam(arg0, arg1);
+  }
+
+  public static int setVoiceParam(String arg0, int arg1, float arg2) {
+    return dsp_faustJNI.setVoiceParam(arg0, arg1, arg2);
+  }
+
+  public static int setVoiceGain(int arg0, float arg1) {
+    return dsp_faustJNI.setVoiceGain(arg0, arg1);
+  }
+
+  public static String getParamAddress(int arg0) {
+    return dsp_faustJNI.getParamAddress(arg0);
+  }
+    
+  public static void propagateAcc(int acc, float arg1) {
+    dsp_faustJNI.propagateAcc(acc, arg1);
+  }
+    
+  public static void setAccConverter(int p, int acc, int curve, float amin, float amid, float amax) {
+     dsp_faustJNI.setAccConverter(p, acc, curve, amin, amid,  amax);
+  }
+  
+  public static void propagateGyr(int gyr, float arg1) {
+    dsp_faustJNI.propagateGyr(gyr, arg1);
+  }
+    
+  public static void setGyrConverter(int p, int gyr, int curve, float amin, float amid, float amax) {
+     dsp_faustJNI.setGyrConverter(p, gyr, curve, amin, amid,  amax);
+  }
+ 
+}
diff --git a/architecture/android/app/src/main/java/com/dsp_faust/dsp_faustJNI.java b/architecture/android/app/src/main/java/com/dsp_faust/dsp_faustJNI.java
new file mode 100644
index 0000000..ef40470
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/dsp_faust/dsp_faustJNI.java
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.11
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package com.dsp_faust;
+
+public class dsp_faustJNI {
+
+  static {
+    try {
+        java.lang.System.loadLibrary("dsp_faust");
+    } catch (UnsatisfiedLinkError e) {
+        java.lang.System.err.println("native code library failed to load.\n" + e);
+        java.lang.System.exit(1);
+    }
+  }
+
+  public final static native void init(int jarg1, int jarg2);
+  public final static native int start();
+  public final static native void stop();
+  public final static native void destroy();
+  public final static native boolean isRunning();
+  public final static native int keyOn(int jarg1, int jarg2);
+  public final static native int keyOff(int jarg1);
+  public final static native int pitchBend(int jarg1, float jarg2);
+  public final static native String getJSON();
+  public final static native int getParamsCount();
+  public final static native float getParam(String jarg1);
+  public final static native void setParam(String jarg1, float jarg2);
+  public final static native int setVoiceParam(String jarg1, int jarg2, float jarg3);
+  public final static native int setVoiceGain(int jarg1, float jarg2);
+  public final static native String getParamAddress(int jarg1);
+  public final static native void propagateAcc(int jarg1, float jarg2);
+  public final static native void setAccConverter(int p, int acc, int curve, float amin, float amid, float amax);
+  public final static native void propagateGyr(int jarg1, float jarg2);
+  public final static native void setGyrConverter(int p, int gyr, int curve, float amin, float amid, float amax);
+}
diff --git a/architecture/android/app/src/main/java/com/faust/AccelUtil.java b/architecture/android/app/src/main/java/com/faust/AccelUtil.java
new file mode 100644
index 0000000..a4b4b3e
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/AccelUtil.java
@@ -0,0 +1,46 @@
+package com.faust;
+
+public class AccelUtil{
+    public float normalize(float accelValue){
+        return accelValue*0.005f+0.5f;
+    }
+	
+	// TODO: curve mode doesn't work properly
+	public float transform(float currentValue, float min, float max, float centerAccel, float centerSlider, int shape){
+		float out = 0.0f;
+
+        float accelMax = 100.0f;
+
+        currentValue = currentValue*-1.0f; //For some reasons the accelerometer orientation is reversed
+
+        if(shape == 1) currentValue = currentValue*-1.0f;
+
+        if(currentValue <= 0.0f) {
+            float downRange = centerAccel - min;
+            float downScaler = downRange/accelMax;
+            //float shiftThreshold = downRange/2;
+            out = centerAccel + currentValue/downScaler;
+            //if(shape == 2 && out < shiftThreshold) out = shiftThreshold - out;
+        }
+        else{
+            float upRange = max - centerAccel;
+            float upScaler = upRange/accelMax;
+            out = centerAccel + currentValue/upScaler;
+        };
+
+        if(out <= 0.0f) {
+            float downRange = centerSlider + 100.0f;
+            float downScaler = downRange/100.0f;
+            out = centerSlider + out*downScaler;
+        }
+        else{
+            float upRange = 100.0f - centerSlider;
+            float upScaler = upRange/accelMax;
+            out = centerSlider + out*upScaler;
+        };
+
+        out = normalize(out);
+
+		return out;
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/BarGraph.java b/architecture/android/app/src/main/java/com/faust/BarGraph.java
new file mode 100644
index 0000000..a884977
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/BarGraph.java
@@ -0,0 +1,69 @@
+package com.faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
+
+import android.util.AttributeSet;
+import android.widget.ProgressBar;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import android.util.Log;
+
+class BarGraph {
+    int id = 0;
+	float min = 0.0f, max = 100.0f;
+    LinearLayout barLayout;
+    String address = "";
+    LinearLayout frame, localVerticalGroup;
+    ProgressBar bar;
+	
+	public BarGraph(Context c, String addr, int currentParameterID,  AttributeSet attrs, int defStyle, int width, int backgroundColor, boolean visibility) {
+	       
+        id = currentParameterID;
+        address = addr;
+        
+        bar = new ProgressBar(c, attrs, defStyle);
+        bar.setMax(1000);
+        //bar.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+        bar.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,100));
+        
+        frame = new LinearLayout(c);
+        frame.setLayoutParams(new ViewGroup.LayoutParams(width, ViewGroup.LayoutParams.WRAP_CONTENT));
+        frame.setOrientation(LinearLayout.VERTICAL);
+        frame.setBackgroundColor(Color.rgb(backgroundColor, backgroundColor, backgroundColor));
+        frame.setPadding(2,2,2,2);
+        
+        barLayout = new LinearLayout(c);
+        barLayout.setLayoutParams(new ViewGroup.LayoutParams(width, ViewGroup.LayoutParams.MATCH_PARENT));
+        
+        
+        localVerticalGroup = new LinearLayout(c);
+        localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+        localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15,
+                                                        backgroundColor+15, backgroundColor+15));
+        
+        if (visibility) {
+            barLayout.addView(bar);
+            localVerticalGroup.addView(barLayout);
+            frame.addView(localVerticalGroup);
+        }
+	}
+	
+	public void setValue(float value){
+        bar.setProgress((int) ((value-min)*1000/(max-min)));
+	}
+    
+    /*
+     * Add the slider to group
+     */
+    public void addTo(LinearLayout group){
+        group.addView(frame);
+    }
+}
diff --git a/architecture/android/app/src/main/java/com/faust/Checkbox.java b/architecture/android/app/src/main/java/com/faust/Checkbox.java
new file mode 100644
index 0000000..514dae8
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/Checkbox.java
@@ -0,0 +1,91 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+class Checkbox{
+	int id = 0;
+	String address = "";
+	LinearLayout frame, localVerticalGroup;
+	CheckBox checkbox;
+    TextView textLabel;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 * label: the parameter's name
+	 */
+	public Checkbox(Context c, String addr, int currentParameterID,
+			int width, int height, int backgroundColor, String label){
+		id = currentParameterID;
+		address = addr;
+		
+		checkbox = new CheckBox(c);
+		checkbox.setGravity(Gravity.CENTER);
+		//checkbox.setText(label);
+        checkbox.setButtonDrawable(null);
+        checkbox.setBackgroundResource(R.drawable.checkbox);
+        checkbox.setLayoutParams(new ViewGroup.LayoutParams(
+                height, height));
+
+        textLabel = new TextView(c);
+        textLabel.setGravity(Gravity.CENTER);
+        textLabel.setText(label);
+		
+		frame = new LinearLayout(c);
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+        localVerticalGroup.setPadding(0,10,0,10);
+		
+		localVerticalGroup.addView(checkbox);
+        localVerticalGroup.addView(textLabel);
+	    frame.addView(localVerticalGroup);
+	}
+	
+	public void setStatus(float value){
+		if(value == 0.0f) checkbox.setChecked(false);
+		else if(value != 0.0f) checkbox.setChecked(true);
+	}
+	
+	/*
+	 * Add the checkbox to group
+	 */
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	/*
+	 * Set the checkbox's listeners
+	 */
+	public void linkTo(final ParametersInfo parametersInfo){
+		checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+        	@Override
+        	public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
+        		if (isChecked) parametersInfo.values[id] = 1.f;
+        		else parametersInfo.values[id] = 0.f;
+        		dsp_faust.setParam(address, parametersInfo.values[id]);
+        	}
+        });
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/ConfigWindow.java b/architecture/android/app/src/main/java/com/faust/ConfigWindow.java
new file mode 100644
index 0000000..db0b473
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/ConfigWindow.java
@@ -0,0 +1,278 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+import android.util.Log;
+
+/*
+ * TODO:
+ * - the min, max and center slider should be aligned
+ */
+
+public class ConfigWindow{
+	PopupWindow mainWindow;
+	LinearLayout mainWindowLayout, minSliderLayout, maxSliderLayout, centerSliderLayout, windowLayout, titleLayout;
+	SelectBar axisSelection, axisOrientation;
+	TextView closeButton,minSliderValue, maxSliderValue, centerSliderValue, windowLabel;
+	SeekBar minSlider, maxSlider, centerSlider;
+	Point size;
+	
+	public void buildWindow(Context c){
+		WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		size = new Point();
+		display.getSize(size);
+		// the global elements are instantiated
+		mainWindowLayout = new LinearLayout(c);
+		minSliderLayout = new LinearLayout(c);
+		maxSliderLayout = new LinearLayout(c);
+		centerSliderLayout = new LinearLayout(c);
+		
+		mainWindow = new PopupWindow(c);
+		
+		closeButton = new TextView(c);
+		minSliderValue = new TextView(c);
+		maxSliderValue = new TextView(c);
+		centerSliderValue = new TextView(c);
+		
+		axisSelection = new SelectBar(c);
+		axisOrientation = new SelectBar(c);
+		
+		minSlider = new SeekBar(c);
+		maxSlider = new SeekBar(c);
+		centerSlider = new SeekBar(c);
+		
+		windowLayout = new LinearLayout(c);
+		titleLayout = new LinearLayout(c);
+		windowLabel = new TextView(c);
+		TextView axisLabel = new TextView(c);
+		TextView orientationLabel = new TextView(c);
+		
+		LayoutParams wrapped = new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+		
+		windowLayout.setLayoutParams(wrapped);
+		windowLayout.setOrientation(LinearLayout.VERTICAL);
+		windowLayout.setPadding(10, 0, 10, 0); // TODO adjust in function of screen size
+		
+		titleLayout.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		titleLayout.setOrientation(LinearLayout.HORIZONTAL);
+		
+		closeButton.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		closeButton.setGravity(Gravity.RIGHT);
+		closeButton.setTextSize(20);
+		closeButton.setText("X");
+			
+		windowLabel.setText("Accelerometer/gyroscope parameters");
+		windowLabel.setTextSize(16.f);
+		
+		axisLabel.setText("Axis ");
+		orientationLabel.setText("Orientation ");
+		
+		String[] items = {"0","aX","aY","aZ","gX","gY","gZ"};
+		axisSelection.setItems(items);
+		
+		int[] iconsOn = {R.drawable.ic_accelnormon,R.drawable.ic_accelinverton,R.drawable.ic_accelcurveon,R.drawable.ic_accelinvertcurveon};
+		int[] iconsOff = {R.drawable.ic_accelnormoff,R.drawable.ic_accelinvertoff,R.drawable.ic_accelcurveoff,R.drawable.ic_accelinvertcurveoff};
+		axisOrientation.setItems(iconsOn,iconsOff);
+		
+		minSlider.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		minSlider.setMax(1000);
+		
+		maxSlider.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		maxSlider.setMax(1000);
+		
+		centerSlider.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		centerSlider.setMax(1000);
+						
+		titleLayout.addView(windowLabel);
+		titleLayout.addView(closeButton);
+		
+		windowLayout.addView(titleLayout);
+		windowLayout.addView(axisLabel);
+		axisSelection.addTo(windowLayout);
+		
+		windowLayout.addView(orientationLabel);
+		axisOrientation.addTo(windowLayout);
+		
+		minSliderLayout.addView(minSliderValue);
+		minSliderLayout.addView(minSlider);
+		
+		maxSliderLayout.addView(maxSliderValue);
+		maxSliderLayout.addView(maxSlider);
+		
+		centerSliderLayout.addView(centerSliderValue);
+		centerSliderLayout.addView(centerSlider);
+		
+		windowLayout.addView(minSliderLayout);
+		windowLayout.addView(maxSliderLayout);
+		windowLayout.addView(centerSliderLayout);
+				
+		mainWindow.setContentView(windowLayout);
+	}
+    
+    void updateAccGyr(final ParametersInfo parametersInfo, int index)
+    {
+        /*
+        Log.d("FaustJava", "updateAccGyr :  " + index
+            + " " + parametersInfo.accgyrType[index]
+            + " " + parametersInfo.accgyrCurve[index]
+            + " " + parametersInfo.accgyrMin[index]
+            + " " + parametersInfo.accgyrCenter[index]
+            + " " + parametersInfo.accgyrMax[index]);
+        */
+        
+        if (parametersInfo.accgyrType[index] == 0) {
+            dsp_faust.setAccConverter(index, -1, 0, 0, 0, 0); // -1 means no mapping
+            dsp_faust.setGyrConverter(index, -1, 0, 0, 0, 0); // -1 means no mapping
+        } else if (parametersInfo.accgyrType[index] <= 3) {
+            dsp_faust.setAccConverter(index,
+                                      parametersInfo.accgyrType[index] - 1,  // Java : from 0 to 3 (0 means no mapping), C : -1 to 2 (-1 means no mapping)
+                                      parametersInfo.accgyrCurve[index],
+                                      parametersInfo.accgyrMin[index],
+                                      parametersInfo.accgyrCenter[index],
+                                      parametersInfo.accgyrMax[index]);
+        
+        } else {
+            dsp_faust.setGyrConverter(index,
+                                      parametersInfo.accgyrType[index] - 4,  // Java : from 0 to 3 (0 means no mapping), C : -1 to 2 (-1 means no mapping)
+                                      parametersInfo.accgyrCurve[index],
+                                      parametersInfo.accgyrMin[index],
+                                      parametersInfo.accgyrCenter[index],
+                                      parametersInfo.accgyrMax[index]);
+        }
+    }
+	
+	public void showWindow(final ParametersInfo parametersInfo, final int currentParameterNumber){
+		// Saved state is used
+		axisSelection.selectTextItem(parametersInfo.accgyrType[currentParameterNumber]);
+		axisOrientation.selectImgItem(parametersInfo.accgyrCurve[currentParameterNumber]);
+		
+		setValue(minSlider,minSliderValue,"Min  ",parametersInfo.accgyrMin[currentParameterNumber]);
+		setValue(maxSlider,maxSliderValue,"Max  ",parametersInfo.accgyrMax[currentParameterNumber]);
+		setValue(centerSlider,centerSliderValue,"Center  ",parametersInfo.accgyrCenter[currentParameterNumber]);
+		
+		mainWindow.showAtLocation(mainWindowLayout, Gravity.CENTER,0,0);
+		mainWindow.update(0, 0, size.x*700/800, ViewGroup.LayoutParams.WRAP_CONTENT);
+		
+		titleLayout.setOnClickListener(new OnClickListener(){
+			public void onClick(View v){
+				mainWindow.dismiss();
+			}
+		});
+		
+		for(int i=0; i<axisSelection.length; i++){
+			final int index = i;
+			axisSelection.parameterLabel[i].setOnClickListener(new OnClickListener(){
+				public void onClick(View v){
+					axisSelection.selectTextItem(index);
+                    Log.d("FaustJava", "OnClickListener : " + index);
+					parametersInfo.accgyrType[currentParameterNumber] = index;
+                    updateAccGyr(parametersInfo, currentParameterNumber);
+				}
+			});
+		}
+		
+		for(int i=0; i<axisOrientation.length; i++){
+			final int index = i;
+			axisOrientation.imgs[i].setOnClickListener(new OnClickListener(){
+				public void onClick(View v){
+					axisOrientation.selectImgItem(index);
+					parametersInfo.accgyrCurve[currentParameterNumber] = index;
+                    updateAccGyr(parametersInfo, currentParameterNumber);
+				}	
+			});
+		}
+		
+		minSlider.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
+			public void onStopTrackingTouch(SeekBar seekBar) {}
+			public void onStartTrackingTouch(SeekBar seekBar) {}
+			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                //Log.d("FaustJava", "onProgressChanged : " + fromUser);
+                if (fromUser) {
+                    float scaledProgress = progress*0.2f - 100.0f;
+                    if(scaledProgress >= parametersInfo.accgyrMax[currentParameterNumber])
+                        setValue(minSlider,minSliderValue,"Min  ",parametersInfo.accgyrMax[currentParameterNumber]);
+                    else{ 
+                        parametersInfo.accgyrMin[currentParameterNumber] = scaledProgress;
+                        minSliderValue.setText("Min  " + String.format("%.1f", scaledProgress));
+                        //Log.d("FaustJava", "onProgressChanged : currentParameterNumber Min " + currentParameterNumber + " " + scaledProgress);
+                        updateAccGyr(parametersInfo, currentParameterNumber);
+                    }
+                }
+            }
+	    });
+		
+		maxSlider.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
+			public void onStopTrackingTouch(SeekBar seekBar) {}
+			public void onStartTrackingTouch(SeekBar seekBar) {}
+			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                //Log.d("FaustJava", "onProgressChanged : " + fromUser);
+                if (fromUser) {
+                    float scaledProgress = progress*0.2f - 100.0f;
+                    if(scaledProgress <= parametersInfo.accgyrMin[currentParameterNumber])
+                        setValue(maxSlider,maxSliderValue,"Max  ",parametersInfo.accgyrMin[currentParameterNumber]);
+                    else{ 
+                        parametersInfo.accgyrMax[currentParameterNumber] = scaledProgress;
+                        maxSliderValue.setText("Max  " + String.format("%.1f", scaledProgress));
+                        //Log.d("FaustJava", "onProgressChanged : currentParameterNumber Max " + currentParameterNumber + " " + scaledProgress);
+                        updateAccGyr(parametersInfo, currentParameterNumber);
+                    }
+                }
+            }
+	    });
+		
+		centerSlider.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
+			public void onStopTrackingTouch(SeekBar seekBar) {}
+			public void onStartTrackingTouch(SeekBar seekBar) {}
+			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                //Log.d("FaustJava", "onProgressChanged : " + fromUser);
+                if (fromUser) {
+                    float scaledProgress = progress*0.2f - 100.0f;
+                    if(scaledProgress <= parametersInfo.accgyrMin[currentParameterNumber])
+                        setValue(centerSlider,centerSliderValue,"Center  ",parametersInfo.accgyrMin[currentParameterNumber]);
+                    else if(scaledProgress >= parametersInfo.accgyrMax[currentParameterNumber])
+                        setValue(centerSlider,centerSliderValue,"Center  ",parametersInfo.accgyrMax[currentParameterNumber]);
+                    else{ 
+                        parametersInfo.accgyrCenter[currentParameterNumber] = scaledProgress;	
+                        centerSliderValue.setText("Center  " + String.format("%.1f", scaledProgress));
+                        //Log.d("FaustJava", "onProgressChanged : currentParameterNumber Center " + currentParameterNumber + " " + scaledProgress);
+                        updateAccGyr(parametersInfo, currentParameterNumber);
+                    }
+                }
+            }
+	    });
+	}
+	
+	void setValue(SeekBar s, TextView t, String name, float x){
+        System.out.println(x);
+		t.setText(name + String.format("%.1f",x));
+        s.setProgress(Math.round(x*5+500));
+	}
+	
+	/*
+	public void registerParameters(int[] UIelementsParameters){
+		UIelementsParameters[0] = axisSelection.id;
+	}
+	*/
+}
diff --git a/architecture/android/app/src/main/java/com/faust/FaustActivity.java b/architecture/android/app/src/main/java/com/faust/FaustActivity.java
new file mode 100644
index 0000000..abfacb5
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/FaustActivity.java
@@ -0,0 +1,266 @@
+package com.faust;
+
+/*
+ * TODO
+ * - Make all accel meta data compatible
+ * - The knob class could be greatly improved
+ * - Drop down menu for actions for small screens 
+ * - Vertical sliders are fucked up with accelerometers.
+ * - Bargraphs are disabled and need more work
+ * - Interface elements could be normalized using android standards
+ * (that would take forever and the difference would be hard to notice)
+ * - The accelerometers window should be finished: weird stuff with up and down
+ * 		- Fancy slider to control min, max and center
+ * - Settings menu should be added actually not sure about that...
+ * - Multitouch zoom
+ * - Try complex examples for debuging
+ * - The compilation script should be tested on OSX
+ * - OSC should be enabled
+ * - If keyboard mode is enabled, elements that removed from the interface should be scaled
+ * - Write a proper documentation
+ * - Make the native API OSX compatible
+ * - Ideally, the C++ API should be able to return min, max, etc... it would be very convenient
+ * when an app uses several activities.
+ * - Xruns sometimes, not sure why...
+ * - Polymax should be defined by "keyboard" in the Faust code...
+ * - It seems that when polyphonic, voices are always computed which is highly ineficient... 
+ * - Multi Params
+ * 		- Cosmetic: Big dots when the parameter is being touched.
+ * 		- Accelerometer should be enabled in function of what was
+ * 		configured in the main interface.
+ * - Piano Keyboard
+ * 		- Add a dot that would follow the finger when going
+ * 		outside of a key.
+ * 		- The way the position of the keys on the keyboard is set
+ * 		is kind of flumsy: this could be improved.
+ * SL : 08/13/15
+ * - use index instead of adresses in JNI to access parameters
+ */
+
+import com.dsp_faust.dsp_faust;
+import com.illposed.osc.OSCListener;
+import com.illposed.osc.OSCMessage;
+import com.illposed.osc.OSCPort;
+import com.illposed.osc.OSCPortIn;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+
+import android.util.Log;
+import android.net.wifi.WifiManager;
+
+import java.net.SocketException;
+
+public class FaustActivity extends Activity {
+	private SensorManager mSensorManager;
+	private int numberOfParameters;
+	private UI ui = new UI();
+	private ParametersInfo parametersInfo = new ParametersInfo();
+    private long lastUIDate;
+    private WifiManager.MulticastLock lock;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.d("FaustJava", "onCreate");
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+	
+        if (!dsp_faust.isRunning()) {
+            
+            WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE );
+            if (wifi != null) {
+                WifiManager.MulticastLock lock = wifi.createMulticastLock("Log_Tag");
+                lock.acquire();
+            }
+            // attempting to open a new OSC port, if default not available create a new one
+            int oscPortNumber = 5510;
+            while (!Osc.init(oscPortNumber)) oscPortNumber++;
+            Log.d("FaustJava", "onCreate : OSC In Port " + oscPortNumber);
+            dsp_faust.init(44100,512);
+            Osc.startListening();
+        }
+      
+        numberOfParameters = dsp_faust.getParamsCount();
+        
+        Log.d("FaustJava", "onCreate : numberOfParameters " + numberOfParameters);
+        
+        parametersInfo.init(numberOfParameters);
+        SharedPreferences settings = getSharedPreferences("savedParameters", 0);
+
+        LinearLayout mainGroup = (LinearLayout) findViewById(R.id.the_layout);
+        HorizontalScrollView horizontalScroll = (HorizontalScrollView) findViewById(R.id.horizontalScroll);
+        ui.horizontalScroll = horizontalScroll;
+        
+        ui.initUI(parametersInfo,settings);	
+        ui.buildUI(this, mainGroup);
+
+        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+    }
+    
+    private final SensorEventListener mSensorListener = new SensorEventListener() {
+		public void onSensorChanged(SensorEvent se) {
+
+            long curDate = java.lang.System.currentTimeMillis();
+            long deltaUI = curDate - lastUIDate;
+    
+            if (se.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+                // Update mapping at sensor rate
+                dsp_faust.propagateAcc(0, se.values[0]);
+                dsp_faust.propagateAcc(1, se.values[1]);
+                dsp_faust.propagateAcc(2, se.values[2]);
+            }
+    
+            if (se.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
+                // Update mapping at sensor rate
+                dsp_faust.propagateGyr(0, se.values[0]);
+                dsp_faust.propagateGyr(1, se.values[1]);
+                dsp_faust.propagateGyr(2, se.values[2]);
+            }
+    
+            // Update UI less often
+            if (deltaUI > 100) {
+                lastUIDate = curDate;
+                ui.updateUIstate();
+            }
+		}
+	    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+	};
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        Log.d("FaustJava", "onCreateOptionsMenu");
+        // Inflate the menu items for use in the action bar
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.main_activity_actions, menu);
+        MenuItem lockItem = menu.getItem(3); // retrieving the registered ID doesn't seem to work -> hardcoded here
+        MenuItem keybItem = menu.getItem(0);
+        if (!parametersInfo.locked) {
+    		lockItem.setIcon(R.drawable.ic_lockiconopen);
+    	} else {
+    		lockItem.setIcon(R.drawable.ic_lockiconclose);
+    		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
+    	}
+        // display the keyboard icon if the Faust code enables keyboard interfaces
+        if (!ui.hasKeyboard && !ui.hasMulti) keybItem.setVisible(false);
+        return super.onCreateOptionsMenu(menu);
+    }
+    
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle presses on the action bar items
+        switch (item.getItemId()) {
+        	case R.id.action_keyboard:
+        		if(ui.hasKeyboard && !ui.hasMulti){
+        			Intent pianoIntent = new Intent(this, PianoActivity.class);
+        			startActivity(pianoIntent);
+        		}
+        		else if(ui.hasMulti && !ui.hasKeyboard){
+        			SharedPreferences settings = getSharedPreferences("savedParameters", 0);
+        		    parametersInfo.saveParameters(settings);
+        			Intent multiIntent = new Intent(this, MultiActivity.class);
+        			startActivity(multiIntent);
+        		}
+        		else if(ui.hasMulti && ui.hasKeyboard){
+        			SharedPreferences settings = getSharedPreferences("savedParameters", 0);
+        		    parametersInfo.saveParameters(settings);
+        			Intent multiIntent = new Intent(this, MultiKeyboardActivity.class);
+        			startActivity(multiIntent);
+        		}
+        		return true;
+            case R.id.action_zoomin:
+            	parametersInfo.zoom++;
+                recreate();
+                return true;
+            case R.id.action_zoomout:
+            	if (parametersInfo.zoom > 0) {
+            		parametersInfo.zoom--;
+            		recreate();
+            	}
+                return true;
+            case R.id.action_reset:
+                parametersInfo.saved = 0;
+                recreate();
+                return true;
+            case R.id.action_lock:
+            	if (parametersInfo.locked) {
+            		item.setIcon(R.drawable.ic_lockiconopen);
+            		parametersInfo.locked = false;
+            		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
+            	}
+            	else {
+            		item.setIcon(R.drawable.ic_lockiconclose);
+            		parametersInfo.locked = true;
+            		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
+            	}
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+    
+    @Override
+   	protected void onPause() {
+        Log.d("FaustJava", "onPause");
+   		mSensorManager.unregisterListener(mSensorListener);
+   		super.onPause();
+   	}
+
+    @Override
+    protected void onResume() {
+        Log.d("FaustJava", "onResume");
+		super.onResume();
+        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(
+	    		Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
+   }
+
+    @Override
+    protected void onStart() {
+        Log.d("FaustJava", "onStart");
+        super.onStart();
+        if (!isChangingConfigurations()) {
+            dsp_faust.start();
+        }
+        ui.updateUIstate();
+    }
+
+    @Override
+    protected void onRestart() {
+        Log.d("FaustJava", "onRestart");
+        super.onRestart();
+    }
+
+    @Override
+    protected void onStop(){
+        Log.d("FaustJava", "onStop");
+        super.onStop();
+        if (!isChangingConfigurations()) {
+            dsp_faust.stop();
+        }
+    }
+
+    @Override
+    public void onDestroy(){
+        Log.d("FaustJava", "onDestroy");
+    	super.onDestroy();
+    	// only stops audio when the user press the return button (and not when the screen is rotated)
+    	if (!isChangingConfigurations()) {
+            Osc.stopListening();
+            lock.release();
+    		dsp_faust.destroy();
+        }
+        SharedPreferences settings = getSharedPreferences("savedParameters", 0);
+        parametersInfo.saveParameters(settings);
+    }
+}
diff --git a/architecture/android/app/src/main/java/com/faust/HorizontalSlider.java b/architecture/android/app/src/main/java/com/faust/HorizontalSlider.java
new file mode 100644
index 0000000..c9ccc98
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/HorizontalSlider.java
@@ -0,0 +1,177 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+
+import android.util.Log;
+
+/*
+ * Create a horizontal slider that displays its current value on its left. 
+ */
+
+class HorizontalSlider {
+	float min = 0.0f, max = 100.0f, step = 1.0f;
+	int id = 0;
+	String decimalsDisplay = "", address = "";
+	LinearLayout frame, sliderLayout, localVerticalGroup;
+	SeekBar slider;
+	TextView textValue, textLabel;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 * padding: padding of the view in pxs
+	 */
+	public HorizontalSlider(Context c, String addr, int currentParameterID, 
+			int width, int backgroundColor, int padding, boolean visibility) {
+		id = currentParameterID;
+		address = addr;
+		
+		slider = new SeekBar(c);
+		slider.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		
+		frame = new LinearLayout(c);
+		setWidth(width);
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		sliderLayout = new LinearLayout(c);
+		sliderLayout.setOrientation(LinearLayout.HORIZONTAL);
+		sliderLayout.setPadding(padding, 0, padding, 0);
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+		
+		textLabel = new TextView(c);
+		textLabel.setGravity(Gravity.CENTER);
+		
+		textValue = new TextView(c);
+		
+		if (visibility) {
+			sliderLayout.addView(textValue);
+			sliderLayout.addView(slider);
+			localVerticalGroup.addView(textLabel);
+			localVerticalGroup.addView(sliderLayout);
+			frame.addView(localVerticalGroup);
+		}
+	}
+	
+	/*
+	 * Set the slider parameters
+	 * label: the name of the parameter
+	 * minimum: the slider's minimum value
+	 * maximum: the slider's maximum value
+	 * stp: the slider's step
+	 */
+	public void setParams(String label, float minimum, float maximum, float stp){
+		textLabel.setText(label);
+		min = minimum;
+		max = maximum;
+		step = stp;
+		slider.setMax(Math.round((max-min)*(1/step)));
+		int decimals = 0;
+		if(step>=1) decimals = 1;
+		else if(step<1 && step>=0.1) decimals = 1;
+		else decimals = 2;
+		decimalsDisplay = "%."+decimals+"f";
+	}
+	
+	public void setWidth(int width){
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+	}
+	
+	/*
+	 * Set the value displayed next to the slider
+	 */
+	public void setDisplayedValue(float theValue){
+		textValue.setText(String.format(decimalsDisplay, theValue));
+	}
+	
+	/*
+	 * Set the slider's value
+	 */
+	// TODO: this screwed but was fixed to work with the multi interface 
+	// but there might still be weird things going on...
+	public void setValue(float theValue){
+        /*
+        if(theValue<=0 && min<0) slider.setProgress(Math.round(theValue*(1/step)+min));
+		else slider.setProgress(Math.round(theValue*(1/step)-min));
+         */
+        //SL : seems wrong, corrected 08/12/2015
+        slider.setProgress(Math.round((theValue-min)/step));
+        setDisplayedValue(theValue);
+	}
+	
+	/*
+	 * Set the value of the slider as a number between 0 and 1
+	 */
+	public void setNormizedValue(float theValue){
+		slider.setProgress(Math.round(theValue*(max-min)/step));
+	}
+	
+	/*
+	 * Add the slider to group
+	 */
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	/*
+	 * Set the slider's listeners
+	 */
+	public void linkTo(final ParametersInfo parametersInfo, final ConfigWindow parametersWindow, final HorizontalScrollView horizontalScroll){
+		localVerticalGroup.setOnLongClickListener(new OnLongClickListener() {
+			public boolean onLongClick (View v){
+       			if(!parametersInfo.locked) parametersWindow.showWindow(parametersInfo, id);
+    			return true;
+			}
+		});
+		
+		slider.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+			public void onStopTrackingTouch(SeekBar seekBar) {
+				parametersInfo.accgyrItemFocus[id] = 0;
+			}
+			public void onStartTrackingTouch(SeekBar seekBar) {
+				parametersInfo.accgyrItemFocus[id] = 1;
+			}
+			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+				parametersInfo.values[id] = (float) progress*step + min;
+				dsp_faust.setParam(address, parametersInfo.values[id]);
+				setDisplayedValue(parametersInfo.values[id]);
+            }
+	    });
+	    
+	    slider.setOnTouchListener(new OnTouchListener()
+	    {
+	        public boolean onTouch(final View view, final MotionEvent event)
+	        {
+	          if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
+	            horizontalScroll.requestDisallowInterceptTouchEvent(true);
+	          return false;
+	        }
+	    });
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/Knob.java b/architecture/android/app/src/main/java/com/faust/Knob.java
new file mode 100644
index 0000000..b4a44c6
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/Knob.java
@@ -0,0 +1,178 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+import com.triggertrap.seekarc.SeekArc;
+import com.triggertrap.seekarc.SeekArc.OnSeekArcChangeListener;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.View.OnLongClickListener;
+import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/*
+ * Create a knob. 
+ */
+
+class Knob {
+	float min = 0.0f, max = 100.0f, step = 1.0f;
+	int id = 0;
+	String decimalsDisplay = "", address = "";
+	FrameLayout knobLayout;
+	LinearLayout frame, localVerticalGroup;
+	SeekArc knob;
+	TextView textValue, textLabel;
+	Point size;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 */
+	public Knob(Context c, String addr, int currentParameterID,
+			int width, int backgroundColor, int padding, boolean visibility) {
+		WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		size = new Point();
+		display.getSize(size);
+		
+		id = currentParameterID;
+		address = addr;
+		
+		knob = new SeekArc(c);
+		knob.setPadding(padding, padding, padding, padding);
+		knob.setRotation(180);
+		knob.setStartAngle(30);
+		knob.setSweepAngle(300);
+		knob.setTouchInSide(true);
+		
+		frame = new LinearLayout(c);
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		knobLayout = new FrameLayout(c);
+		knobLayout.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, width));
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		//localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+		
+		textLabel = new TextView(c);
+		textLabel.setGravity(Gravity.CENTER);
+		
+		textValue = new TextView(c);
+		textValue.setGravity(Gravity.CENTER);
+		
+		if (visibility) {
+			knobLayout.addView(textValue);
+			knobLayout.addView(knob);
+			localVerticalGroup.addView(knobLayout);
+			localVerticalGroup.addView(textLabel);
+			frame.addView(localVerticalGroup);
+		}
+	}
+	
+	/*
+	 * Set the slider parameters
+	 * label: the name of the parameter
+	 * minimum: the slider's minimum value
+	 * maximum: the slider's maximum value
+	 * stp: the slider's step
+	 */
+	public void setParams(String label, float minimum, float maximum, float stp){
+		textLabel.setText(label);
+		min = minimum;
+		max = maximum;
+		step = stp;
+		int decimals = 0;
+		if(step>=1) decimals = 1;
+		else if(step<1 && step>=0.1) decimals = 1;
+		else decimals = 2;
+		decimalsDisplay = "%."+decimals+"f";
+	}
+	
+	/*
+	 * Set the value displayed next to the slider
+	 */
+	public void setDisplayedValue(float theValue){
+		textValue.setText(String.format(decimalsDisplay, theValue));
+	}
+	
+	/*
+	 * Set the slider's value
+	 */
+	public void setValue(float theValue){
+		// the initial value of the knob is set (SeekArc's range is 0-100)
+		knob.setProgress(Math.round(((theValue-min)*100)/(max-min)));
+		setDisplayedValue(theValue);
+	}
+	
+	/*
+	 * Set the value of the slider as a number between 0 and 1
+	 */
+	public void setNormizedValue(float theValue){
+		knob.setProgress(Math.round(theValue*100));
+	}
+	
+	/*
+	 * Add the slider to group
+	 */
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	/*
+	 * Set the slider's listeners
+	 */
+	public void linkTo(final ParametersInfo parametersInfo, final ConfigWindow parametersWindow, final HorizontalScrollView horizontalScroll){
+		localVerticalGroup.setOnLongClickListener(new OnLongClickListener(){
+			public boolean onLongClick (View v){
+				if(!parametersInfo.locked) parametersWindow.showWindow(parametersInfo, id);
+				return true;
+			}
+		});
+		
+		knob.setOnSeekArcChangeListener( new OnSeekArcChangeListener() {
+			public void onStopTrackingTouch(SeekArc seekArc) {
+				parametersInfo.accgyrItemFocus[id] = 0;
+			}
+			public void onStartTrackingTouch(SeekArc seekArc) {
+				parametersInfo.accgyrItemFocus[id] = 1;
+			}
+			public void onProgressChanged(SeekArc seekArc, int progress, boolean fromUser) {
+				parametersInfo.values[id] = (float) progress*0.01f*(max-min) + min;
+				dsp_faust.setParam(address, parametersInfo.values[id]);
+				setDisplayedValue(parametersInfo.values[id]);
+	          }
+	    });
+		
+		/*
+		knob.setOnTouchListener(new OnTouchListener()
+	    {
+	        public boolean onTouch(final View view, final MotionEvent event)
+	        {
+	          if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
+	            horizontalScroll.requestDisallowInterceptTouchEvent(true);
+	          return false;
+	        }
+	    });
+	    */
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/Menu.java b/architecture/android/app/src/main/java/com/faust/Menu.java
new file mode 100644
index 0000000..a87972d
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/Menu.java
@@ -0,0 +1,128 @@
+package com.faust;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+class Menu{
+	int ID = 0;
+	float[] values;
+	String address = "";
+	Spinner menu;
+	List<String> parametersList;
+	LinearLayout frame, localVerticalGroup;
+	TextView textLabel;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 */
+	public Menu(Context c, String addr, int currentParameterID,
+			int width, int backgroundColor, String parsedParameters, boolean visibility){
+		ID = currentParameterID;
+		address = addr;
+		
+		parametersList = new ArrayList<String>();
+		
+		menu = new Spinner(c);
+		menu.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		
+		frame = new LinearLayout(c);
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+		
+		textLabel = new TextView(c);
+		textLabel.setGravity(Gravity.CENTER);
+		
+		// length of the elements array
+		int length = parsedParameters.length(); 
+		int nElements = countStringOccurrences(parsedParameters,";")+1;
+		values = new float[nElements];
+		// a menu item with a value assigned to it is created for each element of the array
+		for(int i=0; i<nElements; i++){
+			String parameterName = parsedParameters.substring(1, parsedParameters.indexOf(":") - 1);
+			if(parsedParameters.indexOf(";") != -1) values[i] = Float.valueOf(parsedParameters.substring(
+					parsedParameters.indexOf(":")+1, parsedParameters.indexOf(";")));
+			else values[i] = Float.valueOf(parsedParameters.substring(
+					parsedParameters.indexOf(":")+1));
+			parsedParameters = parsedParameters.substring(parsedParameters.indexOf(";") + 1, length);
+			length = parsedParameters.length();
+			
+			parametersList.add(parameterName);	
+		}
+		// the menu is configured with the list created in the previous step
+        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
+        (c, android.R.layout.simple_spinner_item,parametersList);
+        dataAdapter.setDropDownViewResource
+        (android.R.layout.simple_spinner_dropdown_item);
+        menu.setAdapter(dataAdapter);
+
+        if(visibility) {
+            localVerticalGroup.addView(textLabel);
+            localVerticalGroup.addView(menu);
+            frame.addView(localVerticalGroup);
+        }
+	}
+	
+	public void setLabel(String label){
+		textLabel.setText(label);
+	}
+	
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	public void setSelection(int item){
+		menu.setSelection(item);
+	}
+	
+	public void linkTo(final ParametersInfo parametersInfo){
+		menu.setOnItemSelectedListener(new OnItemSelectedListener(){
+        	public void onItemSelected(AdapterView parent, View view, int pos, long id) {
+        		parametersInfo.values[ID] = pos;
+        		dsp_faust.setParam(address, values[pos]);
+        	} 
+        	public void onNothingSelected(AdapterView parent) {	 		
+        	}
+        });
+	}
+	
+	private int countStringOccurrences(String input, String pattern){
+		int lastIndex = 0, count = 0;
+		while(lastIndex != -1){
+			lastIndex = input.indexOf(pattern,lastIndex);
+			if( lastIndex != -1){
+				count ++;
+				lastIndex += pattern.length();
+			}
+		}
+		return count;
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/MultiActivity.java b/architecture/android/app/src/main/java/com/faust/MultiActivity.java
new file mode 100644
index 0000000..2a68af9
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/MultiActivity.java
@@ -0,0 +1,59 @@
+package com.faust;
+
+import com.faust.MultiParams.OnMultiParamsChangeListener;
+import com.dsp_faust.dsp_faust;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+public class MultiActivity extends Activity {
+	int nParams;
+	float[] values;
+	ParametersInfo parametersInfo;
+	
+	@Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.multi);
+        
+        int numberOfParameters = dsp_faust.getParamsCount();
+        parametersInfo = new ParametersInfo();
+        parametersInfo.init(numberOfParameters);
+        SharedPreferences settings = getSharedPreferences("savedParameters", 0);
+        parametersInfo.loadParameters(settings);
+        
+        final MultiParams mp = (MultiParams) this.findViewById(R.id.MultiParams);
+        int nMultiParams = parametersInfo.nMultiParams;
+        nParams = parametersInfo.nParams;
+        String[] labels = new String[nMultiParams];
+        final String[] addresses = new String[nMultiParams];
+		float[] min = new float[nMultiParams];
+		float[] max = new float[nMultiParams];
+		values = new float[nMultiParams];
+		
+		for(int i=0; i<nParams; i++){
+			int currentIndex = parametersInfo.order[i];
+			if(currentIndex != -1){	
+				addresses[currentIndex] = dsp_faust.getParamAddress(i);
+				labels[currentIndex] = parametersInfo.label[i];
+				min[currentIndex] = parametersInfo.min[i];
+				max[currentIndex] = parametersInfo.max[i];
+				values[currentIndex] = dsp_faust.getParam(addresses[currentIndex]);
+			}
+		}
+		mp.setParams(labels, min, max, values);
+		
+		mp.setOnMultiParamsChangeListener(new OnMultiParamsChangeListener(){
+			@Override
+			public void onParamChange(int paramID, float value) {
+				dsp_faust.setParam(addresses[paramID], value);
+			}	
+		});
+	}
+	
+	@Override
+	public void onDestroy(){
+    	super.onDestroy();
+    }
+}
diff --git a/architecture/android/app/src/main/java/com/faust/MultiKeyboardActivity.java b/architecture/android/app/src/main/java/com/faust/MultiKeyboardActivity.java
new file mode 100644
index 0000000..ce6a332
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/MultiKeyboardActivity.java
@@ -0,0 +1,79 @@
+package com.faust;
+
+import com.faust.MultiParams.OnMultiParamsChangeListener;
+import com.faust.PianoKeyboard.OnKeyboardChangeListener;
+import com.dsp_faust.dsp_faust;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+public class MultiKeyboardActivity extends Activity {
+	int nParams;
+	float[] values;
+	ParametersInfo parametersInfo;
+	
+	@Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.combined);
+        
+        final PianoKeyboard keyboard = (PianoKeyboard) this.findViewById(R.id.PianoKeyboard);
+        keyboard.setOnKeyboardChangeListener(new OnKeyboardChangeListener(){
+			@Override
+			public void onKeyChanged(int note, int velocity, boolean i) {
+				if(i) dsp_faust.keyOn(note,velocity);
+				else dsp_faust.keyOff(note);
+			}
+			
+			@Override
+			public void onPitchBend(int refPitch, float pitch) {
+				dsp_faust.pitchBend(refPitch, pitch);
+			}
+
+			@Override
+			public void onYChanged(int pitch, float y) {
+				dsp_faust.setVoiceGain(pitch,y);
+			}
+        });
+        
+        int numberOfParameters = dsp_faust.getParamsCount();
+        parametersInfo = new ParametersInfo();
+        parametersInfo.init(numberOfParameters);
+        SharedPreferences settings = getSharedPreferences("savedParameters", 0);
+        parametersInfo.loadParameters(settings);
+        
+        final MultiParams mp = (MultiParams) this.findViewById(R.id.MultiParams);
+        int nMultiParams = parametersInfo.nMultiParams;
+        nParams = parametersInfo.nParams;
+        String[] labels = new String[nMultiParams];
+        final String[] addresses = new String[nMultiParams];
+		float[] min = new float[nMultiParams];
+		float[] max = new float[nMultiParams];
+		values = new float[nMultiParams];
+		
+		for(int i=0; i<nParams; i++){
+			int currentIndex = parametersInfo.order[i];
+			if(currentIndex != -1){	
+				addresses[currentIndex] = dsp_faust.getParamAddress(i);
+				labels[currentIndex] = parametersInfo.label[i];
+				min[currentIndex] = parametersInfo.min[i];
+				max[currentIndex] = parametersInfo.max[i];
+				values[currentIndex] = dsp_faust.getParam(addresses[currentIndex]);
+			}
+		}
+		mp.setParams(labels, min, max, values);
+		
+		mp.setOnMultiParamsChangeListener(new OnMultiParamsChangeListener(){
+			@Override
+			public void onParamChange(int paramID, float value) {
+				dsp_faust.setParam(addresses[paramID], value);
+			}	
+		});
+	}
+	
+	@Override
+	public void onDestroy(){
+    	super.onDestroy();
+    }
+}
diff --git a/architecture/android/app/src/main/java/com/faust/MultiParams.java b/architecture/android/app/src/main/java/com/faust/MultiParams.java
new file mode 100644
index 0000000..1a7cec8
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/MultiParams.java
@@ -0,0 +1,332 @@
+package com.faust;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.graphics.drawable.shapes.RectShape;
+import android.util.AttributeSet;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+/*
+ * MultiParams is a two dimensional control interface where points
+ * can be moved on the screen. It respects the Faust standards and 
+ * can output values constrained between a certain range, etc.
+ */
+public class MultiParams extends ViewGroup{
+	private Context c;
+	private ShapeDrawable frame; // the frame around the interface
+	private ParamPoint points[]; // the points
+	private boolean odd; // true if the number of parameters is odd
+	private int nPoints; // number of points
+	private int nParams; // number of parameters
+	private int colors[] = { // color map for the different points
+		// we assume that the max number of parameters will be 24...
+		Color.parseColor("#0099CC"), Color.parseColor("#33CC33"),
+		Color.parseColor("#CC66FF"), Color.parseColor("#FFFF00"),
+		Color.parseColor("#FF9900"), Color.parseColor("#CC0000"),
+		Color.parseColor("#0099CC"), Color.parseColor("#33CC33"),
+		Color.parseColor("#CC66FF"), Color.parseColor("#FFFF00"),
+		Color.parseColor("#FF9900"), Color.parseColor("#CC0000")};
+	private int poolWidth; // interface width
+	private int poolHeight; // interface height
+	private int maxLabelLength = 10; // max number of characters in
+	// a parameter name
+	
+	// listener interface
+	private OnMultiParamsChangeListener mOnMultiParamsListener;
+	public interface OnMultiParamsChangeListener {
+		// activated when one of the point moved on the screen
+		void onParamChange(int paramID, float value);
+	}
+	
+	public MultiParams(Context context, AttributeSet attrs){
+		super(context, attrs);
+		c = context;
+		setBackgroundColor(Color.parseColor("#A0A0A0")); // frame color
+		frame = new ShapeDrawable(new RectShape()); // new background
+		frame.getPaint().setColor(Color.BLACK); // background color
+	}
+	
+	public void setParams(String labels[], float min[], float max[], float current[]){
+		nParams = labels.length;
+		odd = false;
+		if(nParams%2 != 0){ // if the number of parameters is odd
+			nPoints = nParams/2 + 1;
+			odd = true;
+		}
+		else nPoints = nParams/2;
+		
+		points = new ParamPoint[nPoints];
+		int ii=0; // double counter
+		// points are created
+		for(int i=0; i<nPoints; i++){
+			points[i] = new ParamPoint(c,i*2);	
+			points[i].setColor(colors[i%colors.length]);
+			
+			points[i].setMinX(min[ii]);
+			points[i].setMaxX(max[ii]);
+			points[i].setCurrentValueX(current[ii]);
+			
+			if(labels[ii].length()<maxLabelLength) points[i].setLabelX(labels[ii]);
+			else points[i].setLabelX(labels[ii].substring(0, maxLabelLength));
+			
+			if(odd && i == nPoints-1){
+				points[i].setLabelY("");
+				points[i].setMinY(0);
+				points[i].setMaxY(1000);
+				points[i].setCurrentValueY(0);
+			}
+			else{
+				if(labels[ii+1].length()<maxLabelLength) points[i].setLabelY(labels[ii+1]);
+				else points[i].setLabelY(labels[ii+1].substring(0, maxLabelLength));
+				points[i].setMinY(min[ii+1]);
+				points[i].setMaxY(max[ii+1]);
+				points[i].setCurrentValueY(current[ii+1]);
+			}
+			addView(points[i]);
+			ii+=2;
+		}
+	}
+	
+	@Override
+	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+		super.onSizeChanged(w, h, oldw, oldh);
+    
+		float xpad = (float) (getPaddingLeft() + getPaddingRight());
+		float ypad = (float) (getPaddingTop() + getPaddingBottom());
+		
+		int frameWidth = 2; // this enough to not be adjusted in function of the screen size
+    
+		poolWidth =  (int) (w - xpad);
+		poolHeight = (int) (h - ypad);
+		
+		frame.setBounds(frameWidth, frameWidth, poolWidth-frameWidth, poolHeight-frameWidth);
+		layout(0, 0, poolWidth, poolHeight);
+		
+		for(int i=0; i<nPoints; i++){
+			points[i].updatePosition();
+		}
+	}
+
+	@Override
+	protected void onLayout(boolean changed, int l, int t, int r, int b) {
+	}
+	
+	public void setOnMultiParamsChangeListener(OnMultiParamsChangeListener l){
+		mOnMultiParamsListener = l;
+	}
+	
+	protected void onDraw(Canvas canvas) {
+		super.onDraw(canvas);
+		frame.draw(canvas);
+	}
+	
+	/*
+	 * A single point parameter controller
+	 */
+	class ParamPoint extends View{
+		private ShapeDrawable point;
+		private TextView labelX, labelY;
+		private int ID;
+		private int viewWidth;
+		private int viewHeight;
+		private String nameX;
+		private String nameY;
+		private float minX;
+		private float minY;
+		private float maxX;
+		private float maxY;
+		private float currentX;
+		private float currentY;
+		private float rangeX;
+		private float rangeY;
+		private int screenX; // X screen size
+		private int screenY; // Y screen size
+		private int defPointSize = 50; // default point size (for a 1900 screen)
+		private int defZoneSize = 300; // default point+label width (for a 1900 screen) 
+		private int scaledPointSize;
+		private int scaledZoneSize;
+		
+		public ParamPoint(Context context, int id){
+			super(context);
+			
+			ID = id;
+			
+			// getting the screen size to adapt the point size 
+			WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
+			Display display = wm.getDefaultDisplay();
+			Point size = new Point();
+			display.getSize(size);
+			screenX = size.x;
+			screenY= size.y;
+			
+			// the point...
+			point = new ShapeDrawable(new OvalShape());
+			
+			// label for the X parameter
+			labelX = new TextView(context);
+			addView(labelX);
+			
+			// label for the Y parameter
+			labelY = new TextView(context);
+			addView(labelY);
+			
+			scaledZoneSize = defZoneSize*Math.max(screenX,screenY)/1900;
+			scaledPointSize = defPointSize*Math.max(screenX,screenY)/1900;
+			
+			layout(0, 0, scaledZoneSize, scaledPointSize);
+		}
+		
+		public void setLabelX(String pNameX){
+			nameX = pNameX;
+			labelX.setText(nameX);
+		}
+		
+		public void setLabelY(String pNameY){
+			nameY = pNameY;
+			labelY.setText(nameY);
+		}
+		
+		public void setMinX(float X){
+			minX = X;
+			computeRangeX();
+		}
+		
+		public void setMinY(float Y){
+			minY = Y;
+			computeRangeY();
+		}
+		
+		public void setMaxX(float X){
+			maxX = X;
+			computeRangeX();
+		}
+		
+		public void setMaxY(float Y){
+			maxY = Y;
+			computeRangeY();
+		}
+		
+		public void setCurrentValueX(float X){
+			currentX = X;
+		}
+		
+		public void setCurrentValueY(float Y){
+			currentY = Y;
+		}
+		
+		// update the position of the point in function of the global variables
+		public void updatePosition(){
+			offsetLeftAndRight((int) (currentX*(poolWidth-scaledPointSize)/rangeX));
+			offsetTopAndBottom((int) (currentY*(poolHeight-scaledPointSize)/rangeY));
+		}
+		
+		public void setColor(int color){
+			labelX.setTextColor(color);
+			labelY.setTextColor(color);
+			point.getPaint().setColor(color);
+		}
+		
+		private void computeRangeX(){
+			rangeX = maxX - minX;
+		}
+		
+		private void computeRangeY(){
+			rangeY = maxY - minY;
+		}
+		
+		// TODO nice feature to add: big point when touched...
+		/*
+		private void focus(boolean s){
+			if(s){
+				labelX.setVisibility(INVISIBLE);
+				labelY.setVisibility(INVISIBLE);
+				layout(0, 0, defZoneSize*Math.max(screenX,screenY)/1900, 
+						defPointSize*3*Math.max(screenX,screenY)/1900);
+			}
+			else{
+				labelX.setVisibility(VISIBLE);
+				labelY.setVisibility(VISIBLE);
+				layout(0, 0, defZoneSize*Math.max(screenX,screenY)/1900, 
+						defPointSize*Math.max(screenX,screenY)/1900);
+			}
+		}
+		*/
+		
+		@Override
+		public boolean onTouchEvent(MotionEvent event) {
+			int eventAction = event.getAction();
+			int pointOffset = viewHeight/2; // so that the touch point is centered
+			
+			// moving the point within the pool on the X axis
+			float positionX = getLeft()+event.getX();
+			currentX = positionX*rangeX/(poolWidth-scaledPointSize) + minX;
+			if(getX()+(event.getX()-pointOffset) < (poolWidth-viewHeight)) 
+				offsetLeftAndRight((int)event.getX()-pointOffset);
+			
+			// moving the point within the pool on the Y axis
+			float positionY = getTop()+event.getY();
+			currentY = positionY*rangeY/(poolHeight-scaledPointSize) + minY;
+			if(getY()+(event.getY()-pointOffset) > 0 && getY()+(event.getY()-pointOffset) < poolHeight-viewHeight) 
+				offsetTopAndBottom((int)event.getY()-pointOffset);
+			
+			if (mOnMultiParamsListener != null) {
+				mOnMultiParamsListener.onParamChange(ID, currentX);
+				if(!odd) mOnMultiParamsListener.onParamChange(ID+1, currentY);
+				else if(odd && ID != nPoints-1) mOnMultiParamsListener.onParamChange(ID+1, currentY);
+			}
+	
+			return true;
+		}
+		
+		@Override
+		protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+			super.onSizeChanged(w, h, oldw, oldh);
+			
+			float xpad = (float) (getPaddingLeft() + getPaddingRight());
+			float ypad = (float) (getPaddingTop() + getPaddingBottom());
+        
+			viewWidth =  (int) (w - xpad);
+			viewHeight = (int) (h - ypad);
+			
+			// Default label offset to the point for a 1900px screen
+			int defLabelXOffset = 4;
+			int defLabelYXOffset = -15;
+			int defLabelYYOffset = 25;
+			
+			point.setBounds(0, 0, viewHeight, viewHeight);
+			labelX.layout(viewHeight+(defLabelXOffset*viewHeight/defPointSize), defLabelYXOffset*viewHeight/defPointSize, 
+					(defZoneSize-defPointSize)*viewHeight/defPointSize, viewHeight);
+			labelY.layout(viewHeight+(defLabelXOffset*viewHeight/defPointSize), defLabelYYOffset*viewHeight/defPointSize, 
+					(defZoneSize-defPointSize)*viewHeight/defPointSize, viewHeight+(defLabelYYOffset*viewHeight/defPointSize));
+		}
+		
+		@Override
+		public void offsetLeftAndRight(int offset){
+			super.offsetLeftAndRight(offset);
+			labelX.offsetLeftAndRight(offset);
+			labelY.offsetLeftAndRight(offset);
+		}
+		
+		@Override
+		public void offsetTopAndBottom(int offset){
+			super.offsetTopAndBottom(offset);
+			labelX.offsetTopAndBottom(offset);
+			labelY.offsetTopAndBottom(offset);
+		}
+		
+		protected void onDraw(Canvas canvas) {
+			super.onDraw(canvas);
+			point.draw(canvas);
+		}
+	}
+	
+}
diff --git a/architecture/android/app/src/main/java/com/faust/Nentry.java b/architecture/android/app/src/main/java/com/faust/Nentry.java
new file mode 100644
index 0000000..414a361
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/Nentry.java
@@ -0,0 +1,153 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnLongClickListener;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+class Nentry{
+	float min = 0.0f, max = 100.0f, step = 1.0f;
+	int id = 0;
+	String  address = "";
+	LinearLayout frame, nentryLayout, localVerticalGroup;
+	EditText nentry;
+	TextView textLabel;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 * padding: padding of the view in pxs
+	 */
+	public Nentry(Context c, String addr, int currentParameterID, 
+			int width, int backgroundColor, boolean visibility) {
+		id = currentParameterID;
+		address = addr;
+		
+		nentry = new EditText(c);
+		nentry.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		nentry.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_NUMBER_FLAG_SIGNED);
+		nentry.setGravity(Gravity.CENTER);
+		
+		frame = new LinearLayout(c);
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+		
+		textLabel = new TextView(c);
+		textLabel.setGravity(Gravity.CENTER);
+		
+		if(visibility){
+			localVerticalGroup.addView(nentry);
+			localVerticalGroup.addView(textLabel);
+			frame.addView(localVerticalGroup);
+		}
+	}
+	
+	/*
+	 * Set the slider parameters
+	 * label: the name of the parameter
+	 * minimum: the slider's minimum value
+	 * maximum: the slider's maximum value
+	 * stp: the slider's step
+	 */
+	public void setParams(String label, float minimum, float maximum, float stp){
+		textLabel.setText(label);
+		min = minimum;
+		max = maximum;
+		step = stp;
+	}
+	
+	/*
+	 * Set the nentry's value
+	 */
+	public void setValue(float theValue){
+		nentry.setText(Float.toString(theValue));
+	}
+	
+	/*
+	 * Set the value of the slider as a number between 0 and 1
+	 */
+	public void setNormizedValue(float theValue){
+		setValue((max-min)*theValue + min);
+	}
+	
+	/*
+	 * Add the slider to group
+	 */
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	/*
+	 * Set the slider's listeners
+	 */
+	public void linkTo(final ParametersInfo parametersInfo, final ConfigWindow parametersWindow){
+		localVerticalGroup.setOnLongClickListener(new OnLongClickListener(){
+			public boolean onLongClick (View v){
+				if(!parametersInfo.locked) parametersWindow.showWindow(parametersInfo, id);
+				return true;
+			}
+		});
+		
+		nentry.addTextChangedListener(new TextWatcher() { 
+		    @Override
+		    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+		    }
+		    @Override
+		    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+		    }
+		    @Override
+		    public void afterTextChanged(Editable editable) {
+		       String value = nentry.getText().toString();
+		       float numValue = Float.parseFloat(value);
+		       if(isNumeric(value)){
+		    	   if(numValue >= min && numValue <= max){ 
+		    		   parametersInfo.values[id] = numValue;
+		    		   dsp_faust.setParam(address, parametersInfo.values[id]);
+		    	   }
+		    	   else if(numValue < min) setValue(min);
+		    	   else if(numValue > max) setValue(max);
+		       }
+		    }
+		});
+	}
+	
+	/*
+	 * Check if a string is a number.
+	 */
+	private static boolean isNumeric(String str)  
+	{  
+	  try  
+	  {  
+	    double d = Double.parseDouble(str);  
+	  }  
+	  catch(NumberFormatException nfe)  
+	  {  
+	    return false;  
+	  } 
+	  return true; 
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/Osc.java b/architecture/android/app/src/main/java/com/faust/Osc.java
new file mode 100644
index 0000000..ae5df7a
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/Osc.java
@@ -0,0 +1,35 @@
+package com.faust;
+
+import com.illposed.osc.OSCListener;
+import com.illposed.osc.OSCPortIn;
+
+import java.net.SocketException;
+
+public class Osc{
+    public static int port;
+    private static OSCPortIn receiver;
+
+    public static Boolean init(int inPort){
+        Boolean success = true;
+        port = inPort;
+        try {
+            receiver  = new OSCPortIn(port);
+        } catch (SocketException e) {
+            success = false;
+            e.printStackTrace();
+        }
+        return success;
+    }
+
+    public static void addListener(String address, OSCListener listener){
+        receiver.addListener(address, listener);
+    }
+
+    public static void startListening(){
+        receiver.startListening();
+    }
+
+    public static void stopListening(){
+        receiver.stopListening();
+    }
+}
diff --git a/architecture/android/app/src/main/java/com/faust/ParametersInfo.java b/architecture/android/app/src/main/java/com/faust/ParametersInfo.java
new file mode 100644
index 0000000..7b5198f
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/ParametersInfo.java
@@ -0,0 +1,129 @@
+package com.faust;
+
+import android.content.SharedPreferences;
+
+import android.util.Log;
+
+class ParametersInfo {
+    
+    final String VERSION = "0.11";
+	// Saved Parameters
+	String[] address;
+	float[] values;
+	int zoom;
+	int[] accgyrType;
+	int[] accgyrCurve;
+	float[] accgyrMin;
+	float[] accgyrMax;
+	float[] accgyrCenter;
+    int[] accgyrItemFocus;
+	
+	// Multi interface parameters
+	int nMultiParams;
+	int[] order;
+	String[] label;
+	float[] min;
+	float[] max;
+	float[] step;
+	
+	// Other Parameters
+	int[] parameterType;
+	int[] localId;
+	
+	int nParams = 0;
+	int saved = 1;
+	boolean locked = true;
+	
+	public void init(int numberOfParams){
+		nParams = numberOfParams;
+		address = new String[nParams];
+		values = new float[nParams];
+		accgyrType = new int[nParams];
+		accgyrCurve = new int[nParams];
+		accgyrMin = new float[nParams];
+		accgyrMax = new float[nParams];
+		accgyrCenter = new float[nParams];
+		accgyrItemFocus = new int[nParams];
+		parameterType = new int[nParams]; //0: hslider, 1: vslider
+		localId = new int[nParams];
+		
+		order = new int[nParams];
+		label = new String[nParams];
+		min = new float[nParams];
+		max = new float[nParams];
+		step = new float[nParams];
+		
+		// assigning default values
+		for(int i=0; i<nParams; i++){
+            accgyrType[i] = 0;
+			accgyrMin[i] = -100.0f;
+			accgyrMax[i] = 100.0f;
+			accgyrCenter[i] = 0.0f;
+  			accgyrCurve[i] = 0;
+			accgyrItemFocus[i] = 0;
+			
+			order[i] = -1;
+			min[i] = 0;
+			max[i] = 0;
+			step[i] = 0;
+		}
+	}
+	
+	public void saveParameters(SharedPreferences settings){
+		SharedPreferences.Editor editor = settings.edit();
+		editor.putInt("wasSaved" + VERSION,saved);
+		editor.putInt("zoom", zoom);
+		editor.putBoolean("locked", locked);
+		editor.putInt("nMultiParams", nMultiParams);
+        
+        Log.d("FaustJava", "saveParameters : nParams " + nParams);
+        
+		for (int i = 0; i < nParams; i++){
+			editor.putFloat("value"+i, values[i]);
+			editor.putInt("accgyrType"+i, accgyrType[i]);
+			editor.putFloat("accgyrMin"+i, accgyrMin[i]);
+			editor.putFloat("accgyrMax"+i, accgyrMax[i]);
+			editor.putFloat("accgyrCenter"+i, accgyrCenter[i]);
+            editor.putInt("accgyrCurve"+i, accgyrCurve[i]);
+            //Log.d("FaustJava", "saveParameters accgyrCurve "+i + " " + accgyrCurve[i]);
+            Log.d("FaustJava", "saveParameters accgyrType "+i + " " + accgyrType[i]);
+			
+			editor.putInt("order"+i, order[i]);
+			editor.putString("label"+i, label[i]);
+			editor.putFloat("min"+i, min[i]);
+			editor.putFloat("max"+i, max[i]);
+			editor.putFloat("step"+i, step[i]);
+		}
+		editor.commit();
+	}
+	
+	public boolean loadParameters(SharedPreferences settings){
+		if(settings.getInt("wasSaved" + VERSION,0) == 1){
+			zoom = settings.getInt("zoom", 0);
+			locked = settings.getBoolean("locked",true);
+			nMultiParams = settings.getInt("nMultiParams", 0);
+            
+            Log.d("FaustJava", "loadParameters : nParams " + nParams);
+            
+			for (int i = 0; i < nParams; i++){
+				values[i] = settings.getFloat("value"+i,0.0f);
+				accgyrType[i] = settings.getInt("accgyrType"+i, 0); //TODO: should be done only for controlled parameters
+				accgyrMin[i] = settings.getFloat("accgyrMin"+i, 0);
+				accgyrMax[i] = settings.getFloat("accgyrMax"+i, 0);
+				accgyrCenter[i] = settings.getFloat("accgyrCenter"+i, 0);
+    			accgyrCurve[i] = settings.getInt("accgyrCurve"+i, 0);
+                //Log.d("FaustJava", "loadParameters accgyrCurve "+i + " " + accgyrCurve[i]);
+                Log.d("FaustJava", "loadParameters accgyrType "+i + " " + accgyrType[i]);
+				
+				// TODO perhaps this should be in a separate function for optimization saic...	
+				order[i] = settings.getInt("order"+i, 0);
+				label[i] = settings.getString("label"+i, null);
+				min[i] = settings.getFloat("min"+i, 0f);
+				max[i] = settings.getFloat("max"+i, 0f);
+				step[i] = settings.getFloat("step"+i, 0f);
+			}
+			return true;
+		}
+		else return false;
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/PianoActivity.java b/architecture/android/app/src/main/java/com/faust/PianoActivity.java
new file mode 100644
index 0000000..20cb457
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/PianoActivity.java
@@ -0,0 +1,44 @@
+package com.faust;
+
+import com.faust.PianoKeyboard.OnKeyboardChangeListener;
+import com.dsp_faust.dsp_faust;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/*
+ * This activity implements a full screen keyboard that can control
+ * the pitch and the velocity of a Faust synthesizer.
+ */
+public class PianoActivity extends Activity {
+	@Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.piano);
+        
+        // no need for a dynamic interface: the keyboard is instantiated from the XML layout 
+        final PianoKeyboard keyboard = (PianoKeyboard) this.findViewById(R.id.PianoKeyboard);
+        keyboard.setOnKeyboardChangeListener(new OnKeyboardChangeListener(){
+			@Override
+			public void onKeyChanged(int note, int velocity, boolean i) {
+				if(i) dsp_faust.keyOn(note,velocity);
+				else dsp_faust.keyOff(note);
+			}
+			
+			@Override
+			public void onPitchBend(int refPitch, float pitch) {
+				dsp_faust.pitchBend(refPitch, pitch);
+			}
+
+			@Override
+			public void onYChanged(int pitch, float y) {
+				dsp_faust.setVoiceGain(pitch,y);
+			}
+        });
+	}
+	
+	@Override
+	public void onDestroy(){
+    	super.onDestroy();
+    }
+}
diff --git a/architecture/android/app/src/main/java/com/faust/PianoKeyboard.java b/architecture/android/app/src/main/java/com/faust/PianoKeyboard.java
new file mode 100644
index 0000000..6b25974
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/PianoKeyboard.java
@@ -0,0 +1,271 @@
+package com.faust;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+
+/*
+ * This class implements a polyphonic continuous piano keyboard.
+ */
+public class PianoKeyboard extends ViewGroup{
+	private PianoKey[] keys;
+	
+	// Config variables
+	private int numberOfKeys = 16;
+	private int baseNote = 72; // base MIDI note
+	
+	// local variables
+	private int numberOfWhiteKeys = 0;
+	private int[] keysType = {0,3,1,3,2,0,3,1,3,1,3,2};
+	private int whiteKeysWidth = 0;
+	private int blackKeysWidth = 0;
+	private int blackKeysHeight = 0;
+	
+	// listener interface
+	private OnKeyboardChangeListener mOnKeyboardChangeListener;
+	public interface OnKeyboardChangeListener {
+		/* when a key is pressed or released with:
+		 * note: MIDI note number
+		 * velocity: MIDI velocity
+		 * statu: true for down, false for up
+		 */
+		void onKeyChanged(int note, int velocity, boolean statu);
+		/*
+		 * when the finger position on the Y axis changed where:
+		 * note: the MIDI pitch affected by this change
+		 * y: the normalized Y position (0-1)
+		 */
+		void onYChanged(int refPitch, float y);
+		/*
+		 * replace refPitch by pitch (float, MIDI number)
+		 */
+		void onPitchBend(int refPitch, float pitch);
+	}
+	
+	// set the the pitch of the lowest key as a MIDI number,
+	// can be used for transposition, etc.
+	public void setBaseNote(int n){
+		baseNote = n;
+	}
+	
+	public PianoKeyboard(Context context, AttributeSet attrs){
+		super(context, attrs);
+		TypedArray a = context.getTheme().obtainStyledAttributes(
+				attrs,
+				R.styleable.PianoKeyboard,
+				0, 0);
+		try {
+			// if parameters are declared from XML 
+			numberOfKeys = a.getInt(R.styleable.PianoKeyboard_keys, numberOfKeys);
+			baseNote = a.getInt(R.styleable.PianoKeyboard_basenote, baseNote);
+		} finally {
+			a.recycle();
+		}
+		
+		keys = new PianoKey[numberOfKeys];
+		
+		for(int i=0; i<numberOfKeys; i++){
+			if(keysType[i%12] != 3){
+				keys[i] = new PianoKey(context,keysType[i%12],i);
+				addView(keys[i]);
+				numberOfWhiteKeys++;
+			}
+		}
+		for(int i=0; i<numberOfKeys; i++){
+			if(keysType[i%12] == 3){
+				keys[i] = new PianoKey(context,keysType[i%12],i);
+				addView(keys[i]);
+			}
+		}
+		
+		setBackgroundColor(Color.BLACK);
+	}
+	
+	@Override
+	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+		super.onSizeChanged(w, h, oldw, oldh);
+    
+		float xpad = (float) (getPaddingLeft() + getPaddingRight());
+		float ypad = (float) (getPaddingTop() + getPaddingBottom());
+    
+		int viewWidth =  (int) (w - xpad);
+		int viewHeight = (int) (h - ypad);
+		
+		whiteKeysWidth = viewWidth/(numberOfWhiteKeys);
+		blackKeysWidth = (int) (whiteKeysWidth*0.595f);
+		blackKeysHeight = (int) (viewHeight*0.535f);
+		
+		int whiteKeysIndex = 0;
+		int blackKeysIndex = 1;
+		int whiteKeysOffset = 0;
+		for(int i=0; i<numberOfKeys; i++){
+			if(keysType[i%12] == 3){ 
+				keys[i].layout(0, 0, blackKeysWidth, blackKeysHeight);
+				keys[i].offsetLeftAndRight((int) (whiteKeysOffset+whiteKeysWidth*0.71f));
+				blackKeysIndex++;
+			}
+			else{ 
+				keys[i].layout(0, 0, whiteKeysWidth, viewHeight);
+				whiteKeysOffset = whiteKeysWidth*whiteKeysIndex;
+				keys[i].offsetLeftAndRight(whiteKeysOffset);
+				whiteKeysIndex++;
+			}		
+		}
+	}
+	
+	public void setOnKeyboardChangeListener(OnKeyboardChangeListener l){
+		mOnKeyboardChangeListener = l;
+	}
+	
+	@Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+    }
+	
+	/*
+	 * Subclass implementing a single key and its listener
+	 */
+	class PianoKey extends ViewGroup{
+		private PianoKeyElement keyUp, keyDown;
+		private int ID = 0; // key ID on the keyboard
+		private int keyType = 0; // key type (white left, center, right or black)
+		
+		public PianoKey(Context context, int type, int id){
+			super(context);
+			ID = id;
+			keyType = type;
+			keyUp = new PianoKeyElement(context,keyType,0);
+			keyDown = new PianoKeyElement(context,keyType,1);
+			addView(keyUp);
+			addView(keyDown);
+			keyDown.setVisibility(INVISIBLE);
+		}
+		
+		public void setKeyDown(){
+			keyDown.setVisibility(VISIBLE);
+		}
+		
+		public void setKeyUp(){
+			keyDown.setVisibility(INVISIBLE);
+		}
+		
+		@Override
+		protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+			super.onSizeChanged(w, h, oldw, oldh);
+			
+			float xpad = (float) (getPaddingLeft() + getPaddingRight());
+			float ypad = (float) (getPaddingTop() + getPaddingBottom());
+	    
+			int viewWidth =  (int) (w - xpad);
+			int viewHeight = (int) (h - ypad);
+			
+			keyUp.layout(0, 0, viewWidth, viewHeight);
+			keyDown.layout(0, 0, viewWidth, viewHeight);
+		}
+		
+		@Override
+		public boolean onTouchEvent(MotionEvent event) {
+			int pitch = ID+baseNote;
+			float gain = 0;
+			if (event.getAction() == MotionEvent.ACTION_DOWN){
+				setKeyDown();
+				if (mOnKeyboardChangeListener != null) {
+					mOnKeyboardChangeListener.onKeyChanged(pitch, (int) gain*127, true);
+				}
+			}
+			else if(event.getAction() == MotionEvent.ACTION_UP){
+				setKeyUp();
+				if (mOnKeyboardChangeListener != null) {
+					mOnKeyboardChangeListener.onKeyChanged(pitch, 0, false);
+				}
+			}
+			if (mOnKeyboardChangeListener != null) {
+				if(keyType != 3){
+					if(event.getX() > whiteKeysWidth || event.getX() < 0) 
+						mOnKeyboardChangeListener.onPitchBend(pitch, pitch + (event.getX()/whiteKeysWidth));
+					else mOnKeyboardChangeListener.onPitchBend(pitch, pitch);
+				}
+				if(keyType == 3){
+					if(event.getX() > blackKeysWidth || event.getX() < 0) 
+						mOnKeyboardChangeListener.onPitchBend(pitch, pitch + (event.getX()/blackKeysWidth));
+					else mOnKeyboardChangeListener.onPitchBend(pitch, pitch);
+				}
+				if(event.getY() < blackKeysHeight){
+					gain = event.getY()/blackKeysHeight;
+					mOnKeyboardChangeListener.onYChanged(pitch, gain);
+				}
+				else{ 
+					gain = 1;
+					mOnKeyboardChangeListener.onYChanged(pitch,gain);
+				}
+			}
+			return true;
+		}
+		
+		@Override
+	    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+	    }
+	}
+	
+	/*
+	 * Single piano key element, for example black key down or up
+	 */
+	class PianoKeyElement extends View{
+		private Drawable keyElement;
+	
+		public PianoKeyElement(Context context, int type, int mode){
+			super(context);
+			
+			Resources res = context.getResources();
+			if(type == 0){
+				if(mode == 1) keyElement = res.getDrawable(R.drawable.piano_key_left_down);
+				else keyElement = res.getDrawable(R.drawable.piano_key_left);
+			}
+			else if(type == 1){
+				if(mode == 1) keyElement = res.getDrawable(R.drawable.piano_key_center_down);
+				else keyElement = res.getDrawable(R.drawable.piano_key_center);
+			}
+			else if(type == 2){
+				if(mode == 1) keyElement = res.getDrawable(R.drawable.piano_key_right_down);
+				else keyElement = res.getDrawable(R.drawable.piano_key_right);
+			}
+			else if(type == 3){
+				if(mode == 1) keyElement = res.getDrawable(R.drawable.piano_key_black_down);
+				else keyElement = res.getDrawable(R.drawable.piano_key_black);
+			}
+			else{
+				if(mode == 1) keyElement = res.getDrawable(R.drawable.piano_key_center_down);
+				else keyElement = res.getDrawable(R.drawable.piano_key_center);
+			}
+		}
+	
+		@Override
+		protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+			super.onSizeChanged(w, h, oldw, oldh);
+			
+			// commented to remove the black border around keys: kind of look
+			// better like that but can be reactivated at any time... Plus 
+			// this remove any potential dead zone.
+			//setPadding(3,0,3,3);
+			
+			float xpad = (float) (getPaddingLeft() + getPaddingRight());
+			float ypad = (float) (getPaddingTop() + getPaddingBottom());
+        
+			int ww =  (int) (w - xpad);
+			int hh = (int) (h - ypad);
+
+			keyElement.setBounds(0, 0, ww, hh);
+		}
+	
+		protected void onDraw(Canvas canvas) {
+			super.onDraw(canvas);
+			keyElement.draw(canvas);
+		}
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/PushButton.java b/architecture/android/app/src/main/java/com/faust/PushButton.java
new file mode 100644
index 0000000..e67e44e
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/PushButton.java
@@ -0,0 +1,75 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnTouchListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+class PushButton{
+	int id = 0;
+	String address = "";
+	Button button;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 * label: the parameter's name
+	 */
+	public PushButton(Context c, String addr, int currentParameterID,
+			int width, int backgroundColor, String label){
+		id = currentParameterID;
+		address = addr;
+		
+		button = new Button(c);
+		button.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		button.setText(label);
+		button.setTextColor(Color.WHITE);
+	}
+	
+	/*
+	 * Add the checkbox to group
+	 */
+	public void addTo(LinearLayout group){
+		group.addView(button);
+	}
+	
+	/*
+	 * Set the checkbox's listeners
+	 */
+	public void linkTo(final ParametersInfo parametersInfo){
+		button.setOnTouchListener(new OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if(event.getAction() == MotionEvent.ACTION_DOWN) {
+                	parametersInfo.values[id] = 1.f;
+                	dsp_faust.setParam(address, parametersInfo.values[id]);
+                } else if (event.getAction() == MotionEvent.ACTION_UP || !inViewBounds(v, event)) {
+                	parametersInfo.values[id] = 0.f;
+                	dsp_faust.setParam(address, parametersInfo.values[id]);
+                }
+	          	return true;
+            }
+        });
+	}
+	
+	/*
+	 * Test if event happened within view
+	 */
+	private boolean inViewBounds(View v, MotionEvent event){
+		int vWidth = v.getWidth();
+		int vHeight = v.getHeight();
+		if(event.getY() >= 0 && event.getY() <= vHeight && event.getX() >= 0 && event.getX() <= vWidth)
+			return true;
+		else return false;
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/Radio.java b/architecture/android/app/src/main/java/com/faust/Radio.java
new file mode 100644
index 0000000..d038e8c
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/Radio.java
@@ -0,0 +1,117 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.RadioGroup.OnCheckedChangeListener;
+import android.widget.TextView;
+
+class Radio{
+	int ID = 0;
+	float[] values;
+	String address = "";
+	RadioGroup radio;
+	LinearLayout frame, localVerticalGroup;
+	TextView textLabel;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 */
+	public Radio(Context c, String addr, int currentParameterID,
+			int width, int backgroundColor, String parsedParameters, 
+			int orientation, int init, boolean visibility){
+		ID = currentParameterID;
+		address = addr;
+		
+		radio = new RadioGroup(c);
+		radio.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		if(orientation == 0) radio.setOrientation(LinearLayout.VERTICAL);
+		else radio.setOrientation(LinearLayout.HORIZONTAL);
+		
+		frame = new LinearLayout(c);
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+		
+		textLabel = new TextView(c);
+		textLabel.setGravity(Gravity.CENTER);
+		
+		int length = parsedParameters.length();
+		int nElements = countStringOccurrences(parsedParameters,";")+1;
+		values = new float[nElements];
+		// a menu item with a value assigned to it is created for each element of the array
+		for(int i=0; i<nElements; i++){
+			String parameterName = parsedParameters.substring(1, parsedParameters.indexOf(":") - 1);
+			if(parsedParameters.indexOf(";") != -1) values[i] = Float.valueOf(parsedParameters.substring(
+					parsedParameters.indexOf(":")+1, parsedParameters.indexOf(";")));
+			else values[i] = Float.valueOf(parsedParameters.substring(
+					parsedParameters.indexOf(":")+1));
+			parsedParameters = parsedParameters.substring(parsedParameters.indexOf(";") + 1, length);
+			length = parsedParameters.length();
+			
+			RadioButton button = new RadioButton(c);
+			button.setText(parameterName);
+			button.setId(i);
+			if(init == i){ 
+				button.setChecked(true);
+				dsp_faust.setParam(address, values[i]);
+			}
+			radio.addView(button);
+		}
+		if(visibility) {
+            localVerticalGroup.addView(textLabel);
+            localVerticalGroup.addView(radio);
+            frame.addView(localVerticalGroup);
+        }
+	}
+	
+	public void setLabel(String label){
+		textLabel.setText(label);
+	}
+	
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	public void linkTo(final ParametersInfo parametersInfo){
+		radio.setOnCheckedChangeListener(new OnCheckedChangeListener() 
+	    {
+	        public void onCheckedChanged(RadioGroup group, int checkedId) {
+	        	parametersInfo.values[ID] = (float) checkedId;
+				dsp_faust.setParam(address, values[checkedId]);
+	        }
+	    });
+	}
+	
+	private int countStringOccurrences(String input, String pattern){
+		int lastIndex = 0, count = 0;
+		while(lastIndex != -1){
+			lastIndex = input.indexOf(pattern,lastIndex);
+			if( lastIndex != -1){
+				count ++;
+				lastIndex += pattern.length();
+			}
+		}
+		return count;
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/SelectBar.java b/architecture/android/app/src/main/java/com/faust/SelectBar.java
new file mode 100644
index 0000000..873d638
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/SelectBar.java
@@ -0,0 +1,96 @@
+package com.faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class SelectBar{
+	LinearLayout mainLayout;
+	Context mainContext;
+	TextView[] parameterLabel;
+	LinearLayout[] imgs;
+	int length; 
+	int id = 0;
+	int[] itemsOn, itemsOff;
+	
+	public SelectBar(Context c){
+		mainContext = c;
+		mainLayout = new LinearLayout(mainContext);
+		mainLayout.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+		mainLayout.setOrientation(LinearLayout.HORIZONTAL);
+	}
+	
+	public void addTo(LinearLayout upperLayout){
+		upperLayout.addView(mainLayout);
+	}
+	
+	public void setItems(int[] itOn, int[] itOff){
+		length = itOn.length;
+		itemsOn = itOn;
+		itemsOff = itOff;
+		imgs = new LinearLayout[length];
+		
+		for(int i=0; i<length; i++){
+			LinearLayout frame = new LinearLayout(mainContext);
+			imgs[i] = new LinearLayout(mainContext);
+			frame.setBackgroundColor(Color.rgb(69,160,197));
+			frame.setPadding(1, 1, 1, 1);
+			frame.addView(imgs[i]);
+			mainLayout.addView(frame);
+		}
+		selectImgItem(0);
+	}
+	
+	public void setItems(String[] items){
+		length = items.length;
+		parameterLabel = new TextView[length];
+		
+		for(int i=0; i<length; i++){
+			LinearLayout frame = new LinearLayout(mainContext);
+			parameterLabel[i] = new TextView(mainContext);
+			frame.setBackgroundColor(Color.rgb(69,160,197));
+			frame.setPadding(1, 1, 1, 1);
+			parameterLabel[i].setBackgroundColor(Color.rgb(70,70,70));
+			parameterLabel[i].setPadding(20, 10, 20, 10); // TODO: adjust in function of screen size
+			parameterLabel[i].setText(items[i]);
+			frame.addView(parameterLabel[i]);
+			mainLayout.addView(frame);
+		}
+		selectTextItem(0);
+	}
+	
+	public void selectTextItem(int item){
+		id = item;
+		for(int i=0; i<length; i++){
+			if(i == id){ 
+				parameterLabel[i].setBackgroundColor(Color.rgb(69,160,197));
+				parameterLabel[i].setTextColor(Color.rgb(70,70,70));
+			}
+			else{
+				parameterLabel[i].setBackgroundColor(Color.rgb(70,70,70));
+				parameterLabel[i].setTextColor(Color.rgb(69,160,197));
+			}
+		}
+	}
+	
+	public void selectImgItem(int item){
+		id = item;
+		for(int i=0; i<length; i++){
+			if(i == id){ 
+				imgs[i].setBackgroundResource(itemsOn[i]);
+			}
+			else{
+				imgs[i].setBackgroundResource(itemsOff[i]);
+			}
+		}
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/UI.java b/architecture/android/app/src/main/java/com/faust/UI.java
new file mode 100644
index 0000000..c5a4e5f
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/UI.java
@@ -0,0 +1,951 @@
+package com.faust;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.dsp_faust.dsp_faust;
+import com.illposed.osc.OSCListener;
+import com.illposed.osc.OSCMessage;
+
+import android.util.Log;
+
+/*
+ * REMARKS:
+ * 	- All the UI elements with a size greater than 2 pixels vary
+ * 	in function of the screen definition. The others are considered
+ * 	to be neglectable. The size of the text is the only exception and
+ * 	remains the same on every screen. Perhaps this should be changed?
+ */
+
+public class UI {
+	/*
+	 * Global Variables (accessible from outside the class).
+	 */
+	// string to store the full JSON description
+	String JSONparameters = new String();
+	// the values and parameters of the different UI elements saved and retrieved 
+	// every time a new activity is created
+	ParametersInfo parametersInfo;
+	/*
+	 * Counters for the different UI element types with:
+	 * parametersCounters[0]: hslider 
+	 * parametersCounters[1]: vslider
+	 * parametersCounters[2]: knob
+	 * parametersCounters[3]: nentry
+	 * parametersCounters[4]: menu
+	 * parametersCounters[5]: radio
+	 * parametersCounters[7]: checkbox
+	 * parametersCounters[8]: button 
+     * parametersCounters[9]: hbargraph 
+     * parametersCounters[10]: vbargraph
+	 */
+	int[] parametersCounters = {0,0,0,0,0,0,0,0,0,0};
+	// global counter of the UI elements
+	int parameterNumber = 0; 
+	// screen dimensions
+	int screenSizeX, screenSizeY;
+	// true if parameters were saved during a previous instance
+	boolean isSavedParameters;
+	// keyboard interface specified in the Faust code
+	boolean hasKeyboard;
+	// MultiParam interface specified in the Faust code
+	boolean hasMulti;
+	
+	// public UI elements (accessible from outside the class)
+	HorizontalScrollView horizontalScroll;
+	HorizontalSlider[] hsliders;
+	VerticalSlider[] vsliders;
+	Knob[] knobs;
+	Nentry[] nentries;
+	Menu[] menus;
+	Radio[] radios;
+	Checkbox[] checkboxes;
+	PushButton[] buttons;
+	BarGraph[] bargraphs;
+	
+	ConfigWindow parametersWindow;
+    
+    private void updateAccGyr(final ParametersInfo parametersInfo, int index)
+    {
+        /*
+         Log.d("FaustJava", "updateAccGyr :  " + index
+         + " " + parametersInfo.accgyrType[index]
+         + " " + parametersInfo.accgyrCurve[index]
+         + " " + parametersInfo.accgyrMin[index]
+         + " " + parametersInfo.accgyrCenter[index]
+         + " " + parametersInfo.accgyrMax[index]);
+         */
+        
+        if (parametersInfo.accgyrType[index] == 0) {
+            dsp_faust.setAccConverter(index, -1, 0, 0, 0, 0); // -1 means no mapping
+            dsp_faust.setGyrConverter(index, -1, 0, 0, 0, 0); // -1 means no mapping
+        } else if (parametersInfo.accgyrType[index] <= 3) {
+            dsp_faust.setAccConverter(index,
+                                      parametersInfo.accgyrType[index] - 1,  // Java : from 0 to 3 (0 means no mapping), C : -1 to 2 (-1 means no mapping)
+                                      parametersInfo.accgyrCurve[index],
+                                      parametersInfo.accgyrMin[index],
+                                      parametersInfo.accgyrCenter[index],
+                                      parametersInfo.accgyrMax[index]);
+            
+        } else {
+            dsp_faust.setGyrConverter(index,
+                                      parametersInfo.accgyrType[index] - 4,  // Java : from 0 to 3 (0 means no mapping), C : -1 to 2 (-1 means no mapping)
+                                      parametersInfo.accgyrCurve[index],
+                                      parametersInfo.accgyrMin[index],
+                                      parametersInfo.accgyrCenter[index],
+                                      parametersInfo.accgyrMax[index]);
+        }
+    }
+	
+	/*
+	 * Initialize parametersValues in function of the total
+	 * number of parameters.
+	 */
+	public void initUI(ParametersInfo paramsInfo, SharedPreferences settings) {
+		parametersWindow = new ConfigWindow();
+		
+		// get the JSON description from the native code
+		JSONparameters = dsp_faust.getJSON();
+		
+		// get the total number of parameters
+		int numberOfParameters = dsp_faust.getParamsCount();
+		
+		// get the number of each UI elements
+		int numberOfVsliders = countStringOccurrences(JSONparameters,"vslider");
+		int numberOfHsliders = countStringOccurrences(JSONparameters,"hslider");
+		int numberOfKnobs = countStringOccurrences(JSONparameters,"knob");
+		int numberOfNentries = countStringOccurrences(JSONparameters,"nentry");
+		int numberOfMenus = countStringOccurrences(JSONparameters,"menu");
+		int numberOfRadios = countStringOccurrences(JSONparameters,"radio");
+		int numberOfCheckboxes = countStringOccurrences(JSONparameters,"checkbox");
+		int numberOfButtons = countStringOccurrences(JSONparameters,"button");
+		int numberOfBarGraphs = countStringOccurrences(JSONparameters,"hbargraph") +
+				countStringOccurrences(JSONparameters,"vbargraph");
+		
+		// the instance of ParametersInfo from the class Faust is associated to parametersInfo
+		parametersInfo = paramsInfo;
+		
+		// the addresses of each param in the tree are retrieved from the native code
+		for(int i = 0; i < numberOfParameters; i++){
+			parametersInfo.address[i] = dsp_faust.getParamAddress(i);
+		}
+		
+		// the saved parameters of each UI element are retrieved
+		isSavedParameters = parametersInfo.loadParameters(settings);
+		
+		// UI elements are instantiated
+		if(numberOfVsliders>0) vsliders = new VerticalSlider[numberOfVsliders];
+		if(numberOfHsliders>0) hsliders = new HorizontalSlider[numberOfHsliders];
+		if(numberOfKnobs>0) knobs = new Knob[numberOfKnobs];
+		if(numberOfNentries>0) nentries = new Nentry[numberOfNentries];
+		if(numberOfMenus>0) menus = new Menu[numberOfMenus];
+		if(numberOfRadios>0) radios = new Radio[numberOfRadios];
+		if(numberOfCheckboxes>0) checkboxes = new Checkbox[numberOfCheckboxes];
+		if(numberOfButtons>0) buttons = new PushButton[numberOfButtons];
+		if(numberOfBarGraphs>0) bargraphs = new BarGraph[numberOfBarGraphs];
+	}
+	
+	/*
+	 * Extract the UI element of the JSON description
+	 */
+	public JSONArray getJSONui() {
+        JSONArray uiArray = new JSONArray();
+        try {		
+			JSONObject parametersObject = new JSONObject(JSONparameters);
+			uiArray = parametersObject.getJSONArray("ui");
+		} catch (Exception e) {
+			e.printStackTrace();
+		} 
+        return uiArray;
+	}
+	
+	/*
+	 * Build the UI in function of the JSON description by calling the
+	 * first iteration of parseJSON(). 
+	 */
+	public void buildUI(Context c, LinearLayout mainGroup) {
+		int groupLevel = 0;
+		WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		Point size = new Point();
+		display.getSize(size);
+		screenSizeX = size.x;
+		screenSizeY = size.y;
+		parametersWindow.buildWindow(c);
+		JSONArray uiArray = getJSONui();
+		
+		// TODO Dirty way to detect keyboard: could be improved
+		if (uiArray.toString().contains("\"style\":\"keyboard\"")) {
+			hasKeyboard = true;
+			hasMulti = false;
+		}
+		else if (uiArray.toString().contains("\"style\":\"multi\"")) {
+			hasMulti = true;
+			hasKeyboard = false;
+		}
+		else if (uiArray.toString().contains("\"style\":\"multikeyboard\"")) {
+			hasMulti = true;
+			hasKeyboard = true;
+		}
+		else {
+			hasMulti = false;
+			hasKeyboard = false;
+		}
+		
+		parseJSON(c,uiArray,mainGroup,groupLevel,0,Math.round(screenSizeX*(1+parametersInfo.zoom*0.1f)));
+	}
+	
+	/*
+	 * Returns the content of a specific "member" of a JSON "object" contained
+	 * in the meta member
+	 */
+	public String parseJSONMetaData(JSONObject object, String member) {
+		JSONArray currentArray = new JSONArray();
+		JSONObject currentObject = new JSONObject();
+		String value = new String();
+		try {
+			// gets the content of the meta member
+			currentArray = object.getJSONArray("meta");
+			// we parse the object
+			int length = currentArray.length();
+			for(int i=0; i<length; i++){
+				currentObject = currentArray.getJSONObject(i);
+				try{
+					value = currentObject.getString(member);
+				} catch (JSONException e) {
+				}
+			}
+		} catch (JSONException e) {}
+		// returns the content of the member or 
+		// null if it doesn't exist
+		return value;
+	}
+	
+	/*
+	 * Parse a JSON array and build the UI elements in function of the content
+	 * PARAMETERS:
+	 * 	c: context (this)
+	 * 	uiArray: the JSON array to analyze
+	 * 	currentGroup: the current group
+	 * 	currentGroupLevel: the ID of the current group
+	 * 	currentGroupType: 0 for vertical, 1 for horizontal
+	 * 	currentViewWidth: the current group width
+	 */
+	public void parseJSON(Context c, JSONArray uiArray, LinearLayout currentGroup, 
+			int currentGroupLevel, int currentGroupType, int currentViewWidth) {
+		int nItemsTopLevel = uiArray.length(), groupDivisions;
+		JSONObject currentObject = new JSONObject();
+		JSONArray currentArray = new JSONArray();
+		if (currentGroupType == 0) groupDivisions = 1;
+		else groupDivisions = nItemsTopLevel;
+		int localPadding = 10*screenSizeX/800;
+		int localScreenWidth = (currentViewWidth-localPadding*2)/groupDivisions;
+		int localBackgroundColor = currentGroupLevel*15;
+   	
+		try {
+			for (int i = 0; i < nItemsTopLevel; i++) {
+				boolean paramVisible = true; 
+				currentObject = uiArray.getJSONObject(i);
+				String metaDataStyle = parseJSONMetaData(currentObject, "style");
+                String metaDataHidden = parseJSONMetaData(currentObject, "hidden");
+				String metaDataMulti = parseJSONMetaData(currentObject, "multi");
+				
+				if (!isSavedParameters) {
+                    
+                    // New accgyrerometer MetaData
+					String metaDataAcc = parseJSONMetaData(currentObject, "acc");
+                	if (!metaDataAcc.equals("")) {
+          				float[] accParams = {0,0,0,0,0};
+						for(int j=0; j<4; j++){
+							accParams[j] = Float.valueOf(metaDataAcc.substring(0, metaDataAcc.indexOf(" ")));
+							metaDataAcc = metaDataAcc.substring(metaDataAcc.indexOf(" ")+1);
+						}
+						accParams[4] = Float.valueOf(metaDataAcc);
+                        parametersInfo.accgyrType[parameterNumber] = (int) accParams[0] + 1;  // Java : from 1 to 3
+						parametersInfo.accgyrCurve[parameterNumber] = (int) accParams[1];
+						parametersInfo.accgyrMin[parameterNumber] = accParams[2];
+						parametersInfo.accgyrCenter[parameterNumber] = accParams[3];
+						parametersInfo.accgyrMax[parameterNumber] = accParams[4];
+                    }
+                    
+                    // New gyroscope MetaData
+                    String metaDataGyr = parseJSONMetaData(currentObject, "gyr");
+                    if (!metaDataGyr.equals("")) {
+                        float[] gyrParams = {0,0,0,0,0};
+                        for(int j=0; j<4; j++){
+                            gyrParams[j] = Float.valueOf(metaDataGyr.substring(0, metaDataGyr.indexOf(" ")));
+                            metaDataGyr = metaDataGyr.substring(metaDataGyr.indexOf(" ")+1);
+                        }
+                        gyrParams[4] = Float.valueOf(metaDataGyr);
+                        parametersInfo.accgyrType[parameterNumber] = (int) gyrParams[0] + 4;  // Java : from 4 to 6 
+                        parametersInfo.accgyrCurve[parameterNumber] = (int) gyrParams[1];
+                        parametersInfo.accgyrMin[parameterNumber] = gyrParams[2];
+                        parametersInfo.accgyrCenter[parameterNumber] = gyrParams[3];
+                        parametersInfo.accgyrMax[parameterNumber] = gyrParams[4];
+                    }
+                }
+				
+				// Skipping freq, gain and gate if a keyboard interface was specified
+				if (hasKeyboard && (currentObject.getString("label").equals("freq") ||
+                    currentObject.getString("label").equals("gain") ||
+                    currentObject.getString("label").equals("gate"))) {
+					paramVisible = false;
+				}
+
+                if (metaDataHidden.equals("1")) {
+                    paramVisible = false;
+                }
+
+                if (currentObject.getString("type").equals("vgroup")) {
+					currentArray = currentObject.getJSONArray("items");
+					vgroup(c,currentArray,currentGroup,currentObject.getString("label"),
+							currentGroupLevel,groupDivisions,currentViewWidth);
+				}
+				else if (currentObject.getString("type").equals("hgroup")){
+					currentArray = currentObject.getJSONArray("items");
+					hgroup(c,currentArray,currentGroup,currentObject.getString("label"),
+							currentGroupLevel,groupDivisions,currentViewWidth);
+				}
+				else if (currentObject.getString("type").equals("vslider")
+                         || currentObject.getString("type").equals("hslider")
+                         || currentObject.getString("type").equals("nentry")) {
+                    
+					if (!isSavedParameters) {
+						if (isNumeric(metaDataMulti)) {
+							parametersInfo.order[parameterNumber] = Integer.valueOf(metaDataMulti);
+							parametersInfo.nMultiParams++;
+						}
+						else parametersInfo.order[parameterNumber] = -1;
+						parametersInfo.label[parameterNumber] = currentObject.getString("label"); 
+						parametersInfo.min[parameterNumber] = Float.parseFloat(currentObject.getString("min"));
+						parametersInfo.max[parameterNumber] = Float.parseFloat(currentObject.getString("max"));
+						parametersInfo.step[parameterNumber] = Float.parseFloat(currentObject.getString("step"));
+             		}
+                    
+					if (metaDataStyle.equals("knob")) {
+						knob(c, currentGroup, currentObject.getString("address"),
+								currentObject.getString("label"), 
+								Float.parseFloat(currentObject.getString("init")), 
+								Float.parseFloat(currentObject.getString("min")), 
+								Float.parseFloat(currentObject.getString("max")), 
+								Float.parseFloat(currentObject.getString("step")), 
+								localScreenWidth,localBackgroundColor,localPadding,paramVisible);
+					}
+                    else if (metaDataStyle.contains("menu")) {
+						menu(c,currentGroup,currentObject.getString("address"),
+								currentObject.getString("label"),
+								localScreenWidth,localBackgroundColor,metaDataStyle,paramVisible);
+					}
+                    else if (metaDataStyle.contains("radio")) {
+						radio(c,currentGroup,currentObject.getString("address"),
+								currentObject.getString("label"),
+								localScreenWidth,localBackgroundColor,metaDataStyle,0,paramVisible);
+					}
+                    else if (currentObject.getString("type").equals("vslider")) {
+						vslider(c,currentGroup,currentObject.getString("address"),
+								currentObject.getString("label"), 
+								Float.parseFloat(currentObject.getString("init")), 
+								Float.parseFloat(currentObject.getString("min")), 
+								Float.parseFloat(currentObject.getString("max")), 
+								Float.parseFloat(currentObject.getString("step")), 
+								localScreenWidth,localBackgroundColor,paramVisible);
+                    }
+					else if (currentObject.getString("type").equals("hslider")) {
+                        hslider(c, currentGroup, currentObject.getString("address"),
+                                currentObject.getString("label"),
+                                Float.parseFloat(currentObject.getString("init")),
+                                Float.parseFloat(currentObject.getString("min")),
+                                Float.parseFloat(currentObject.getString("max")),
+                                Float.parseFloat(currentObject.getString("step")),
+                                localScreenWidth,localBackgroundColor,localPadding,paramVisible);
+                    }
+                    else if (currentObject.getString("type").equals("nentry")) {
+                        nentry(c,currentGroup,currentObject.getString("address"),
+                               currentObject.getString("label"),
+                               Float.parseFloat(currentObject.getString("init")),
+                               Float.parseFloat(currentObject.getString("min")),
+                               Float.parseFloat(currentObject.getString("max")),
+                               Float.parseFloat(currentObject.getString("step")),
+                               localScreenWidth,localBackgroundColor,paramVisible);	
+                    }
+					parameterNumber++;
+				}
+                else if (currentObject.getString("type").equals("button")) {
+					button(c,currentGroup,currentObject.getString("address"),
+							currentObject.getString("label"), 
+							localScreenWidth,localBackgroundColor,paramVisible);	
+					parameterNumber++;
+				}
+				else if (currentObject.getString("type").equals("checkbox")) {
+					checkbox(c,currentGroup,currentObject.getString("address"),
+							currentObject.getString("label"), 
+							localScreenWidth,localBackgroundColor,paramVisible);	
+					parameterNumber++;
+				}
+				else if (currentObject.getString("type").equals("hbargraph")) {
+					hbargraph(c, currentGroup, currentObject.getString("address"),
+							currentObject.getString("label"), 
+							Float.parseFloat(currentObject.getString("min")), 
+							Float.parseFloat(currentObject.getString("max")),  
+							localScreenWidth,localBackgroundColor,paramVisible);
+					parameterNumber++;
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void updateUIstate() {
+		for (int i = 0; i < 10; i++){
+			parametersCounters[i] = 0;
+		}
+		for (int i = 0; i < parameterNumber; i++) {
+			if (parametersInfo.parameterType[i] == 0) {       //0: hslider
+				hsliders[parametersCounters[0]].setValue(dsp_faust.getParam(hsliders[parametersCounters[0]].address));
+				parametersCounters[0]++;
+			}
+			else if (parametersInfo.parameterType[i] == 1) {  //1: vslider
+				vsliders[parametersCounters[1]].setValue(dsp_faust.getParam(vsliders[parametersCounters[1]].address));
+				parametersCounters[1]++;
+			}
+			else if (parametersInfo.parameterType[i] == 2) {  //2 : knob
+				knobs[parametersCounters[2]].setValue(dsp_faust.getParam(knobs[parametersCounters[2]].address));
+				parametersCounters[2]++;
+			}
+			else if (parametersInfo.parameterType[i] == 3) {  //3 : nentry
+				nentries[parametersCounters[3]].setValue(dsp_faust.getParam(nentries[parametersCounters[3]].address));
+				parametersCounters[3]++;
+			}
+            else if (parametersInfo.parameterType[i] == 9) {  //9 : hbargraph
+                bargraphs[parametersCounters[9]].setValue(dsp_faust.getParam(bargraphs[parametersCounters[9]].address));
+                parametersCounters[9]++;
+                
+                //Log.d("FaustJava", "updateUIstate bargraphs");
+                
+            }
+		}
+		// Other parameters are ignored because they are not continuous
+	}
+	
+	public void hbargraph(Context c, LinearLayout currentGroup, final String address, final String label, 
+			final float min, final float max, int localScreenWidth, int localBackgroundColor, boolean visibility) {
+		bargraphs[parametersCounters[9]] = new BarGraph(c, address,parameterNumber, null, android.R.attr.progressBarStyleHorizontal, localScreenWidth, localBackgroundColor, visibility);
+		bargraphs[parametersCounters[9]].id = parameterNumber;
+		bargraphs[parametersCounters[9]].min = min;
+		bargraphs[parametersCounters[9]].max = max;
+        bargraphs[parametersCounters[9]].addTo(currentGroup);
+		
+        parametersInfo.parameterType[parameterNumber] = 9;
+        parametersInfo.localId[parameterNumber] = parametersCounters[9];
+        parametersCounters[9]++;
+	}
+	
+	/*
+	 * Creates a drop down menu and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 *  label: the name of the menu
+	 *  localScreenWidth: width of the view
+	 *  localBackgroundColor: background color of the view
+	 *  currentGroupLevel: the "depth" of the parameter in the UI
+	 *  parameters: string containing the parameters of the menu extracted
+	 *  	from the JSON description
+	 */
+	//TODO: init?
+	public void menu(Context c, LinearLayout currentGroup, final String address, final String label,
+			int localScreenWidth, int localBackgroundColor, String parameters, boolean visibility) {
+        
+		String parsedParameters = parameters.substring(parameters.indexOf("{") + 1, 
+				parameters.indexOf("}"));
+		menus[parametersCounters[4]] = new Menu(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, parsedParameters, visibility);
+		menus[parametersCounters[4]].setLabel(label);
+		int init = 0;
+		if(isSavedParameters) init = (int) parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		menus[parametersCounters[4]].setSelection(init);
+        menus[parametersCounters[4]].linkTo(parametersInfo);
+	    menus[parametersCounters[4]].addTo(currentGroup);
+        
+        //dsp_faust.setParam(address, init);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 4;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[4];
+	    parametersCounters[4]++;
+	}
+	
+	/*
+	 * Creates a radio buttons menu and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 *  label: the name of the menu
+	 *  localScreenWidth: width of the view
+	 *  localBackgroundColor: background color of the view
+	 *  currentGroupLevel: the "depth" of the parameter in the UI
+	 *  parameters: string containing the parameters of the menu extracted
+	 *  	from the JSON description
+	 *  orientation: 0 for vertical, 1 for horizontal
+	 */
+	//TODO: init?
+	public void radio(Context c, LinearLayout currentGroup, final String address, final String label,
+			int localScreenWidth, int localBackgroundColor, String parameters, int orientation, boolean visibility) {
+        
+		String parsedParameters = parameters.substring(parameters.indexOf("{") + 1, parameters.indexOf("}"));
+    	int init = 0;
+		if(isSavedParameters) init = (int) parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		radios[parametersCounters[5]] = new Radio(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, parsedParameters, orientation, init, visibility);
+		radios[parametersCounters[5]].setLabel(label);
+        radios[parametersCounters[5]].linkTo(parametersInfo);
+	    radios[parametersCounters[5]].addTo(currentGroup);
+        
+        //dsp_faust.setParam(address, init);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 5;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[5];
+	    parametersCounters[5]++;
+	}
+	
+	/*
+	 * Creates a horizontal slider and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 * 	address: the parameter address
+	 *  label: the name of the menu
+	 *  init: the default item of the menu
+	 *  min: the minimum value
+	 *  max: the maximum value
+	 *  step: the slider step
+	 *  localScreenWidth: the width of the view
+	 *  localBackgroundColor: the background color of the view
+	 *  localPadding: the padding of the view
+	 */
+	public void hslider(Context c, LinearLayout currentGroup, final String address, final String label, float init, 
+			final float min, final float max, final float step, int localScreenWidth, int localBackgroundColor, 
+			int localPadding, boolean visibility) {
+       
+        // the slider
+		hsliders[parametersCounters[0]] = new HorizontalSlider(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, localPadding, visibility);
+		hsliders[parametersCounters[0]].setParams(label, min, max, step);
+    	if(isSavedParameters) init = parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		hsliders[parametersCounters[0]].setValue(init);
+	    hsliders[parametersCounters[0]].linkTo(parametersInfo, parametersWindow, horizontalScroll);
+	    hsliders[parametersCounters[0]].addTo(currentGroup);
+        
+        // Accelerometer mappings restored before so that we are sure they are allocated on C side before restoring the actual values...
+        updateAccGyr(parametersInfo, parameterNumber);
+        dsp_faust.setParam(address, init);
+      
+        // OSC listener
+        final int parameterId = parametersCounters[0];
+        final FaustActivity faustActivity = (FaustActivity) c;
+        OSCListener listener = new OSCListener() {
+            public void acceptMessage(java.util.Date time, final OSCMessage message) {
+                faustActivity.runOnUiThread(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                hsliders[parameterId].setValue((float) message.getArguments().get(0));
+                            }
+                        }
+                );
+            }
+        };
+        Osc.addListener(address,listener);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 0;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[0];
+	    parametersCounters[0]++;
+	}
+	
+	/*
+	 * Creates a vertical slider and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 * 	address: the parameter address
+	 *  label: the name of the menu
+	 *  init: the default item of the menu
+	 *  min: the minimum value
+	 *  max: the maximum value
+	 *  step: the slider step
+	 *  localScreenWidth: the width of the view
+	 *  localBackgroundColor: the background color of the view
+	 */
+	public void vslider(Context c, LinearLayout currentGroup, final String address, final String label, float init, 
+			final float min, final float max, final float step, int localScreenWidth, int localBackgroundColor,
+			boolean visibility){
+        
+		// the slider
+		vsliders[parametersCounters[1]] = new VerticalSlider(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, visibility);
+        vsliders[parametersCounters[1]].setParams(label, min, max, step);
+    	if(isSavedParameters) init = parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		vsliders[parametersCounters[1]].setValue(init);
+	    vsliders[parametersCounters[1]].linkTo(parametersInfo, parametersWindow, horizontalScroll);
+	    vsliders[parametersCounters[1]].addTo(currentGroup);
+        
+        // Accelerometer mappings restored before so that we are sure they are allocated on C side before restoring the actual values...
+        updateAccGyr(parametersInfo, parameterNumber);
+        dsp_faust.setParam(address, init);
+
+        // OSC listener
+        final int parameterId = parametersCounters[1];
+        final FaustActivity faustActivity = (FaustActivity) c;
+        OSCListener listener = new OSCListener() {
+            public void acceptMessage(java.util.Date time, final OSCMessage message) {
+                faustActivity.runOnUiThread(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                vsliders[parameterId].setValue((float) message.getArguments().get(0));
+                            }
+                        }
+                );
+            }
+        };
+        Osc.addListener(address,listener);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 1;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[1];
+	    parametersCounters[1]++;
+	}
+	
+	/*
+	 * Creates a knob and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 * 	address: the parameter address
+	 *  label: the name of the menu
+	 *  init: the default item of the menu
+	 *  min: the minimum value
+	 *  max: the maximum value
+	 *  step: the slider step
+	 *  localScreenWidth: the width of the view
+	 *  localBackgroundColor: the background color of the view
+	 *  localPadding: the padding of the view
+	 */
+	public void knob(Context c, LinearLayout currentGroup, final String address, final String label, float init, 
+			final float min, final float max, final float step, int localScreenWidth, int localBackgroundColor,
+			int localPadding, boolean visibility){
+        
+		knobs[parametersCounters[2]] = new Knob(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, localPadding, visibility);
+		knobs[parametersCounters[2]].setParams(label, min, max, step);
+        if(isSavedParameters) init = parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		knobs[parametersCounters[2]].setValue(init);
+	    knobs[parametersCounters[2]].linkTo(parametersInfo, parametersWindow, horizontalScroll);
+	    knobs[parametersCounters[2]].addTo(currentGroup);
+        
+        // Accelerometer mappings restored before so that we are sure they are allocated on C side before restoring the actual values...
+        updateAccGyr(parametersInfo, parameterNumber);
+        dsp_faust.setParam(address, init);
+       
+        // OSC listener
+        final int parameterId = parametersCounters[2];
+        final FaustActivity faustActivity = (FaustActivity) c;
+        OSCListener listener = new OSCListener() {
+            public void acceptMessage(java.util.Date time, final OSCMessage message) {
+                faustActivity.runOnUiThread(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                knobs[parameterId].setValue((float) message.getArguments().get(0));
+                            }
+                        }
+                );
+            }
+        };
+        Osc.addListener(address,listener);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 2;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[2];
+	    parametersCounters[2]++;
+	}
+	
+	/*
+	 * Creates a nentry and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 * 	address: the parameter address
+	 *  label: the name of the menu
+	 *  init: the default item of the menu
+	 *  min: the minimum value
+	 *  max: the maximum value
+	 *  step: the slider step
+	 *  localScreenWidth: the width of the view
+	 *  localBackgroundColor: the background color of the view
+	 */
+	public void nentry(Context c, LinearLayout currentGroup, final String address, final String label, float init, 
+			final float min, final float max, final float step, int localScreenWidth, int localBackgroundColor,
+			boolean visibility){
+        
+		nentries[parametersCounters[3]] = new Nentry(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, visibility);
+		nentries[parametersCounters[3]].setParams(label, min, max, step);
+		if(isSavedParameters) init = parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		nentries[parametersCounters[3]].setValue(init);
+        nentries[parametersCounters[3]].linkTo(parametersInfo, parametersWindow);
+	    nentries[parametersCounters[3]].addTo(currentGroup);
+        
+        // Accelerometer mappings restored before so that we are sure they are allocated on C side before restoring the actual values...
+        updateAccGyr(parametersInfo, parameterNumber);
+        dsp_faust.setParam(address, init);
+    
+        // OSC listener
+        final int parameterId = parametersCounters[3];
+        final FaustActivity faustActivity = (FaustActivity) c;
+        OSCListener listener = new OSCListener() {
+            public void acceptMessage(java.util.Date time, final OSCMessage message) {
+                faustActivity.runOnUiThread(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                nentries[parameterId].setValue((float) message.getArguments().get(0));
+                            }
+                        }
+                );
+            }
+        };
+        Osc.addListener(address,listener);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 3;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[3];
+	    parametersCounters[3]++;
+	}
+	
+	/*
+	 * Creates a button and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 * 	address: the parameter address
+	 *  label: the name of the menu
+	 *  localScreenWidth: the width of the view
+	 *  localBackgroundColor: the background color of the view
+	 */
+	public void button(Context c, LinearLayout currentGroup, final String address, final String label, 
+			int localScreenWidth, int localBackgroundColor, boolean visibility){
+        
+		buttons[parametersCounters[6]] = new PushButton(c,address,parameterNumber,
+				localScreenWidth, localBackgroundColor, label);
+	    buttons[parametersCounters[6]].linkTo(parametersInfo);
+	    if(visibility) buttons[parametersCounters[6]].addTo(currentGroup);
+	    parametersInfo.parameterType[parameterNumber] = 6;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[6];
+	    parametersCounters[6]++;
+	}
+	
+	/*
+	 * Creates a button and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 * 	currentGroup: the group to add the menu
+	 * 	address: the parameter address
+	 *  label: the name of the menu
+	 *  localScreenWidth: the width of the view
+	 *  localBackgroundColor: the background color of the view
+	 */
+	public void checkbox(Context c, LinearLayout currentGroup, final String address, final String label, 
+			int localScreenWidth, int localBackgroundColor, boolean visibility){
+        
+        int height = Math.round(screenSizeY*0.1f);
+		checkboxes[parametersCounters[7]] = new Checkbox(c,address,parameterNumber,
+				localScreenWidth, height, localBackgroundColor, label);
+		float init = 0.0f; //default value for the checkbox
+		if(isSavedParameters) init = parametersInfo.values[parameterNumber];
+		else parametersInfo.values[parameterNumber] = init;
+		checkboxes[parametersCounters[7]].setStatus(init);
+	    checkboxes[parametersCounters[7]].linkTo(parametersInfo);
+	    if(visibility) checkboxes[parametersCounters[7]].addTo(currentGroup);
+        
+        dsp_faust.setParam(address, init);
+
+        // OSC listener
+        final int parameterId = parametersCounters[7];
+        final FaustActivity faustActivity = (FaustActivity) c;
+        OSCListener listener = new OSCListener() {
+            public void acceptMessage(java.util.Date time, final OSCMessage message) {
+                faustActivity.runOnUiThread(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                checkboxes[parameterId].setStatus((float) message.getArguments().get(0));
+                            }
+                        }
+                );
+            }
+        };
+        Osc.addListener(address,listener);
+	    
+	    parametersInfo.parameterType[parameterNumber] = 7;
+	    parametersInfo.localId[parameterNumber] = parametersCounters[7];
+	    parametersCounters[7]++;
+	}
+	
+	/*
+	 * Creates a vertical group and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 *  currentArray: current JSON array containing the items of the group
+	 * 	currentGroup: the group to add the menu
+	 *  label: the name of the menu
+	 *  currentGroupLevel: current group's depth
+	 *  nItemsUpperLevel: number of items in the upper group
+	 *  upperViewWidth: width of the upper group
+	 */
+	public void vgroup(Context c, JSONArray currentArray, LinearLayout currentGroup, String label, 
+			int currentGroupLevel, int nItemsUpperLevel, int upperViewWidth){
+		// frame to create some padding around the view
+		LinearLayout frame = new LinearLayout(c);
+		// the local group
+		LinearLayout localGroup = new LinearLayout(c);
+		
+		// for the local groups background color
+		int localGroupLevel = currentGroupLevel+1;
+		// padding is adjusted in function of the screen definition
+		int padding = 10*screenSizeX/800;
+		int currentViewPadding = padding;
+		if(currentGroupLevel == 0) currentViewPadding = 0;
+		int localViewWidth  = (upperViewWidth-currentViewPadding*2)/nItemsUpperLevel;
+		
+		// frame to create some padding around the view
+		// the layout's width is "hard coded"
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				localViewWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(currentGroupLevel*15,
+				currentGroupLevel*15, currentGroupLevel*15));
+		frame.setPadding(2,2,2,2);
+		
+		localGroup.setOrientation(LinearLayout.VERTICAL);
+		localGroup.setBackgroundColor(Color.rgb(localGroupLevel*15,localGroupLevel*15,localGroupLevel*15));
+		localGroup.setPadding(padding,padding,padding,padding);
+		
+		if(!label.contains("0x00")){
+			TextView textLabel = new TextView(c);
+			textLabel.setText(label);
+			textLabel.setTextSize(22.f);
+			localGroup.addView(textLabel);
+		}
+		
+		frame.addView(localGroup);
+		currentGroup.addView(frame);
+		
+		// we iterate the group's items
+		parseJSON(c,currentArray,localGroup,localGroupLevel,0,localViewWidth);
+	}
+	
+	/*
+	 * Creates a horizontal group and adds it to currentGroup.
+	 * PARAMETERS:
+	 * 	c: the context (this)
+	 *  currentArray: current JSON array containing the items of the group
+	 * 	currentGroup: the group to add the menu
+	 *  label: the name of the menu
+	 *  currentGroupLevel: current group's depth
+	 *  nItemsUpperLevel: number of items in the upper group
+	 *  upperViewWidth: width of the upper group
+	 */
+	public void hgroup(Context c, JSONArray currentArray, LinearLayout currentGroup, String label, 
+			int currentGroupLevel, int nItemsUpperLevel, int upperViewWidth){
+		// frame to create some padding around the view
+		LinearLayout frame = new LinearLayout(c);
+		// the local group
+		LinearLayout localGroup = new LinearLayout(c);
+		// the local vertical group (required to have the group name above the content of the group)
+		LinearLayout localVerticalGroup = new LinearLayout(c);
+		
+		// for the local groups background color
+		int localGroupLevel = currentGroupLevel+1;
+		// padding is adjusted in function of the screen definition
+		int padding = 10*screenSizeX/800;
+		int currentViewPadding = padding;
+		if(currentGroupLevel == 0) currentViewPadding = 0;
+		int localViewWidth  = (upperViewWidth-currentViewPadding*2)/nItemsUpperLevel;
+		
+		localGroup.setOrientation(LinearLayout.HORIZONTAL);
+		
+		// frame to create some padding around the view
+		// the layout's width is "hard coded"
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				localViewWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(currentGroupLevel*15,
+				currentGroupLevel*15, currentGroupLevel*15));
+		frame.setPadding(2,2,2,2);
+		
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setBackgroundColor(Color.rgb(localGroupLevel*15,localGroupLevel*15,localGroupLevel*15));
+		localVerticalGroup.setPadding(padding,padding,padding,padding);
+		
+		if(!label.contains("0x00")){
+			TextView textLabel = new TextView(c);
+			textLabel.setText(label);
+			textLabel.setTextSize(22.f);
+			localVerticalGroup.addView(textLabel);
+		}
+		
+		localVerticalGroup.addView(localGroup);
+		frame.addView(localVerticalGroup);
+		currentGroup.addView(frame);
+		
+		// we iterate the group's items
+		parseJSON(c,currentArray,localGroup,localGroupLevel,1,localViewWidth);
+	}
+	
+	/*
+	 * Count the number of pattern in input
+	 */
+	private int countStringOccurrences(String input, String pattern){
+		int lastIndex = 0, count = 0;
+		while(lastIndex != -1){
+			lastIndex = input.indexOf(pattern,lastIndex);
+			if( lastIndex != -1){
+				count ++;
+				lastIndex += pattern.length();
+			}
+		}
+		return count;
+	}
+	
+	/*
+	 * Check if a string is numeric
+	 */
+	private static boolean isNumeric(String str)  
+	{  
+	  try  
+	  {  
+	    double d = Double.parseDouble(str);  
+	  }  
+	  catch(NumberFormatException nfe)  
+	  {  
+	    return false;  
+	  }  
+	  return true;  
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/faust/VerticalSlider.java b/architecture/android/app/src/main/java/com/faust/VerticalSlider.java
new file mode 100644
index 0000000..08b5681
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/faust/VerticalSlider.java
@@ -0,0 +1,188 @@
+package com.faust;
+
+import com.dsp_faust.dsp_faust;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+import android.widget.VerticalSeekBar;
+
+/*
+ * TODO: with accelerometers, when using setNormalizedValue the handle of the 
+ * slider doesn't move. I think the only way to solve this problem might be
+ * to have our own implementation of vertical slider which obviously would be
+ * a lot of work...
+ */
+
+/*
+ * Create a horizontal slider that displays its current value on its left. 
+ */
+
+class VerticalSlider {
+	float min = 0.0f, max = 100.0f, step = 1.0f;
+	int id = 0;
+	String decimalsDisplay = "", address = "";
+	LinearLayout frame, sliderLayout, localVerticalGroup;
+	VerticalSeekBar slider;
+	TextView textValue, textLabel;
+	Point size;
+	
+	/*
+	 * The constructor.
+	 * addr: the tree address of the parameter controlled by the slider
+	 * currentParameterID: the current parameter id in the parameters tree
+	 * width: width of the view in pxs
+	 * backgroundColor: grey level of the background of the view (0-255)
+	 */
+	public VerticalSlider(Context c, String addr, int currentParameterID,
+			int width, int backgroundColor, boolean visibility) {
+		WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		size = new Point();
+		display.getSize(size);
+		
+		id = currentParameterID;
+		address = addr;
+		
+		int sliderHeight = 300*(size.x+size.y)/2080;
+		slider = new VerticalSeekBar(c);
+		slider.setLayoutParams(new ViewGroup.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT, sliderHeight));
+		
+		frame = new LinearLayout(c);
+		frame.setLayoutParams(new ViewGroup.LayoutParams(
+				width, ViewGroup.LayoutParams.WRAP_CONTENT));
+		frame.setOrientation(LinearLayout.VERTICAL);
+		frame.setBackgroundColor(Color.rgb(backgroundColor, 
+				backgroundColor, backgroundColor));
+		frame.setPadding(2,2,2,2);
+		
+		sliderLayout = new LinearLayout(c);
+		sliderLayout.setOrientation(LinearLayout.VERTICAL);
+		sliderLayout.setGravity(Gravity.CENTER);
+		
+		localVerticalGroup = new LinearLayout(c);
+		localVerticalGroup.setOrientation(LinearLayout.VERTICAL);
+		localVerticalGroup.setGravity(Gravity.CENTER);
+		localVerticalGroup.setBackgroundColor(Color.rgb(backgroundColor+15, 
+				backgroundColor+15, backgroundColor+15));
+		
+		textLabel = new TextView(c);
+		textLabel.setGravity(Gravity.CENTER);
+		
+		textValue = new TextView(c);
+		textValue.setGravity(Gravity.CENTER);
+		if (visibility) {
+			sliderLayout.addView(textValue);
+			sliderLayout.addView(slider);
+			localVerticalGroup.addView(textLabel);
+			localVerticalGroup.addView(sliderLayout);
+			frame.addView(localVerticalGroup);
+		}
+	}
+	
+	/*
+	 * Set the slider parameters
+	 * label: the name of the parameter
+	 * minimum: the slider's minimum value
+	 * maximum: the slider's maximum value
+	 * stp: the slider's step
+	 */
+	public void setParams(String label, float minimum, float maximum, float stp){
+		textLabel.setText(label);
+		min = minimum;
+		max = maximum;
+		step = stp;
+		slider.setMax(Math.round((max-min)*(1/step)));
+		int decimals = 0;
+		if(step>=1) decimals = 1;
+		else if(step<1 && step>=0.1) decimals = 1;
+		else decimals = 2;
+		decimalsDisplay = "%."+decimals+"f";
+	}
+	
+	/*
+	 * Set the value displayed next to the slider
+	 */
+	public void setDisplayedValue(float theValue){
+		textValue.setText(String.format(decimalsDisplay, theValue));
+	}
+	
+	/*
+	 * Set the slider's value
+	 */
+	// TODO: this screwed but was fixed to work with the multi interface 
+	// but there might still be weird things going on...
+	public void setValue(float theValue){
+        /*
+		if(theValue<=0 && min<0) slider.setProgress(Math.round(theValue*(1/step)+min));
+		else slider.setProgress(Math.round(theValue*(1/step)-min));
+        */
+        //SL : seems wrong, corrected 08/12/2015
+        slider.setProgress(Math.round((theValue-min)/step));
+		setDisplayedValue(theValue);
+	}
+	
+	/*
+	 * Set the value of the slider as a number between 0 and 1
+	 */
+	public void setNormizedValue(float theValue){
+		slider.setProgress(Math.round(theValue*(max-min)/step));
+	}
+	
+	/*
+	 * Add the slider to group
+	 */
+	public void addTo(LinearLayout group){
+		group.addView(frame);
+	}
+	
+	/*
+	 * Set the slider's listeners
+	 */
+	public void linkTo(final ParametersInfo parametersInfo, final ConfigWindow parametersWindow, final HorizontalScrollView horizontalScroll){
+		localVerticalGroup.setOnLongClickListener(new OnLongClickListener(){
+			public boolean onLongClick (View v){
+				if(!parametersInfo.locked) parametersWindow.showWindow(parametersInfo, id);
+				return true;
+			}
+		});
+		
+		slider.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
+			public void onStopTrackingTouch(SeekBar seekBar) {
+				parametersInfo.accgyrItemFocus[id] = 0;
+			}
+			public void onStartTrackingTouch(SeekBar seekBar) {
+				parametersInfo.accgyrItemFocus[id] = 1;
+			}
+			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+				parametersInfo.values[id] = (float) progress*step + min;
+				dsp_faust.setParam(address, parametersInfo.values[id]);
+				setDisplayedValue(parametersInfo.values[id]);
+	          }
+	    });
+	    
+	    slider.setOnTouchListener(new OnTouchListener()
+	    {
+	        public boolean onTouch(final View view, final MotionEvent event)
+	        {
+	          if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
+	            horizontalScroll.requestDisallowInterceptTouchEvent(true);
+	          return false;
+	        }
+	    });
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/AbstractOSCPacket.java b/architecture/android/app/src/main/java/com/illposed/osc/AbstractOSCPacket.java
new file mode 100644
index 0000000..c9e4856
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/AbstractOSCPacket.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import com.illposed.osc.utility.OSCJavaToByteArrayConverter;
+import java.nio.charset.Charset;
+
+/**
+ * OSCPacket is the abstract superclass for the various
+ * kinds of OSC Messages.
+ *
+ * The actual packets are:
+ * <ul>
+ * <li>{@link OSCMessage}: simple OSC messages
+ * <li>{@link OSCBundle}: OSC messages with timestamps
+ *   and/or made up of multiple messages
+ * </ul>
+ */
+abstract class AbstractOSCPacket implements OSCPacket {
+
+	/** Used to encode message addresses and string parameters. */
+	private Charset charset;
+	private byte[] byteArray;
+
+	public AbstractOSCPacket() {
+		this.charset = Charset.defaultCharset();
+		this.byteArray = null;
+	}
+
+	@Override
+	public Charset getCharset() {
+		return charset;
+	}
+
+	@Override
+	public void setCharset(Charset charset) {
+		this.charset = charset;
+	}
+
+	/**
+	 * Generate a representation of this packet conforming to the
+	 * the OSC byte stream specification. Used Internally.
+	 */
+	private byte[] computeByteArray() {
+		final OSCJavaToByteArrayConverter stream = new OSCJavaToByteArrayConverter();
+		stream.setCharset(charset);
+		return computeByteArray(stream);
+	}
+
+	/**
+	 * Produces a byte array representation of this packet.
+	 * @param stream where to write the arguments to
+	 * @return the OSC specification conform byte array representation
+	 *   of this packet
+	 */
+	protected abstract byte[] computeByteArray(OSCJavaToByteArrayConverter stream);
+
+	@Override
+	public byte[] getByteArray() {
+		if (byteArray == null) {
+			byteArray = computeByteArray();
+		}
+		return byteArray;
+	}
+
+	protected void contentChanged() {
+		byteArray = null;
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/AddressSelector.java b/architecture/android/app/src/main/java/com/illposed/osc/AddressSelector.java
new file mode 100644
index 0000000..f5d8f1d
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/AddressSelector.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014, C. Ramakrishnan / Auracle.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+/**
+ * Checks whether an OSC <i>Address Pattern</i> fulfills certain criteria.
+ */
+public interface AddressSelector {
+
+	/**
+	 * Checks whether the OSC <i>Address Pattern</i> in question
+	 * matches this selector.
+	 * @param messageAddress for example "/sc/mixer/volume"
+	 * @return true if this matcher selects the message address in question.
+	 */
+	boolean matches(String messageAddress);
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCBundle.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCBundle.java
new file mode 100644
index 0000000..1b3fd76
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCBundle.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import com.illposed.osc.utility.OSCJavaToByteArrayConverter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A bundle represents a collection of OSC packets
+ * (either messages or other bundles)
+ * and has a time-tag which can be used by a scheduler to execute
+ * a bundle in the future,
+ * instead of immediately.
+ * {@link OSCMessage}s are executed immediately.
+ *
+ * Bundles should be used if you want to send multiple messages to be executed
+ * atomically together, or you want to schedule one or more messages to be
+ * executed in the future.
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCBundle extends AbstractOSCPacket {
+
+	/**
+	 * 2208988800 seconds -- includes 17 leap years
+	 */
+	public static final long SECONDS_FROM_1900_TO_1970 = 2208988800L;
+
+	/**
+	 * The Java representation of an OSC timestamp with the semantics of
+	 * "immediately".
+	 */
+	public static final Date TIMESTAMP_IMMEDIATE = new Date(0);
+
+	private Date timestamp;
+	private List<OSCPacket> packets;
+
+	/**
+	 * Create a new empty OSCBundle with a timestamp of immediately.
+	 * You can add packets to the bundle with addPacket()
+	 */
+	public OSCBundle() {
+		this(TIMESTAMP_IMMEDIATE);
+	}
+
+	/**
+	 * Create an OSCBundle with the specified timestamp.
+	 * @param timestamp the time to execute the bundle
+	 */
+	public OSCBundle(Date timestamp) {
+		this(null, timestamp);
+	}
+
+	/**
+	 * Creates an OSCBundle made up of the given packets
+	 * with a timestamp of now.
+	 * @param packets array of OSCPackets to initialize this object with
+	 */
+	public OSCBundle(Collection<OSCPacket> packets) {
+		this(packets, TIMESTAMP_IMMEDIATE);
+	}
+
+	/**
+	 * Create an OSCBundle, specifying the packets and timestamp.
+	 * @param packets the packets that make up the bundle
+	 * @param timestamp the time to execute the bundle
+	 */
+	public OSCBundle(Collection<OSCPacket> packets, Date timestamp) {
+
+		if (null == packets) {
+			this.packets = new LinkedList<OSCPacket>();
+		} else {
+			this.packets = new ArrayList<OSCPacket>(packets);
+		}
+		this.timestamp = clone(timestamp);
+	}
+
+	private static Date clone(final Date toBeCloned) {
+		return (toBeCloned == null) ? toBeCloned : (Date) toBeCloned.clone();
+	}
+
+	/**
+	 * Return the time the bundle will execute.
+	 * @return a Date
+	 */
+	public Date getTimestamp() {
+		return clone(timestamp);
+	}
+
+	/**
+	 * Set the time the bundle will execute.
+	 * @param timestamp Date
+	 */
+	public void setTimestamp(Date timestamp) {
+		this.timestamp = clone(timestamp);
+	}
+
+	/**
+	 * Add a packet to the list of packets in this bundle.
+	 * @param packet OSCMessage or OSCBundle
+	 */
+	public void addPacket(OSCPacket packet) {
+		packets.add(packet);
+		contentChanged();
+	}
+
+	/**
+	 * Get the packets contained in this bundle.
+	 * @return the packets contained in this bundle.
+	 */
+	public List<OSCPacket> getPackets() {
+		return Collections.unmodifiableList(packets);
+	}
+
+	/**
+	 * Convert the time-tag (a Java Date) into the OSC byte stream.
+	 * Used Internally.
+	 * @param stream where to write the time-tag to
+	 */
+	private void computeTimeTagByteArray(OSCJavaToByteArrayConverter stream) {
+		if ((null == timestamp) || (timestamp.equals(TIMESTAMP_IMMEDIATE))) {
+			stream.write((int) 0);
+			stream.write((int) 1);
+			return;
+		}
+
+		final long millisecs = timestamp.getTime();
+		final long secsSince1970 = (long) (millisecs / 1000);
+		final long secs = secsSince1970 + SECONDS_FROM_1900_TO_1970;
+
+		// this line was cribbed from jakarta commons-net's NTP TimeStamp code
+		final long fraction = ((millisecs % 1000) * 0x100000000L) / 1000;
+
+		stream.write((int) secs);
+		stream.write((int) fraction);
+	}
+
+	@Override
+	protected byte[] computeByteArray(OSCJavaToByteArrayConverter stream) {
+		stream.write("#bundle");
+		computeTimeTagByteArray(stream);
+		byte[] packetBytes;
+		for (final OSCPacket pkg : packets) {
+			packetBytes = pkg.getByteArray();
+			stream.write(packetBytes);
+		}
+		return stream.toByteArray();
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCImpulse.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCImpulse.java
new file mode 100644
index 0000000..5587904
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCImpulse.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+/**
+ * An OSC 1.0 optional, and OSC 1.1 required argument type.
+ * Impulse aka "bang", is used for event triggers.
+ * No bytes are allocated in the argument data.
+ * This type was named "Infinitum" in OSC 1.0.
+ * Use like this:
+ * <blockquote><pre>{@code
+ * OSCMessage msg = new OSCMessage("/my/address");
+ * msg.addArgument(OSCImpulse.INSTANCE);
+ * }</pre></blockquote>
+ */
+public final class OSCImpulse {
+
+	public static final OSCImpulse INSTANCE = new OSCImpulse();
+
+	private OSCImpulse() {}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCListener.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCListener.java
new file mode 100644
index 0000000..edc3814
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCListener.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import java.util.Date;
+
+/**
+ * Allows to listen to incoming messages that match some selector pattern.
+ * In OSC speak, this is a <i>Method</i>, and it listens to <i>Messages</i>.
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public interface OSCListener {
+
+	/**
+	 * Process a matching, incoming OSC Message.
+	 * @param time     The time this message is to be executed.
+	 *   <code>null</code> means: process immediately
+	 * @param message  The message to process.
+	 */
+	void acceptMessage(Date time, OSCMessage message);
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCMessage.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCMessage.java
new file mode 100644
index 0000000..48dcc04
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCMessage.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import com.illposed.osc.utility.OSCJavaToByteArrayConverter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * An simple (non-bundle) OSC message.
+ *
+ * An OSC <i>Message</i> is made up of
+ * an <i>Address Pattern</i> (the receiver of the message)
+ * and <i>Arguments</i> (the content of the message).
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCMessage extends AbstractOSCPacket {
+
+	/**
+	 * Java regular expression pattern matching a single invalid character.
+	 * The invalid characters are:
+	 * ' ', '#', '*', ',', '?', '[', ']', '{', '}'
+	 */
+	private static final Pattern ILLEGAL_ADDRESS_CHAR
+			= Pattern.compile("[ \\#\\*\\,\\?\\[\\]\\{\\}]");
+
+	private String address;
+	private List<Object> arguments;
+
+	/**
+	 * Creates an empty OSC Message.
+	 * In order to send this OSC message,
+	 * you need to set the address and optionally some arguments.
+	 */
+	public OSCMessage() {
+		this(null);
+	}
+
+	/**
+	 * Creates an OSCMessage with an address already initialized.
+	 * @param address  the recipient of this OSC message
+	 */
+	public OSCMessage(String address) {
+		this(address, null);
+	}
+
+	/**
+	 * Creates an OSCMessage with an address
+	 * and arguments already initialized.
+	 * @param address  the recipient of this OSC message
+	 * @param arguments  the data sent to the receiver
+	 */
+	public OSCMessage(String address, Collection<Object> arguments) {
+
+		checkAddress(address);
+		this.address = address;
+		if (arguments == null) {
+			this.arguments = new LinkedList<Object>();
+		} else {
+			this.arguments = new ArrayList<Object>(arguments);
+		}
+	}
+
+	/**
+	 * The receiver of this message.
+	 * @return the receiver of this OSC Message
+	 */
+	public String getAddress() {
+		return address;
+	}
+
+	/**
+	 * Set the address of this message.
+	 * @param address the receiver of the message
+	 */
+	public void setAddress(String address) {
+		checkAddress(address);
+		this.address = address;
+		contentChanged();
+	}
+
+	/**
+	 * Add an argument to the list of arguments.
+	 * @param argument a Float, Double, String, Character, Integer, Long, Boolean, null
+	 *   or an array of these
+	 */
+	public void addArgument(Object argument) {
+		arguments.add(argument);
+		contentChanged();
+	}
+
+	/**
+	 * The arguments of this message.
+	 * @return the arguments to this message
+	 */
+	public List<Object> getArguments() {
+		return Collections.unmodifiableList(arguments);
+	}
+
+	/**
+	 * Convert the address into a byte array.
+	 * Used internally only.
+	 * @param stream where to write the address to
+	 */
+	private void computeAddressByteArray(OSCJavaToByteArrayConverter stream) {
+		stream.write(address);
+	}
+
+	/**
+	 * Convert the arguments into a byte array.
+	 * Used internally only.
+	 * @param stream where to write the arguments to
+	 */
+	private void computeArgumentsByteArray(OSCJavaToByteArrayConverter stream) {
+		stream.write(',');
+		stream.writeTypes(arguments);
+		for (final Object argument : arguments) {
+			stream.write(argument);
+		}
+	}
+
+	@Override
+	protected byte[] computeByteArray(OSCJavaToByteArrayConverter stream) {
+		computeAddressByteArray(stream);
+		computeArgumentsByteArray(stream);
+		return stream.toByteArray();
+	}
+
+	/**
+	 * Throws an exception if the given address is invalid.
+	 * We explicitly allow <code>null</code> here,
+	 * because we want to allow to set the address in a lazy fashion.
+	 * @param address to be checked for validity
+	 */
+	private static void checkAddress(String address) {
+		// NOTE We explicitly allow <code>null</code> here,
+		//   because we want to allow to set in a lazy fashion.
+		if ((address != null) && !isValidAddress(address)) {
+			throw new IllegalArgumentException("Not a valid OSC address: " + address);
+		}
+	}
+
+	/**
+	 * Checks whether a given string is a valid OSC <i>Address Pattern</i>.
+	 * @param address to be checked for validity
+	 * @return true if the supplied string constitutes a valid OSC address
+	 */
+	public static boolean isValidAddress(String address) {
+		return (address != null)
+				&& !address.isEmpty()
+				&& address.charAt(0) == '/'
+				&& !address.contains("//")
+				&& !ILLEGAL_ADDRESS_CHAR.matcher(address).find();
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCPacket.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCPacket.java
new file mode 100644
index 0000000..da06c9f
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCPacket.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import java.nio.charset.Charset;
+
+/**
+ * OSCPacket is the abstract superclass for the various
+ * kinds of OSC Messages.
+ *
+ * The actual packets are:
+ * <ul>
+ * <li>{@link OSCMessage}: simple OSC messages
+ * <li>{@link OSCBundle}: OSC messages with timestamps
+ *   and/or made up of multiple messages
+ * </ul>
+ */
+public interface OSCPacket {
+
+	/**
+	 * Returns the character set used by this packet.
+	 * @return the character set used to encode message addresses and string
+	 *   arguments.
+	 */
+	Charset getCharset();
+
+	/**
+	 * Sets the character set used by this packet.
+	 * @param charset used to encode message addresses and string arguments.
+	 */
+	void setCharset(Charset charset);
+
+	/**
+	 * Return the OSC byte stream for this packet.
+	 * @return byte[]
+	 */
+	byte[] getByteArray();
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCPort.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCPort.java
new file mode 100644
index 0000000..1c4d2e0
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCPort.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import java.net.DatagramSocket;
+
+/**
+ * OSCPort is an abstract superclass, to send OSC messages,
+ * use {@link OSCPortOut}.
+ * To listen for OSC messages, use {@link OSCPortIn}.
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCPort {
+
+	private final DatagramSocket socket;
+	private final int port;
+
+	public static final int DEFAULT_SC_OSC_PORT = 57110;
+	public static final int DEFAULT_SC_LANG_OSC_PORT = 57120;
+
+	protected OSCPort(DatagramSocket socket, int port) {
+		this.socket = socket;
+		this.port = port;
+	}
+
+	/**
+	 * The port that the SuperCollider <b>synth</b> engine
+	 * usually listens to.
+	 * @return default SuperCollider <b>synth</b> UDP port
+	 * @see #DEFAULT_SC_OSC_PORT
+	 */
+	public static int defaultSCOSCPort() {
+		return DEFAULT_SC_OSC_PORT;
+	}
+
+	/**
+	 * The port that the SuperCollider <b>language</b> engine
+	 * usually listens to.
+	 * @return default SuperCollider <b>language</b> UDP port
+	 * @see #DEFAULT_SC_LANG_OSC_PORT
+	 */
+	public static int defaultSCLangOSCPort() {
+		return DEFAULT_SC_LANG_OSC_PORT;
+	}
+
+	/**
+	 * Returns the socket associated with this port.
+	 * @return this ports socket
+	 */
+	protected DatagramSocket getSocket() {
+		return socket;
+	}
+
+	/**
+	 * Returns the port number associated with this port.
+	 * @return this ports number
+	 */
+	protected int getPort() {
+		return port;
+	}
+
+	/**
+	 * Close the socket and free-up resources.
+	 * It is recommended that clients call this when they are done with the
+	 * port.
+	 */
+	public void close() {
+		socket.close();
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCPortIn.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCPortIn.java
new file mode 100644
index 0000000..2966343
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCPortIn.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2004-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import com.illposed.osc.utility.OSCByteArrayToJavaConverter;
+import com.illposed.osc.utility.OSCPacketDispatcher;
+import com.illposed.osc.utility.OSCPatternAddressSelector;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.SocketException;
+import java.nio.charset.Charset;
+
+/**
+ * OSCPortIn is the class that listens for OSC messages.
+ *
+ * An example:<br>
+ * (loosely based on {com.illposed.osc.OSCPortTest#testReceiving()})
+ * <blockquote><pre>{@code
+ * receiver = new OSCPortIn(OSCPort.DEFAULT_SC_OSC_PORT());
+ * OSCListener listener = new OSCListener() {
+ * 	public void acceptMessage(java.util.Date time, OSCMessage message) {
+ * 		System.out.println("Message received!");
+ * 	}
+ * };
+ * receiver.addListener("/message/receiving", listener);
+ * receiver.startListening();
+ * }</pre></blockquote>
+ *
+ * Then, using a program such as SuperCollider or sendOSC, send a message
+ * to this computer, port {@link #DEFAULT_SC_OSC_PORT},
+ * with the address "/message/receiving".
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCPortIn extends OSCPort implements Runnable {
+
+	/**
+	 * Buffers were 1500 bytes in size, but were
+	 * increased to 1536, as this is a common MTU.
+	 */
+	private static final int BUFFER_SIZE = 1536;
+
+	/** state for listening */
+	private boolean listening;
+	private final OSCByteArrayToJavaConverter converter;
+	private final OSCPacketDispatcher dispatcher;
+
+	/**
+	 * Create an OSCPort that listens using a specified socket.
+	 * @param socket DatagramSocket to listen on.
+	 */
+	public OSCPortIn(DatagramSocket socket) {
+		super(socket, socket.getLocalPort());
+
+		this.converter = new OSCByteArrayToJavaConverter();
+		this.dispatcher = new OSCPacketDispatcher();
+	}
+
+	/**
+	 * Create an OSCPort that listens on the specified port.
+	 * Strings will be decoded using the systems default character set.
+	 * @param port UDP port to listen on.
+	 * @throws SocketException if the port number is invalid,
+	 *   or there is already a socket listening on it
+	 */
+	public OSCPortIn(int port) throws SocketException {
+		this(new DatagramSocket(port));
+	}
+
+	/**
+	 * Create an OSCPort that listens on the specified port,
+	 * and decodes strings with a specific character set.
+	 * @param port UDP port to listen on.
+	 * @param charset how to decode strings read from incoming packages.
+	 *   This includes message addresses and string parameters.
+	 * @throws SocketException if the port number is invalid,
+	 *   or there is already a socket listening on it
+	 */
+	public OSCPortIn(int port, Charset charset) throws SocketException {
+		this(port);
+
+		this.converter.setCharset(charset);
+	}
+
+	/**
+	 * Run the loop that listens for OSC on a socket until
+	 * {@link #isListening()} becomes false.
+	 * @see java.lang.Runnable#run()
+	 */
+	@Override
+	public void run() {
+		final byte[] buffer = new byte[BUFFER_SIZE];
+		final DatagramPacket packet = new DatagramPacket(buffer, BUFFER_SIZE);
+		final DatagramSocket socket = getSocket();
+		while (listening) {
+			try {
+				try {
+					socket.receive(packet);
+				} catch (SocketException ex) {
+					if (listening) {
+						throw ex;
+					} else {
+						// if we closed the socket while receiving data,
+						// the exception is expected/normal, so we hide it
+						continue;
+					}
+				}
+                try {
+                    final OSCPacket oscPacket = converter.convert(buffer, packet.getLength());
+                    dispatcher.dispatchPacket(oscPacket);
+                } catch (IllegalArgumentException ex) {
+                    ex.printStackTrace();
+                }
+			} catch (IOException ex) {
+				ex.printStackTrace(); // XXX This may not be a good idea, as this could easily lead to a never ending series of exceptions thrown (due to the non-exited while loop), and because the user of the lib may want to handle this case himself
+			}
+		}
+	}
+
+	/**
+	 * Start listening for incoming OSCPackets
+	 */
+	public void startListening() {
+		listening = true;
+		final Thread thread = new Thread(this);
+		// The JVM exits when the only threads running are all daemon threads.
+		thread.setDaemon(true);
+		thread.start();
+	}
+
+	/**
+	 * Stop listening for incoming OSCPackets
+	 */
+	public void stopListening() {
+		listening = false;
+	}
+
+	/**
+	 * Am I listening for packets?
+	 * @return true if this port is in listening mode
+	 */
+	public boolean isListening() {
+		return listening;
+	}
+
+	/**
+	 * Registers a listener that will be notified of incoming messages,
+	 * if their address matches the given pattern.
+	 *
+	 * @param addressSelector either a fixed address like "/sc/mixer/volume",
+	 *   or a selector pattern (a mix between wildcards and regex)
+	 *   like "/??/mixer/*", see {@link OSCPatternAddressSelector} for details
+	 * @param listener will be notified of incoming packets, if they match
+	 */
+	public void addListener(String addressSelector, OSCListener listener) {
+		this.addListener(new OSCPatternAddressSelector(addressSelector), listener);
+	}
+
+	/**
+	 * Registers a listener that will be notified of incoming messages,
+	 * if their address matches the given selector.
+	 * @param addressSelector a custom address selector
+	 * @param listener will be notified of incoming packets, if they match
+	 */
+	public void addListener(AddressSelector addressSelector, OSCListener listener) {
+		dispatcher.addListener(addressSelector, listener);
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/OSCPortOut.java b/architecture/android/app/src/main/java/com/illposed/osc/OSCPortOut.java
new file mode 100644
index 0000000..b5219a4
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/OSCPortOut.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2004-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+/**
+ * OSCPortOut is the class that sends OSC messages
+ * to a specific address and port.
+ *
+ * To send an OSC message, call {@link #send(OSCPacket)}.
+ *
+ * An example:<br>
+ * (loosely based on {com.illposed.osc.OSCPortTest#testMessageWithArgs()})
+ * <blockquote><pre>{@code
+ * OSCPort sender = new OSCPort();
+ * List<Object> args = new ArrayList<Object>(2);
+ * args.add(3);
+ * args.add("hello");
+ * OSCMessage msg = new OSCMessage("/sayhello", args);
+ * try {
+ * 	sender.send(msg);
+ * } catch (Exception ex) {
+ * 	showError("Couldn't send");
+ * }
+ * }</pre></blockquote>
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCPortOut extends OSCPort {
+
+	private InetAddress address;
+
+	/**
+	 * Create an OSCPort that sends to address:port using a specified socket.
+	 * @param address the UDP address to send to
+	 * @param port the UDP port to send to
+	 * @param socket the DatagramSocket to send from
+	 */
+	public OSCPortOut(InetAddress address, int port, DatagramSocket socket) {
+		super(socket, port);
+		this.address = address;
+	}
+
+	/**
+	 * Create an OSCPort that sends to address:port.
+	 * @param address the UDP address to send to
+	 * @param port the UDP port to send to
+	 * @throws SocketException when failing to create a (UDP) out socket
+	 */
+	public OSCPortOut(InetAddress address, int port) throws SocketException {
+		this(address, port, new DatagramSocket());
+	}
+
+	/**
+	 * Create an OSCPort that sends to address,
+	 * using the standard SuperCollider port.
+	 * @param address the UDP address to send to
+	 * @throws SocketException when failing to create a (UDP) out socket
+	 */
+	public OSCPortOut(InetAddress address) throws SocketException {
+		this(address, DEFAULT_SC_OSC_PORT);
+	}
+
+	/**
+	 * Create an OSCPort that sends to "localhost",
+	 * on the standard SuperCollider port.
+	 * @throws UnknownHostException if the local host name could not be resolved into an address
+	 * @throws SocketException when failing to create a (UDP) out socket
+	 */
+	public OSCPortOut() throws UnknownHostException, SocketException {
+		this(InetAddress.getLocalHost(), DEFAULT_SC_OSC_PORT);
+	}
+
+	/**
+	 * Send an OSC packet (message or bundle) to the receiver we are bound to.
+	 * @param aPacket the bundle or message to send
+	 * @throws IOException if a (UDP) socket I/O error occurs
+	 */
+	public void send(OSCPacket aPacket) throws IOException {
+		final byte[] byteArray = aPacket.getByteArray();
+		final DatagramPacket packet =
+				new DatagramPacket(byteArray, byteArray.length, address, getPort());
+		getSocket().send(packet);
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/package-info.java b/architecture/android/app/src/main/java/com/illposed/osc/package-info.java
new file mode 100644
index 0000000..7a92d08
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+/**
+ * Provides the Java OSC API, which should be everything users of this library need.
+ */
+package com.illposed.osc;
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/utility/JavaRegexAddressSelector.java b/architecture/android/app/src/main/java/com/illposed/osc/utility/JavaRegexAddressSelector.java
new file mode 100644
index 0000000..a78f166
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/utility/JavaRegexAddressSelector.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014, C. Ramakrishnan / Auracle.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc.utility;
+
+import com.illposed.osc.AddressSelector;
+import java.util.regex.Pattern;
+
+/**
+ * Checks whether an OSC <i>Address Pattern</i> matches a given
+ * Java regular expression.
+ */
+public class JavaRegexAddressSelector implements AddressSelector {
+
+	private final Pattern selector;
+
+	public JavaRegexAddressSelector(Pattern selector) {
+		this.selector = selector;
+	}
+
+	public JavaRegexAddressSelector(String selectorRegex) {
+		this(Pattern.compile(selectorRegex));
+	}
+
+	@Override
+	public boolean matches(String messageAddress) {
+		return selector.matcher(messageAddress).matches();
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCByteArrayToJavaConverter.java b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCByteArrayToJavaConverter.java
new file mode 100644
index 0000000..160a536
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCByteArrayToJavaConverter.java
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2004-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc.utility;
+
+import com.illposed.osc.OSCBundle;
+import com.illposed.osc.OSCImpulse;
+import com.illposed.osc.OSCMessage;
+import com.illposed.osc.OSCPacket;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Utility class to convert a byte array,
+ * conforming to the OSC byte stream format,
+ * into Java objects.
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCByteArrayToJavaConverter {
+
+	private static final String BUNDLE_START = "#bundle";
+	private static final char BUNDLE_IDENTIFIER = BUNDLE_START.charAt(0);
+	private static final String NO_ARGUMENT_TYPES = "";
+
+	private static class Input {
+
+		private final byte[] bytes;
+		private final int bytesLength;
+		private int streamPosition;
+
+		Input(final byte[] bytes, final int bytesLength) {
+
+			this.bytes = bytes;
+			this.bytesLength = bytesLength;
+			this.streamPosition = 0;
+		}
+
+		public byte[] getBytes() {
+			return bytes;
+		}
+
+		public int getBytesLength() {
+			return bytesLength;
+		}
+
+		public int getAndIncreaseStreamPositionByOne() {
+			return streamPosition++;
+		}
+
+		public void addToStreamPosition(int toAdd) {
+			streamPosition += toAdd;
+		}
+
+		public int getStreamPosition() {
+			return streamPosition;
+		}
+	}
+
+	/** Used to decode message addresses and string parameters. */
+	private Charset charset;
+
+	/**
+	 * Creates a helper object for converting from a byte array
+	 * to an {@link OSCPacket} object.
+	 */
+	public OSCByteArrayToJavaConverter() {
+
+		this.charset = Charset.defaultCharset();
+	}
+
+	/**
+	 * Returns the character set used to decode message addresses
+	 * and string parameters.
+	 * @return the character-encoding-set used by this converter
+	 */
+	public Charset getCharset() {
+		return charset;
+	}
+
+	/**
+	 * Sets the character set used to decode message addresses
+	 * and string parameters.
+	 * @param charset the desired character-encoding-set to be used by this converter
+	 */
+	public void setCharset(Charset charset) {
+		this.charset = charset;
+	}
+
+	/**
+	 * Converts a byte array into an {@link OSCPacket}
+	 * (either an {@link OSCMessage} or {@link OSCBundle}).
+	 * @param bytes the storage containing the raw OSC packet
+	 * @param bytesLength indicates how many bytes the package consists of (<code><= bytes.length</code>)
+	 * @return the successfully parsed OSC packet; in case of a problem,
+	 *   a <code>RuntimeException</code> is thrown
+	 */
+	public OSCPacket convert(byte[] bytes, int bytesLength) {
+
+		final Input rawInput = new Input(bytes, bytesLength);
+		final OSCPacket packet;
+		if (isBundle(rawInput)) {
+			packet = convertBundle(rawInput);
+		} else {
+			packet = convertMessage(rawInput);
+		}
+
+		return packet;
+	}
+
+	/**
+	 * Checks whether my byte array is a bundle.
+	 * From the OSC 1.0 specifications:
+	 * <quote>
+	 * The contents of an OSC packet must be either an OSC Message
+	 * or an OSC Bundle. The first byte of the packet's contents unambiguously
+	 * distinguishes between these two alternatives.
+	 * </quote>
+	 * @return true if it the byte array is a bundle, false o.w.
+	 */
+	private boolean isBundle(final Input rawInput) {
+		// The shortest valid packet may be no shorter then 4 bytes,
+		// thus we may assume to always have a byte at index 0.
+		return rawInput.getBytes()[0] == BUNDLE_IDENTIFIER;
+	}
+
+	/**
+	 * Converts the byte array to a bundle.
+	 * Assumes that the byte array is a bundle.
+	 * @return a bundle containing the data specified in the byte stream
+	 */
+	private OSCBundle convertBundle(final Input rawInput) {
+		// skip the "#bundle " stuff
+		rawInput.addToStreamPosition(BUNDLE_START.length() + 1);
+		final Date timestamp = readTimeTag(rawInput);
+		final OSCBundle bundle = new OSCBundle(timestamp);
+		final OSCByteArrayToJavaConverter myConverter
+				= new OSCByteArrayToJavaConverter();
+		myConverter.setCharset(charset);
+		while (rawInput.getStreamPosition() < rawInput.getBytesLength()) {
+			// recursively read through the stream and convert packets you find
+			final int packetLength = readInteger(rawInput);
+			if (packetLength == 0) {
+				throw new IllegalArgumentException("Packet length may not be 0");
+			} else if ((packetLength % 4) != 0) {
+				throw new IllegalArgumentException("Packet length has to be a multiple of 4, is:"
+						+ packetLength);
+			}
+			final byte[] packetBytes = new byte[packetLength];
+			System.arraycopy(rawInput.getBytes(), rawInput.getStreamPosition(), packetBytes, 0, packetLength);
+			rawInput.addToStreamPosition(packetLength);
+			final OSCPacket packet = myConverter.convert(packetBytes, packetLength);
+			bundle.addPacket(packet);
+		}
+		return bundle;
+	}
+
+	/**
+	 * Converts the byte array to a simple message.
+	 * Assumes that the byte array is a message.
+	 * @return a message containing the data specified in the byte stream
+	 */
+	private OSCMessage convertMessage(final Input rawInput) {
+		final OSCMessage message = new OSCMessage();
+		message.setAddress(readString(rawInput));
+		final CharSequence types = readTypes(rawInput);
+		for (int ti = 0; ti < types.length(); ++ti) {
+			if ('[' == types.charAt(ti)) {
+				// we're looking at an array -- read it in
+				message.addArgument(readArray(rawInput, types, ++ti));
+				// then increment i to the end of the array
+				while (types.charAt(ti) != ']') {
+					ti++;
+				}
+			} else {
+				message.addArgument(readArgument(rawInput, types.charAt(ti)));
+			}
+		}
+		return message;
+	}
+
+	/**
+	 * Reads a string from the byte stream.
+	 * @return the next string in the byte stream
+	 */
+	private String readString(final Input rawInput) {
+		final int strLen = lengthOfCurrentString(rawInput);
+		final String res = new String(rawInput.getBytes(), rawInput.getStreamPosition(), strLen, charset);
+		rawInput.addToStreamPosition(strLen);
+		moveToFourByteBoundry(rawInput);
+		return res;
+	}
+
+	/**
+	 * Reads a binary blob from the byte stream.
+	 * @return the next blob in the byte stream
+	 */
+	private byte[] readBlob(final Input rawInput) {
+		final int blobLen = readInteger(rawInput);
+		final byte[] res = new byte[blobLen];
+		System.arraycopy(rawInput.getBytes(), rawInput.getStreamPosition(), res, 0, blobLen);
+		rawInput.addToStreamPosition(blobLen);
+		moveToFourByteBoundry(rawInput);
+		return res;
+	}
+
+	/**
+	 * Reads the types of the arguments from the byte stream.
+	 * @return a char array with the types of the arguments,
+	 *   or <code>null</code>, in case of no arguments
+	 */
+	private CharSequence readTypes(final Input rawInput) {
+		final String typesStr;
+
+		// The next byte should be a ',', but some legacy code may omit it
+		// in case of no arguments, refering to "OSC Messages" in:
+		// http://opensoundcontrol.org/spec-1_0
+		if (rawInput.getBytes().length <= rawInput.getStreamPosition()) {
+			typesStr = NO_ARGUMENT_TYPES;
+		} else if (rawInput.getBytes()[rawInput.getStreamPosition()] != ',') {
+			// XXX should we not rather fail-fast -> throw exception?
+			typesStr = NO_ARGUMENT_TYPES;
+		} else {
+			rawInput.getAndIncreaseStreamPositionByOne();
+			typesStr = readString(rawInput);
+		}
+
+		return typesStr;
+	}
+
+	/**
+	 * Reads an object of the type specified by the type char.
+	 * @param type type of the argument to read
+	 * @return a Java representation of the argument
+	 */
+	private Object readArgument(final Input rawInput, final char type) {
+		switch (type) {
+			case 'u' :
+				return readUnsignedInteger(rawInput);
+			case 'i' :
+				return readInteger(rawInput);
+			case 'h' :
+				return readLong(rawInput);
+			case 'f' :
+				return readFloat(rawInput);
+			case 'd' :
+				return readDouble(rawInput);
+			case 's' :
+				return readString(rawInput);
+			case 'b' :
+				return readBlob(rawInput);
+			case 'c' :
+				return readChar(rawInput);
+			case 'N' :
+				return null;
+			case 'T' :
+				return Boolean.TRUE;
+			case 'F' :
+				return Boolean.FALSE;
+			case 'I' :
+				return OSCImpulse.INSTANCE;
+			case 't' :
+				return readTimeTag(rawInput);
+			default:
+				// XXX Maybe we should let the user choose what to do in this
+				//   case (we encountered an unknown argument type in an
+				//   incomming message):
+				//   just ignore (return null), or throw an exception?
+//				throw new UnsupportedOperationException(
+//						"Invalid or not yet supported OSC type: '" + type + "'");
+				return null;
+		}
+	}
+
+	/**
+	 * Reads a char from the byte stream.
+	 * @return a {@link Character}
+	 */
+	private Character readChar(final Input rawInput) {
+		return (char) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()];
+	}
+
+	private BigInteger readBigInteger(final Input rawInput, final int numBytes) {
+		final byte[] myBytes = new byte[numBytes];
+		System.arraycopy(rawInput.getBytes(), rawInput.getStreamPosition(), myBytes, 0, numBytes);
+		rawInput.addToStreamPosition(numBytes);
+		return  new BigInteger(myBytes);
+	}
+
+	/**
+	 * Reads a double from the byte stream.
+	 * @return a 64bit precision floating point value
+	 */
+	private Object readDouble(final Input rawInput) {
+		final BigInteger doubleBits = readBigInteger(rawInput, 8);
+		return Double.longBitsToDouble(doubleBits.longValue());
+	}
+
+	/**
+	 * Reads a float from the byte stream.
+	 * @return a 32bit precision floating point value
+	 */
+	private Float readFloat(final Input rawInput) {
+		final BigInteger floatBits = readBigInteger(rawInput, 4);
+		return Float.intBitsToFloat(floatBits.intValue());
+	}
+
+	/**
+	 * Reads a double precision integer (64 bit integer) from the byte stream.
+	 * @return double precision integer (64 bit)
+	 */
+	private Long readLong(final Input rawInput) {
+		final BigInteger longintBytes = readBigInteger(rawInput, 8);
+		return longintBytes.longValue();
+	}
+
+	/**
+	 * Reads an Integer (32 bit integer) from the byte stream.
+	 * @return an {@link Integer}
+	 */
+	private Integer readInteger(final Input rawInput) {
+		final BigInteger intBits = readBigInteger(rawInput, 4);
+		return intBits.intValue();
+	}
+
+	/**
+	 * Reads an unsigned integer (32 bit) from the byte stream.
+	 * This code is copied from {@see http://darksleep.com/player/JavaAndUnsignedTypes.html},
+	 * which is licensed under the Public Domain.
+	 * @return single precision, unsigned integer (32 bit) wrapped in a 64 bit integer (long)
+	 */
+	private Long readUnsignedInteger(final Input rawInput) {
+
+		final int firstByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()]));
+		final int secondByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()]));
+		final int thirdByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()]));
+		final int fourthByte = (0x000000FF & ((int) rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()]));
+		return ((long) (firstByte << 24
+				| secondByte << 16
+				| thirdByte << 8
+				| fourthByte))
+				& 0xFFFFFFFFL;
+	}
+
+	/**
+	 * Reads the time tag and convert it to a Java Date object.
+	 * A timestamp is a 64 bit number representing the time in NTP format.
+	 * The first 32 bits are seconds since 1900, the second 32 bits are
+	 * fractions of a second.
+	 * @return a {@link Date}
+	 */
+	private Date readTimeTag(final Input rawInput) {
+		final byte[] secondBytes = new byte[8];
+		final byte[] fractionBytes = new byte[8];
+		for (int bi = 0; bi < 4; bi++) {
+			// clear the higher order 4 bytes
+			secondBytes[bi] = 0;
+			fractionBytes[bi] = 0;
+		}
+		// while reading in the seconds & fraction, check if
+		// this timetag has immediate semantics
+		boolean isImmediate = true;
+		for (int bi = 4; bi < 8; bi++) {
+			secondBytes[bi] = rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()];
+			if (secondBytes[bi] > 0) {
+				isImmediate = false;
+			}
+		}
+		for (int bi = 4; bi < 8; bi++) {
+			fractionBytes[bi] = rawInput.getBytes()[rawInput.getAndIncreaseStreamPositionByOne()];
+			if (bi < 7) {
+				if (fractionBytes[bi] > 0) {
+					isImmediate = false;
+				}
+			} else {
+				if (fractionBytes[bi] > 1) {
+					isImmediate = false;
+				}
+			}
+		}
+
+		if (isImmediate) {
+			return OSCBundle.TIMESTAMP_IMMEDIATE;
+		}
+
+		final long secsSince1900 = new BigInteger(secondBytes).longValue();
+		long secsSince1970 = secsSince1900 - OSCBundle.SECONDS_FROM_1900_TO_1970;
+
+		// no point maintaining times in the distant past
+		if (secsSince1970 < 0) {
+			secsSince1970 = 0;
+		}
+		long fraction = new BigInteger(fractionBytes).longValue();
+
+		// this line was cribbed from jakarta commons-net's NTP TimeStamp code
+		fraction = (fraction * 1000) / 0x100000000L;
+
+		// I do not know where, but I'm losing 1ms somewhere...
+		fraction = (fraction > 0) ? fraction + 1 : 0;
+		final long millisecs = (secsSince1970 * 1000) + fraction;
+		return new Date(millisecs);
+	}
+
+	/**
+	 * Reads an array from the byte stream.
+	 * @param types
+	 * @param pos at which position to start reading
+	 * @return the array that was read
+	 */
+	private List<Object> readArray(final Input rawInput, final CharSequence types, int pos) {
+		int arrayLen = 0;
+		while (types.charAt(pos + arrayLen) != ']') {
+			arrayLen++;
+		}
+		final List<Object> array = new ArrayList<Object>(arrayLen);
+		for (int ai = 0; ai < arrayLen; ai++) {
+			array.add(readArgument(rawInput, types.charAt(pos + ai)));
+		}
+		return array;
+	}
+
+	/**
+	 * Get the length of the string currently in the byte stream.
+	 */
+	private int lengthOfCurrentString(final Input rawInput) {
+		int len = 0;
+		while (rawInput.getBytes()[rawInput.getStreamPosition() + len] != 0) {
+			len++;
+		}
+		return len;
+	}
+
+	/**
+	 * Move to the next byte with an index in the byte array
+	 * which is dividable by four.
+	 */
+	private void moveToFourByteBoundry(final Input rawInput) {
+		// If i am already at a 4 byte boundry, I need to move to the next one
+		final int mod = rawInput.getStreamPosition() % 4;
+		rawInput.addToStreamPosition(4 - mod);
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCJavaToByteArrayConverter.java b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCJavaToByteArrayConverter.java
new file mode 100644
index 0000000..27a8ae8
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCJavaToByteArrayConverter.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc.utility;
+
+import com.illposed.osc.OSCImpulse;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * OSCJavaToByteArrayConverter is a helper class that translates
+ * from Java types to their byte stream representations according to
+ * the OSC spec.
+ *
+ * The implementation is based on
+ * <a href="http://www.emergent.de">Markus Gaelli</a> and
+ * Iannis Zannos's OSC implementation in Squeak (a Smalltalk dialect).
+ *
+ * This version includes bug fixes and improvements from
+ * Martin Kaltenbrunner and Alex Potsides.
+ *
+ * @author Chandrasekhar Ramakrishnan
+ * @author Martin Kaltenbrunner
+ * @author Alex Potsides
+ */
+public class OSCJavaToByteArrayConverter {
+
+	/**
+	 * baseline NTP time if bit-0=0 is 7-Feb-2036 @ 06:28:16 UTC
+	 */
+	protected static final long MSB_0_BASE_TIME = 2085978496000L;
+	/**
+	 * baseline NTP time if bit-0=1 is 1-Jan-1900 @ 01:00:00 UTC
+	 */
+	protected static final long MSB_1_BASE_TIME = -2208988800000L;
+
+	private final ByteArrayOutputStream stream;
+	/** Used to encode message addresses and string parameters. */
+	private Charset charset;
+	private final byte[] intBytes;
+	private final byte[] longintBytes;
+
+	public OSCJavaToByteArrayConverter() {
+
+		this.stream = new ByteArrayOutputStream();
+		this.charset = Charset.defaultCharset();
+		this.intBytes = new byte[4];
+		this.longintBytes = new byte[8];
+	}
+
+	/**
+	 * Returns the character set used to encode message addresses
+	 * and string parameters.
+	 * @return the character-encoding-set used by this converter
+	 */
+	public Charset getCharset() {
+		return charset;
+	}
+
+	/**
+	 * Sets the character set used to encode message addresses
+	 * and string parameters.
+	 * @param charset the desired character-encoding-set to be used by this converter
+	 */
+	public void setCharset(Charset charset) {
+		this.charset = charset;
+	}
+
+	/**
+	 * Align the stream by padding it with '0's so it has a size divisible by 4.
+	 */
+	private void alignStream() {
+		final int alignmentOverlap = stream.size() % 4;
+		final int padLen = (4 - alignmentOverlap) % 4;
+		for (int pci = 0; pci < padLen; pci++) {
+			stream.write(0);
+		}
+	}
+
+	/**
+	 * Convert the contents of the output stream to a byte array.
+	 * @return the byte array containing the byte stream
+	 */
+	public byte[] toByteArray() {
+		return stream.toByteArray();
+	}
+
+	/**
+	 * Write bytes into the byte stream.
+	 * @param bytes  bytes to be written
+	 */
+	public void write(byte[] bytes) {
+		writeInteger32ToByteArray(bytes.length);
+		writeUnderHandler(bytes);
+		alignStream();
+	}
+
+	/**
+	 * Write an integer into the byte stream.
+	 * @param anInt the integer to be written
+	 */
+	public void write(int anInt) {
+		writeInteger32ToByteArray(anInt);
+	}
+
+	/**
+	 * Write a float into the byte stream.
+	 * @param aFloat floating point number to be written
+	 */
+	public void write(Float aFloat) {
+		writeInteger32ToByteArray(Float.floatToIntBits(aFloat));
+	}
+
+	/**
+	 * Write a double into the byte stream (8 bytes).
+	 * @param aDouble double precision floating point number to be written
+	 */
+	public void write(Double aDouble) {
+		writeInteger64ToByteArray(Double.doubleToRawLongBits(aDouble));
+	}
+
+	/**
+	 * @param anInt the integer to be written
+	 */
+	public void write(Integer anInt) {
+		writeInteger32ToByteArray(anInt);
+	}
+
+	/**
+	 * @param aLong the double precision integer to be written
+	 */
+	public void write(Long aLong) {
+		writeInteger64ToByteArray(aLong);
+	}
+
+	/**
+	 * @param timestamp the timestamp to be written
+	 */
+	public void write(Date timestamp) {
+		writeInteger64ToByteArray(javaToNtpTimeStamp(timestamp.getTime()));
+	}
+
+	/**
+	 * Converts a Java time-stamp to a 64-bit NTP time representation.
+	 * This code was copied in from the "Apache Jakarta Commons - Net" library,
+	 * which is licensed under the
+	 * <a href="http://www.apache.org/licenses/LICENSE-2.0.html">ASF 2.0 license</a>.
+	 * The original source file can be found
+	 * <a href="http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ntp/TimeStamp.java?view=co">here</a>.
+	 * @param javaTime Java time-stamp, as returned by {@link Date#getTime()}
+	 * @return NTP time-stamp representation of the Java time value.
+	 */
+	protected static long javaToNtpTimeStamp(long javaTime) {
+		final boolean useBase1 = javaTime < MSB_0_BASE_TIME; // time < Feb-2036
+		final long baseTime;
+		if (useBase1) {
+			baseTime = javaTime - MSB_1_BASE_TIME; // dates <= Feb-2036
+		} else {
+			// if base0 needed for dates >= Feb-2036
+			baseTime = javaTime - MSB_0_BASE_TIME;
+		}
+
+		long seconds = baseTime / 1000;
+		final long fraction = ((baseTime % 1000) * 0x100000000L) / 1000;
+
+		if (useBase1) {
+			seconds |= 0x80000000L; // set high-order bit if msb1baseTime 1900 used
+		}
+
+		final long ntpTime = seconds << 32 | fraction;
+
+		return ntpTime;
+	}
+
+	/**
+	 * Write a string into the byte stream.
+	 * @param aString the string to be written
+	 */
+	public void write(String aString) {
+		final byte[] stringBytes = aString.getBytes(charset);
+		writeUnderHandler(stringBytes);
+		stream.write(0);
+		alignStream();
+	}
+
+	/**
+	 * Write a char into the byte stream, and ensure it is 4 byte aligned again.
+	 * @param aChar the character to be written
+	 */
+	public void write(Character aChar) {
+		stream.write((char) aChar);
+		alignStream();
+	}
+
+	/**
+	 * Write a char into the byte stream.
+	 * CAUTION, this does not ensure 4 byte alignment (it actually breaks it)!
+	 * @param aChar the character to be written
+	 */
+	public void write(char aChar) {
+		stream.write(aChar);
+	}
+
+	/**
+	 * Checks whether the given object is represented by a type that comes without data.
+	 * @param anObject the object to inspect
+	 * @return whether the object to check consists of only its type information
+	 */
+	private boolean isNoDataObject(Object anObject) {
+		return ((anObject instanceof OSCImpulse)
+				|| (anObject instanceof Boolean)
+				|| (anObject == null));
+	}
+
+	/**
+	 * Write an object into the byte stream.
+	 * @param anObject (usually) one of Float, Double, String, Character, Integer, Long,
+	 *   or array of these.
+	 */
+	public void write(Object anObject) {
+		// Can't do switch on class
+		if (anObject instanceof Collection) {
+			final Collection<Object> theArray = (Collection<Object>) anObject;
+			for (final Object entry : theArray) {
+				write(entry);
+			}
+		} else if (anObject instanceof Float) {
+			write((Float) anObject);
+		} else if (anObject instanceof Double) {
+			write((Double) anObject);
+		} else if (anObject instanceof String) {
+			write((String) anObject);
+		} else if (anObject instanceof byte[]) {
+			write((byte[]) anObject);
+		} else if (anObject instanceof Character) {
+			write((Character) anObject);
+		} else if (anObject instanceof Integer) {
+			write((Integer) anObject);
+		} else if (anObject instanceof Long) {
+			write((Long) anObject);
+		} else if (anObject instanceof Date) {
+			write((Date) anObject);
+		} else if (!isNoDataObject(anObject)) {
+			throw new UnsupportedOperationException("Do not know how to write an object of class: "
+					+ anObject.getClass());
+		}
+	}
+
+	/**
+	 * Write the OSC specification type tag for the type a certain Java type
+	 * converts to.
+	 * @param typeClass Class of a Java object in the arguments
+	 */
+	public void writeType(Class typeClass) {
+
+		// A big ol' else-if chain -- what's polymorphism mean, again?
+		// I really wish I could extend the base classes!
+		if (Integer.class.equals(typeClass)) {
+			stream.write('i');
+		} else if (Long.class.equals(typeClass)) {
+			stream.write('h');
+		} else if (Date.class.equals(typeClass)) {
+			stream.write('t');
+		} else if (Float.class.equals(typeClass)) {
+			stream.write('f');
+		} else if (Double.class.equals(typeClass)) {
+			stream.write('d');
+		} else if (String.class.equals(typeClass)) {
+			stream.write('s');
+		} else if (byte[].class.equals(typeClass)) {
+			stream.write('b');
+		} else if (Character.class.equals(typeClass)) {
+			stream.write('c');
+		} else if (OSCImpulse.class.equals(typeClass)) {
+			stream.write('I');
+		} else {
+			throw new UnsupportedOperationException("Do not know the OSC type for the java class: "
+					+ typeClass);
+		}
+	}
+
+	/**
+	 * Write the types for an array element in the arguments.
+	 * @param arguments array of base Objects
+	 */
+	private void writeTypesArray(Collection<Object> arguments) {
+
+		for (final Object argument : arguments) {
+			if (null == argument) {
+				stream.write('N');
+			} else if (argument instanceof Collection) {
+				// If the array at i is a type of array, write a '['.
+				// This is used for nested arguments.
+				stream.write('[');
+				// fill the [] with the SuperCollider types corresponding to
+				// the object (e.g., Object of type String needs -s).
+				// XXX Why not call this function, recursively? The only reason would be, to not allow nested arrays, but the specification does not say anythign about them not being allowed.
+				writeTypesArray((Collection<Object>) argument);
+				// close the array
+				stream.write(']');
+			} else if (Boolean.TRUE.equals(argument)) {
+				stream.write('T');
+			} else if (Boolean.FALSE.equals(argument)) {
+				stream.write('F');
+			} else {
+				// go through the array and write the superCollider types as shown
+				// in the above method.
+				// The classes derived here are used as the arg to the above method.
+				writeType(argument.getClass());
+			}
+		}
+	}
+
+	/**
+	 * Write types for the arguments.
+	 * @param arguments  the arguments to an OSCMessage
+	 */
+	public void writeTypes(Collection<Object> arguments) {
+
+		writeTypesArray(arguments);
+		// we always need to terminate with a zero,
+		// even if (especially when) the stream is already aligned.
+		stream.write(0);
+		// align the stream with padded bytes
+		alignStream();
+	}
+
+	/**
+	 * Write bytes to the stream, catching IOExceptions and converting them to
+	 * RuntimeExceptions.
+	 * @param bytes to be written to the stream
+	 */
+	private void writeUnderHandler(byte[] bytes) {
+
+		try {
+			stream.write(bytes);
+		} catch (IOException ex) {
+			throw new RuntimeException("You're screwed:"
+					+ " IOException writing to a ByteArrayOutputStream", ex);
+		}
+	}
+
+	/**
+	 * Write a 32 bit integer to the byte array without allocating memory.
+	 * @param value a 32 bit integer.
+	 */
+	private void writeInteger32ToByteArray(int value) {
+		//byte[] intBytes = new byte[4];
+		//I allocated the this buffer globally so the GC has less work
+
+		intBytes[3] = (byte)value; value >>>= 8;
+		intBytes[2] = (byte)value; value >>>= 8;
+		intBytes[1] = (byte)value; value >>>= 8;
+		intBytes[0] = (byte)value;
+
+		writeUnderHandler(intBytes);
+	}
+
+	/**
+	 * Write a 64 bit integer to the byte array without allocating memory.
+	 * @param value a 64 bit integer.
+	 */
+	private void writeInteger64ToByteArray(long value) {
+		longintBytes[7] = (byte)value; value >>>= 8;
+		longintBytes[6] = (byte)value; value >>>= 8;
+		longintBytes[5] = (byte)value; value >>>= 8;
+		longintBytes[4] = (byte)value; value >>>= 8;
+		longintBytes[3] = (byte)value; value >>>= 8;
+		longintBytes[2] = (byte)value; value >>>= 8;
+		longintBytes[1] = (byte)value; value >>>= 8;
+		longintBytes[0] = (byte)value;
+
+		writeUnderHandler(longintBytes);
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCPacketDispatcher.java b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCPacketDispatcher.java
new file mode 100644
index 0000000..5e03f9e
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCPacketDispatcher.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2014, C. Ramakrishnan / Auracle.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc.utility;
+
+import com.illposed.osc.AddressSelector;
+import com.illposed.osc.OSCBundle;
+import com.illposed.osc.OSCListener;
+import com.illposed.osc.OSCMessage;
+import com.illposed.osc.OSCPacket;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Dispatches {@link OSCPacket}s to registered listeners (<i>Method</i>s).
+ *
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OSCPacketDispatcher {
+
+	private final Map<AddressSelector, OSCListener> selectorToListener;
+
+	public OSCPacketDispatcher() {
+		this.selectorToListener = new HashMap<AddressSelector, OSCListener>();
+	}
+
+	/**
+	 * Adds a listener (<i>Method</i> in OSC speak) that will be notified
+	 * of incoming messages that match the selector.
+	 * @param addressSelector selects which messages will be forwarded to the listener,
+	 *   depending on the message address
+	 * @param listener receives messages accepted by the selector
+	 */
+	public void addListener(AddressSelector addressSelector, OSCListener listener) {
+		selectorToListener.put(addressSelector, listener);
+	}
+
+	public void dispatchPacket(OSCPacket packet) {
+		dispatchPacket(packet, null);
+	}
+
+	public void dispatchPacket(OSCPacket packet, Date timestamp) {
+		if (packet instanceof OSCBundle) {
+			dispatchBundle((OSCBundle) packet);
+		} else {
+			dispatchMessage((OSCMessage) packet, timestamp);
+		}
+	}
+
+	private void dispatchBundle(OSCBundle bundle) {
+		final Date timestamp = bundle.getTimestamp();
+		final List<OSCPacket> packets = bundle.getPackets();
+		for (final OSCPacket packet : packets) {
+			dispatchPacket(packet, timestamp);
+		}
+	}
+
+	private void dispatchMessage(OSCMessage message, Date time) {
+		for (final Entry<AddressSelector, OSCListener> addrList : selectorToListener.entrySet()) {
+			if (addrList.getKey().matches(message.getAddress())) {
+				addrList.getValue().acceptMessage(time, message);
+			}
+		}
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCPatternAddressSelector.java b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCPatternAddressSelector.java
new file mode 100644
index 0000000..baec859
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/utility/OSCPatternAddressSelector.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2014, C. Ramakrishnan / Auracle.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+package com.illposed.osc.utility;
+
+import com.illposed.osc.AddressSelector;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Checks whether an OSC message address matches a given wildcard expression,
+ * as specified in the OSC protocol specification.
+ * For details, see the "OSC Message Dispatching and Pattern Matching" section on
+ * <a href="http://opensoundcontrol.org/spec-1_0">the OSC 1.0 specification</a>.
+ * Also supports the path-traversal wildcard "//", as specified in OSC 1.1 (borrowed from XPath).
+ *
+ * <p>
+ * A coarse history of the code in the function
+ * {@link OSCPatternAddressSelector#matches(String, String)},
+ * from the origin to JavaOSC:
+ * </p>
+ * <ol>
+ * <li>
+ *   <b>robust glob pattern matcher</b><br>
+ *   language: <i>C</i><br>
+ *   author: <i>ozan s. yigit/dec 1994</i><br>
+ *   matching code license: <i>public domain</i><br>
+ *   <a href="http://www.cse.yorku.ca/~oz/glob.bun">source location</a><br>
+ * </li>
+ * <li>
+ *   <b>Open SoundControl kit</b><br>
+ *   language: <i>C++</i><br>
+ *   matching code license: <i>public domain</i><br>
+ *   library license: <i>LGPL 2.1+</i><br>
+ *   <a href="http://archive.cnmat.berkeley.edu/OpenSoundControl/src/OSC-Kit/OSC-pattern-match.c">source location</a><br>
+ * </li>
+ * <li>
+ *   <b>LibLO</b><br>
+ *   language: <i>C++</i><br>
+ *   library license: <i>LGPL 2.1+</i><br>
+ *   <a href="https://sourceforge.net/p/liblo/git/ci/master/tree/src/pattern_match.c">source location</a><br>
+ * </li>
+ * <li>
+ *   <b>JavaOSC</b><br>
+ *   language: <i>Java</i><br>
+ *   matching code license: <i>public domain</i><br>
+ *   library license: <i>BSD 3-Clause</i><br>
+ * </li>
+ * </ol>
+ */
+public class OSCPatternAddressSelector implements AddressSelector {
+
+	private final List<String> patternParts;
+
+	public OSCPatternAddressSelector(String selector) {
+		this.patternParts = splitIntoParts(selector);
+	}
+
+	@Override
+	public boolean matches(String messageAddress) {
+
+		final List<String> messageAddressParts = splitIntoParts(messageAddress);
+		return matches(patternParts, 0, messageAddressParts, 0);
+	}
+
+	/**
+	 * Splits an OSC message address or address selector pattern into parts that are convenient
+	 * during the matching process.
+	 * @param addressOrPattern to be split into parts, e.g.: "/hello/", "/hello//world//"
+	 * @return the given address or pattern split into parts: {"hello"}, {"hello, "", "world", ""}
+	 */
+	private static List<String> splitIntoParts(String addressOrPattern) {
+
+		final List<String> parts = new ArrayList<String>(Arrays.asList(addressOrPattern.split("/", -1)));
+		if (addressOrPattern.startsWith("/")) {
+			// as "/hello" gets split into {"", "hello"}, we remove the first empty entry,
+			// so we end up with {"hello"}
+			parts.remove(0);
+		}
+		if (addressOrPattern.endsWith("/")) {
+			// as "hello/" gets split into {"hello", ""}, we also remove the last empty entry,
+			// so we end up with {"hello"}
+			parts.remove(parts.size() - 1);
+		}
+		return Collections.unmodifiableList(parts);
+	}
+
+	/**
+	 * Tries to match an OSC <i>Address Pattern</i> to a selector,
+	 * both already divided into their parts.
+	 * @param patternParts all the parts of the pattern
+	 * @param ppi index/pointer to the current part of the pattern we are looking at
+	 * @param messageAddressParts all the parts of the address
+	 * @param api index/pointer to the current part of the address we are looking at
+	 * @return true if the address matches, false otherwise
+	 */
+	private static boolean matches(List<String> patternParts, int ppi, List<String> messageAddressParts, int api) {
+
+		while (ppi < patternParts.size()) {
+			// There might be some path-traversal wildcards (PTW) "//" in the pattern.
+			// "//" in the pattern translates to an empty String ("") in the pattern parts.
+			// We skip all consecutive "//"s at the current pattern position.
+			boolean pathTraverser = false;
+			while ((ppi < patternParts.size()) && patternParts.get(ppi).isEmpty()) {
+				ppi++;
+				pathTraverser = true;
+			}
+			// ppi is now at the end, or at the first non-PTW part
+			if (pathTraverser) {
+				if (ppi == patternParts.size()) {
+					// trailing PTW matches the whole rest of the address
+					return true;
+				}
+				while (api < messageAddressParts.size()) {
+					if (matches(messageAddressParts.get(api), patternParts.get(ppi))
+							&& matches(patternParts, ppi + 1, messageAddressParts, api + 1))
+					{
+						return true;
+					}
+					api++;
+				}
+				// end of address parts reached, but there are still non-PTW pattern parts
+				// left
+				return false;
+			} else {
+				if ((ppi == patternParts.size()) != (api == messageAddressParts.size())) {
+					// end of pattern, no trailing PTW, but there are still address parts left
+					// OR
+					// end of address, but there are still non-PTW pattern parts left
+					return false;
+				}
+				if (!matches(messageAddressParts.get(api), patternParts.get(ppi))) {
+					return false;
+				}
+				api++;
+			}
+			ppi++;
+		}
+
+		return (api == messageAddressParts.size());
+	}
+
+	/**
+	 * Tries to match an OSC <i>Address Pattern</i> part to a part of
+	 * a selector.
+	 * This code was copied and adapted from LibLo,
+	 * and is licensed under the Public Domain.
+	 * For more details see: {@link OSCPatternAddressSelector}.
+	 * @param str address part
+	 * @param p pattern part
+	 * @return true if the address part matches, false otherwise
+	 */
+	private static boolean matches(String str, String p) {
+
+		boolean negate;
+		boolean match;
+		char c;
+
+		int si = 0;
+		int pi = 0;
+		while (pi < p.length()) {
+			if ((si == str.length()) && p.charAt(pi) != '*') {
+				return false;
+			}
+
+			c = p.charAt(pi++);
+			switch (c) {
+				case '*':
+					while ((pi < p.length()) && p.charAt(pi) == '*' && p.charAt(pi) != '/') {
+						pi++;
+					}
+
+					if (pi == p.length()) {
+						return true;
+					}
+
+//					if (p.charAt(pi) != '?' && p.charAt(pi) != '[' && p.charAt(pi) != '\\')
+					if (p.charAt(pi) != '?' && p.charAt(pi) != '[' && p.charAt(pi) != '{') {
+						while (si < str.length() && p.charAt(pi) != str.charAt(si)) {
+							si++;
+						}
+					}
+
+					while (si < str.length()) {
+						if (matches(str.substring(si), p.substring(pi))) {
+							return true;
+						}
+						si++;
+					}
+					return false;
+
+				case '?':
+					if (si < str.length()) {
+						break;
+					}
+					return false;
+
+				/*
+				 * set specification is inclusive, that is [a-z] is a, z and
+				 * everything in between. this means [z-a] may be interpreted
+				 * as a set that contains z, a and nothing in between.
+				 */
+				case '[':
+					if (p.charAt(pi) == '!') {
+						negate = true;
+						pi++;
+					} else {
+						negate = false;
+					}
+
+					match = false;
+
+					while (!match && (pi < p.length())) {
+						c = p.charAt(pi++);
+						if (pi == p.length()) {
+							return false;
+						}
+						if (p.charAt(pi) == '-') { // c-c
+							pi++;
+							if (pi == p.length()) {
+								return false;
+							}
+							if (p.charAt(pi) != ']') {
+								if (str.charAt(si) == c || str.charAt(si) == p.charAt(pi)
+										|| (str.charAt(si) > c && str.charAt(si) < p.charAt(pi)))
+								{
+									match = true;
+								}
+							} else { // c-]
+								if (str.charAt(si) >= c) {
+									match = true;
+								}
+								break;
+							}
+						} else { // cc or c]
+							if (c == str.charAt(si)) {
+								match = true;
+							}
+							if (p.charAt(pi) != ']') {
+								if (p.charAt(pi) == str.charAt(si)) {
+									match = true;
+								}
+							} else {
+								break;
+							}
+						}
+					}
+
+					if (negate == match) {
+						return false;
+					}
+					// if there is a match, skip past the cset and continue on
+					while (pi < p.length() && p.charAt(pi) != ']') {
+						pi++;
+					}
+					if (pi++ == p.length()) { // oops!
+						return false;
+					}
+					break;
+
+				// {astring,bstring,cstring}
+				case '{':
+					// p.charAt(pi) is now first character in the {brace list}
+					final int place = si; // to backtrack
+					int remainder = pi; // to forwardtrack
+
+					// find the end of the brace list
+					while ((remainder < p.length()) && (p.charAt(remainder) != '}')) {
+						remainder++;
+					}
+					if (remainder == p.length()) /* oops! */ {
+						return false;
+					}
+					remainder++;
+
+					c = p.charAt(pi++);
+					while (pi <= p.length()) {
+						if (c == ',') {
+							if (matches(str.substring(si), p.substring(remainder))) {
+								return true;
+							} else {
+								// backtrack on test string
+								si = place;
+								// continue testing,
+								// skip comma
+								if (pi++ == p.length()) { // oops
+									return false;
+								}
+							}
+						} else if (c == '}') {
+							// continue normal pattern matching
+							if ((pi == p.length()) && (si == str.length())) {
+								return true;
+							}
+							si--; // str is incremented again below
+							break;
+						} else if (c == str.charAt(si)) {
+							si++;
+							if ((si == str.length()) && (remainder < p.length())) {
+								return false;
+							}
+						} else { // skip to next comma
+							si = place;
+							while ((pi < p.length()) && (p.charAt(pi) != ',') && (p.charAt(pi) != '}')) {
+								pi++;
+							}
+							if (pi < p.length()) {
+								if (p.charAt(pi) == ',') {
+									pi++;
+								} else if (p.charAt(pi) == '}') {
+									return false;
+								}
+							}
+						}
+						c = p.charAt(pi++);
+					}
+					break;
+
+				/*
+				 * Not part of OSC pattern matching
+					case '\\':
+						if (p.charAt(pi)) {
+							c = p.charAt(pi)++;
+						}
+				 */
+				default:
+					if (c != str.charAt(si)) {
+						return false;
+					}
+					break;
+			}
+			si++;
+		}
+
+		return (si == str.length());
+	}
+}
diff --git a/architecture/android/app/src/main/java/com/illposed/osc/utility/package-info.java b/architecture/android/app/src/main/java/com/illposed/osc/utility/package-info.java
new file mode 100644
index 0000000..32f3c57
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/illposed/osc/utility/package-info.java
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014, C. Ramakrishnan / Illposed Software.
+ * All rights reserved.
+ *
+ * This code is licensed under the BSD 3-Clause license.
+ * See file LICENSE (or LICENSE.html) for more information.
+ */
+
+/**
+ * Provides utility classes, used internally by the Java OSC API classes.
+ * Users of the library should not need to use these classes directly.
+ *
+ * @see com.illposed.osc
+ */
+package com.illposed.osc.utility;
diff --git a/architecture/android/app/src/main/java/com/triggertrap/seekarc/SeekArc.java b/architecture/android/app/src/main/java/com/triggertrap/seekarc/SeekArc.java
new file mode 100644
index 0000000..7a7e972
--- /dev/null
+++ b/architecture/android/app/src/main/java/com/triggertrap/seekarc/SeekArc.java
@@ -0,0 +1,530 @@
+/*******************************************************************************
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2013 Triggertrap Ltd
+ * Author Neil Davies
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ******************************************************************************/
+package com.triggertrap.seekarc;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.faust.R;
+
+/**
+ * 
+ * SeekArc.java
+ * 
+ * This is a class that functions much like a SeekBar but
+ * follows a circle path instead of a straight line.
+ * 
+ * @author Neil Davies
+ * 
+ */
+public class SeekArc extends View {
+
+	private static final String TAG = SeekArc.class.getSimpleName();
+	private static int INVALID_PROGRESS_VALUE = -1;
+	// The initial rotational offset -90 means we start at 12 o'clock
+	private final int mAngleOffset = -90;
+
+	/**
+	 * The Drawable for the seek arc thumbnail
+	 */
+	private Drawable mThumb;
+	
+	/**
+	 * The Maximum value that this SeekArc can be set to
+	 */
+	private int mMax = 100;
+	
+	/**
+	 * The Current value that the SeekArc is set to
+	 */
+	private int mProgress = 0;
+		
+	/**
+	 * The width of the progress line for this SeekArc
+	 */
+	private int mProgressWidth = 4;
+	
+	/**
+	 * The Width of the background arc for the SeekArc 
+	 */
+	private int mArcWidth = 2;
+	
+	/**
+	 * The Angle to start drawing this Arc from
+	 */
+	private int mStartAngle = 0;
+	
+	/**
+	 * The Angle through which to draw the arc (Max is 360)
+	 */
+	private int mSweepAngle = 360;
+	
+	/**
+	 * The rotation of the SeekArc- 0 is twelve o'clock
+	 */
+	private int mRotation = 0;
+	
+	/**
+	 * Give the SeekArc rounded edges
+	 */
+	private boolean mRoundedEdges = false;
+	
+	/**
+	 * Enable touch inside the SeekArc
+	 */
+	private boolean mTouchInside = true;
+	
+	/**
+	 * Will the progress increase clockwise or anti-clockwise
+	 */
+	private boolean mClockwise = true;
+
+	// Internal variables
+	private int mArcRadius = 0;
+	private float mProgressSweep = 0;
+	private RectF mArcRect = new RectF();
+	private Paint mArcPaint;
+	private Paint mProgressPaint;
+	private int mTranslateX;
+	private int mTranslateY;
+	private int mThumbXPos;
+	private int mThumbYPos;
+	private double mTouchAngle;
+	private float mTouchIgnoreRadius;
+	private OnSeekArcChangeListener mOnSeekArcChangeListener;
+
+	public interface OnSeekArcChangeListener {
+
+		/**
+		 * Notification that the progress level has changed. Clients can use the
+		 * fromUser parameter to distinguish user-initiated changes from those
+		 * that occurred programmatically.
+		 * 
+		 * @param seekArc
+		 *            The SeekArc whose progress has changed
+		 * @param progress
+		 *            The current progress level. This will be in the range
+		 *            0..max where max was set by
+		 *            {@link ProgressArc#setMax(int)}. (The default value for
+		 *            max is 100.)
+		 * @param fromUser
+		 *            True if the progress change was initiated by the user.
+		 */
+		void onProgressChanged(SeekArc seekArc, int progress, boolean fromUser);
+
+		/**
+		 * Notification that the user has started a touch gesture. Clients may
+		 * want to use this to disable advancing the seekbar.
+		 * 
+		 * @param seekArc
+		 *            The SeekArc in which the touch gesture began
+		 */
+		void onStartTrackingTouch(SeekArc seekArc);
+
+		/**
+		 * Notification that the user has finished a touch gesture. Clients may
+		 * want to use this to re-enable advancing the seekarc.
+		 * 
+		 * @param seekArc
+		 *            The SeekArc in which the touch gesture began
+		 */
+		void onStopTrackingTouch(SeekArc seekArc);
+	}
+
+	public SeekArc(Context context) {
+		super(context);
+		init(context, null, 0);
+	}
+
+	public SeekArc(Context context, AttributeSet attrs) {
+		super(context, attrs);
+		init(context, attrs, R.attr.seekArcStyle);
+	}
+
+	public SeekArc(Context context, AttributeSet attrs, int defStyle) {
+		super(context, attrs, defStyle);
+		init(context, attrs, defStyle);
+	}
+
+	private void init(Context context, AttributeSet attrs, int defStyle) {
+
+		Log.d(TAG, "Initialising SeekArc");
+		final Resources res = getResources();
+		float density = context.getResources().getDisplayMetrics().density;
+
+		// Defaults, may need to link this into theme settings
+		int arcColor = res.getColor(R.color.progress_gray);
+		int progressColor = res.getColor(android.R.color.holo_blue_light);
+		int thumbHalfheight = 0;
+		int thumbHalfWidth = 0;
+		mThumb = res.getDrawable(R.drawable.seek_arc_control_selector);
+		// Convert progress width to pixels for current density
+		mProgressWidth = (int) (mProgressWidth * density);
+
+		
+		if (attrs != null) {
+			// Attribute initialization
+			final TypedArray a = context.obtainStyledAttributes(attrs,
+					R.styleable.SeekArc, defStyle, 0);
+
+			Drawable thumb = a.getDrawable(R.styleable.SeekArc_thumb);
+			if (thumb != null) {
+				mThumb = thumb;
+			}
+
+			
+			
+			thumbHalfheight = (int) mThumb.getIntrinsicHeight() / 2;
+			thumbHalfWidth = (int) mThumb.getIntrinsicWidth() / 2;
+			mThumb.setBounds(-thumbHalfWidth, -thumbHalfheight, thumbHalfWidth,
+					thumbHalfheight);
+
+			mMax = a.getInteger(R.styleable.SeekArc_max, mMax);
+			mProgress = a.getInteger(R.styleable.SeekArc_progress, mProgress);
+			mProgressWidth = (int) a.getDimension(
+					R.styleable.SeekArc_progressWidth, mProgressWidth);
+			mArcWidth = (int) a.getDimension(R.styleable.SeekArc_arcWidth,
+					mArcWidth);
+			mStartAngle = a.getInt(R.styleable.SeekArc_startAngle, mStartAngle);
+			mSweepAngle = a.getInt(R.styleable.SeekArc_sweepAngle, mSweepAngle);
+			mRotation = a.getInt(R.styleable.SeekArc_rotation, mRotation);
+			mRoundedEdges = a.getBoolean(R.styleable.SeekArc_roundEdges,
+					mRoundedEdges);
+			mTouchInside = a.getBoolean(R.styleable.SeekArc_touchInside,
+					mTouchInside);
+			mClockwise = a.getBoolean(R.styleable.SeekArc_clockwise,
+					mClockwise);
+			
+			arcColor = a.getColor(R.styleable.SeekArc_arcColor, arcColor);
+			progressColor = a.getColor(R.styleable.SeekArc_progressColor,
+					progressColor);
+
+			a.recycle();
+		}
+
+		mProgress = (mProgress > mMax) ? mMax : mProgress;
+		mProgress = (mProgress < 0) ? 0 : mProgress;
+
+		mSweepAngle = (mSweepAngle > 360) ? 360 : mSweepAngle;
+		mSweepAngle = (mSweepAngle < 0) ? 0 : mSweepAngle;
+
+		mStartAngle = (mStartAngle > 360) ? 0 : mStartAngle;
+		mStartAngle = (mStartAngle < 0) ? 0 : mStartAngle;
+
+		mArcPaint = new Paint();
+		mArcPaint.setColor(arcColor);
+		mArcPaint.setAntiAlias(true);
+		mArcPaint.setStyle(Paint.Style.STROKE);
+		mArcPaint.setStrokeWidth(mArcWidth);
+		//mArcPaint.setAlpha(45);
+
+		mProgressPaint = new Paint();
+		mProgressPaint.setColor(progressColor);
+		mProgressPaint.setAntiAlias(true);
+		mProgressPaint.setStyle(Paint.Style.STROKE);
+		mProgressPaint.setStrokeWidth(mProgressWidth);
+
+		if (mRoundedEdges) {
+			mArcPaint.setStrokeCap(Paint.Cap.ROUND);
+			mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
+		}
+	}
+
+	@Override
+	protected void onDraw(Canvas canvas) {		
+		if(!mClockwise) {
+			canvas.scale(-1, 1, mArcRect.centerX(), mArcRect.centerY() );
+		}
+		
+		// Draw the arcs
+		final int arcStart = mStartAngle + mAngleOffset + mRotation;
+		final int arcSweep = mSweepAngle;
+		canvas.drawArc(mArcRect, arcStart, arcSweep, false, mArcPaint);
+		canvas.drawArc(mArcRect, arcStart, mProgressSweep, false,
+				mProgressPaint);
+
+		// Draw the thumb nail
+		canvas.translate(mTranslateX -mThumbXPos, mTranslateY -mThumbYPos);
+		mThumb.draw(canvas);		
+	}
+
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+		final int height = getDefaultSize(getSuggestedMinimumHeight(),
+				heightMeasureSpec);
+		final int width = getDefaultSize(getSuggestedMinimumWidth(),
+				widthMeasureSpec);
+		final int min = Math.min(width, height);
+		float top = 0;
+		float left = 0;
+		int arcDiameter = 0;
+
+		mTranslateX = (int) (width * 0.5f);
+		mTranslateY = (int) (height * 0.5f);
+		
+		arcDiameter = min - getPaddingLeft();
+		mArcRadius = arcDiameter / 2;
+		top = height / 2 - (arcDiameter / 2);
+		left = width / 2 - (arcDiameter / 2);
+		mArcRect.set(left, top, left + arcDiameter, top + arcDiameter);
+	
+		int arcStart = (int)mProgressSweep + mStartAngle  + mRotation + 90;
+		mThumbXPos = (int) (mArcRadius * Math.cos(Math.toRadians(arcStart)));
+		mThumbYPos = (int) (mArcRadius * Math.sin(Math.toRadians(arcStart)));
+		
+		setTouchInSide(mTouchInside);
+		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+	}
+
+	@Override
+	public boolean onTouchEvent(MotionEvent event) {
+		switch (event.getAction()) {
+		case MotionEvent.ACTION_DOWN:
+			onStartTrackingTouch();
+			updateOnTouch(event);
+			break;
+		case MotionEvent.ACTION_MOVE:
+			updateOnTouch(event);
+			break;
+		case MotionEvent.ACTION_UP:
+			onStopTrackingTouch();
+			setPressed(false);
+			break;
+		case MotionEvent.ACTION_CANCEL:
+			onStopTrackingTouch();
+			setPressed(false);
+
+			break;
+		}
+
+		return true;
+	}
+
+	@Override
+	protected void drawableStateChanged() {
+		super.drawableStateChanged();
+		if (mThumb != null && mThumb.isStateful()) {
+			int[] state = getDrawableState();
+			mThumb.setState(state);
+		}
+		invalidate();
+	}
+
+	private void onStartTrackingTouch() {
+		if (mOnSeekArcChangeListener != null) {
+			mOnSeekArcChangeListener.onStartTrackingTouch(this);
+		}
+	}
+
+	private void onStopTrackingTouch() {
+		if (mOnSeekArcChangeListener != null) {
+			mOnSeekArcChangeListener.onStopTrackingTouch(this);
+		}
+	}
+
+	private void updateOnTouch(MotionEvent event) {
+		boolean ignoreTouch = ignoreTouch(event.getX(), event.getY());
+		if (ignoreTouch) {
+			return;
+		}
+		setPressed(true);
+		mTouchAngle = getTouchDegrees(event.getX(), event.getY());
+		int progress = getProgressForAngle(mTouchAngle);
+		onProgressRefresh(progress, true);
+	}
+
+	private boolean ignoreTouch(float xPos, float yPos) {
+		boolean ignore = false;
+		float x = xPos - mTranslateX;
+		float y = yPos - mTranslateY;
+
+		float touchRadius = (float) Math.sqrt(((x * x) + (y * y)));
+		if (touchRadius < mTouchIgnoreRadius) {
+			ignore = true;
+		}
+		return ignore;
+	}
+
+	private double getTouchDegrees(float xPos, float yPos) {
+		float x = xPos - mTranslateX;
+		float y = yPos - mTranslateY;
+		//invert the x-coord if we are rotating anti-clockwise
+		x= (mClockwise) ? x:-x;
+		// convert to arc Angle
+		double angle = Math.toDegrees(Math.atan2(y, x) + (Math.PI / 2)
+				- Math.toRadians(mRotation));
+		if (angle < 0) {
+			angle = 360 + angle;
+		}
+		angle -= mStartAngle;
+		return angle;
+	}
+
+	private int getProgressForAngle(double angle) {
+		int touchProgress = (int) Math.round(valuePerDegree() * angle);
+
+		touchProgress = (touchProgress < 0) ? INVALID_PROGRESS_VALUE
+				: touchProgress;
+		touchProgress = (touchProgress > mMax) ? INVALID_PROGRESS_VALUE
+				: touchProgress;
+		return touchProgress;
+	}
+
+	private float valuePerDegree() {
+		return (float) mMax / mSweepAngle;
+	}
+
+	private void onProgressRefresh(int progress, boolean fromUser) {
+		updateProgress(progress, fromUser);
+	}
+
+	private void updateThumbPosition() {
+		int thumbAngle = (int) (mStartAngle + mProgressSweep + mRotation + 90);
+		mThumbXPos = (int) (mArcRadius * Math.cos(Math.toRadians(thumbAngle)));
+		mThumbYPos = (int) (mArcRadius * Math.sin(Math.toRadians(thumbAngle)));
+	}
+	
+	private void updateProgress(int progress, boolean fromUser) {
+
+		if (progress == INVALID_PROGRESS_VALUE) {
+			return;
+		}
+
+		if (mOnSeekArcChangeListener != null) {
+			mOnSeekArcChangeListener
+					.onProgressChanged(this, progress, fromUser);
+		}
+
+		progress = (progress > mMax) ? mMax : progress;
+		progress = (mProgress < 0) ? 0 : progress;
+
+		mProgress = progress;
+		mProgressSweep = (float) progress / mMax * mSweepAngle;
+
+		updateThumbPosition();
+
+		invalidate();
+	}
+
+	/**
+	 * Sets a listener to receive notifications of changes to the SeekArc's
+	 * progress level. Also provides notifications of when the user starts and
+	 * stops a touch gesture within the SeekArc.
+	 * 
+	 * @param l
+	 *            The seek bar notification listener
+	 * 
+	 * @see SeekArc.OnSeekBarChangeListener
+	 */
+	public void setOnSeekArcChangeListener(OnSeekArcChangeListener l) {
+		mOnSeekArcChangeListener = l;
+	}
+
+	public void setProgress(int progress) {
+		updateProgress(progress, false);
+	}
+
+	public int getProgressWidth() {
+		return mProgressWidth;
+	}
+
+	public void setProgressWidth(int mProgressWidth) {
+		this.mProgressWidth = mProgressWidth;
+		mProgressPaint.setStrokeWidth(mProgressWidth);
+	}
+	
+	public int getArcWidth() {
+		return mArcWidth;
+	}
+
+	public void setArcWidth(int mArcWidth) {
+		this.mArcWidth = mArcWidth;
+		mArcPaint.setStrokeWidth(mArcWidth);
+	}
+	public int getArcRotation() {
+		return mRotation;
+	}
+
+	public void setArcRotation(int mRotation) {
+		this.mRotation = mRotation;
+		updateThumbPosition();
+	}
+
+	public int getStartAngle() {
+		return mStartAngle;
+	}
+
+	public void setStartAngle(int mStartAngle) {
+		this.mStartAngle = mStartAngle;
+		updateThumbPosition();
+	}
+
+	public int getSweepAngle() {
+		return mSweepAngle;
+	}
+
+	public void setSweepAngle(int mSweepAngle) {
+		this.mSweepAngle = mSweepAngle;
+		updateThumbPosition();
+	}
+	
+	public void setRoundedEdges(boolean isEnabled) {
+		mRoundedEdges = isEnabled;
+		if (mRoundedEdges) {
+			mArcPaint.setStrokeCap(Paint.Cap.ROUND);
+			mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
+		} else {
+			mArcPaint.setStrokeCap(Paint.Cap.SQUARE);
+			mProgressPaint.setStrokeCap(Paint.Cap.SQUARE);
+		}
+	}
+	
+	public void setTouchInSide(boolean isEnabled) {
+		int thumbHalfheight = (int) mThumb.getIntrinsicHeight() / 2;
+		int thumbHalfWidth = (int) mThumb.getIntrinsicWidth() / 2;
+		mTouchInside = isEnabled;
+		if (mTouchInside) {
+			mTouchIgnoreRadius = (float) mArcRadius / 4;
+		} else {
+			// Don't use the exact radius makes interaction too tricky
+			mTouchIgnoreRadius = mArcRadius
+					- Math.min(thumbHalfWidth, thumbHalfheight);
+		}
+	}
+	
+	public void setClockwise(boolean isClockwise) {
+		mClockwise = isClockwise;
+	}
+}
diff --git a/architecture/android/app/src/main/jni/dsp_faust.h b/architecture/android/app/src/main/jni/dsp_faust.h
new file mode 100644
index 0000000..3b05a4c
--- /dev/null
+++ b/architecture/android/app/src/main/jni/dsp_faust.h
@@ -0,0 +1,38 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File for Android
+ Copyright (C) 2014 GRAME, Romain Michon, CCRMA - Stanford University
+ Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+bool init(int, int);
+bool start(void);
+void stop(void);
+void destroy(void);
+bool isRunning(void);
+int keyOn(int, int);
+int keyOff(int);
+int pitchBend(int, float);
+const char* getJSON(void);
+int getParamsCount(void);
+float getParam(const char*);
+void setParam(const char*, float);
+int setVoiceParam(const char*, int, float);
+int setVoiceGain(int, float);
+const char* getParamAddress(int);
+void propagateAcc(int acc, float v);
+void setAccConverter(int p, int acc, int curve, float amin, float amid, float amax);
+void propagateGyr(int acc, float v);
+void setGyrConverter(int p, int gyr, int curve, float amin, float amid, float amax);
diff --git a/architecture/android/app/src/main/jni/java_interface_wrap.cpp b/architecture/android/app/src/main/jni/java_interface_wrap.cpp
new file mode 100644
index 0000000..47cd5a2
--- /dev/null
+++ b/architecture/android/app/src/main/jni/java_interface_wrap.cpp
@@ -0,0 +1,471 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.11
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGJAVA
+
+
+#ifdef __cplusplus
+/* SwigValueWrapper is described in swig.swg */
+template<typename T> class SwigValueWrapper {
+  struct SwigMovePointer {
+    T *ptr;
+    SwigMovePointer(T *p) : ptr(p) { }
+    ~SwigMovePointer() { delete ptr; }
+    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+  } pointer;
+  SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
+  SwigValueWrapper(const SwigValueWrapper<T>& rhs);
+public:
+  SwigValueWrapper() : pointer(0) { }
+  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+  operator T&() const { return *pointer.ptr; }
+  T *operator&() { return pointer.ptr; }
+};
+
+template <typename T> T SwigValueInit() {
+  return T();
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ *  This section contains generic SWIG labels for method/variable
+ *  declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+#  define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+#  define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+#  define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+#   define SWIGINLINE inline
+# else
+#   define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define SWIGUNUSED __attribute__ ((__unused__))
+#   else
+#     define SWIGUNUSED
+#   endif
+# elif defined(__ICC)
+#   define SWIGUNUSED __attribute__ ((__unused__))
+# else
+#   define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+#   pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+#   define SWIGUNUSEDPARM(p)
+# else
+#   define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#  ifndef GCC_HASCLASSVISIBILITY
+#    define GCC_HASCLASSVISIBILITY
+#  endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#   if defined(STATIC_LINKED)
+#     define SWIGEXPORT
+#   else
+#     define SWIGEXPORT __declspec(dllexport)
+#   endif
+# else
+#   if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+#     define SWIGEXPORT __attribute__ ((visibility("default")))
+#   else
+#     define SWIGEXPORT
+#   endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#   define SWIGSTDCALL __stdcall
+# else
+#   define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+
+/* Fix for jlong on some versions of gcc on Windows */
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+  typedef long long __int64;
+#endif
+
+/* Fix for jlong on 64-bit x86 Solaris */
+#if defined(__x86_64)
+# ifdef _LP64
+#   undef _LP64
+# endif
+#endif
+
+#include <jni.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Support for throwing Java exceptions */
+typedef enum {
+  SWIG_JavaOutOfMemoryError = 1, 
+  SWIG_JavaIOException, 
+  SWIG_JavaRuntimeException, 
+  SWIG_JavaIndexOutOfBoundsException,
+  SWIG_JavaArithmeticException,
+  SWIG_JavaIllegalArgumentException,
+  SWIG_JavaNullPointerException,
+  SWIG_JavaDirectorPureVirtual,
+  SWIG_JavaUnknownError
+} SWIG_JavaExceptionCodes;
+
+typedef struct {
+  SWIG_JavaExceptionCodes code;
+  const char *java_exception;
+} SWIG_JavaExceptions_t;
+
+
+static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) {
+  jclass excep;
+  static const SWIG_JavaExceptions_t java_exceptions[] = {
+    { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" },
+    { SWIG_JavaIOException, "java/io/IOException" },
+    { SWIG_JavaRuntimeException, "java/lang/RuntimeException" },
+    { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" },
+    { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" },
+    { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" },
+    { SWIG_JavaNullPointerException, "java/lang/NullPointerException" },
+    { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" },
+    { SWIG_JavaUnknownError,  "java/lang/UnknownError" },
+    { (SWIG_JavaExceptionCodes)0,  "java/lang/UnknownError" }
+  };
+  const SWIG_JavaExceptions_t *except_ptr = java_exceptions;
+
+  while (except_ptr->code != code && except_ptr->code)
+    except_ptr++;
+
+  jenv->ExceptionClear();
+  excep = jenv->FindClass(except_ptr->java_exception);
+  if (excep)
+    jenv->ThrowNew(excep, msg);
+}
+
+
+/* Contract support */
+
+#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else
+
+
+#include "dsp_faust.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_init(JNIEnv *jenv, jclass jcls, jint jarg1, jint jarg2) {
+  jint jresult = 0 ;
+  int arg1;
+  int arg2;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = (int)jarg1; 
+  arg2 = (int)jarg2; 
+  result = init(arg1,arg2);
+  jresult = (jint)result;
+  return jresult;
+}
+
+    
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_start(JNIEnv *jenv, jclass jcls) {
+  jint jresult = 0 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  result = (int)start();
+  jresult = (jint)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_stop(JNIEnv *jenv, jclass jcls) {
+  (void)jenv;
+  (void)jcls;
+  stop();
+}
+
+    
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_destroy(JNIEnv *jenv, jclass jcls) {
+    (void)jenv;
+    (void)jcls;
+    destroy();
+}
+
+SWIGEXPORT jboolean JNICALL Java_com_dsp_1faust_dsp_1faustJNI_isRunning(JNIEnv *jenv, jclass jcls) {
+  jboolean jresult = 0 ;
+  bool result;
+  
+  (void)jenv;
+  (void)jcls;
+  result = (bool)isRunning();
+  jresult = (jboolean)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_keyOn(JNIEnv *jenv, jclass jcls, jint jarg1, jint jarg2) {
+  jint jresult = 0 ;
+  int arg1 ;
+  int arg2 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = (int)jarg1; 
+  arg2 = (int)jarg2; 
+  result = (int)keyOn(arg1,arg2);
+  jresult = (jint)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_keyOff(JNIEnv *jenv, jclass jcls, jint jarg1) {
+  jint jresult = 0 ;
+  int arg1 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = (int)jarg1; 
+  result = (int)keyOff(arg1);
+  jresult = (jint)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_pitchBend(JNIEnv *jenv, jclass jcls, jint jarg1, jfloat jarg2) {
+  jint jresult = 0 ;
+  int arg1 ;
+  float arg2 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = (int)jarg1; 
+  arg2 = (float)jarg2; 
+  result = (int)pitchBend(arg1,arg2);
+  jresult = (jint)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT jstring JNICALL Java_com_dsp_1faust_dsp_1faustJNI_getJSON(JNIEnv *jenv, jclass jcls) {
+  jstring jresult = 0 ;
+  char *result = 0 ;
+  
+  (void)jenv;
+  (void)jcls;
+  result = (char *)getJSON();
+  if (result) jresult = jenv->NewStringUTF((const char *)result);
+  return jresult;
+}
+
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_getParamsCount(JNIEnv *jenv, jclass jcls) {
+  jint jresult = 0 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  result = (int)getParamsCount();
+  jresult = (jint)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT jfloat JNICALL Java_com_dsp_1faust_dsp_1faustJNI_getParam(JNIEnv *jenv, jclass jcls, jstring jarg1) {
+  jfloat jresult = 0 ;
+  char *arg1 = (char *) 0 ;
+  float result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = 0;
+  if (jarg1) {
+    arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
+    if (!arg1) return 0;
+  }
+  result = (float)getParam((char const *)arg1);
+  jresult = (jfloat)result; 
+  if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
+  return jresult;
+}
+
+
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_setParam(JNIEnv *jenv, jclass jcls, jstring jarg1, jfloat jarg2) {
+  char *arg1 = (char *) 0 ;
+  float arg2 ;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = 0;
+  if (jarg1) {
+    arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
+    if (!arg1) return ;
+  }
+  arg2 = (float)jarg2; 
+  setParam((char const *)arg1,arg2);
+  if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
+}
+
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_setVoiceParam(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2, jfloat jarg3) {
+  jint jresult = 0 ;
+  char *arg1 = (char *) 0 ;
+  int arg2 ;
+  float arg3 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = 0;
+  if (jarg1) {
+    arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
+    if (!arg1) return 0;
+  }
+  arg2 = (int)jarg2; 
+  arg3 = (float)jarg3; 
+  result = (int)setVoiceParam((char const *)arg1,arg2,arg3);
+  jresult = (jint)result; 
+  if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
+  return jresult;
+}
+
+
+SWIGEXPORT jint JNICALL Java_com_dsp_1faust_dsp_1faustJNI_setVoiceGain(JNIEnv *jenv, jclass jcls, jint jarg1, jfloat jarg2) {
+  jint jresult = 0 ;
+  int arg1 ;
+  float arg2 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = (int)jarg1; 
+  arg2 = (float)jarg2; 
+  result = (int)setVoiceGain(arg1,arg2);
+  jresult = (jint)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT jstring JNICALL Java_com_dsp_1faust_dsp_1faustJNI_getParamAddress(JNIEnv *jenv, jclass jcls, jint jarg1) {
+  jstring jresult = 0 ;
+  int arg1 ;
+  char *result = 0 ;
+  
+  (void)jenv;
+  (void)jcls;
+  arg1 = (int)jarg1; 
+  result = (char *)getParamAddress(arg1);
+  if (result) jresult = jenv->NewStringUTF((const char *)result);
+  return jresult;
+}
+
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_propagateAcc(JNIEnv *jenv, jclass jcls,  jint jarg1, jfloat jarg2) {
+    int arg1 ;
+    float arg2 ;
+    
+    (void)jenv;
+    (void)jcls;
+    arg1 = (int)jarg1;
+    arg2 = (float)jarg2;
+    propagateAcc(arg1, arg2);
+}
+    
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_setAccConverter(JNIEnv *jenv, jclass jcls, jint p, jint acc, jint curve, jfloat amin, jfloat amid, jfloat amax) {
+    
+    (void)jenv;
+    (void)jcls;
+    setAccConverter((int)p, (int)acc, (int)curve, (float)amin, (float)amid, (float)amax);
+}
+
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_propagateGyr(JNIEnv *jenv, jclass jcls,  jint jarg1, jfloat jarg2) {
+    int arg1 ;
+    float arg2 ;
+    
+    (void)jenv;
+    (void)jcls;
+    arg1 = (int)jarg1;
+    arg2 = (float)jarg2;
+    propagateGyr(arg1, arg2);
+}
+    
+SWIGEXPORT void JNICALL Java_com_dsp_1faust_dsp_1faustJNI_setGyrConverter(JNIEnv *jenv, jclass jcls, jint p, jint gyr, jint curve, jfloat amin, jfloat amid, jfloat amax) {
+    
+    (void)jenv;
+    (void)jcls;
+    setGyrConverter((int)p, (int)gyr, (int)curve, (float)amin, (float)amid, (float)amax);
+}
+    
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelcurveoff.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelcurveoff.png
new file mode 100644
index 0000000..c945e1f
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelcurveoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelcurveon.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelcurveon.png
new file mode 100644
index 0000000..c490f17
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelcurveon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertcurveoff.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertcurveoff.png
new file mode 100644
index 0000000..0df41a0
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertcurveoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertcurveon.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertcurveon.png
new file mode 100644
index 0000000..3286a81
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertcurveon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertoff.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertoff.png
new file mode 100644
index 0000000..12ffaad
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinvertoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinverton.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinverton.png
new file mode 100644
index 0000000..a3c0180
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelinverton.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelnormoff.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelnormoff.png
new file mode 100644
index 0000000..1a62097
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelnormoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_accelnormon.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelnormon.png
new file mode 100644
index 0000000..bd2a139
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_accelnormon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_keyboardicon.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_keyboardicon.png
new file mode 100644
index 0000000..1d0212e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_keyboardicon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_launcher.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..817a81a
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_lockiconclose.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_lockiconclose.png
new file mode 100644
index 0000000..da84211
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_lockiconclose.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_lockiconopen.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_lockiconopen.png
new file mode 100644
index 0000000..4cc819e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_lockiconopen.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_reset.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_reset.png
new file mode 100644
index 0000000..561ba4e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_reset.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_zoomin.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_zoomin.png
new file mode 100644
index 0000000..c7c9260
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_zoomin.png differ
diff --git a/architecture/android/app/src/main/res/drawable-hdpi/ic_zoomout.png b/architecture/android/app/src/main/res/drawable-hdpi/ic_zoomout.png
new file mode 100644
index 0000000..1ab079b
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-hdpi/ic_zoomout.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelcurveoff.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelcurveoff.png
new file mode 100644
index 0000000..2bc0ba6
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelcurveoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelcurveon.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelcurveon.png
new file mode 100644
index 0000000..c853c07
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelcurveon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertcurveoff.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertcurveoff.png
new file mode 100644
index 0000000..c7f5baa
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertcurveoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertcurveon.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertcurveon.png
new file mode 100644
index 0000000..cd84f8f
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertcurveon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertoff.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertoff.png
new file mode 100644
index 0000000..714889e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinvertoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinverton.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinverton.png
new file mode 100644
index 0000000..4df6d33
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelinverton.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelnormoff.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelnormoff.png
new file mode 100644
index 0000000..17c6b30
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelnormoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_accelnormon.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelnormon.png
new file mode 100644
index 0000000..8c1bbc4
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_accelnormon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_keyboardicon.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_keyboardicon.png
new file mode 100644
index 0000000..546b03c
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_keyboardicon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_launcher.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..dbe4107
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_lockiconclose.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_lockiconclose.png
new file mode 100644
index 0000000..11d790b
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_lockiconclose.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_lockiconopen.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_lockiconopen.png
new file mode 100644
index 0000000..cdc7a9d
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_lockiconopen.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_reset.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_reset.png
new file mode 100644
index 0000000..057a1ff
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_reset.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_zoomin.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_zoomin.png
new file mode 100644
index 0000000..f54b6a8
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_zoomin.png differ
diff --git a/architecture/android/app/src/main/res/drawable-mdpi/ic_zoomout.png b/architecture/android/app/src/main/res/drawable-mdpi/ic_zoomout.png
new file mode 100644
index 0000000..c49420f
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-mdpi/ic_zoomout.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/check_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/check_down.png
new file mode 100644
index 0000000..26a2f5c
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/check_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/check_up.png b/architecture/android/app/src/main/res/drawable-xhdpi/check_up.png
new file mode 100644
index 0000000..9ff1be5
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/check_up.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelcurveoff.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelcurveoff.png
new file mode 100644
index 0000000..65f7527
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelcurveoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelcurveon.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelcurveon.png
new file mode 100644
index 0000000..8d4498c
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelcurveon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertcurveoff.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertcurveoff.png
new file mode 100644
index 0000000..00dcdb8
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertcurveoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertcurveon.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertcurveon.png
new file mode 100644
index 0000000..f0c91be
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertcurveon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertoff.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertoff.png
new file mode 100644
index 0000000..58d4bf7
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinvertoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinverton.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinverton.png
new file mode 100644
index 0000000..6cceb6a
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelinverton.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelnormoff.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelnormoff.png
new file mode 100644
index 0000000..4dc0e47
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelnormoff.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelnormon.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelnormon.png
new file mode 100644
index 0000000..3a3b5b7
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_accelnormon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_keyboardicon.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_keyboardicon.png
new file mode 100644
index 0000000..5bf07bd
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_keyboardicon.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_launcher.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bc1e9e2
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_lockiconclose.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_lockiconclose.png
new file mode 100644
index 0000000..75f9751
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_lockiconclose.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_lockiconopen.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_lockiconopen.png
new file mode 100644
index 0000000..1c31e76
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_lockiconopen.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_reset.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_reset.png
new file mode 100644
index 0000000..8b7762a
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_reset.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_zoomin.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_zoomin.png
new file mode 100644
index 0000000..0b5dd7e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_zoomin.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/ic_zoomout.png b/architecture/android/app/src/main/res/drawable-xhdpi/ic_zoomout.png
new file mode 100644
index 0000000..5c5756e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/ic_zoomout.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black.png
new file mode 100644
index 0000000..196a3b5
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_.png
new file mode 100644
index 0000000..b14ee20
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_down.png
new file mode 100644
index 0000000..dc0d200
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_down_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_down_.png
new file mode 100644
index 0000000..3f372a4
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_black_down_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center.png
new file mode 100644
index 0000000..7ef5bdd
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_.png
new file mode 100644
index 0000000..b9a1451
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_down.png
new file mode 100644
index 0000000..2356999
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_down_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_down_.png
new file mode 100644
index 0000000..e02e63c
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_center_down_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left.png
new file mode 100644
index 0000000..6093ff2
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left_.png
new file mode 100644
index 0000000..1ab7952
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left_down.png
new file mode 100644
index 0000000..06f8b2e
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_left_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right.png
new file mode 100644
index 0000000..402db6b
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_.png
new file mode 100644
index 0000000..4dc3498
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_down.png
new file mode 100644
index 0000000..1fa4873
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_down_.png b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_down_.png
new file mode 100644
index 0000000..7763f7b
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/oldKeys/piano_key_right_down_.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_black.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_black.png
new file mode 100644
index 0000000..1a16698
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_black.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_black_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_black_down.png
new file mode 100644
index 0000000..752f7fe
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_black_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_center.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_center.png
new file mode 100644
index 0000000..f4b73bc
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_center.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_center_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_center_down.png
new file mode 100644
index 0000000..a5490bd
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_center_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_left.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_left.png
new file mode 100644
index 0000000..7cad052
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_left.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_left_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_left_down.png
new file mode 100644
index 0000000..c687504
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_left_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_right.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_right.png
new file mode 100644
index 0000000..bb5b659
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_right.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_right_down.png b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_right_down.png
new file mode 100644
index 0000000..759806f
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/piano_key_right_down.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_disabled_holo.png b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..62be77c
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_disabled_holo.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_focused_holo.png b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_focused_holo.png
new file mode 100644
index 0000000..754dd2f
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_focused_holo.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_normal_holo.png b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_normal_holo.png
new file mode 100644
index 0000000..d546a73
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_normal_holo.png differ
diff --git a/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_pressed_holo.png b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..0b62072
Binary files /dev/null and b/architecture/android/app/src/main/res/drawable-xhdpi/scrubber_control_pressed_holo.png differ
diff --git a/architecture/android/app/src/main/res/drawable/checkbox.xml b/architecture/android/app/src/main/res/drawable/checkbox.xml
new file mode 100644
index 0000000..cf0d802
--- /dev/null
+++ b/architecture/android/app/src/main/res/drawable/checkbox.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true"
+        android:drawable="@drawable/check_down" />
+    <item android:state_checked="false"
+        android:drawable="@drawable/check_up" />
+</selector>
\ No newline at end of file
diff --git a/architecture/android/app/src/main/res/drawable/seek_arc_control_selector.xml b/architecture/android/app/src/main/res/drawable/seek_arc_control_selector.xml
new file mode 100644
index 0000000..3414842
--- /dev/null
+++ b/architecture/android/app/src/main/res/drawable/seek_arc_control_selector.xml
@@ -0,0 +1,31 @@
+<!--
+  The MIT License (MIT)
+  
+  Copyright (c) 2013 Triggertrap Ltd
+  Author Neil Davies
+  
+  Permission is hereby granted, free of charge, to any person obtaining a copy of
+  this software and associated documentation files (the "Software"), to deal in
+  the Software without restriction, including without limitation the rights to
+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+  the Software, and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+  
+  The above copyright notice and this permission notice shall be included in all
+  copies or substantial portions of the Software.
+  
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:drawable="@drawable/scrubber_control_disabled_holo" android:state_enabled="false"/>
+    <item android:drawable="@drawable/scrubber_control_pressed_holo" android:state_pressed="true"/>
+    <item android:drawable="@drawable/scrubber_control_focused_holo" android:state_selected="true"/>
+    <item android:drawable="@drawable/scrubber_control_normal_holo"/>
+
+</selector>
diff --git a/architecture/android/app/src/main/res/layout/combined.xml b/architecture/android/app/src/main/res/layout/combined.xml
new file mode 100644
index 0000000..f0d283b
--- /dev/null
+++ b/architecture/android/app/src/main/res/layout/combined.xml
@@ -0,0 +1,25 @@
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:custom="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:weightSum="2"
+	android:keepScreenOn="true">
+    
+    <com.faust.MultiParams
+        android:id="@+id/MultiParams"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="top"
+        android:layout_weight="1"/>
+
+    <com.faust.PianoKeyboard
+        android:id="@+id/PianoKeyboard"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom"
+        custom:keys="21"
+        android:layout_weight="1"/>
+    
+</LinearLayout>
diff --git a/architecture/android/app/src/main/res/layout/main.xml b/architecture/android/app/src/main/res/layout/main.xml
new file mode 100644
index 0000000..250d82a
--- /dev/null
+++ b/architecture/android/app/src/main/res/layout/main.xml
@@ -0,0 +1,36 @@
+<!--
+ FAUST Architecture File for Android
+ Copyright (C) 2013 GRAME, Romain Michon, CCRMA Stanford University
+ Copyright (C) 2003-2013 GRAME, Centre National de Creation Musicale
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+-->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="#000000">
+   	<HorizontalScrollView
+   	    android:id="@+id/horizontalScroll"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <LinearLayout
+            android:orientation="vertical"
+        	android:layout_width="wrap_content"
+        	android:layout_height="wrap_content"
+        	android:id="@+id/the_layout"
+        	android:gravity="left"
+			android:keepScreenOn="true">
+    	</LinearLayout>
+    </HorizontalScrollView>
+</ScrollView>
diff --git a/architecture/android/app/src/main/res/layout/multi.xml b/architecture/android/app/src/main/res/layout/multi.xml
new file mode 100644
index 0000000..6eae15b
--- /dev/null
+++ b/architecture/android/app/src/main/res/layout/multi.xml
@@ -0,0 +1,15 @@
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:custom="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+	android:keepScreenOn="true">
+    
+    <com.faust.MultiParams
+        android:id="@+id/MultiParams"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="top"/>
+    
+</LinearLayout>
diff --git a/architecture/android/app/src/main/res/layout/piano.xml b/architecture/android/app/src/main/res/layout/piano.xml
new file mode 100644
index 0000000..590994b
--- /dev/null
+++ b/architecture/android/app/src/main/res/layout/piano.xml
@@ -0,0 +1,16 @@
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:custom="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+	android:keepScreenOn="true">
+
+    <com.faust.PianoKeyboard
+        android:id="@+id/PianoKeyboard"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom"
+        custom:keys="21"/>
+    
+</LinearLayout>
diff --git a/architecture/android/app/src/main/res/menu/main_activity_actions.xml b/architecture/android/app/src/main/res/menu/main_activity_actions.xml
new file mode 100644
index 0000000..892779c
--- /dev/null
+++ b/architecture/android/app/src/main/res/menu/main_activity_actions.xml
@@ -0,0 +1,28 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+    <!-- Search, should appear as action button -->
+    <item android:id="@+id/action_keyboard"
+          android:icon="@drawable/ic_keyboardicon"
+          android:title="@string/keyboard"
+          android:showAsAction="ifRoom" />
+    <item android:id="@+id/action_zoomin"
+          android:icon="@drawable/ic_zoomin"
+          android:title="@string/zoomin"
+          android:showAsAction="ifRoom" />
+    <item android:id="@+id/action_zoomout"
+          android:icon="@drawable/ic_zoomout"
+          android:title="@string/zoomout"
+          android:showAsAction="ifRoom" />
+    <item android:id="@+id/action_lock"
+        android:icon="@drawable/ic_lockiconclose"
+        android:title="@string/lock"
+        android:showAsAction="ifRoom" />
+    <item android:id="@+id/action_reset"
+        android:icon="@drawable/ic_reset"
+        android:title="@string/reset"
+        android:showAsAction="ifRoom" />
+          <!--
+    <item android:id="@+id/action_settings"
+          android:title="@string/action_settings"
+          android:showAsAction="never" />
+          -->
+</menu>
\ No newline at end of file
diff --git a/architecture/android/app/src/main/res/values-v11/styles.xml b/architecture/android/app/src/main/res/values-v11/styles.xml
new file mode 100644
index 0000000..3c02242
--- /dev/null
+++ b/architecture/android/app/src/main/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/architecture/android/app/src/main/res/values-v14/styles.xml b/architecture/android/app/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..a91fd03
--- /dev/null
+++ b/architecture/android/app/src/main/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/architecture/android/app/src/main/res/values/attrs.xml b/architecture/android/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..4e358a7
--- /dev/null
+++ b/architecture/android/app/src/main/res/values/attrs.xml
@@ -0,0 +1,28 @@
+<resources>
+    <declare-styleable name="PianoKeyboard">
+        <attr name="keys" format="integer"/>
+        <attr name="basenote" format="integer"/>
+    </declare-styleable>
+    
+    <declare-styleable name="SeekArc">
+        <attr name="thumb" format="reference" />
+        <attr name="thumbOffset" format="dimension" />
+        <attr name="max" format="integer" />
+        <attr name="progressWidth" format="dimension" />
+        <attr name="arcWidth" format="dimension" />
+        <attr name="progress" format="integer" />
+        <attr name="rotation" format="integer" />
+        <attr name="startAngle" format="integer" />
+        <attr name="sweepAngle" format="integer" />
+        <attr name="arcColor" format="color" />
+        <attr name="progressColor" format="color" />
+        <attr name="roundEdges" format="boolean" />
+        <attr name="touchInside" format="boolean" />
+        <attr name="clockwise" format="boolean" />
+    </declare-styleable>
+    
+    <declare-styleable name="SeekArcTheme">
+        <attr name="seekArcStyle" format="reference"></attr>        
+    </declare-styleable>
+
+</resources>
diff --git a/architecture/android/app/src/main/res/values/colors.xml b/architecture/android/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..9e86417
--- /dev/null
+++ b/architecture/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  The MIT License (MIT)
+  
+  Copyright (c) 2013 Triggertrap Ltd
+  Author Neil Davies
+  
+  Permission is hereby granted, free of charge, to any person obtaining a copy of
+  this software and associated documentation files (the "Software"), to deal in
+  the Software without restriction, including without limitation the rights to
+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+  the Software, and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+  
+  The above copyright notice and this permission notice shall be included in all
+  copies or substantial portions of the Software.
+  
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+-->
+<resources>
+    <color name="progress_gray">#FFD8D8D8</color>
+    <color name="progress_gray_dark">#FF383838</color>
+</resources>
diff --git a/architecture/android/app/src/main/res/values/strings.xml b/architecture/android/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..39fbdf8
--- /dev/null
+++ b/architecture/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,13 @@
+<resources>
+
+    <string name="app_name">1</string>
+    <string name="zoomin">Zoom In</string>
+    <string name="zoomout">Zoom Out</string>
+    <string name="reset">Reset</string>
+    <string name="keyboard">Keyboard Interface</string>
+    <string name="lock">Lock</string>
+    <string name="keyboard_activity">Keyboard Activity</string>
+    <string name="multi_activity">Multi Activity</string>
+    <string name="multi_keyboard_activity">Multi Keyboard Activity</string>
+
+</resources>
diff --git a/architecture/android/app/src/main/res/values/styles.xml b/architecture/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..47a360d
--- /dev/null
+++ b/architecture/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,28 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+    
+    <style name="SeekArc">
+        <item name="arcColor">@color/progress_gray_dark</item>
+    </style>
+    
+    <style name="SeekArcLight">
+        <item name="arcColor">@color/progress_gray</item>
+    </style>
+
+</resources>
diff --git a/architecture/android/app/tools/faust2android.keystore b/architecture/android/app/tools/faust2android.keystore
new file mode 100644
index 0000000..89da54f
Binary files /dev/null and b/architecture/android/app/tools/faust2android.keystore differ
diff --git a/architecture/android/build.gradle b/architecture/android/build.gradle
new file mode 100644
index 0000000..e26cdee
--- /dev/null
+++ b/architecture/android/build.gradle
@@ -0,0 +1,15 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.0.0'
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
diff --git a/architecture/android/dsp_faust_interface.i b/architecture/android/dsp_faust_interface.i
new file mode 100644
index 0000000..901ca0c
--- /dev/null
+++ b/architecture/android/dsp_faust_interface.i
@@ -0,0 +1,37 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File for Android
+ Copyright (C) 2013 GRAME, Romain Michon, CCRMA - Stanford University
+ Copyright (C) 2003-2013 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+%module dsp_faust
+%{
+#include "dsp_faust.h"
+%}
+
+// Enable the JNI class to load the required native library.
+%pragma(java) jniclasscode=%{
+  static {
+    try {
+        java.lang.System.loadLibrary("dsp_faust");
+    } catch (UnsatisfiedLinkError e) {
+        java.lang.System.err.println("native code library failed to load.\n" + e);
+        java.lang.System.exit(1);
+    }
+  }
+%}
+
+%include "dsp_faust.h"
\ No newline at end of file
diff --git a/architecture/android/gradle/wrapper/gradle-wrapper.jar b/architecture/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/architecture/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/architecture/android/gradle/wrapper/gradle-wrapper.properties b/architecture/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/architecture/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/architecture/android/gradlew b/architecture/android/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/architecture/android/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/architecture/android/local.properties b/architecture/android/local.properties
new file mode 100644
index 0000000..b28bdd2
--- /dev/null
+++ b/architecture/android/local.properties
@@ -0,0 +1,8 @@
+## This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+#
+#Fri Jan 02 13:30:44 CET 2015
+sdk.dir=/opt/android/sdk
+ndk.dir=/opt/android/ndk
diff --git a/architecture/android/settings.gradle b/architecture/android/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/architecture/android/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/architecture/au-effect.cpp b/architecture/au-effect.cpp
new file mode 100644
index 0000000..22afce6
--- /dev/null
+++ b/architecture/au-effect.cpp
@@ -0,0 +1,480 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2013 Reza Payami
+ All rights reserved.
+ ----------------------------BSD License------------------------------
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Remy Muller nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ ----------------------------Audio Unit SDK----------------------------------
+ In order to compile a AU (TM) plugin with this architecture file
+ you will need the proprietary AU SDK from Apple. Please check
+ the corresponding license.
+ 
+ ************************************************************************
+ ************************************************************************/
+
+
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+#include <string>
+#include <vector>
+
+
+#include "AUEffectBase.h"
+#include <AudioToolbox/AudioUnitUtilities.h>
+#include "FaustAUVersion.h"
+
+#include "faust/misc.h"
+
+#ifndef FaustAU_FaustAUEffect_h
+#include "FaustAU.h" //TODO
+#endif
+
+using namespace std;
+
+/******************************************************************************
+ *******************************************************************************
+ *
+ *	VECTOR INTRINSICS
+ *
+ *******************************************************************************
+ *******************************************************************************/
+
+<<includeIntrinsic>>
+
+/********************END ARCHITECTURE SECTION (part 1/2)****************/
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+static const int kPreset_One = 0;
+static const int kNumberPresets = 1;
+static AUPreset kPresets[kNumberPresets] =
+{ { kPreset_One, CFSTR("Default") }, };
+
+
+#define MAX_OUT_CHANNELS 1000
+
+class FaustAUEffect: public AUEffectBase {
+    
+public:
+    
+	FaustAUEffect(AudioUnit component);
+    
+	~FaustAUEffect();
+    
+	virtual OSStatus Version() {
+		return kFaustAUVersion;
+	}
+    
+	virtual OSStatus Initialize();
+    
+	virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID,
+                                     AudioUnitScope inScope, AudioUnitElement inElement,
+                                     UInt32 & outDataSize, Boolean & outWritable);
+    
+	virtual OSStatus GetProperty(AudioUnitPropertyID inID,
+                                 AudioUnitScope inScope, AudioUnitElement inElement, void * outData);
+    
+	virtual OSStatus GetParameterInfo(AudioUnitScope inScope,
+                                      AudioUnitParameterID inParameterID,
+                                      AudioUnitParameterInfo &outParameterInfo);
+    
+	void SetParameter(AudioUnitParameterID paramID,
+                      AudioUnitParameterValue value);
+    
+	virtual OSStatus SetParameter(AudioUnitParameterID inID,
+                                  AudioUnitScope inScope, AudioUnitElement inElement,
+                                  AudioUnitParameterValue inValue, UInt32);
+    
+	virtual OSStatus GetPresets(CFArrayRef *outData) const;
+    
+	virtual OSStatus NewFactoryPresetSet(const AUPreset & inNewFactoryPreset);
+    
+	virtual bool SupportsTail() {
+		return true;
+	}
+    
+	virtual Float64 GetTailTime() {
+		return 3.0;
+	}
+    
+	//For example, a lookahead compressor or FFT-based processor should report the true latency in seconds
+	virtual Float64 GetLatency() {
+		return 0.0;
+	}
+    
+	virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags &ioActionFlags,
+                                        const AudioBufferList &inBuffer, AudioBufferList &outBuffer,
+                                        UInt32 inFramesToProcess);
+    
+private:
+	auUI* dspUI;
+    
+protected:
+	float* outBuffer[MAX_OUT_CHANNELS];
+    
+public:
+	mydsp* dsp;
+};
+
+/**********************************************************************************/
+
+
+AUDIOCOMPONENT_ENTRY(AUBaseFactory, FaustAU)
+
+FaustAUEffect::FaustAUEffect(AudioUnit component)
+: AUEffectBase(component)
+{
+    CreateElements();
+    
+    dspUI = new auUI();
+    
+	dsp = new mydsp();
+    
+	int inChannels = dsp->getNumInputs();
+	int outChannels = dsp->getNumOutputs();
+    
+	SetParamHasSampleRateDependency(true);
+    
+	UInt32 frames = GetMaxFramesPerSlice();
+    
+	for (int i = 0; i < outChannels; i++)
+        outBuffer[i] = new float[frames];
+    
+	dsp->buildUserInterface(dspUI);
+    
+	if (dspUI)
+        for (int i = 0; i < dspUI->fUITable.size(); i++)
+            if (dspUI->fUITable[i] && dspUI->fUITable[i]->fZone)
+            {
+                if (dynamic_cast<auButton*>(dspUI->fUITable[i])) {
+                    SetParameter(i, 0);
+                }
+                else if (dynamic_cast<auToggleButton*>(dspUI->fUITable[i])) {
+                    SetParameter(i, 0);
+                }
+                else if (dynamic_cast<auCheckButton*>(dspUI->fUITable[i])) {
+                    SetParameter(i, 0);
+                }
+                else {
+                    auSlider* slider = (auSlider*)dspUI->fUITable[i];
+                    SetParameter(i, slider->fInit );
+                }
+            }
+}
+
+FaustAUEffect::~FaustAUEffect() {
+    
+	int outChannels = dsp->getNumOutputs();
+    
+	for (int i = 0; i < outChannels; i++)
+		if (outBuffer[i])
+			delete[] outBuffer[i];
+    
+}
+
+OSStatus FaustAUEffect::Initialize() {
+	OSStatus result = AUEffectBase::Initialize();
+    
+	dsp->init(long(GetSampleRate()));
+    
+	return result;
+}
+
+OSStatus FaustAUEffect::GetParameterInfo(AudioUnitScope inScope,
+										 AudioUnitParameterID inParameterID,
+										 AudioUnitParameterInfo &outParameterInfo) {
+	OSStatus result = noErr;
+    
+	char name[100];
+	CFStringRef str;
+    
+	outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable + kAudioUnitParameterFlag_IsReadable;
+    
+	if (inScope == kAudioUnitScope_Global) {
+        
+		if (dspUI && dspUI->fUITable[inParameterID]
+            && dspUI->fUITable[inParameterID]->fZone) {
+            
+			if (dynamic_cast<auButton*>(dspUI->fUITable[inParameterID])) {
+				auToggleButton* toggle = (auToggleButton*) dspUI->fUITable[inParameterID];
+				toggle->GetName(name);
+				str = CFStringCreateWithCString(kCFAllocatorDefault, name, 0);
+                
+				AUBase::FillInParameterName(outParameterInfo, str, false);
+				outParameterInfo.unit = kAudioUnitParameterUnit_Boolean;
+				outParameterInfo.minValue = 0;
+				outParameterInfo.maxValue = 1;
+				outParameterInfo.defaultValue = 0;
+			} else if (dynamic_cast<auToggleButton*>(dspUI->fUITable[inParameterID])) {
+				auToggleButton* toggle = (auToggleButton*) dspUI->fUITable[inParameterID];
+				toggle->GetName(name);
+                
+				str = CFStringCreateWithCString(kCFAllocatorDefault, name, 0);
+                
+				AUBase::FillInParameterName(outParameterInfo, str, false);
+				outParameterInfo.unit = kAudioUnitParameterUnit_Boolean;
+				outParameterInfo.minValue = 0;
+				outParameterInfo.maxValue = 1;
+				outParameterInfo.defaultValue = 0;
+                
+			} else if (dynamic_cast<auCheckButton*>(dspUI->fUITable[inParameterID])) {
+				auCheckButton* check = (auCheckButton*) dspUI->fUITable[inParameterID];
+				check->GetName(name);
+                
+				str = CFStringCreateWithCString(kCFAllocatorDefault, name, 0);
+                
+				AUBase::FillInParameterName(outParameterInfo, str, false);
+				outParameterInfo.unit = kAudioUnitParameterUnit_Boolean;
+				outParameterInfo.minValue = 0;
+				outParameterInfo.maxValue = 1;
+				outParameterInfo.defaultValue = 0;
+                
+			} else {
+                
+				auSlider* slider = (auSlider*) dspUI->fUITable[inParameterID];
+				slider->GetName(name);
+				str = CFStringCreateWithCString(kCFAllocatorDefault, name, 0);
+                
+				AUBase::FillInParameterName(outParameterInfo, str, false);
+				outParameterInfo.unit = kAudioUnitParameterUnit_Generic;
+				outParameterInfo.minValue = slider->fMin;
+				outParameterInfo.maxValue = slider->fMax;
+				outParameterInfo.defaultValue = slider->fInit;
+			}
+            
+		}
+	} else {
+		result = kAudioUnitErr_InvalidParameter;
+	}
+    
+	return result;
+}
+
+void FaustAUEffect::SetParameter(AudioUnitParameterID paramID,
+								 AudioUnitParameterValue value) {
+	AUEffectBase::SetParameter(paramID, value);
+}
+
+OSStatus FaustAUEffect::SetParameter(AudioUnitParameterID inID, AudioUnitScope inScope,
+									 AudioUnitElement inElement, AudioUnitParameterValue inValue,
+									 UInt32 inBufferOffsetInFrames) {
+	if (inScope == kAudioUnitScope_Global) {
+        
+		if (dspUI) {
+			if (dspUI->fUITable[inID] && dspUI->fUITable[inID]->fZone)
+				*(dspUI->fUITable[inID]->fZone) = (FAUSTFLOAT) inValue;
+            
+			if (dynamic_cast<auButton*>(dspUI->fUITable[inID]))
+				return AUEffectBase::SetParameter(inID, inScope, inElement, 0,
+                                                  inBufferOffsetInFrames);
+            
+		}
+	}
+    
+	return AUEffectBase::SetParameter(inID, inScope, inElement, inValue,
+                                      inBufferOffsetInFrames);
+}
+
+
+OSStatus FaustAUEffect::NewFactoryPresetSet(const AUPreset & inNewFactoryPreset) {
+	SInt32 chosenPreset = inNewFactoryPreset.presetNumber;
+    
+	for (int i = 0; i < kNumberPresets; ++i) {
+		if (chosenPreset == kPresets[i].presetNumber) {
+			switch (chosenPreset) {
+                case kPreset_One:
+                    break;
+			}
+            
+			SetAFactoryPresetAsCurrent(kPresets[i]);
+			return noErr;
+		}
+	}
+    
+	return kAudioUnitErr_InvalidPropertyValue;
+}
+
+OSStatus FaustAUEffect::GetPresets(CFArrayRef * outData) const {
+    
+	if (outData == NULL)
+		return noErr;
+    
+	CFMutableArrayRef theArray = CFArrayCreateMutable(NULL, kNumberPresets,
+                                                      NULL);
+	for (int i = 0; i < kNumberPresets; ++i) {
+		CFArrayAppendValue(theArray, &kPresets[i]);
+	}
+    
+	*outData = (CFArrayRef) theArray;
+	return noErr;
+}
+
+OSStatus FaustAUEffect::GetPropertyInfo (AudioUnitPropertyID				inID,
+                                         AudioUnitScope					inScope,
+                                         AudioUnitElement				inElement,
+                                         UInt32 &						outDataSize,
+                                         Boolean &						outWritable)
+
+{
+    if (inScope == kAudioUnitScope_Global)
+	{
+		switch (inID)
+		{
+			case kAudioUnitProperty_CocoaUI:
+				outWritable = false;
+				outDataSize = sizeof (AudioUnitCocoaViewInfo);
+				return noErr;
+                
+            case kAudioUnitCustomProperty_dspUI:
+            {
+				if(inScope != kAudioUnitScope_Global ) return kAudioUnitErr_InvalidScope;
+                
+ 				outWritable = false;
+				outDataSize = sizeof (int*);
+				return noErr;
+            }
+		}
+	}
+	
+	return AUEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+}
+
+OSStatus FaustAUEffect::GetProperty (AudioUnitPropertyID 		inID,
+                                     AudioUnitScope 				inScope,
+                                     AudioUnitElement			inElement,
+                                     void *						outData)
+{
+    switch (inID)
+    {
+            
+            
+            // This property allows the host application to find the UI associated with this AudioUnit
+        case kAudioUnitProperty_CocoaUI:
+        {
+            // Look for a resource in the main bundle by name and type.
+            CFBundleRef bundle = CFBundleGetBundleWithIdentifier( CFSTR("com.grame.audiounit.FaustAU") );
+            
+            if (bundle == NULL) return fnfErr;
+            
+            CFURLRef bundleURL = CFBundleCopyResourceURL( bundle,
+                                                         CFSTR("FaustAUCustomView"),	// this is the name of the cocoa bundle as specified in the CocoaViewFactory.plist
+                                                         CFSTR("bundle"),			// this is the extension of the cocoa bundle
+                                                         NULL);
+            
+            if (bundleURL == NULL) return fnfErr;
+            
+            CFStringRef className = CFSTR("FaustAU_CustomViewFactory");	// name of the main class that implements the AUCocoaUIBase protocol
+            AudioUnitCocoaViewInfo cocoaInfo = { bundleURL, { className }};
+            *((AudioUnitCocoaViewInfo *)outData) = cocoaInfo;
+            
+            return noErr;
+        }
+            
+            // This is our custom property which reports the dspUI
+        case kAudioUnitCustomProperty_dspUI:
+        {
+            if(inScope != kAudioUnitScope_Global)
+                return kAudioUnitErr_InvalidScope;
+            
+            // the kernels are only created if we are initialized
+            // since we're using the kernels to get the curve info, let
+            // the caller know we can't do it if we're un-initialized
+            // the UI should check for the error and not draw the curve in this case
+            if(!IsInitialized() ) return kAudioUnitErr_Uninitialized;
+            
+            *((auUI**)outData)= dspUI;
+            
+            return noErr;
+        }
+    }
+    
+    
+    // if we've gotten this far, handles the standard properties
+    return AUEffectBase::GetProperty (inID, inScope, inElement, outData);
+}
+
+
+OSStatus FaustAUEffect::ProcessBufferLists(AudioUnitRenderActionFlags& iFlags,
+										   const AudioBufferList& inBufferList, AudioBufferList& outBufferList,
+										   UInt32 iFrames) {
+    
+	int inChannels = dsp->getNumInputs();
+	int outChannels = dsp->getNumOutputs();
+    
+	float* audioData[inChannels];
+    
+	for (int i = 0; i < inChannels; i++) {
+		audioData[i] = (float*) inBufferList.mBuffers[i].mData;
+	}
+    
+	dsp->compute(iFrames, audioData, outBuffer);
+    
+	for (int i = 0; i < outChannels; i++) {
+		outBufferList.mBuffers[i].mData = outBuffer[i];
+	}
+	
+    
+    //TODO
+    /*
+     AudioUnitEvent myEvent;
+     myEvent.mArgument.mParameter.mAudioUnit = mComponentInstance;
+     myEvent.mArgument.mParameter.mScope = kAudioUnitScope_Global;
+     myEvent.mArgument.mParameter.mElement = 0;
+     myEvent.mEventType = kAudioUnitEvent_ParameterValueChange;
+     
+     if (dspUI)
+     {
+     for (int i = 0; i < dspUI->fUITable.size(); i++)
+     {
+     myEvent.mArgument.mParameter.mParameterID = i; //TODO
+     AUEventListenerNotify(NULL, NULL, &myEvent);
+     }
+     }
+     */
+    return noErr;
+}
diff --git a/architecture/au-instrument.cpp b/architecture/au-instrument.cpp
new file mode 100644
index 0000000..d74ac44
--- /dev/null
+++ b/architecture/au-instrument.cpp
@@ -0,0 +1,548 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2013 Reza Payami
+ All rights reserved.
+ ----------------------------BSD License------------------------------
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Remy Muller nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ ----------------------------Audio Unit SDK----------------------------------
+ In order to compile a AU (TM) Synth plugin with this architecture file
+ you will need the proprietary AU SDK from Apple. Please check
+ the corresponding license.
+ 
+ ************************************************************************
+ ************************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+#include <string>
+#include <vector>
+
+/*
+ #include "faust/misc.h"
+ #include "faust/audio/dsp.h"
+ 
+ #include "faust/au/AUUI.h"
+ */
+
+#include "AUInstrumentBase.h"
+#include "FaustAUVersion.h"
+
+#include "faust/misc.h"
+
+#include "FaustAU.h"
+
+using namespace std;
+
+static const UInt32 kNumNotes = 32;
+static const UInt32 kMaxActiveNotes = 32;
+
+/******************************************************************************
+ *******************************************************************************
+ *
+ *	VECTOR INTRINSICS
+ *
+ *******************************************************************************
+ *******************************************************************************/
+
+<<includeIntrinsic>>
+
+
+/********************END ARCHITECTURE SECTION (part 1/2)****************/
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+class FaustAUInstrument;
+
+struct FaustAUInstrumentNote: public SynthNote {
+  FaustAUInstrumentNote();
+  virtual ~FaustAUInstrumentNote();
+  virtual OSStatus Initialize();
+  virtual bool Attack(const MusicDeviceNoteParams &inParams);
+  virtual void Kill(UInt32 inFrame); // voice is being stolen.
+  virtual void Release(UInt32 inFrame);
+  virtual void FastRelease(UInt32 inFrame);
+  virtual Float32 Amplitude() {
+    return amp;
+  } // used for finding quietest note for voice stealing.
+  virtual OSStatus Render(UInt64 inAbsoluteSampleFrame, UInt32 inNumFrames,
+			  AudioBufferList** inBufferList, UInt32 inOutBusCount);
+  FaustAUInstrument* synth;
+  double amp, maxAmp, upSlope, dnSlope;
+public:
+  auUI* dspUI = NULL;
+  mydsp* dsp = NULL;
+};
+
+class FaustAUInstrument: public AUMonotimbralInstrumentBase {
+    public:
+	FaustAUInstrument(ComponentInstance inComponentInstance);
+	virtual ~FaustAUInstrument();
+    
+	virtual OSStatus Initialize();
+	virtual void Cleanup();
+	virtual OSStatus Version() {
+		return kFaustAUVersion;
+	}
+    
+	virtual AUElement* CreateElement(AudioUnitScope scope,
+                                     AudioUnitElement element);
+    
+    virtual OSStatus GetPropertyInfo (AudioUnitPropertyID			inID,
+                                      AudioUnitScope				inScope,
+                                      AudioUnitElement			inElement,
+                                      UInt32 &					outDataSize,
+                                      Boolean &					outWritable);
+    
+    virtual OSStatus GetProperty(	AudioUnitPropertyID 		inID,
+                                 AudioUnitScope 				inScope,
+                                 AudioUnitElement		 	inElement,
+                                 void *						outData);
+    
+	virtual OSStatus GetParameterInfo(AudioUnitScope inScope,
+                                      AudioUnitParameterID inParameterID,
+                                      AudioUnitParameterInfo & outParameterInfo);
+    
+	void SetParameter(AudioUnitParameterID paramID,
+                      AudioUnitParameterValue value);
+    
+	virtual OSStatus SetParameter(AudioUnitParameterID inID,
+                                  AudioUnitScope inScope, AudioUnitElement inElement,
+                                  AudioUnitParameterValue inValue, UInt32);
+    
+	MidiControls* GetControls(MusicDeviceGroupID inChannel) {
+		SynthGroupElement *group = GetElForGroupID(inChannel);
+		return (MidiControls *) group->GetMIDIControlHandler();
+	}
+    
+    private:
+    
+        FaustAUInstrumentNote mNotes[kNumNotes];
+    
+    private:
+	auUI* dspUI = NULL;
+    
+    public:
+	mydsp* dsp = NULL;
+    
+	int frequencyParameterID = -1;
+    float freqMin = 0.0;
+    float freqMax = 1.0;
+    int gateParameterID = -1;
+    int gainParameterID = -1;
+    
+};
+
+bool FaustAUInstrumentNote::Attack(const MusicDeviceNoteParams &inParams) {
+  double sampleRate = SampleRate();
+  amp = inParams.mVelocity / 127.;
+  if (synth->gateParameterID != -1) {
+    if (dspUI) {
+      auUIObject* gate = (auUIObject*) dspUI->fUITable[synth->gateParameterID];
+      if (gate)
+	gate->SetValue(1.0); // Tell Faust code to enter "attack" phase
+    }
+  }
+  return true;
+}
+
+/**********************************************************************************/
+
+AUDIOCOMPONENT_ENTRY(AUMusicDeviceFactory, FaustAU)
+
+//TODO set the output channels
+FaustAUInstrument::FaustAUInstrument(ComponentInstance inComponentInstance)
+: AUMonotimbralInstrumentBase(inComponentInstance, 0, 1)
+{
+	CreateElements();
+    
+	dspUI = new auUI();
+    
+	dsp = new mydsp();
+    
+	//int inChannels = dsp->getNumInputs();
+	//int outChannels = dsp->getNumOutputs();
+    
+	//SetParamHasSampleRateDependency(true);
+    
+	dsp->buildUserInterface(dspUI);
+    
+	Globals()->UseIndexedParameters(dspUI->fUITable.size());
+    
+	if (dspUI)
+    for (int i = 0; i < dspUI->fUITable.size(); i++)
+    if (dspUI->fUITable[i] && dspUI->fUITable[i]->fZone)
+    {
+        if (dynamic_cast<auButton*>(dspUI->fUITable[i])) {
+            Globals()->SetParameter(i, 0);
+        }
+        else if (dynamic_cast<auToggleButton*>(dspUI->fUITable[i])) {
+            Globals()->SetParameter(i, 0);
+        }
+        else if (dynamic_cast<auCheckButton*>(dspUI->fUITable[i])) {
+            Globals()->SetParameter(i, 0);
+        }
+        else {
+            auSlider* slider = (auSlider*)dspUI->fUITable[i];
+            Globals()->SetParameter(i, slider->fInit );
+        }
+    }
+}
+
+FaustAUInstrument::~FaustAUInstrument() {
+	if (dsp)
+    delete dsp;
+    
+	if (dspUI)
+    delete dspUI;
+}
+
+void FaustAUInstrument::Cleanup() {
+    
+}
+
+OSStatus FaustAUInstrument::Initialize() {
+	OSStatus result = AUMonotimbralInstrumentBase::Initialize();
+    
+	for (int i = 0; i < kNumNotes; i++) {
+		mNotes[i].Initialize();
+		mNotes[i].synth = this;
+	}
+    
+	SetNotes(kNumNotes, kMaxActiveNotes, mNotes, sizeof(FaustAUInstrumentNote));
+    
+	return result;
+}
+
+AUElement* FaustAUInstrument::CreateElement(AudioUnitScope scope,
+                                            AudioUnitElement element) {
+	switch (scope) {
+        case kAudioUnitScope_Group:
+        return new SynthGroupElement(this, element, new MidiControls);
+        case kAudioUnitScope_Part:
+        return new SynthPartElement(this, element);
+        default:
+        return AUBase::CreateElement(scope, element);
+	}
+}
+
+OSStatus FaustAUInstrument::GetPropertyInfo (AudioUnitPropertyID inID,
+                                             AudioUnitScope				inScope,
+                                             AudioUnitElement			inElement,
+                                             UInt32 &					outDataSize,
+                                             Boolean &					outWritable)
+{
+    if (inScope == kAudioUnitScope_Global)
+	{
+		switch (inID)
+		{
+			case kAudioUnitProperty_CocoaUI:
+            outWritable = false;
+            outDataSize = sizeof (AudioUnitCocoaViewInfo);
+            return noErr;
+            
+            case kAudioUnitCustomProperty_dspUI:
+            {
+				if(inScope != kAudioUnitScope_Global ) return kAudioUnitErr_InvalidScope;
+                
+ 				outWritable = false;
+				outDataSize = sizeof (int*);
+				return noErr;
+            }
+		}
+	}
+	
+	return AUInstrumentBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+}
+
+OSStatus FaustAUInstrument::GetProperty (AudioUnitPropertyID 		inID,
+                                         AudioUnitScope 				inScope,
+                                         AudioUnitElement			inElement,
+                                         void *						outData)
+{
+    switch (inID)
+    {
+        
+        
+        // This property allows the host application to find the UI associated with this AudioUnit
+        case kAudioUnitProperty_CocoaUI:
+        {
+            // Look for a resource in the main bundle by name and type.
+            CFBundleRef bundle = CFBundleGetBundleWithIdentifier( CFSTR("com.grame.audiounit.FaustAU") );
+            
+            if (bundle == NULL) return fnfErr;
+            
+            CFURLRef bundleURL = CFBundleCopyResourceURL( bundle,
+                                                         CFSTR("FaustAUCustomView"),	// this is the name of the cocoa bundle as specified in the CocoaViewFactory.plist
+                                                         CFSTR("bundle"),			// this is the extension of the cocoa bundle
+                                                         NULL);
+            
+            if (bundleURL == NULL) return fnfErr;
+            
+            CFStringRef className = CFSTR("FaustAU_CustomViewFactory");	// name of the main class that implements the AUCocoaUIBase protocol
+            AudioUnitCocoaViewInfo cocoaInfo = { bundleURL, { className }};
+            *((AudioUnitCocoaViewInfo *)outData) = cocoaInfo;
+            
+            return noErr;
+        }
+        
+        // This is our custom property which reports the dspUI
+        case kAudioUnitCustomProperty_dspUI:
+        {
+            if(inScope != kAudioUnitScope_Global)
+            return kAudioUnitErr_InvalidScope;
+            
+            // the kernels are only created if we are initialized
+            // since we're using the kernels to get the curve info, let
+            // the caller know we can't do it if we're un-initialized
+            // the UI should check for the error and not draw the curve in this case
+            if(!IsInitialized() ) return kAudioUnitErr_Uninitialized;
+            
+            *((auUI**)outData)= mNotes[0].dspUI; //TODO
+            
+            return noErr;
+        }
+    }
+    
+    
+    // if we've gotten this far, handles the standard properties
+    return AUInstrumentBase::GetProperty (inID, inScope, inElement, outData);
+}
+
+
+OSStatus FaustAUInstrument::GetParameterInfo(AudioUnitScope inScope,
+                                             AudioUnitParameterID inParameterID,
+                                             AudioUnitParameterInfo & outParameterInfo) {
+    
+  OSStatus result = noErr;
+    
+  char name[100];
+  CFStringRef str;
+    
+  outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable
+    + kAudioUnitParameterFlag_IsReadable;
+    
+  if (inScope == kAudioUnitScope_Global) {
+        
+    if (dspUI && dspUI->fUITable[inParameterID]
+	&& dspUI->fUITable[inParameterID]->fZone) {
+            
+      if (dynamic_cast<auButton*>(dspUI->fUITable[inParameterID]) || 
+	  dynamic_cast<auToggleButton*>(dspUI->fUITable[inParameterID]) || 
+	  dynamic_cast<auCheckButton*>(dspUI->fUITable[inParameterID])) {
+	dspUI->fUITable[inParameterID]->GetName(name);
+	if (strcmp(name, "gate")==0) {
+	  // Faust synth modules use "gate" as the name for the parameter
+	  // to be set to 1 by MIDI-in NoteOn and set to 0 by NoteOff.
+	  // We leave it in the AU GUI for manual testing w/o MIDI.
+	  gateParameterID = inParameterID;
+	}
+	str = CFStringCreateWithCString(kCFAllocatorDefault, name, 0);
+	AUBase::FillInParameterName(outParameterInfo, str, false);
+	outParameterInfo.unit = kAudioUnitParameterUnit_Boolean;
+	outParameterInfo.minValue = 0;
+	outParameterInfo.maxValue = 1;
+	outParameterInfo.defaultValue = 0;
+      } else {
+	auSlider* slider = (auSlider*) dspUI->fUITable[inParameterID];
+	slider->GetName(name);
+	if (strcmp(name, "gain")==0) {
+	  // Faust synth modules use "gain" as the name for the parameter
+	  // to be set by MIDI-in NoteOn key velocity:
+	  // We leave it in the AU GUI for manual testing w/o MIDI.
+	  gainParameterID = inParameterID;
+	  // gainMin = slider->fMin;
+	  // gainMax = slider->fMax;
+	} else if (strcmp(name, "freq")==0) {
+	  frequencyParameterID = inParameterID;
+	  freqMin = slider->fMin;
+	  freqMax = slider->fMax;
+	}
+	str = CFStringCreateWithCString(kCFAllocatorDefault, name, 0);
+	AUBase::FillInParameterName(outParameterInfo, str, false);
+	outParameterInfo.unit = kAudioUnitParameterUnit_Generic;
+	outParameterInfo.minValue = slider->fMin;
+	outParameterInfo.maxValue = slider->fMax;
+	outParameterInfo.defaultValue = slider->fInit;
+      }
+
+    }
+  } else {
+    result = kAudioUnitErr_InvalidParameter;
+  }
+  return result;
+}
+
+OSStatus FaustAUInstrument::SetParameter(AudioUnitParameterID inID,
+                                         AudioUnitScope inScope, AudioUnitElement inElement,
+                                         AudioUnitParameterValue inValue, UInt32 inBufferOffsetInFrames) {
+	if (inScope == kAudioUnitScope_Global) {
+        
+		if (dspUI) {
+			if (dspUI->fUITable[inID] && dspUI->fUITable[inID]->fZone)
+            
+            *(dspUI->fUITable[inID]->fZone) = (FAUSTFLOAT) inValue;
+            
+			for (int i = 0; i < kNumNotes; i++) {
+				if (mNotes[i].dspUI)
+                *(mNotes[i].dspUI->fUITable[inID]->fZone) =
+                (FAUSTFLOAT) inValue;
+			}
+		}
+	}
+    
+	return AUMonotimbralInstrumentBase::SetParameter(inID, inScope, inElement,
+                                                     inValue, inBufferOffsetInFrames);
+}
+
+/**********************************************************************************/
+
+FaustAUInstrumentNote::FaustAUInstrumentNote() {
+    
+}
+
+OSStatus FaustAUInstrumentNote::Initialize() {
+	dspUI = new auUI();
+	dsp = new mydsp();
+    
+	dsp->buildUserInterface(dspUI);
+    
+	//TODO find a way to call GetSampleRate(), there will be a NullPointerException if it is called
+	if (dsp)
+    dsp->init(44100);
+    
+	return noErr;
+}
+
+FaustAUInstrumentNote::~FaustAUInstrumentNote() {
+	if (dsp)
+    delete dsp;
+    
+	if (dspUI)
+    delete dspUI;
+}
+
+void FaustAUInstrumentNote::Release(UInt32 inFrame) {
+  auUIObject* gate = NULL;
+  if (synth->gateParameterID != -1) {
+    if (dspUI) {
+      gate = (auUIObject*) dspUI->fUITable[synth->gateParameterID];
+      if (gate)
+	gate->SetValue(0.0); // Tell Faust code to enter "release" phase
+    }
+  }
+  SynthNote::Release(inFrame);
+}
+
+void FaustAUInstrumentNote::FastRelease(UInt32 inFrame) // voice is being stolen.
+{
+	SynthNote::Release(inFrame);
+}
+
+void FaustAUInstrumentNote::Kill(UInt32 inFrame) // voice is being stolen.
+{
+	SynthNote::Kill(inFrame);
+}
+
+OSStatus FaustAUInstrumentNote::Render(UInt64 inAbsoluteSampleFrame,
+                                       UInt32 inNumFrames, AudioBufferList** inBufferList,
+                                       UInt32 inOutBusCount) {
+	int MAX_OUT_CHANNELS = 1000;
+    
+	float* outBuffer[MAX_OUT_CHANNELS];
+	float* audioData[MAX_OUT_CHANNELS];
+    
+	int inChannels = dsp->getNumInputs();
+	int outChannels = dsp->getNumOutputs();
+    
+    // bus number is assumed to be zero
+    for (int i = 0; i < outChannels; i++) {
+		outBuffer[i] = new float[inNumFrames];
+        
+		audioData[i] = (float*) inBufferList[0]->mBuffers[i].mData;
+	}
+    
+	if (synth) {
+		auSlider* frequencySlider = NULL;
+		if (synth->frequencyParameterID != -1) {
+			if (dspUI)
+            frequencySlider =
+            (auSlider*) dspUI->fUITable[synth->frequencyParameterID];
+			if (frequencySlider)
+            //TODO change the SetValue function call accordingly
+            frequencySlider->SetValue( (Frequency() - synth->freqMin) / (synth->freqMax - synth->freqMin) );
+			//frequencySlider->SetValue((float) GetMidiKey() / 88.0);
+		}
+        
+		dsp->compute(inNumFrames, audioData, outBuffer);
+	}
+	switch (GetState()) {
+        case kNoteState_Attacked:
+        case kNoteState_Sostenutoed:
+        case kNoteState_ReleasedButSostenutoed:
+        case kNoteState_ReleasedButSustained: {
+            for (int i = 0; i < outChannels; i++) {
+                for (UInt32 frame = 0; frame < inNumFrames; ++frame) {
+                    audioData[i][frame] += outBuffer[i][frame] * amp;
+                }
+            }
+            break;
+            
+        }
+        
+        case kNoteState_Released:
+        case kNoteState_FastReleased: {
+            
+            NoteEnded(0xFFFFFFFF);
+            
+            break;
+        }
+        default:
+        break;
+	}
+	return noErr;
+    
+}
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
diff --git a/architecture/audio/alsa-dsp.h b/architecture/audio/alsa-dsp.h
deleted file mode 100644
index e3a4f28..0000000
--- a/architecture/audio/alsa-dsp.h
+++ /dev/null
@@ -1,693 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections :
-	the ARCHITECTURE section (in two parts) and the USER section. Each section
-	is governed by its own copyright and license. Please check individually
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work
-	that contains this FAUST architecture section and distribute
-	that work under terms of your choice, so long as this FAUST
-	architecture section is not modified.
-
-
- ************************************************************************
- ************************************************************************/
-
-#ifndef __alsa_dsp__
-#define __alsa_dsp__
-
-#include <stdio.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <pwd.h>
-
-#include <alsa/asoundlib.h>
-#include "audio.h"
-#include "dsp.h"
-
-/**
-DEFAULT ALSA PARAMETERS CONTROLLED BY ENVIRONMENT VARIABLES
-
-Some default parameters of Faust's ALSA applications are controlled by the following environment variables :
-
-    FAUST2ALSA_DEVICE   = "hw:0"
-    FAUST2ALSA_FREQUENCY= 44100
-    FAUST2ALSA_BUFFER   = 1024
-    FAUST2ALSA_PERIODS  = 2
-
-*/
-
-using namespace std;
-
-// handle 32/64 bits int size issues
-
-#ifdef __x86_64__
-
-#define uint32	unsigned int
-#define uint64	unsigned long int
-
-#define int32	int
-#define int64	long int
-
-#else
-
-#define uint32	unsigned int
-#define uint64	unsigned long long int
-
-#define int32	int
-#define int64	long long int
-#endif
-
-// check 32/64 bits issues are correctly handled
-
-#define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); }
-#define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); }
-#define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); }
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-/**
- * Used to set the priority and scheduling of the audi#include <sys/types.h>
-       #include <pwd.h>
-o thread
- */
-static bool setRealtimePriority ()
-{
-    struct passwd *         pw;
-    int                     err;
-    uid_t                   uid;
-    struct sched_param      param;
-
-    uid = getuid ();
-    pw = getpwnam ("root");
-    setuid (pw->pw_uid);
-    param.sched_priority = 50; /* 0 to 99  */
-    err = sched_setscheduler(0, SCHED_RR, &param);
-    setuid (uid);
-    return (err != -1);
-}
-
-/******************************************************************************
-*******************************************************************************
-
-								AUDIO INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-enum { kRead = 1, kWrite = 2, kReadWrite = 3 };
-
-/**
- * A convenient class to pass parameters to AudioInterface
- */
-class AudioParam
-{
-  public:
-
-	const char*		fCardName;
-	unsigned int	fFrequency;
-	unsigned int	fBuffering;
-	unsigned int	fPeriods;
-
-	unsigned int	fSoftInputs;
-	unsigned int	fSoftOutputs;
-
-  public :
-	AudioParam() :
-		fCardName("hw:0"),
-		fFrequency(44100),
-		fBuffering(512),
-		fPeriods(2),
-		fSoftInputs(2),
-		fSoftOutputs(2)
-	{}
-
-	AudioParam&	cardName(const char* n)	{ fCardName = n; 		return *this; }
-	AudioParam&	frequency(int f)		{ fFrequency = f; 		return *this; }
-	AudioParam&	buffering(int fpb)		{ fBuffering = fpb; 	return *this; }
-	AudioParam&	periods(int p)			{ fPeriods = p; 		return *this; }
-	AudioParam&	inputs(int n)			{ fSoftInputs = n; 		return *this; }
-	AudioParam&	outputs(int n)			{ fSoftOutputs = n; 	return *this; }
-};
-
-/**
- * An ALSA audio interface
- */
-class AudioInterface : public AudioParam
-{
- public :
-	snd_pcm_t*				fOutputDevice ;
-	snd_pcm_t*				fInputDevice ;
-	snd_pcm_hw_params_t* 	fInputParams;
-	snd_pcm_hw_params_t* 	fOutputParams;
-
-	snd_pcm_format_t 		fSampleFormat;
-	snd_pcm_access_t 		fSampleAccess;
-
-	unsigned int			fCardInputs;
-	unsigned int			fCardOutputs;
-
-	unsigned int			fChanInputs;
-	unsigned int			fChanOutputs;
-
-	// interleaved mode audiocard buffers
-	void*		fInputCardBuffer;
-	void*		fOutputCardBuffer;
-
-	// non interleaved mode audiocard buffers
-	void*		fInputCardChannels[256];
-	void*		fOutputCardChannels[256];
-
-	// non interleaved mod, floating point software buffers
-	float*		fInputSoftChannels[256];
-	float*		fOutputSoftChannels[256];
-
- public :
-
-	const char*	cardName()				{ return fCardName;  	}
- 	int			frequency()				{ return fFrequency; 	}
-	int			buffering()				{ return fBuffering;  	}
-	int			periods()				{ return fPeriods;  	}
-
-	float**		inputSoftChannels()		{ return fInputSoftChannels;	}
-	float**		outputSoftChannels()	{ return fOutputSoftChannels;	}
-
-
-	AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap)
-	{
-
-		fInputDevice 			= 0;
-		fOutputDevice 			= 0;
-		fInputParams			= 0;
-		fOutputParams			= 0;
-	}
-
-	/**
-	 * Open the audio interface
-	 */
-	void open()
-	{
-		int err;
-
-		// allocation d'un stream d'entree et d'un stream de sortie
-		err = snd_pcm_open( &fInputDevice,  fCardName, SND_PCM_STREAM_CAPTURE, 0 ); 	check_error(err)
-		err = snd_pcm_open( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ); 	check_error(err)
-
-		// recherche des parametres d'entree
-		err = snd_pcm_hw_params_malloc	( &fInputParams ); 	check_error(err);
-		setAudioParams(fInputDevice, fInputParams);
-
-		// recherche des parametres de sortie
-		err = snd_pcm_hw_params_malloc	( &fOutputParams ); 		check_error(err)
-		setAudioParams(fOutputDevice, fOutputParams);
-
-		// set the number of physical input and output channels close to what we need
-		fCardInputs 	= fSoftInputs;
-		fCardOutputs 	= fSoftOutputs;
-
-		snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
-		snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
-
-		printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs);
-
-		// enregistrement des parametres d'entree-sortie
-
-		err = snd_pcm_hw_params (fInputDevice,  fInputParams );	 	check_error (err);
-		err = snd_pcm_hw_params (fOutputDevice, fOutputParams );	check_error (err);
-
-		//assert(snd_pcm_hw_params_get_period_size(fInputParams,NULL) == snd_pcm_hw_params_get_period_size(fOutputParams,NULL));
-
-		// allocation of alsa buffers
-		if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
-			fInputCardBuffer = calloc(interleavedBufferSize(fInputParams), 1);
-	 		fOutputCardBuffer = calloc(interleavedBufferSize(fOutputParams), 1);
-
-		} else {
-			for (unsigned int i = 0; i < fCardInputs; i++) {
-				fInputCardChannels[i] = calloc(noninterleavedBufferSize(fInputParams), 1);
-			}
-			for (unsigned int i = 0; i < fCardOutputs; i++) {
-				fOutputCardChannels[i] = calloc(noninterleavedBufferSize(fOutputParams), 1);
-			}
-
-		}
-
-		// allocation of floating point buffers needed by the dsp code
-
-		fChanInputs = max(fSoftInputs, fCardInputs);		assert (fChanInputs < 256);
-		fChanOutputs = max(fSoftOutputs, fCardOutputs);		assert (fChanOutputs < 256);
-
-		for (unsigned int i = 0; i < fChanInputs; i++) {
-			fInputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float));
-			for (unsigned int j = 0; j < fBuffering; j++) {
-				fInputSoftChannels[i][j] = 0.0;
-			}
-		}
-
-		for (unsigned int i = 0; i < fChanOutputs; i++) {
-			fOutputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float));
-			for (unsigned int j = 0; j < fBuffering; j++) {
-				fOutputSoftChannels[i][j] = 0.0;
-			}
-		}
-	}
-
-	void setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params)
-	{
-		int	err;
-
-		// set params record with initial values
-		err = snd_pcm_hw_params_any	( stream, params );
-		check_error_msg(err, "unable to init parameters")
-
-		// set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
-
-		err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
-		if (err) {
-			err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED );
-			check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved");
-		}
-		snd_pcm_hw_params_get_access(params, &fSampleAccess);
-
-
-		// search for 32-bits or 16-bits format
-		err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32);
-		if (err) {
-			err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16);
-		 	check_error_msg(err, "unable to set format to either 32-bits or 16-bits");
-		}
-		snd_pcm_hw_params_get_format(params, &fSampleFormat);
-		// set sample frequency
-		snd_pcm_hw_params_set_rate_near (stream, params, &fFrequency, 0);
-
-		// set period and period size (buffering)
-		err = snd_pcm_hw_params_set_period_size	(stream, params, fBuffering, 0);
-		check_error_msg(err, "period size not available");
-
-		err = snd_pcm_hw_params_set_periods (stream, params, fPeriods, 0);
-		check_error_msg(err, "number of periods not available");
-	}
-
-	ssize_t interleavedBufferSize (snd_pcm_hw_params_t* params)
-	{
-		_snd_pcm_format 	format;  	snd_pcm_hw_params_get_format(params, &format);
-		snd_pcm_uframes_t 	psize;		snd_pcm_hw_params_get_period_size(params, &psize, NULL);
-		unsigned int 		channels; 	snd_pcm_hw_params_get_channels(params, &channels);
-		ssize_t bsize = snd_pcm_format_size (format, psize * channels);
-		return bsize;
-	}
-
-	ssize_t noninterleavedBufferSize (snd_pcm_hw_params_t* params)
-	{
-		_snd_pcm_format 	format;  	snd_pcm_hw_params_get_format(params, &format);
-		snd_pcm_uframes_t 	psize;		snd_pcm_hw_params_get_period_size(params, &psize, NULL);
-		ssize_t bsize = snd_pcm_format_size (format, psize);
-		return bsize;
-	}
-
-	void close()
-	{}
-
-	/**
-	 * Read audio samples from the audio card. Convert samples to floats and take
-	 * care of interleaved buffers
-	 */
-	void read()
-	{
-        if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
-
-			int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering);
-			if (count<0) {
-				display_error_msg(count, "reading samples");
-				 int err = snd_pcm_prepare(fInputDevice);
-				 check_error_msg(err, "preparing input stream");
-			}
-
-			if (fSampleFormat == SND_PCM_FORMAT_S16) {
-
-				short* 	buffer16b = (short*) fInputCardBuffer;
-				for (unsigned int s = 0; s < fBuffering; s++) {
-					for (unsigned int c = 0; c < fCardInputs; c++) {
-						fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX));
-					}
-				}
-
-			} else if (fSampleFormat == SND_PCM_FORMAT_S32) {
-
-				int32* 	buffer32b = (int32*) fInputCardBuffer;
-				for (unsigned int s = 0; s < fBuffering; s++) {
-					for (unsigned int c = 0; c < fCardInputs; c++) {
-						fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(INT_MAX));
-					}
-				}
-			} else {
-
-				printf("unrecognized input sample format : %u\n", fSampleFormat);
-				exit(1);
-			}
-
-		} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
-
-			int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering);
-			if (count<0) {
-				display_error_msg(count, "reading samples");
-				 int err = snd_pcm_prepare(fInputDevice);
-				 check_error_msg(err, "preparing input stream");
-			}
-
-			if (fSampleFormat == SND_PCM_FORMAT_S16) {
-
-				for (unsigned int c = 0; c < fCardInputs; c++) {
-					short* 	chan16b = (short*) fInputCardChannels[c];
-					for (unsigned int s = 0; s < fBuffering; s++) {
-						fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX));
-					}
-				}
-
-			} else if (fSampleFormat == SND_PCM_FORMAT_S32) {
-
-				for (unsigned int c = 0; c < fCardInputs; c++) {
-					int32* 	chan32b = (int32*) fInputCardChannels[c];
-					for (unsigned int s = 0; s < fBuffering; s++) {
-						fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(INT_MAX));
-					}
-				}
-			} else {
-
-				printf("unrecognized input sample format : %u\n", fSampleFormat);
-				exit(1);
-			}
-
-		} else {
-			check_error_msg(-10000, "unknow access mode");
-		}
-    }
-
-	/**
-	 * write the output soft channels to the audio card. Convert sample
-	 * format and interleaves buffers when needed
-	 */
-	void write()
-	{
-		recovery :
-
-		if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
-
-			if (fSampleFormat == SND_PCM_FORMAT_S16) {
-
-				short* buffer16b = (short*) fOutputCardBuffer;
-				for (unsigned int f = 0; f < fBuffering; f++) {
-					for (unsigned int c = 0; c < fCardOutputs; c++) {
-						float x = fOutputSoftChannels[c][f];
-						buffer16b[c + f*fCardOutputs] = short( max(min(x,1.0),-1.0) * float(SHRT_MAX) ) ;
-					}
-				}
-
-			} else if (fSampleFormat == SND_PCM_FORMAT_S32)  {
-
-				int32* buffer32b = (int32*) fOutputCardBuffer;
-				for (unsigned int f = 0; f < fBuffering; f++) {
-					for (unsigned int c = 0; c < fCardOutputs; c++) {
-						float x = fOutputSoftChannels[c][f];
-						buffer32b[c + f*fCardOutputs] = int( max(min(x,1.0),-1.0) * float(INT_MAX) ) ;
-					}
-				}
-			} else {
-
-				printf("unrecognized output sample format : %u\n", fSampleFormat);
-				exit(1);
-			}
-
-			int count = snd_pcm_writei(fOutputDevice, fOutputCardBuffer, fBuffering);
-			if (count<0) {
-				display_error_msg(count, "w3");
-				int err = snd_pcm_prepare(fOutputDevice);
-				check_error_msg(err, "preparing output stream");
-				goto recovery;
-			}
-
-
-		} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
-
-			if (fSampleFormat == SND_PCM_FORMAT_S16) {
-
-				for (unsigned int c = 0; c < fCardOutputs; c++) {
-					short* chan16b = (short*) fOutputCardChannels[c];
-					for (unsigned int f = 0; f < fBuffering; f++) {
-						float x = fOutputSoftChannels[c][f];
-						chan16b[f] = short( max(min(x,1.0),-1.0) * float(SHRT_MAX) ) ;
-					}
-				}
-
-			} else if (fSampleFormat == SND_PCM_FORMAT_S32) {
-
-				for (unsigned int c = 0; c < fCardOutputs; c++) {
-					int32* chan32b = (int32*) fOutputCardChannels[c];
-					for (unsigned int f = 0; f < fBuffering; f++) {
-						float x = fOutputSoftChannels[c][f];
-						chan32b[f] = int( max(min(x,1.0),-1.0) * float(INT_MAX) ) ;
-					}
-				}
-
-			} else {
-
-				printf("unrecognized output sample format : %u\n", fSampleFormat);
-				exit(1);
-			}
-
-			int count = snd_pcm_writen(fOutputDevice, fOutputCardChannels, fBuffering);
-			if (count<0) {
-				display_error_msg(count, "w3");
-				int err = snd_pcm_prepare(fOutputDevice);
-				check_error_msg(err, "preparing output stream");
-				goto recovery;
-			}
-
-		} else {
-			check_error_msg(-10000, "unknow access mode");
-		}
-	}
-
-	/**
-	 *  print short information on the audio device
-	 */
-	void shortinfo()
-	{
-		int						err;
-		snd_ctl_card_info_t*	card_info;
-    	snd_ctl_t*				ctl_handle;
-		err = snd_ctl_open (&ctl_handle, fCardName, 0);		check_error(err);
-		snd_ctl_card_info_alloca (&card_info);
-		err = snd_ctl_card_info(ctl_handle, card_info);		check_error(err);
-		printf("%s|%d|%d|%d|%d|%s\n",
-				snd_ctl_card_info_get_driver(card_info),
-				fCardInputs, fCardOutputs,
-				fFrequency, fBuffering,
-				snd_pcm_format_name((_snd_pcm_format)fSampleFormat));
-	}
-
-	/**
-	 *  print more detailled information on the audio device
-	 */
-	void longinfo()
-	{
-		int						err;
-		snd_ctl_card_info_t*	card_info;
-    	snd_ctl_t*				ctl_handle;
-
-		printf("Audio Interface Description :\n");
-		printf("Sampling Frequency : %d, Sample Format : %s, buffering : %d\n",
-				fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering);
-		printf("Software inputs : %2d, Software outputs : %2d\n", fSoftInputs, fSoftOutputs);
-		printf("Hardware inputs : %2d, Hardware outputs : %2d\n", fCardInputs, fCardOutputs);
-		printf("Channel inputs  : %2d, Channel outputs  : %2d\n", fChanInputs, fChanOutputs);
-
-		// affichage des infos de la carte
-		err = snd_ctl_open (&ctl_handle, fCardName, 0);		check_error(err);
-		snd_ctl_card_info_alloca (&card_info);
-		err = snd_ctl_card_info(ctl_handle, card_info);		check_error(err);
-		printCardInfo(card_info);
-
-		// affichage des infos liees aux streams d'entree-sortie
-		if (fSoftInputs > 0)	printHWParams(fInputParams);
-		if (fSoftOutputs > 0)	printHWParams(fOutputParams);
-	}
-
-	void printCardInfo(snd_ctl_card_info_t*	ci)
-	{
-		printf("Card info (address : %p)\n", ci);
-		printf("\tID         = %s\n", snd_ctl_card_info_get_id(ci));
-		printf("\tDriver     = %s\n", snd_ctl_card_info_get_driver(ci));
-		printf("\tName       = %s\n", snd_ctl_card_info_get_name(ci));
-		printf("\tLongName   = %s\n", snd_ctl_card_info_get_longname(ci));
-		printf("\tMixerName  = %s\n", snd_ctl_card_info_get_mixername(ci));
-		printf("\tComponents = %s\n", snd_ctl_card_info_get_components(ci));
-		printf("--------------\n");
-	}
-
-	void printHWParams( snd_pcm_hw_params_t* params )
-	{
-		printf("HW Params info (address : %p)\n", params);
-#if 0
-		printf("\tChannels    = %d\n", snd_pcm_hw_params_get_channels(params));
-		printf("\tFormat      = %s\n", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params)));
-		printf("\tAccess      = %s\n", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params)));
-		printf("\tRate        = %d\n", snd_pcm_hw_params_get_rate(params, NULL));
-		printf("\tPeriods     = %d\n", snd_pcm_hw_params_get_periods(params, NULL));
-		printf("\tPeriod size = %d\n", (int)snd_pcm_hw_params_get_period_size(params, NULL));
-		printf("\tPeriod time = %d\n", snd_pcm_hw_params_get_period_time(params, NULL));
-		printf("\tBuffer size = %d\n", (int)snd_pcm_hw_params_get_buffer_size(params));
-		printf("\tBuffer time = %d\n", snd_pcm_hw_params_get_buffer_time(params, NULL));
-#endif
-		printf("--------------\n");
-	}
-
-};
-
-// lopt : Scan Command Line long int Arguments
-long lopt(int argc, char *argv[], const char* longname, const char* shortname, long def)
-{
-	for (int i=2; i<argc; i++)
-		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
-			return atoi(argv[i]);
-	return def;
-}
-
-// sopt : Scan Command Line string Arguments
-const char* sopt(int argc, char *argv[], const char* longname, const char* shortname, const char* def)
-{
-	for (int i=2; i<argc; i++)
-		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
-			return argv[i];
-	return def;
-}
-
-// fopt : Scan Command Line flag option (without argument), return true if the flag
-bool fopt(int argc, char *argv[], const char* longname, const char* shortname)
-{
-	for (int i=1; i<argc; i++)
-		if ( strcmp(argv[i], shortname) == 0 || strcmp(argv[i], longname) == 0 )
-			return true;
-	return false;
-}
-
-/**
- * Return the value of an environment variable or defval if undefined.
- */
-static int getDefaultEnv(const char* name, int defval)
-{
-    const char* str = getenv(name);
-    if (str) {
-        return atoi(str);
-    } else {
-        return defval;
-    }
-}
-
-/**
- * Return the value of an environment variable or defval if undefined.
- */
-static const char* getDefaultEnv(const char* name, const char* defval)
-{
-    const char* str = getenv(name);
-    if (str) {
-        return str;
-    } else {
-        return defval;
-    }
-}
-
-/******************************************************************************
-*******************************************************************************
-
-							   ALSA audio interface
-
-*******************************************************************************
-*******************************************************************************/
-void* __run(void* ptr);
-
-class alsaaudio : public audio {
-	AudioInterface*	fAudio;
-	dsp* 			fDSP;
-	pthread_t 	fAudioThread;
-	bool 		fRunning;
-
- public:
-			 alsaaudio(int argc, char *argv[], dsp* DSP) : fAudio(0), fDSP(DSP), fRunning(false) {
-					fAudio = new AudioInterface (
-						AudioParam().cardName( sopt(argc, argv, "--device", "-d",     getDefaultEnv("FAUST2ALSA_DEVICE", "hw:0")  ) )
-						.frequency( lopt(argc, argv, "--frequency", "-f", getDefaultEnv("FAUST2ALSA_FREQUENCY",44100) ) )
-						.buffering( lopt(argc, argv, "--buffer", "-b",    getDefaultEnv("FAUST2ALSA_BUFFER",1024)     ) )
-						.periods( lopt(argc, argv, "--periods", "-p",     getDefaultEnv("FAUST2ALSA_PERIODS",2)       ) )
-						.inputs(DSP->getNumInputs())
-						.outputs(DSP->getNumOutputs()));
-				}
-	virtual ~alsaaudio() { stop(); delete fAudio; }
-
-	virtual bool init(const char */*name*/, dsp* DSP) {
-		AVOIDDENORMALS;
-		fAudio->open();
-	    DSP->init(fAudio->frequency());
- 		return true;
-	}
-
-	virtual bool start() {
-		fRunning = true;
-		if (pthread_create( &fAudioThread, 0, __run, this))
-			fRunning = false;
-		return fRunning;
-	}
-
-	virtual void stop() {
-		if (fRunning) {
-			fRunning = false;
-			pthread_join (fAudioThread, 0);
-		}
-	}
-
-	virtual void run() {
-		bool rt = setRealtimePriority();
-		printf(rt ? "RT : ":"NRT: "); fAudio->shortinfo();
-		fAudio->write();
-		fAudio->write();
-		while(fRunning) {
-			fAudio->read();
-			fDSP->compute(fAudio->buffering(), fAudio->inputSoftChannels(), fAudio->outputSoftChannels());
-			fAudio->write();
-		}
-	}
-};
-
-void* __run (void* ptr)
-{
-	alsaaudio * alsa = (alsaaudio*)ptr;
-	alsa->run();
-	return 0;
-}
-
-#endif
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
diff --git a/architecture/audio/audio.h b/architecture/audio/audio.h
deleted file mode 100644
index 18d794d..0000000
--- a/architecture/audio/audio.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-/******************************************************************************
-*******************************************************************************
-
-						An abstraction layer over audio layer
-
-*******************************************************************************
-*******************************************************************************/
-
-#ifndef __audio__
-#define __audio__
-			
-class dsp;
-class audio {
- public:
-			 audio() {}
-	virtual ~audio() {}
-	
-	virtual bool init(const char* name, dsp*)	= 0;
-	virtual bool start()						= 0;
-	virtual void stop()							= 0;
-};
-					
-#endif
diff --git a/architecture/audio/coreaudio-dsp.h b/architecture/audio/coreaudio-dsp.h
deleted file mode 100644
index e1b952c..0000000
--- a/architecture/audio/coreaudio-dsp.h
+++ /dev/null
@@ -1,1157 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections :
-	the ARCHITECTURE section (in two parts) and the USER section. Each section
-	is governed by its own copyright and license. Please check individually
-	each section for license and copyright information.
-*************************************************************************/
-
-#ifndef __coreaudio_dsp__
-#define __coreaudio_dsp__
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work
-	that contains this FAUST architecture section and distribute
-	that work under terms of your choice, so long as this FAUST
-	architecture section is not modified.
-
-
- ************************************************************************
- ************************************************************************/
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <vector>
-#include <iostream>
-#include <libgen.h>
-
-#include <AudioToolbox/AudioConverter.h>
-#include <CoreAudio/CoreAudio.h>
-#include <AudioUnit/AudioUnit.h>
-#include <CoreServices/CoreServices.h>
-
-#include "audio.h"
-#include "dsp.h"
-
-using namespace std;
-
-/******************************************************************************
-*******************************************************************************
-
-							COREAUDIO INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-//----------------------------------------------------------------------------
-// 	number of physical input and output channels of the CA device
-//----------------------------------------------------------------------------
-
-int	gDevNumInChans;
-int	gDevNumOutChans;
-
-//----------------------------------------------------------------------------
-// tables of noninterleaved input and output channels for FAUST
-//----------------------------------------------------------------------------
-
-float* 	gInChannel[256];
-float* 	gOutChannel[256];
-
-#define OPEN_ERR -1
-#define NO_ERR 0
-
-#define WAIT_COUNTER 60
-
-typedef	UInt8	CAAudioHardwareDeviceSectionID;
-#define	kAudioDeviceSectionInput	((CAAudioHardwareDeviceSectionID)0x01)
-#define	kAudioDeviceSectionOutput	((CAAudioHardwareDeviceSectionID)0x00)
-#define	kAudioDeviceSectionGlobal	((CAAudioHardwareDeviceSectionID)0x00)
-#define	kAudioDeviceSectionWildcard	((CAAudioHardwareDeviceSectionID)0xFF)
-
-dsp * gDsp;
-
-class TCoreAudioRenderer
-{
-    private:
-		AudioBufferList* fInputData;
-		AudioDeviceID fDeviceID;
-		AudioUnit fAUHAL;
-        AudioObjectID fPluginID;    // Used for aggregate device
-         bool fState;
-
-		OSStatus GetDefaultDevice(int inChan, int outChan, int samplerate, AudioDeviceID* id);
-
-        OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice);
-        OSStatus CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice);
-        OSStatus DestroyAggregateDevice();
-
-        OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name);
-
-        int SetupSampleRateAux(AudioDeviceID inDevice, int samplerate);
-
-		static OSStatus Render(void *inRefCon,
-                               AudioUnitRenderActionFlags *ioActionFlags,
-                               const AudioTimeStamp *inTimeStamp,
-                               UInt32 inBusNumber,
-                               UInt32 inNumberFrames,
-                               AudioBufferList *ioData);
-
-
-        static OSStatus SRNotificationCallback(AudioDeviceID inDevice,
-                                            UInt32 inChannel,
-                                            Boolean	isInput,
-                                            AudioDevicePropertyID inPropertyID,
-                                            void* inClientData);
-
-    public:
-
-        TCoreAudioRenderer()
-            :fInputData(0),fDeviceID(0),fAUHAL(0),fPluginID(0),fState(false)
-        {}
-        virtual ~TCoreAudioRenderer()
-        {}
-
-        long OpenDefault(long inChan, long outChan, long bufferSize, long sampleRate);
-        long Close();
-
-        long Start();
-        long Stop();
-
-};
-
-typedef TCoreAudioRenderer * TCoreAudioRendererPtr;
-
-static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
-{
-    cout << "- - - - - - - - - - - - - - - - - - - -" << endl;
-    cout << "  Sample Rate: "		<< inDesc->mSampleRate  << endl;
-    cout << "  Format ID:%.*s\n"	<< sizeof(inDesc->mFormatID) << (char*)&inDesc->mFormatID << endl;
-    cout << "  Format Flags "		<< inDesc->mFormatFlags << endl;
-    cout << "  Bytes per Packet: "	<< inDesc->mBytesPerPacket << endl;
-    cout << "  Frames per Packet: "	<< inDesc->mFramesPerPacket << endl;
-    cout << "  Bytes per Frame: "	<< inDesc->mBytesPerFrame << endl;
-    cout << "  Channels per Frame: "<< inDesc->mChannelsPerFrame << endl;
-    cout << "  Bits per Channel: "	<< inDesc->mBitsPerChannel << endl;
-    cout << "- - - - - - - - - - - - - - - - - - - -" << endl;
-}
-
-static void printError(OSStatus err)
-{
-    switch (err) {
-        case kAudioHardwareNoError:
-            printf("error code : kAudioHardwareNoError\n");
-            break;
-		case kAudioConverterErr_FormatNotSupported:
-            printf("error code : kAudioConverterErr_FormatNotSupported\n");
-            break;
-        case kAudioConverterErr_OperationNotSupported:
-            printf("error code : kAudioConverterErr_OperationNotSupported\n");
-            break;
-        case kAudioConverterErr_PropertyNotSupported:
-            printf("error code : kAudioConverterErr_PropertyNotSupported\n");
-            break;
-        case kAudioConverterErr_InvalidInputSize:
-            printf("error code : kAudioConverterErr_InvalidInputSize\n");
-            break;
-        case kAudioConverterErr_InvalidOutputSize:
-            printf("error code : kAudioConverterErr_InvalidOutputSize\n");
-            break;
-        case kAudioConverterErr_UnspecifiedError:
-            printf("error code : kAudioConverterErr_UnspecifiedError\n");
-            break;
-        case kAudioConverterErr_BadPropertySizeError:
-            printf("error code : kAudioConverterErr_BadPropertySizeError\n");
-            break;
-        case kAudioConverterErr_RequiresPacketDescriptionsError:
-            printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n");
-            break;
-        case kAudioConverterErr_InputSampleRateOutOfRange:
-            printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n");
-            break;
-        case kAudioConverterErr_OutputSampleRateOutOfRange:
-            printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n");
-            break;
-		case kAudioHardwareNotRunningError:
-            printf("error code : kAudioHardwareNotRunningError\n");
-            break;
-        case kAudioHardwareUnknownPropertyError:
-            printf("error code : kAudioHardwareUnknownPropertyError\n");
-            break;
-        case kAudioHardwareIllegalOperationError:
-            printf("error code : kAudioHardwareIllegalOperationError\n");
-            break;
-        case kAudioHardwareBadDeviceError:
-            printf("error code : kAudioHardwareBadDeviceError\n");
-            break;
-        case kAudioHardwareBadStreamError:
-            printf("error code : kAudioHardwareBadStreamError\n");
-            break;
-        case kAudioDeviceUnsupportedFormatError:
-            printf("error code : kAudioDeviceUnsupportedFormatError\n");
-            break;
-        case kAudioDevicePermissionsError:
-            printf("error code : kAudioDevicePermissionsError\n");
-            break;
-        default:
-            printf("error code : unknown\n");
-            break;
-    }
-}
-
-OSStatus TCoreAudioRenderer::Render(void *inRefCon,
-                                     AudioUnitRenderActionFlags *ioActionFlags,
-                                     const AudioTimeStamp *inTimeStamp,
-                                     UInt32,
-                                     UInt32 inNumberFrames,
-                                     AudioBufferList *ioData)
-{
-    TCoreAudioRendererPtr renderer = (TCoreAudioRendererPtr)inRefCon;
-    AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fInputData);
-    for (int i = 0; i < gDevNumInChans; i++) {
-        gInChannel[i] = (float*)renderer->fInputData->mBuffers[i].mData;
-    }
-    for (int i = 0; i < gDevNumOutChans; i++) {
-        gOutChannel[i] = (float*)ioData->mBuffers[i].mData;
-    }
-    gDsp->compute((int)inNumberFrames, gInChannel, gOutChannel);
-	return 0;
-}
-
-static CFStringRef GetDeviceName(AudioDeviceID id)
-{
-    UInt32 size = sizeof(CFStringRef);
-    CFStringRef UIname;
-    OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname);
-    return (err == noErr) ? UIname : NULL;
-}
-
-OSStatus TCoreAudioRenderer::GetDeviceNameFromID(AudioDeviceID id, char* name)
-{
-    UInt32 size = 256;
-    return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name);
-}
-
-OSStatus TCoreAudioRenderer::GetDefaultDevice(int inChan, int outChan, int samplerate, AudioDeviceID* id)
-{
-    UInt32 theSize = sizeof(UInt32);
-    AudioDeviceID inDefault;
-    AudioDeviceID outDefault;
-	OSStatus res;
-
-    if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
-                                        &theSize, &inDefault)) != noErr)
-        return res;
-
-    if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
-                                        &theSize, &outDefault)) != noErr)
-        return res;
-
-	// Duplex mode
-	if (inChan > 0 && outChan > 0) {
-		// Get the device only if default input and output are the same
-		if (inDefault == outDefault) {
-			*id = inDefault;
-			return noErr;
-		} else {
-            printf("GetDefaultDevice : input = %ld and output = %ld are not the same, create aggregate device...\n", inDefault, outDefault);
-            if (CreateAggregateDevice(inDefault, outDefault, samplerate, id) != noErr)
-                return kAudioHardwareBadDeviceError;
-       	}
-	} else if (inChan > 0) {
-		*id = inDefault;
-		return noErr;
-	} else if (outChan > 0) {
-		*id = outDefault;
-		return noErr;
-	} else {
-		return kAudioHardwareBadDeviceError;
-	}
-
-	return noErr;
-}
-
-OSStatus TCoreAudioRenderer::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice)
-{
-    OSStatus err = noErr;
-    AudioObjectID sub_device[32];
-    UInt32 outSize = sizeof(sub_device);
-
-    err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
-    vector<AudioDeviceID> captureDeviceIDArray;
-
-    if (err != noErr) {
-        printf("Input device does not have subdevices\n");
-        captureDeviceIDArray.push_back(captureDeviceID);
-    } else {
-        int num_devices = outSize / sizeof(AudioObjectID);
-        printf("Input device has %d subdevices\n", num_devices);
-        for (int i = 0; i < num_devices; i++) {
-            captureDeviceIDArray.push_back(sub_device[i]);
-        }
-    }
-
-    err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
-    vector<AudioDeviceID> playbackDeviceIDArray;
-
-    if (err != noErr) {
-        printf("Output device does not have subdevices\n");
-        playbackDeviceIDArray.push_back(playbackDeviceID);
-    } else {
-        int num_devices = outSize / sizeof(AudioObjectID);
-        printf("Output device has %d subdevices\n", num_devices);
-        for (int i = 0; i < num_devices; i++) {
-            playbackDeviceIDArray.push_back(sub_device[i]);
-        }
-    }
-
-    return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice);
-}
-
-
-OSStatus TCoreAudioRenderer::SRNotificationCallback(AudioDeviceID inDevice,
-                                                    UInt32 /*inChannel*/,
-                                                    Boolean	/*isInput*/,
-                                                    AudioDevicePropertyID inPropertyID,
-                                                    void* inClientData)
-{
-    TCoreAudioRenderer* driver = (TCoreAudioRenderer*)inClientData;
-
-    switch (inPropertyID) {
-
-        case kAudioDevicePropertyNominalSampleRate: {
-            printf("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate\n");
-            driver->fState = true;
-            // Check new sample rate
-            Float64 sampleRate;
-            UInt32 outSize =  sizeof(Float64);
-            OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
-            if (err != noErr) {
-                printf("Cannot get current sample rate\n");
-                printError(err);
-            } else {
-                printf("SRNotificationCallback : checked sample rate = %f\n", sampleRate);
-            }
-            break;
-        }
-    }
-
-    return noErr;
-}
-
-int TCoreAudioRenderer::SetupSampleRateAux(AudioDeviceID inDevice, int samplerate)
-{
-    OSStatus err = noErr;
-    UInt32 outSize;
-    Float64 sampleRate;
-
-    // Get sample rate
-    outSize =  sizeof(Float64);
-    err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
-    if (err != noErr) {
-        printf("Cannot get current sample rate\n");
-        printError(err);
-        return -1;
-    } else {
-        printf("Current sample rate = %f\n", sampleRate);
-    }
-
-    // If needed, set new sample rate
-    if (samplerate != (int)sampleRate) {
-        sampleRate = (Float64)samplerate;
-
-        // To get SR change notification
-        err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this);
-        if (err != noErr) {
-            printf("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate\n");
-            printError(err);
-            return -1;
-        }
-        err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate);
-        if (err != noErr) {
-            printf("Cannot set sample rate = %d\n", samplerate);
-            printError(err);
-            return -1;
-        }
-
-        // Waiting for SR change notification
-        int count = 0;
-        while (!fState && count++ < WAIT_COUNTER) {
-            usleep(100000);
-            printf("Wait count = %d\n", count);
-        }
-
-        // Check new sample rate
-        outSize =  sizeof(Float64);
-        err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
-        if (err != noErr) {
-            printf("Cannot get current sample rate\n");
-            printError(err);
-        } else {
-            printf("Checked sample rate = %f\n", sampleRate);
-        }
-
-        // Remove SR change notification
-        AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
-    }
-
-    return 0;
-}
-
-OSStatus TCoreAudioRenderer::CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice)
-{
-    OSStatus osErr = noErr;
-    UInt32 outSize;
-    Boolean outWritable;
-
-    bool fClockDriftCompensate = true;
-
-    // Prepare sub-devices for clock drift compensation
-    // Workaround for bug in the HAL : until 10.6.2
-    AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-    AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-    UInt32 theQualifierDataSize = sizeof(AudioObjectID);
-    AudioClassID inClass = kAudioSubDeviceClassID;
-    void* theQualifierData = &inClass;
-    UInt32 subDevicesNum = 0;
-
-    //---------------------------------------------------------------------------
-    // Setup SR of both devices otherwise creating AD may fail...
-    //---------------------------------------------------------------------------
-    UInt32 keptclockdomain = 0;
-    UInt32 clockdomain = 0;
-    outSize = sizeof(UInt32);
-    bool need_clock_drift_compensation = false;
-
-    for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
-        if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) {
-            printf("TCoreAudioRenderer::CreateAggregateDevice : cannot set SR of input device\n");
-        } else  {
-            // Check clock domain
-            osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
-            if (osErr != 0) {
-                printf("TCoreAudioRenderer::CreateAggregateDevice : kAudioDevicePropertyClockDomain error\n");
-                printError(osErr);
-            } else {
-                keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
-                printf("TCoreAudioRenderer::CreateAggregateDevice : input clockdomain = %d\n", clockdomain);
-                if (clockdomain != 0 && clockdomain != keptclockdomain) {
-                    printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n");
-                    need_clock_drift_compensation = true;
-                }
-            }
-        }
-    }
-
-    for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
-        if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) {
-            printf("TCoreAudioRenderer::CreateAggregateDevice : cannot set SR of output device\n");
-        } else {
-            // Check clock domain
-            osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
-            if (osErr != 0) {
-                printf("TCoreAudioRenderer::CreateAggregateDevice : kAudioDevicePropertyClockDomain error\n");
-                printError(osErr);
-            } else {
-                keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
-                printf("TCoreAudioRenderer::CreateAggregateDevice : output clockdomain = %d", clockdomain);
-                if (clockdomain != 0 && clockdomain != keptclockdomain) {
-                    printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n");
-                    need_clock_drift_compensation = true;
-                }
-            }
-        }
-    }
-
-    // If no valid clock domain was found, then assume we have to compensate...
-    if (keptclockdomain == 0) {
-        need_clock_drift_compensation = true;
-    }
-
-    //---------------------------------------------------------------------------
-    // Start to create a new aggregate by getting the base audio hardware plugin
-    //---------------------------------------------------------------------------
-
-    char device_name[256];
-    for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
-        GetDeviceNameFromID(captureDeviceID[i], device_name);
-        printf("Separated input = '%s' \n", device_name);
-    }
-
-    for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
-        GetDeviceNameFromID(playbackDeviceID[i], device_name);
-        printf("Separated output = '%s' \n", device_name);
-    }
-
-    osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable);
-    if (osErr != noErr) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error\n");
-        printError(osErr);
-        return osErr;
-    }
-
-    AudioValueTranslation pluginAVT;
-
-    CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio");
-
-    pluginAVT.mInputData = &inBundleRef;
-    pluginAVT.mInputDataSize = sizeof(inBundleRef);
-    pluginAVT.mOutputData = &fPluginID;
-    pluginAVT.mOutputDataSize = sizeof(fPluginID);
-
-    osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT);
-    if (osErr != noErr) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error\n");
-        printError(osErr);
-        return osErr;
-    }
-
-    //-------------------------------------------------
-    // Create a CFDictionary for our aggregate device
-    //-------------------------------------------------
-
-    CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
-    CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex");
-    CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex");
-
-    // add the name of the device to the dictionary
-    CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef);
-
-    // add our choice of UID for the aggregate device to the dictionary
-    CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef);
-
-    // add a "private aggregate key" to the dictionary
-    int value = 1;
-    CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value);
-
-    SInt32 system;
-    Gestalt(gestaltSystemVersion, &system);
-
-    printf("TCoreAudioRenderer::CreateAggregateDevice : system version = %x limit = %x\n", system, 0x00001054);
-
-    // Starting with 10.5.4 systems, the AD can be internal... (better)
-    if (system < 0x00001054) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : public aggregate device....\n");
-    } else {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : private aggregate device....\n");
-        CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef);
-    }
-
-    // Prepare sub-devices for clock drift compensation
-    CFMutableArrayRef subDevicesArrayClock = NULL;
-
-    /*
-    if (fClockDriftCompensate) {
-        if (need_clock_drift_compensation) {
-            jack_info("Clock drift compensation activated...");
-            subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
-            for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
-                CFStringRef UID = GetDeviceName(captureDeviceID[i]);
-                if (UID) {
-                    CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-                    CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID);
-                    CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef);
-                    //CFRelease(UID);
-                    CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
-                }
-            }
-
-            for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
-                CFStringRef UID = GetDeviceName(playbackDeviceID[i]);
-                if (UID) {
-                    CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-                    CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID);
-                    CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef);
-                    //CFRelease(UID);
-                    CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
-                }
-            }
-
-            // add sub-device clock array for the aggregate device to the dictionary
-            CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock);
-        } else {
-            jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)");
-        }
-    }
-    */
-
-    //-------------------------------------------------
-    // Create a CFMutableArray for our sub-device list
-    //-------------------------------------------------
-
-    // we need to append the UID for each device to a CFMutableArray, so create one here
-    CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
-    vector<CFStringRef> captureDeviceUID;
-    for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
-        CFStringRef ref = GetDeviceName(captureDeviceID[i]);
-        if (ref == NULL)
-            return -1;
-        captureDeviceUID.push_back(ref);
-        // input sub-devices in this example, so append the sub-device's UID to the CFArray
-        CFArrayAppendValue(subDevicesArray, ref);
-   }
-
-    vector<CFStringRef> playbackDeviceUID;
-    for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
-        CFStringRef ref = GetDeviceName(playbackDeviceID[i]);
-        if (ref == NULL)
-            return -1;
-        playbackDeviceUID.push_back(ref);
-        // output sub-devices in this example, so append the sub-device's UID to the CFArray
-        CFArrayAppendValue(subDevicesArray, ref);
-    }
-
-    //-----------------------------------------------------------------------
-    // Feed the dictionary to the plugin, to create a blank aggregate device
-    //-----------------------------------------------------------------------
-
-    AudioObjectPropertyAddress pluginAOPA;
-    pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice;
-    pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
-    pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
-    UInt32 outDataSize;
-
-    osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
-    if (osErr != noErr) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectGetPropertyDataSize error\n");
-        printError(osErr);
-        goto error;
-    }
-
-    osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice);
-    if (osErr != noErr) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectGetPropertyData error\n");
-        printError(osErr);
-        goto error;
-    }
-
-    // pause for a bit to make sure that everything completed correctly
-    // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created
-    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
-
-    //-------------------------
-    // Set the sub-device list
-    //-------------------------
-
-    pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList;
-    pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
-    pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
-    outDataSize = sizeof(CFMutableArrayRef);
-    osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray);
-    if (osErr != noErr) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error\n");
-        printError(osErr);
-        goto error;
-    }
-
-    // pause again to give the changes time to take effect
-    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
-
-    //-----------------------
-    // Set the master device
-    //-----------------------
-
-    // set the master device manually (this is the device which will act as the master clock for the aggregate device)
-    // pass in the UID of the device you want to use
-    pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice;
-    pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
-    pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
-    outDataSize = sizeof(CFStringRef);
-    osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]);  // First apture is master...
-    if (osErr != noErr) {
-        printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectSetPropertyData for master device error\n");
-        printError(osErr);
-        goto error;
-    }
-
-    // pause again to give the changes time to take effect
-    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
-
-    // Prepare sub-devices for clock drift compensation
-    // Workaround for bug in the HAL : until 10.6.2
-
-    if (fClockDriftCompensate) {
-        if (need_clock_drift_compensation) {
-            printf("Clock drift compensation activated...\n");
-
-            // Get the property data size
-            osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize);
-            if (osErr != noErr) {
-                printf("TCoreAudioRenderer::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error\n");
-                printError(osErr);
-            }
-
-            //	Calculate the number of object IDs
-            subDevicesNum = outSize / sizeof(AudioObjectID);
-            printf("TCoreAudioRenderer::CreateAggregateDevice clock drift compensation, number of sub-devices = %d\n", subDevicesNum);
-            AudioObjectID subDevices[subDevicesNum];
-            outSize = sizeof(subDevices);
-
-            osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices);
-            if (osErr != noErr) {
-                printf("TCoreAudioRenderer::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error\n");
-                printError(osErr);
-            }
-
-            // Set kAudioSubDevicePropertyDriftCompensation property...
-            for (UInt32 index = 0; index < subDevicesNum; ++index) {
-                UInt32 theDriftCompensationValue = 1;
-                osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue);
-                if (osErr != noErr) {
-                    printf("TCoreAudioRenderer::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error\n");
-                    printError(osErr);
-                }
-            }
-        } else {
-            printf("Clock drift compensation was asked but is not needed (devices use the same clock domain)\n");
-        }
-    }
-
-    // pause again to give the changes time to take effect
-    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
-
-    //----------
-    // Clean up
-    //----------
-
-    // release the private AD key
-    CFRelease(AggregateDeviceNumberRef);
-
-    // release the CF objects we have created - we don't need them any more
-    CFRelease(aggDeviceDict);
-    CFRelease(subDevicesArray);
-
-    if (subDevicesArrayClock)
-        CFRelease(subDevicesArrayClock);
-
-    // release the device UID
-    for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
-        CFRelease(captureDeviceUID[i]);
-    }
-
-    for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) {
-        CFRelease(playbackDeviceUID[i]);
-    }
-
-    printf("New aggregate device %d\n", *outAggregateDevice);
-    return noErr;
-
-error:
-    DestroyAggregateDevice();
-    return -1;
-}
-
-OSStatus TCoreAudioRenderer::DestroyAggregateDevice()
-{
-    OSStatus osErr = noErr;
-    AudioObjectPropertyAddress pluginAOPA;
-    pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice;
-    pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
-    pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
-    UInt32 outDataSize;
-
-    if (fPluginID > 0)   {
-
-        osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
-        if (osErr != noErr) {
-            printf("TCoreAudioRenderer::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error\n");
-            printError(osErr);
-            return osErr;
-        }
-
-        osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID);
-        if (osErr != noErr) {
-            printf("TCoreAudioRenderer::DestroyAggregateDevice : AudioObjectGetPropertyData error\n");
-            printError(osErr);
-            return osErr;
-        }
-
-    }
-
-    return noErr;
-}
-
-
-long TCoreAudioRenderer::OpenDefault(long inChan, long outChan, long bufferSize, long samplerate)
-{
-	OSStatus err = noErr;
-    ComponentResult err1;
-    UInt32 outSize;
-    UInt32 enableIO;
-	Boolean isWritable;
-	AudioStreamBasicDescription srcFormat, dstFormat, sampleRate;
-    long in_nChannels, out_nChannels;
-
-    printf("OpenDefault inChan = %ld outChan = %ld bufferSize = %ld samplerate = %ld\n", inChan, outChan, bufferSize, samplerate);
-
-    SInt32 major;
-    SInt32 minor;
-    Gestalt(gestaltSystemVersionMajor, &major);
-    Gestalt(gestaltSystemVersionMinor, &minor);
-
-    // Starting with 10.6 systems, the HAL notification thread is created internally
-    if (major == 10 && minor >= 6) {
-        CFRunLoopRef theRunLoop = NULL;
-        AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-        OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
-        if (osErr != noErr) {
-            printf("TCoreAudioRenderer::Open kAudioHardwarePropertyRunLoop error\n");
-            printError(osErr);
-        }
-    }
-
-	if (GetDefaultDevice(inChan, outChan, samplerate,&fDeviceID) != noErr) {
-		printf("Cannot open default device\n");
-		return OPEN_ERR;
-	}
-
-	// Setting buffer size
-    outSize = sizeof(UInt32);
-    err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &bufferSize);
-    if (err != noErr) {
-        printf("Cannot set buffer size %ld\n", bufferSize);
-        printError(err);
-        return OPEN_ERR;
-    }
-
-    // Setting sample rate
-    outSize = sizeof(AudioStreamBasicDescription);
-    err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &outSize, &sampleRate);
-    if (err != noErr) {
-        printf("Cannot get current sample rate\n");
-        printError(err);
-        return OPEN_ERR;
-    }
-
-    if (samplerate != long(sampleRate.mSampleRate)) {
-        sampleRate.mSampleRate = (Float64)(samplerate);
-        err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyStreamFormat, outSize, &sampleRate);
-        if (err != noErr) {
-            printf("Cannot set sample rate = %ld\n", samplerate);
-            printError(err);
-            return OPEN_ERR;
-        }
-    }
-
-    // AUHAL
-    ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
-    Component HALOutput = FindNextComponent(NULL, &cd);
-
-    err1 = OpenAComponent(HALOutput, &fAUHAL);
-    if (err1 != noErr) {
-		printf("Error calling OpenAComponent\n");
-        printError(err1);
-        goto error;
-	}
-
-    err1 = AudioUnitInitialize(fAUHAL);
-    if (err1 != noErr) {
-		printf("Cannot initialize AUHAL unit\n");
-		printError(err1);
-        goto error;
-	}
-
-    enableIO = 1;
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n");
-        printError(err1);
-        goto error;
-    }
-
-    enableIO = 1;
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable);
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 1\n");
-        printError(err1);
-    }
-
-    in_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0;
-    printf("in_nChannels = %ld\n", in_nChannels);
-
-    err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable);
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 0\n");
-        printError(err1);
-    }
-
-    out_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0;
-    printf("out_nChannels = %ld\n", out_nChannels);
-
-    /*
-    Just ignore this case : seems to work without any further change...
-
-    if (outChan > out_nChannels) {
-        printf("This device hasn't required output channels\n");
-        goto error;
-    }
-    if (inChan > in_nChannels) {
-        printf("This device hasn't required input channels\n");
-        goto error;
-    }
-    */
-
-    if (outChan < out_nChannels) {
-        SInt32 chanArr[out_nChannels];
-        for (int i = 0;	i < out_nChannels; i++) {
-            chanArr[i] = -1;
-        }
-        for (int i = 0; i < outChan; i++) {
-            chanArr[i] = i;
-        }
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n");
-            printError(err1);
-        }
-    }
-
-    if (inChan < in_nChannels) {
-        SInt32 chanArr[in_nChannels];
-        for (int i = 0; i < in_nChannels; i++) {
-            chanArr[i] = -1;
-        }
-        for (int i = 0; i < inChan; i++) {
-            chanArr[i] = i;
-        }
-        AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n");
-            printError(err1);
-        }
-    }
-
-    if (inChan > 0) {
-        outSize = sizeof(AudioStreamBasicDescription);
-        err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-        PrintStreamDesc(&srcFormat);
-
-        srcFormat.mSampleRate = samplerate;
-        srcFormat.mFormatID = kAudioFormatLinearPCM;
-        srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
-        srcFormat.mBytesPerPacket = sizeof(float);
-        srcFormat.mFramesPerPacket = 1;
-        srcFormat.mBytesPerFrame = sizeof(float);
-        srcFormat.mChannelsPerFrame = inChan;
-        srcFormat.mBitsPerChannel = 32;
-
-        PrintStreamDesc(&srcFormat);
-
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-    }
-
-    if (outChan > 0) {
-        outSize = sizeof(AudioStreamBasicDescription);
-        err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-        PrintStreamDesc(&dstFormat);
-
-        dstFormat.mSampleRate = samplerate;
-        dstFormat.mFormatID = kAudioFormatLinearPCM;
-        dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
-        dstFormat.mBytesPerPacket = sizeof(float);
-        dstFormat.mFramesPerPacket = 1;
-        dstFormat.mBytesPerFrame = sizeof(float);
-        dstFormat.mChannelsPerFrame = outChan;
-        dstFormat.mBitsPerChannel = 32;
-
-        PrintStreamDesc(&dstFormat);
-
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-    }
-
-    if (inChan > 0 && outChan == 0) {
-        AURenderCallbackStruct output;
-        output.inputProc = Render;
-        output.inputProcRefCon = this;
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n");
-            printError(err1);
-            goto error;
-        }
-    } else {
-        AURenderCallbackStruct output;
-        output.inputProc = Render;
-        output.inputProcRefCon = this;
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n");
-            printError(err1);
-            goto error;
-        }
-    }
-
-    fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inChan * sizeof(AudioBuffer));
-    if (fInputData == 0) {
-		printf("Cannot allocate memory for input buffers\n");
-        goto error;
-	}
-    fInputData->mNumberBuffers = inChan;
-
-    // Prepare buffers
-    for (int i = 0; i < inChan; i++) {
-        fInputData->mBuffers[i].mNumberChannels = 1;
-        fInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(float));
-        fInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(float);
-    }
-
-    return NO_ERR;
-
-error:
-    AudioUnitUninitialize(fAUHAL);
-    CloseComponent(fAUHAL);
-    return OPEN_ERR;
-}
-
-long TCoreAudioRenderer::Close()
-{
-    for (int i = 0; i < gDevNumInChans; i++) {
-        free(fInputData->mBuffers[i].mData);
-    }
-	free(fInputData);
-	AudioUnitUninitialize(fAUHAL);
-    CloseComponent(fAUHAL);
-    DestroyAggregateDevice();
-    return NO_ERR;
-}
-
-long TCoreAudioRenderer::Start()
-{
-	OSStatus err = AudioOutputUnitStart(fAUHAL);
-
-    if (err != noErr) {
-        printf("Error while opening device : device open error \n");
-        return OPEN_ERR;
-    } else {
-        return NO_ERR;
-	}
-}
-
-long TCoreAudioRenderer::Stop()
-{
-    OSStatus err = AudioOutputUnitStop(fAUHAL);
-
-    if (err != noErr) {
-        printf("Error while closing device : device close error \n");
-        return OPEN_ERR;
-    } else {
-        return NO_ERR;
-	}
-}
-
-
-
-/******************************************************************************
-*******************************************************************************
-
-							CORE AUDIO INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-class coreaudio : public audio {
-
-    TCoreAudioRenderer audio_device;
-	long			fSampleRate, fFramesPerBuf;
-
- public:
-			 coreaudio(long srate, long fpb) : fSampleRate(srate), fFramesPerBuf(fpb) {}
-	virtual ~coreaudio() {}
-
-	virtual bool init(const char* /*name*/, dsp* DSP) {
-		gDsp = DSP;
-		DSP->init (fSampleRate);
-		gDevNumInChans = DSP->getNumInputs();
-		gDevNumOutChans = DSP->getNumOutputs();
-		if (audio_device.OpenDefault(gDevNumInChans, gDevNumOutChans, fFramesPerBuf, fSampleRate) < 0) {
-			printf("Cannot open CoreAudio device\n");
-			return false;
-		}
-        return true;
-    }
-
-	virtual bool start() {
-		if (audio_device.Start() < 0) {
-			printf("Cannot start CoreAudio device\n");
-			return false;
-		}
-		return true;
-	}
-
-	virtual void stop() {
-		audio_device.Stop();
-		audio_device.Close();
-	}
-
-};
-
-#endif
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
-
diff --git a/architecture/audio/dsp.h b/architecture/audio/dsp.h
deleted file mode 100644
index 37227f3..0000000
--- a/architecture/audio/dsp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-
-/******************************************************************************
-*******************************************************************************
-
-								FAUST DSP
-
-*******************************************************************************
-*******************************************************************************/
-
-#ifndef __dsp__
-#define __dsp__
-
-class UI;
-
-//----------------------------------------------------------------
-//  signal processor definition
-//----------------------------------------------------------------
-
-class dsp {
- protected:
-	int fSamplingFreq;
- public:
-	dsp() {}
-	virtual ~dsp() {}
-
-	virtual int getNumInputs() 										= 0;
-	virtual int getNumOutputs() 									= 0;
-	virtual void buildUserInterface(UI* interface) 					= 0;
-	virtual void init(int samplingRate) 							= 0;
- 	virtual void compute(int len, float** inputs, float** outputs) 	= 0;
-};
-
-#endif
diff --git a/architecture/audio/jack-dsp.h b/architecture/audio/jack-dsp.h
deleted file mode 100644
index 01ae0f2..0000000
--- a/architecture/audio/jack-dsp.h
+++ /dev/null
@@ -1,156 +0,0 @@
-
-#ifndef __jack_dsp__
-#define __jack_dsp__
-
-#include <stdio.h>
-#include <jack/jack.h>
-#include "audio.h"
-#include "dsp.h"
-
-static int		_srate(jack_nframes_t nframes, void *);
-static void		_jack_shutdown(void *);
-static int		_process (jack_nframes_t nframes, void *client);
-#ifdef _OPENMP
-static void*	_jackthread(void* arg);
-#endif
-
-/******************************************************************************
-*******************************************************************************
-
-							JACK AUDIO INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-class jackaudio : public audio {
-	dsp*			fDsp;
-	jack_client_t*	fClient;
-	int				fNumInChans;			// 	number of input channels
-	int				fNumOutChans;			// 	number of output channels
-	jack_port_t *	fInput_ports[256];		// Jack input ports
-	jack_port_t *	fOutput_ports[256];		// Jack output ports
-	float*			fInChannel[256];		// tables of noninterleaved input channels for FAUST
-	float*			fOutChannel[256];		// tables of noninterleaved output channels for FAUST
-
- public:
-			 jackaudio() : fClient(0), fNumInChans(0), fNumOutChans(0) {}
-	virtual ~jackaudio() { stop(); }
-
-	virtual bool init(const char*name, dsp* DSP) {
-		fDsp = DSP;
-		if ((fClient = jack_client_open(name, JackNullOption, NULL)) == 0) {
-			fprintf(stderr, "jack server not running?\n");
-			return false;
-		}
-	#ifdef _OPENMP
-		jack_set_process_thread(fClient, _jackthread, this);
-	#else
-		jack_set_process_callback(fClient, _process, this);
-	#endif
-
-		jack_set_sample_rate_callback(fClient, _srate, 0);
-		jack_on_shutdown(fClient, _jack_shutdown, 0);
-
-		fNumInChans  = fDsp->getNumInputs();
-		fNumOutChans = fDsp->getNumOutputs();
-
-		for (int i = 0; i < fNumInChans; i++) {
-			char buf[256];
-			snprintf(buf, 256, "in_%d", i);
-			fInput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
-		}
-		for (int i = 0; i < fNumOutChans; i++) {
-			char buf[256];
-			snprintf(buf, 256, "out_%d", i);
-			fOutput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
-		}
-		fDsp->init(jack_get_sample_rate(fClient));
-		return true;
-	}
-
-	virtual bool start() {
-		if (jack_activate(fClient)) {
-			fprintf(stderr, "cannot activate client");
-			return false;
-		}
-
-		char** physicalInPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
-		char** physicalOutPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
-		if (physicalOutPorts != NULL) {
-			for (int i = 0; i < fNumInChans && physicalOutPorts[i]; i++)
-				jack_connect(fClient, physicalOutPorts[i], jack_port_name(fInput_ports[i]));
-		}
-		if (physicalInPorts != NULL) {
-			for (int i = 0; i < fNumOutChans && physicalInPorts[i]; i++)
-				jack_connect(fClient, jack_port_name(fOutput_ports[i]), physicalInPorts[i]);
-		}
-		return true;
-	}
-
-	virtual void stop() {
-		if (fClient) {
-			jack_deactivate(fClient);
-			for (int i = 0; i < fNumInChans; i++)
-				jack_port_unregister(fClient, fInput_ports[i]);
-			for (int i = 0; i < fNumOutChans; i++)
-				jack_port_unregister(fClient, fOutput_ports[i]);
-			jack_client_close(fClient);
-			fClient = 0;
-		}
-	}
-
-	// jack callbacks
-	int	process (jack_nframes_t nframes) {
-		AVOIDDENORMALS;
-		for (int i = 0; i < fNumInChans; i++)
-			fInChannel[i] = (float *)jack_port_get_buffer(fInput_ports[i], nframes);
-		for (int i = 0; i < fNumOutChans; i++)
-			fOutChannel[i] = (float *)jack_port_get_buffer(fOutput_ports[i], nframes);
-		fDsp->compute(nframes, fInChannel, fOutChannel);
-		return 0;
-	}
-
-#ifdef _OPENMP
-	void process_thread () {
-		jack_nframes_t nframes;
-		while (1) {
-			nframes = jack_cycle_wait(fClient);
-			process (nframes);
-			jack_cycle_signal(fClient, 0);
-		}
-	}
-#endif
-};
-
-//----------------------------------------------------------------------------
-// Jack Callbacks
-//----------------------------------------------------------------------------
-static int _srate(jack_nframes_t nframes, void *)
-{
-	printf("the sample rate is now %u/sec\n", nframes);
-	return 0;
-}
-
-static void _jack_shutdown(void *)
-{
-	exit(1);
-}
-
-static int _process(jack_nframes_t nframes, void *client)
-{
-	jackaudio* jackclient = (jackaudio*)client;
-	return jackclient->process (nframes);
-}
-
-#ifdef _OPENMP
-static void* _jackthread(void* arg)
-{
-	jackaudio* jackclient = (jackaudio*)arg;
-	jackclient->process_thread();
-	return 0;
-}
-#endif
-
-
-
-#endif
diff --git a/architecture/audio/netjack-dsp.h b/architecture/audio/netjack-dsp.h
deleted file mode 100644
index 83f5a81..0000000
--- a/architecture/audio/netjack-dsp.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections :
-	the ARCHITECTURE section (in two parts) and the USER section. Each section
-	is governed by its own copyright and license. Please check individually
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work
-	that contains this FAUST architecture section and distribute
-	that work under terms of your choice, so long as this FAUST
-	architecture section is not modified.
-
-
- ************************************************************************
- ************************************************************************/
-
-#ifndef __netjack_dsp__
-#define __netjack_dsp__
-
-#include "audio.h"
-#include "dsp.h"
-#include <string>
-#include <jack/net.h>
-
-class netjackaudio : public audio {
-
-        dsp* fDsp;
-        jack_net_slave_t* fNet;
-        int fCelt;
-        std::string fMasterIP;
-        int fMasterPort;
-
-        static void net_shutdown(void *)
-        {
-            printf("Network failure, restart...\n");
-        }
-
-        static int net_process(jack_nframes_t buffer_size,
-                                int,
-                                float** audio_input_buffer,
-                                int,
-                                void**,
-                                int,
-                                float** audio_output_buffer,
-                                int,
-                                void**,
-                                void* arg)
-        {
-            AVOIDDENORMALS;
-            netjackaudio* obj = (netjackaudio*)arg;
-            obj->fDsp->compute(buffer_size, audio_input_buffer, audio_output_buffer);
-            return 0;
-        }
-
-    public:
-
-        netjackaudio(int celt, const std::string master_ip, int master_port)
-            :fCelt(celt), fMasterIP(master_ip), fMasterPort(master_port)
-        {}
-
-        bool init(const char* name, dsp* DSP)
-        {
-            fDsp = DSP;
-            jack_slave_t request = {
-                DSP->getNumInputs(),
-                DSP->getNumOutputs(),
-                0, 0,
-                DEFAULT_MTU,
-                -1,
-                (fCelt > 0) ? JackCeltEncoder: JackFloatEncoder,
-                (fCelt > 0) ? fCelt : 0,
-                2
-            };
-
-            jack_master_t result;
-            if ((fNet = jack_net_slave_open(fMasterIP.c_str(), fMasterPort, name, &request, &result)) == 0) {
-                printf("jack remote server not running ?\n");
-                return false;
-            }
-
-            jack_set_net_slave_process_callback(fNet, net_process, this);
-            jack_set_net_slave_shutdown_callback(fNet, net_shutdown, 0);
-
-            fDsp->init(result.sample_rate);
-            return true;
-        }
-
-        bool start()
-        {
-            if (jack_net_slave_activate(fNet)) {
-                printf("cannot activate net");
-                return false;
-            }
-            return true;
-        }
-
-        void stop()
-        {
-            jack_net_slave_deactivate(fNet);
-            jack_net_slave_close(fNet);
-        }
-
-};
-
-
-#endif
-
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
diff --git a/architecture/audio/oscdsp.h b/architecture/audio/oscdsp.h
deleted file mode 100644
index 4521d53..0000000
--- a/architecture/audio/oscdsp.h
+++ /dev/null
@@ -1,71 +0,0 @@
-
-#ifndef __osc_dsp__
-#define __osc_dsp__
-
-#include <stdio.h>
-#include "audio/audio.h"
-#include "audio/dsp.h"
-#include "OSCIO.h"
-
-/******************************************************************************
-*******************************************************************************
-
-							OSC AUDIO INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-#define kMaxBuffer 4096
-
-class oscdsp : public audio, public oscfaust::OSCIO {
-	dsp*	 fDsp;
-	float ** fInBuffers, **fOutBuffers;
-
- public:
-			 oscdsp(const char * dst, int argc, char *argv[]) : OSCIO(dst), fDsp(0), fInBuffers(0), fOutBuffers(0)
-			 {
-				for (int i = 1; i < argc-1; i++)
-					if (!strcmp(argv[i], "-iodst")) setDest (argv[i+1]);
-			 }
-	virtual ~oscdsp() { stop(); }
-
-	virtual bool init(const char*name, dsp* DSP) {
-		fDsp = DSP;
-		fDsp->init(44100);
-		fInBuffers  = new float*[numInputs()];
-		fOutBuffers = new float*[numOutputs()];
-		for (int i= 0; i < numInputs(); i++)
-			fInBuffers[i] = new float[kMaxBuffer];
-		for (int i= 0; i < numOutputs(); i++)
-			fOutBuffers [i] = new float[kMaxBuffer];
-		return true;
-	}
-
-	virtual bool start()	{ return true; }
-	virtual void stop()		{}
-
-	void compute( int nframes ) {
-		fDsp->compute(nframes, fInBuffers, fOutBuffers);
-		for (int i= 0; i < numOutputs(); i++)
-			send( nframes, fOutBuffers [i], i);
-	}
-
-	void receive( int nvalues, float * val ) {
-		int inChans = numInputs();
-		if (!inChans) {
-			compute(nvalues);
-			return;
-		}
-
-		for (int i=0; i < nvalues; i++) {
-			int c = i % inChans;
-			int frame = i / inChans;
-			fInBuffers[c][frame] = val[i];
-		}
-		compute (nvalues / inChans);
-	}
-	int		numOutputs() const	{ return fDsp ? fDsp->getNumOutputs() : 0; }
-	int		numInputs() const	{ return fDsp ? fDsp->getNumInputs() : 0; }
-};
-
-#endif
diff --git a/architecture/audio/portaudio-dsp.h b/architecture/audio/portaudio-dsp.h
deleted file mode 100644
index 726a906..0000000
--- a/architecture/audio/portaudio-dsp.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections :
-	the ARCHITECTURE section (in two parts) and the USER section. Each section
-	is governed by its own copyright and license. Please check individually
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work
-	that contains this FAUST architecture section and distribute
-	that work under terms of your choice, so long as this FAUST
-	architecture section is not modified.
-
-
- ************************************************************************
- ************************************************************************/
-
-
-#ifndef __portaudio_dsp__
-#define __portaudio_dsp__
-
-#include <stdio.h>
-#include <assert.h>
-#include <portaudio.h>
-
-#include "audio.h"
-#include "dsp.h"
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-
-static int audioCallback(const void *ibuf, void *obuf, unsigned long frames, const PaStreamCallbackTimeInfo*,  PaStreamCallbackFlags, void * drv);
-//----------------------------------------------------------------------------
-static void pa_error(int err)
-{
-	if (err != paNoError) {
-		printf(  "PortAudio error: %s\n", Pa_GetErrorText( err ) );
-	}
-}
-
-/******************************************************************************
-*******************************************************************************
-
-							PORT AUDIO INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-class portaudio : public audio {
-
-        dsp*			fDsp;
-        PaStream*		fAudioStream;
-        long fSampleRate, fBufferSize;
-        //----------------------------------------------------------------------------
-        // 	number of physical input and output channels of the PA device
-        //----------------------------------------------------------------------------
-        int		fDevNumInChans;
-        int		fDevNumOutChans;
-
-        //----------------------------------------------------------------------------
-        // tables of noninterleaved input and output channels for FAUST
-        //----------------------------------------------------------------------------
-        float* 	fInChannel[256];
-        float* 	fOutChannel[256];
-
-        //----------------------------------------------------------------------------
-        // allocated the noninterleaved input and output channels for FAUST
-        //----------------------------------------------------------------------------
-        void allocChannels (int size, int numInChan, int numOutChan)
-        {
-            assert (numInChan < 256);
-            assert (numOutChan < 256);
-
-            for (int i = 0; i < numInChan; i++) {
-                fInChannel[i] = (float*) calloc (size, sizeof(float));
-                for (int j = 0; j < size; j++)
-                    fInChannel[i][j] = 0.0;
-            }
-
-            for (int i = 0; i < numOutChan; i++) {
-                fOutChannel[i] = (float*) calloc (size, sizeof(float));
-                for (int j = 0; j < size; j++)
-                    fOutChannel[i][j] = 0.0;
-            }
-        }
-
-	public:
-			 portaudio(long srate, long bsize) : fDsp(0), fAudioStream(0),
-				fSampleRate(srate), fBufferSize(bsize), fDevNumInChans(0), fDevNumOutChans(0) {}
-	virtual ~portaudio() { stop(); }
-
-	virtual bool init(const char* name, dsp* DSP){
-		fDsp = DSP;
-		pa_error(Pa_Initialize());
-
-		const PaDeviceInfo*	idev = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice());
-		const PaDeviceInfo*	odev = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
-
-		fDevNumInChans = (fDsp->getNumInputs() > 0) ? idev->maxInputChannels : 0 ;
-		fDevNumOutChans = (fDsp->getNumOutputs() > 0) ? odev->maxOutputChannels : 0;
-
-		PaStreamParameters inputParameters;
-		PaStreamParameters outputParameters;
-
-		inputParameters.device = Pa_GetDefaultInputDevice();
-		inputParameters.sampleFormat = paFloat32;
-		inputParameters.channelCount = fDevNumInChans;
-		inputParameters.hostApiSpecificStreamInfo = 0;
-
-		outputParameters.device = Pa_GetDefaultOutputDevice();
-		outputParameters.sampleFormat = paFloat32;
-		outputParameters.channelCount = fDevNumOutChans;
-		outputParameters.hostApiSpecificStreamInfo = 0;
-
-		PaError err;
-		if ((err = Pa_IsFormatSupported(
-			((fDevNumInChans > 0) ? &inputParameters : 0),
-			((fDevNumOutChans > 0) ? &outputParameters : 0), fSampleRate)) != 0) {
-			printf("stream format is not supported err = %d\n", err);
-			return false;
-		}
-
-		allocChannels(fBufferSize, max(fDevNumInChans, fDsp->getNumInputs()), max(fDevNumOutChans, fDsp->getNumOutputs()));
-		fDsp->init(fSampleRate);
-		return true;
-	}
-
-	virtual bool start() {
-		pa_error(Pa_OpenDefaultStream(&fAudioStream, fDevNumInChans, fDevNumOutChans, paFloat32, fSampleRate, fBufferSize, audioCallback, this));
-		Pa_StartStream(fAudioStream);
-		return true;
-	}
-
-	virtual void stop() {
-		if (fAudioStream) {
-			Pa_StopStream (fAudioStream);
-			Pa_CloseStream(fAudioStream);
-			fAudioStream = 0;
-		}
-	}
-
-	int processAudio(const float *ibuf, float *obuf, unsigned long frames) {
-		const float* fInputBuffer = ibuf;
-		float* fOutputBuffer = obuf;
-
-		// split input samples
-		for (unsigned long s = 0; s < frames; s++) {
-			for (int c = 0; c < fDevNumInChans; c++) {
-				fInChannel[c][s] = fInputBuffer[c + s*fDevNumInChans];
-			}
-		}
-
-		// process samples
-		fDsp->compute(frames, fInChannel, fOutChannel);
-
-		// merge output samples
-		for (unsigned long s = 0; s < frames; s++) {
-			for (int c = 0; c < fDevNumOutChans; c++) {
-				fOutputBuffer[c + s*fDevNumOutChans] = fOutChannel[c][s];
-			}
-		}
-		return 0;
-	}
-};
-
-//----------------------------------------------------------------------------
-// Port Audio Callback
-//----------------------------------------------------------------------------
-static int audioCallback(const void *ibuf, void *obuf, unsigned long frames, const PaStreamCallbackTimeInfo*,  PaStreamCallbackFlags, void * drv)
-{
-	portaudio * pa = (portaudio*) drv;
-	return pa->processAudio ((const float*)ibuf, (float*)obuf, frames);
-}
-
-#endif
diff --git a/architecture/bench.cpp b/architecture/bench.cpp
index 85a42fb..0c1db82 100644
--- a/architecture/bench.cpp
+++ b/architecture/bench.cpp
@@ -34,9 +34,6 @@
  ************************************************************************
  ************************************************************************/
 
-
-/* link with  */
-/* link with : "" */
 #include <stdlib.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -54,35 +51,15 @@
 #include <pthread.h>
 #include <sys/wait.h>
 #include <list>
-
 #include <iostream>
-
-
-using namespace std;
-
 #include <map>
+#include <sys/time.h>
 
-using namespace std;
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #define AVOIDDENORMALS 
-#endif
-
-struct Meta : map<const char*, const char*>
-{
-    void declare (const char* key, const char* value) { (*this)[key]=value; }
-};
-
+#include "faust/gui/UI.h"
+#include "faust/audio/dsp.h"
+#include "faust/misc.h"
 
+using namespace std;
 
 float*          gBuffer = 0;        // a buffer of NV*VSize samples
 
@@ -92,65 +69,6 @@ unsigned int    ITER    = 10;       // number of iterations per measure
 unsigned int    VSIZE   = 4096;     // size of a vector in samples
 unsigned int    IDX     = 0;        // current vector number (0 <= VIdx < NV)
 
-
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
-
-
-// g++ -Wall -O3 -lm -lpthread -lasound `gtk-config --cflags --libs` test.cpp -o test
-
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-
-
-inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
-
-
 bool setRealtimePriority ()
 {
     struct passwd *         pw;
@@ -172,16 +90,12 @@ bool setRealtimePriority ()
     return (err != -1);
 }
 
-#include <sys/time.h>
-
 double mysecond()
 {
-        struct timeval tp;
-        struct timezone tzp;
-        int i;
-
-        i = gettimeofday(&tp,&tzp);
-        return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
+    struct timeval tp;
+    struct timezone tzp;
+    int i = gettimeofday(&tp,&tzp);
+    return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
 }
 
 /******************************************************************************
@@ -192,86 +106,7 @@ double mysecond()
 *******************************************************************************
 *******************************************************************************/
 
-
-
 <<includeIntrinsic>>
-
-
-
-/******************************************************************************
-*******************************************************************************
-
-			ABSTRACT USER INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-class UI
-{
-	bool	fStopped;
-public:
-
-	UI() : fStopped(false) {}
-	virtual ~UI() {}
-
-	virtual void addButton(const char* label, float* zone) = 0;
-	virtual void addToggleButton(const char* label, float* zone) = 0;
-	virtual void addCheckButton(const char* label, float* zone) = 0;
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-
-        // -- passive widgets
-
-        virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-        virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
-        virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-
-	virtual void openFrameBox(const char* label) = 0;
-        virtual void openTabBox(const char* label) = 0;
-        virtual void openHorizontalBox(const char* label) = 0;
-        virtual void openVerticalBox(const char* label) = 0;
-
-        virtual void closeBox() = 0;
-
-        virtual void run() = 0;
-
-	void stop()	{ fStopped = true; }
-	bool stopped() 	{ return fStopped; }
-
-    virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
-
-
-
-/******************************************************************************
-*******************************************************************************
-
-								DSP
-
-*******************************************************************************
-*******************************************************************************/
-
-
-
-//----------------------------------------------------------------
-//  definition du processeur de signal
-//----------------------------------------------------------------
-
-class dsp {
- protected:
-	int fSamplingFreq;
- public:
-	dsp() {}
-	virtual ~dsp() {}
-	virtual int getNumInputs() 										= 0;
-	virtual int getNumOutputs() 									= 0;
-	virtual void buildUserInterface(UI* interface) 					= 0;
-	virtual void init(int samplingRate) 							= 0;
- 	virtual void compute(int len, float** inputs, float** outputs) 	= 0;
-};
 		
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
@@ -285,14 +120,13 @@ class dsp {
 					
 mydsp	DSP;
 
-
 #if 0
 
 static __inline__ unsigned long long int rdtsc(void)
 {
-  unsigned long long int x;
-     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
-     return x;
+    unsigned long long int x;
+    __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+    return x;
 }
 
 #endif
@@ -349,7 +183,6 @@ float* nextVect()
 
 void bench(const char* name)
 {
-
     int numInChan = DSP.getNumInputs();
     int numOutChan = DSP.getNumOutputs();
 
@@ -386,16 +219,16 @@ void bench(const char* name)
 //-------------------------------------------------------------------------
 
 // lopt : Scan Command Line long int Arguments
-
 long lopt (int argc, char *argv[], const char* longname, const char* shortname, long def)
 {
-	for (int i=2; i<argc; i++)
-		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
+	for (int i=2; i<argc; i++) {
+		if (strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0) {
 			return atoi(argv[i]);
+        }
+    }
 	return def;
 }
 
-
 int main(int argc, char *argv[] )
 {
     AVOIDDENORMALS;
@@ -408,7 +241,6 @@ int main(int argc, char *argv[] )
   	return 0;
 }
 
-
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
 
 
diff --git a/architecture/ca-qt.cpp b/architecture/ca-qt.cpp
index aaa2272..db48ba6 100644
--- a/architecture/ca-qt.cpp
+++ b/architecture/ca-qt.cpp
@@ -34,18 +34,28 @@
  ************************************************************************
  ************************************************************************/
 
-
 #include <libgen.h>
 #include <stdlib.h>
 #include <iostream>
+#include <list>
 
-#include "gui/FUI.h"
-#include "gui/faustqt.h"
-#include "misc.h"
-#include "audio/coreaudio-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/gui/faustqt.h"
+#include "faust/misc.h"
+#include "faust/audio/coreaudio-dsp.h"
+#include "faust/midi/midi.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+#if MIDICTRL
+#include "faust/midi/rt-midi.h"
+#include "faust/gui/MidiUI.h"
 #endif
 
 /**************************BEGIN USER SECTION **************************/
@@ -59,16 +69,20 @@
 *******************************************************************************/
 <<includeIntrinsic>>
 
-
 <<includeclass>>
 
+#ifdef POLY
+#include "faust/dsp/poly-dsp.h"
+mydsp_poly*	DSP;
+#else
+mydsp* DSP;
+#endif
+
 /***************************END USER SECTION ***************************/
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 
-mydsp	DSP;
-
-list<GUI*>               GUI::fGuiList;
+std::list<GUI*> GUI::fGuiList;
 
 /******************************************************************************
 *******************************************************************************
@@ -86,36 +100,96 @@ int main(int argc, char *argv[])
 
 	snprintf(name, 255, "%s", basename(argv[0]));
 	snprintf(rcfilename, 255, "%s/.%src", home, basename(argv[0]));
+    
+    long srate = (long)lopt(argv, "--frequency", -1);
+    int fpb = lopt(argv, "--buffer", 512);
+    int poly = lopt(argv, "--poly", 4);
+     
+#if MIDICTRL
+    rtmidi midi(name);
+#endif
 
-    long srate = (long)lopt(argv, "--frequency", 44100);
-    int	fpb = lopt(argv, "--buffer", 512);
+#ifdef POLY
+#if MIDICTRL
+    DSP = new mydsp_poly(poly, true);
+    midi.addMidiIn(DSP);
+#else
+    DSP = new mydsp_poly(poly);
+#endif
+#else
+    DSP = new mydsp();
+#endif
+    if (DSP == 0) {
+        std::cerr << "Unable to allocate Faust DSP object" << std::endl;
+        exit(1);
+    }
+ 
+	QApplication myApp(argc, argv);
+    
+    QTGUI interface;
+    FUI finterface;
+    DSP->buildUserInterface(&interface);
+    DSP->buildUserInterface(&finterface);
+
+#ifdef MIDICTRL
+    MidiUI midiinterface(name);
+    DSP->buildUserInterface(&midiinterface);
+    std::cout << "MIDI is on" << std::endl;
+#endif
 
-	GUI* interface = new QTGUI(argc, argv);
-	DSP.buildUserInterface(interface);
-	FUI* finterface	= new FUI();
-	DSP.buildUserInterface(finterface);
+#ifdef HTTPCTRL
+    httpdUI httpdinterface(name, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
+    DSP->buildUserInterface(&httpdinterface);
+    std::cout << "HTTPD is on" << std::endl;
+ #endif
 
 #ifdef OSCCTRL
-	GUI*	oscinterface = new OSCUI(name, argc, argv);
-	DSP.buildUserInterface(oscinterface);
+	OSCUI oscinterface(name, argc, argv);
+	DSP->buildUserInterface(&oscinterface);
+    std::cout << "OSC is on" << std::endl;
 #endif
 
 	coreaudio audio(srate, fpb);
-	audio.init(name, &DSP);
-	finterface->recallState(rcfilename);
+	audio.init(name, DSP);
+	finterface.recallState(rcfilename);
 	audio.start();
+    
+    printf("ins %d\n", audio.get_num_inputs());
+    printf("outs %d\n", audio.get_num_outputs());
+    
+#if MIDICTRL
+    midi.start();
+#endif
+
+#ifdef HTTPCTRL
+	httpdinterface.run();
+#ifdef QRCODECTRL
+    interface.displayQRCode(httpdinterface.getTCPPort());
+#endif
+#endif
 
 #ifdef OSCCTRL
-	oscinterface->run();
+	oscinterface.run();
+#endif
+#ifdef MIDICTRL
+	midiinterface.run();
 #endif
-	interface->run();
+	interface.run();
 
+    myApp.setStyleSheet(interface.styleSheet());
+    myApp.exec();
+    interface.stop();
+    
 	audio.stop();
-	finterface->saveState(rcfilename);
+	finterface.saveState(rcfilename);
+    
+#ifdef MIDICTRL
+    midi.stop();
+#endif
+
   	return 0;
 }
 
-
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
 
 
diff --git a/architecture/csound.cpp b/architecture/csound.cpp
index 07f9859..5a02318 100644
--- a/architecture/csound.cpp
+++ b/architecture/csound.cpp
@@ -1,44 +1,44 @@
 /************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections : 
-	the ARCHITECTURE section (in two parts) and the USER section. Each section 
-	is governed by its own copyright and license. Please check individually 
-	each section for license and copyright information.
-*************************************************************************/
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections : 
+ the ARCHITECTURE section (in two parts) and the USER section. Each section 
+ is governed by its own copyright and license. Please check individually 
+ each section for license and copyright information.
+ *************************************************************************/
 
 /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
 
 /************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2010-2011 V. Lazzarini and GRAME
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work 
-	that contains this FAUST architecture section and distribute  
-	that work under terms of your choice, so long as this FAUST 
-	architecture section is not modified. 
-
-
+ FAUST Architecture File
+ Copyright (C) 2010-2011 V. Lazzarini and GRAME
+ ---------------------------------------------------------------------
+ This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+ EXCEPTION : As a special exception, you may create a larger work 
+ that contains this FAUST architecture section and distribute  
+ that work under terms of your choice, so long as this FAUST 
+ architecture section is not modified. 
+ 
+ 
  ************************************************************************
  ************************************************************************/
 
 //==============================================================================
 //
-//          CSOUND architecture file for FAUST
+//          CSOUND6 architecture file for FAUST
 //          Y. Orlarey & V. Lazzarini
-//
+//          
 //          Usage : faust -uim -a csound.cpp <myfx>.dsp -o <myfx>.cpp
 //                  g++ -O3 -DOPCODE_NAME=<myfx> -c <myfx>.cpp -o <myfx>.o
 //                  ld -E --shared <myfx>.o -o <myfx>.so
@@ -46,6 +46,7 @@
 //          History :
 //          - 28/04/09 : first version
 //          - 29/04/09 : dynamic allocation
+//          - 10/07/14 : updated to csound6 (Paul Batchelor)
 //
 //==============================================================================
 
@@ -72,139 +73,67 @@
 #define FAUST_ADDVERTICALBARGRAPH(l,f,a,b)
 #define FAUST_ADDHORIZONTALBARGRAPH(l,f,a,b)
 
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-using namespace std;
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #define AVOIDDENORMALS 
-#endif
-
-
-
+#include "faust/misc.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/meta.h"
+#include "faust/gui/UI.h"
 
 /******************************************************************************
-*******************************************************************************
-
-                                   VECTOR INTRINSICS
-
-*******************************************************************************
-*******************************************************************************/
-
+ *******************************************************************************
+ 
+ VECTOR INTRINSICS
+ 
+ *******************************************************************************
+ *******************************************************************************/
 
 <<includeIntrinsic>>
 
-
-
-/**
- * We will ignore metadata declarations
- */
-struct Meta 
-{
-    void declare (const char* key, const char* value) { }
-};
-
 /**
- * Abstract Definition of a user interface
+ * A UI that simply collects the active zones in a vector
+ * and provides a method to copy the csound controls
  */
-class UI 
+class CSUI : public UI
 {
- public:
-        
-    virtual ~UI() {}
-
-    // -- active widgets
-    
-    virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
-    virtual void addToggleButton(const char* label, FAUSTFLOAT* zone) = 0;
-    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
-    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
-    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
-    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
+    std::vector<FAUSTFLOAT*>  vZone;
     
-    // -- passive widgets
-    
-    virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision)                           {}
-    virtual void addTextDisplay(const char* label, FAUSTFLOAT* zone, char* names[], FAUSTFLOAT min, FAUSTFLOAT max)    {}
-    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)            {}
-    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)              {}
+public:
     
     // -- widget's layouts
     
-    virtual void openFrameBox(const char* label)                                                        {}
     virtual void openTabBox(const char* label)                                                          {}
     virtual void openHorizontalBox(const char* label)                                                   {}
     virtual void openVerticalBox(const char* label)                                                     {}
     virtual void closeBox()                                                                             {}
-
-    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value) {}
-};
-
-/**
- * A UI that simply collects the active zones in a vector
- * and provides a method to copy the csound controls
- */
-class CSUI : public UI
-{
-    vector<FAUSTFLOAT*>  vZone;
-
- public:
+    
     // -- active widgets
     
     virtual void addButton(const char* label, FAUSTFLOAT* zone)                                                          { vZone.push_back(zone); }
-    virtual void addToggleButton(const char* label, FAUSTFLOAT* zone)                                                    { vZone.push_back(zone); }
     virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)                                                     { vZone.push_back(zone); }
     virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)    { vZone.push_back(zone); }
     virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)  { vZone.push_back(zone); }
     virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)          { vZone.push_back(zone); }
-
+    
+    // -- passive widgets
+    
+    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)            {}
+    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)              {}
+    
     void copyfrom(MYFLT* mem[]) {
         for (unsigned int i=0; i<vZone.size(); i++) { *vZone[i] = *(mem[i]); }
     }
-
+    
     int size()                  { return vZone.size(); }
 };
 
-
-
-/**
- * Abstract Definition of a DSP
- */
-
-class dsp {
- protected:
-    int fSamplingFreq;
-  public:
-    virtual int getNumInputs() = 0;
-    virtual int getNumOutputs() = 0;
-    virtual void instanceInit(int samplingFreq) = 0;
-    virtual void init(int samplingFreq)= 0;
-    virtual void buildUserInterface(UI* interface) = 0;
-    virtual void compute (int count, FAUSTFLOAT** input, FAUSTFLOAT** output) = 0;
-};
-
-		
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
 /**************************BEGIN USER SECTION **************************/
-		
+
 <<includeclass>>
 
 /***************************END USER SECTION ***************************/
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
-					
-
 
 struct dataspace {
     OPDS      h;                          /* basic attributes */
@@ -217,7 +146,6 @@ struct dataspace {
     AUXCH     intmem;                     /* aux memory allocated once to store the interface object */
 };
 
-
 /**
  * Creates a "aaakkkk" CSound description string. Note that
  * these string will never be released. Potential memory leak
@@ -233,7 +161,6 @@ static char* makeDescription(int numa, int numk=0)
     return str;
 }
 
-
 /**
  * CSOUND callback that allocates and initializes
  * the FAUST generated DSP object and it's CSound interface
@@ -242,23 +169,21 @@ static int init(CSOUND *csound, dataspace *p)
 {
     if (p->dspmem.auxp == NULL)
         csound->AuxAlloc(csound, sizeof(mydsp), &p->dspmem);
-
+    
     if(p->intmem.auxp == NULL)
         csound->AuxAlloc(csound, sizeof(CSUI), &p->intmem);
-
-
+    
     p->DSP = new (p->dspmem.auxp) mydsp;
     p->interface = new (p->intmem.auxp) CSUI;
-
+    
     if ((p->DSP == 0) | (p->interface == 0)) return NOTOK;
-
+    
     p->DSP->init((int)csound->GetSr(csound));   
     p->DSP->buildUserInterface(p->interface);
-
+    
     return OK;
 }
 
-
 /**
  * CSound callback that process the samples by updating
  * the controls values and calling the compute() method
@@ -266,26 +191,25 @@ static int init(CSOUND *csound, dataspace *p)
  */
 static int process32bits(CSOUND *csound, dataspace *p)
 {
-  AVOIDDENORMALS;
-
-  // update all the control values
-  p->interface->copyfrom(p->ktl);
-
-  p->DSP->compute(csound->GetKsmps(csound), p->ain, p->aout);
-  return OK;
+    AVOIDDENORMALS;
+    
+    // update all the control values
+    p->interface->copyfrom(p->ktl);
+    
+    p->DSP->compute(csound->GetKsmps(csound), p->ain, p->aout);
+    return OK;
 }
 
 extern "C" {
-
-static OENTRY localops[] = {
-    {(char*)sym(OPCODE_NAME), sizeof(dataspace),5,makeDescription(FAUST_OUTPUTS), makeDescription(FAUST_INPUTS,FAUST_ACTIVES),
-     (SUBR)init, NULL,(SUBR)process32bits }
-};
-LINKAGE
+    static OENTRY localops[] = {
+        {(char*)sym(OPCODE_NAME), sizeof(dataspace), 0, 7, makeDescription(FAUST_OUTPUTS), makeDescription(FAUST_INPUTS, FAUST_ACTIVES),
+            (SUBR)init, NULL, (SUBR)process32bits }
+    };
+    LINKAGE
 }
-  
-		
+
+
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
-					
-   
- 
+
+
+
diff --git a/architecture/dssi.cpp b/architecture/dssi.cpp
index 9aef8af..f7aa009 100644
--- a/architecture/dssi.cpp
+++ b/architecture/dssi.cpp
@@ -68,12 +68,15 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <iostream>
 #include <stack>
 #include <string>
 #include <map>
 #include <vector>
 #include <list>
 
+using namespace std;
+
 // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
 // flags to avoid costly denormals
 #ifdef __SSE__
@@ -93,8 +96,6 @@ struct Meta : std::map<const char*, const char*>
     void declare (const char* key, const char* value) { (*this)[key]=value; }
 };
 
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
 
 #define sym(name) xsym(name)
 #define xsym(name) #name
@@ -207,7 +208,7 @@ DSSI_Program_Descriptor g_program_descriptor;
 std::vector<LADSPA_PortDescriptor> g_port_descriptors;
 std::vector<LADSPA_PortRangeHint> g_port_range_hints;
 std::vector<const char*> g_port_names;
-std::string g_name;
+const char* g_name;
 
 ////////////////////////////////////////////////////////////////////////////////
 // The enclosed code is from ladspa.cpp 
@@ -432,7 +433,7 @@ private:
     // Helper methods:
     void updateControlZones();
     void runImpl(unsigned long, snd_seq_event_t *, unsigned long);
-    void addSamples(int);
+    void addSamples(size_t);
 
     // Helpers for UI building:
     // TODO organize this a bit better later...
@@ -842,10 +843,10 @@ void Plugin::runImpl(unsigned long sampleCount, snd_seq_event_t *events, unsigne
     }
 }
 
-void Plugin::addSamples(int samples)
+void Plugin::addSamples(size_t samples)
 {
     size_t i;
-    int j;
+    size_t j;
     size_t v;
 
     // TODO this isn't very efficient right now...
@@ -1185,9 +1186,9 @@ extern "C"
             // Fill the descriptors:
             // TODO figure out strdup with const strings
             g_ladspa_descriptor->UniqueID = 0;
-            g_ladspa_descriptor->Label = get_metadata_if_exists("name", g_name.c_str());
+            g_ladspa_descriptor->Label = get_metadata_if_exists("name", g_name);
             g_ladspa_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
-            g_ladspa_descriptor->Name = get_metadata_if_exists("name", g_name.c_str());
+            g_ladspa_descriptor->Name = get_metadata_if_exists("name", g_name);
             g_ladspa_descriptor->Maker = get_metadata_if_exists("author", "Maker");
             g_ladspa_descriptor->Copyright = get_metadata_if_exists("copyright", "Copyright");
             g_ladspa_descriptor->PortCount = g_port_descriptors.size();
@@ -1218,7 +1219,7 @@ extern "C"
             // Program description (TODO if we eventually support multiple programs we will need to handle this differently)
             g_program_descriptor.Bank = 0;
             g_program_descriptor.Program = 0;
-            g_program_descriptor.Name = get_metadata_if_exists("name", g_name.c_str());
+            g_program_descriptor.Name = get_metadata_if_exists("name", g_name);
 
             delete temp_mydsp;
             delete temp_descriptor_ui;
diff --git a/architecture/effect.lib b/architecture/effect.lib
index 0eec145..81efc4a 100644
--- a/architecture/effect.lib
+++ b/architecture/effect.lib
@@ -3,15 +3,16 @@ declare author "Julius O. Smith (jos at ccrma.stanford.edu)";
 declare copyright "Julius O. Smith III";
 declare version "1.33";
 declare license "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license)
-declare reference "https://ccrma.stanford.edu/realsimple/faust_strings/";
 
 import("filter.lib"); // dcblocker*, lowpass, filterbank, ...
 
 // The following utilities (or equivalents) could go in music.lib:
 
 //----------------------- midikey2hz,pianokey2hz ------------------------
-midikey2hz(x) = 440.0*pow(2.0, (x-69.0)/12); // MIDI key 69 = A440
-pianokey2hz(x) = 440.0*pow(2.0, (x-49.0)/12); // piano key 49 = A440
+midikey2hz(mk)  = 440.0*pow(2.0, (mk-69.0)/12); // MIDI key 69 = A440
+pianokey2hz(pk) = 440.0*pow(2.0, (pk-49.0)/12); // piano key 49 = A440
+hz2pianokey(f)  = 12*log2(f/440.0) + 49.0;
+log2(x) = log(x)/log(2.0);
 
 //---------------- cross2, bypass1, bypass2, select2stereo --------------
 //
@@ -83,7 +84,7 @@ with {
     pregain = pow(10.0,2*drive);
     clip(lo,hi) = min(hi) : max(lo);
     cubic(x) = x - x*x*x/3;
-    postgain = max(1.0,1.0/pregain); // unity gain when nearly linear
+    postgain = max(1.0,1.0/pregain);
 };
 
 cubicnl_nodc(drive,offset) = cubicnl(drive,offset) : dcblocker;
@@ -97,21 +98,95 @@ with {
    cnl_group(x)  = vgroup("CUBIC NONLINEARITY cubicnl
         [tooltip: Reference:
          https://ccrma.stanford.edu/~jos/pasp/Cubic_Soft_Clipper.html]", x);
-//   bypass_group(x) = cnl_group(hgroup("[0]", x));
-   slider_group(x)  = cnl_group(hgroup("[1]", x));
-//   bp = bypass_group(checkbox("[0] Bypass
-   bp = slider_group(checkbox("[0] Bypass
+   bp = cnl_group(checkbox("[0] Bypass
         [tooltip: When this is checked, the nonlinearity has no effect]"));
-//   drive = slider_group(vslider("[1] Drive [style: knob]
-   drive = slider_group(hslider("[1] Drive
+   drive = cnl_group(hslider("[1] Drive
                        [tooltip: Amount of distortion]",
                        0, 0, 1, 0.01));
-//   offset = slider_group(vslider("[2] Offset [style: knob]
-   offset = slider_group(hslider("[2] Offset
+   offset = cnl_group(hslider("[2] Offset
                        [tooltip: Brings in even harmonics]",
                        0, 0, 1, 0.01));
 };
 
+//------------------------------- exciter -------------------------------
+// Psychoacoustic harmonic exciter, with GUI
+//
+// USAGE: _ : exciter : _
+// REFERENCES:
+//  https://secure.aes.org/forum/pubs/ebriefs/?elib=16939
+//  https://www.researchgate.net/publication/258333577_Modeling_the_Harmonic_Exciter
+
+declare exciter_name "Harmonic Exciter";
+declare exciter_author "Priyanka Shekar (pshekar at ccrma.stanford.edu)";
+declare exciter_copyright "Copyright (c) 2013 Priyanka Shekar";
+declare exciter_version "1.0";
+declare exciter_license "MIT License (MIT)"; 
+
+exciter = _ <: (highpass : compressor : pregain : harmonicCreator : postgain), _ : balance with {
+
+  compressor = bypass1(cbp,compressorMono) with {
+
+    comp_group(x) = vgroup("COMPRESSOR  [tooltip: Reference: http://en.wikipedia.org/wiki/Dynamic_range_compression]", x);
+
+    meter_group(x)  = comp_group(hgroup("[0]", x));
+    knob_group(x)  = comp_group(hgroup("[1]", x));
+
+    cbp = meter_group(checkbox("[0] Bypass  [tooltip: When this is checked, the compressor has no effect]"));
+
+    gainview = compression_gain_mono(ratio,threshold,attack,release) : linear2db : meter_group(hbargraph("[1] Compressor Gain [unit:dB] [tooltip: Current gain of the compressor in dB]",-50,+10));
+
+    displaygain = _ <: _,abs : _,gainview : attach;
+
+    compressorMono = displaygain(compressor_mono(ratio,threshold,attack,release));
+
+    ctl_group(x)  = knob_group(hgroup("[3] Compression Control", x));
+
+    ratio = ctl_group(hslider("[0] Ratio [style:knob]  [tooltip: A compression Ratio of N means that for each N dB increase in input signal level above Threshold, the output level goes up 1 dB]",
+    5, 1, 20, 0.1));
+
+    threshold = ctl_group(hslider("[1] Threshold [unit:dB] [style:knob]  [tooltip: When the signal level exceeds the Threshold (in dB), its level is compressed according to the Ratio]",
+    -30, -100, 10, 0.1));
+
+    env_group(x)  = knob_group(hgroup("[4] Compression Response", x));
+
+    attack = env_group(hslider("[1] Attack [unit:ms] [style:knob]  [tooltip: Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new lower target level (the compression `kicking in')]",
+    50, 0, 500, 0.1)) : *(0.001) : max(1/SR);
+
+    release = env_group(hslider("[2] Release [unit:ms] [style: knob]  [tooltip: Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new higher target level (the compression 'releasing')]",
+    500, 0, 1000, 0.1)) : *(0.001) : max(1/SR);
+
+  };
+
+  //Exciter GUI controls
+  ex_group(x) = hgroup("EXCITER  [tooltip: Reference: Patent US4150253 A]", x);
+
+  //Highpass - selectable cutoff frequency
+  fc = ex_group(hslider("[0] Cutoff Frequency [unit:Hz] [style:knob] [scale:log] 
+                        [tooltip: Cutoff frequency for highpassed components to be excited]", 
+			5000, 1000, 10000, 100));
+  highpass = component("filter.lib").highpass(2, fc);
+  x = highpass;
+
+  //Pre-distortion gain - selectable percentage of harmonics
+  ph = ex_group(hslider("[1] Harmonics [unit:percent] [style:knob] [tooltip: Percentage of harmonics generated]", 20, 0, 200, 1)) / 100;
+  pregain = * (ph);
+  x = pregain;
+
+  //Asymmetric cubic soft clipper
+  harmonicCreator(x) = x <: cubDist1, cubDist2, cubDist3 :> _;
+  cubDist1(x) = (x < 0) * x;
+  cubDist2(x) = (x >= 0) * (x <= 1) * (x - x ^ 3 / 3);
+  cubDist3(x) = (x > 1) * 2/3;
+
+  //Post-distortion gain - undoes effect of pre-gain
+  postgain = * (1/ph);
+
+  //Balance - selectable dry/wet mix
+  ml = ex_group(hslider("[2] Mix [style:knob] [tooltip: Dry/Wet mix of original signal to excited signal]", 0.50, 0.00, 1.00, 0.01));
+  balance = (_ * ml), (_ * (1.0 - ml)) :> _;
+
+};
+
 //------------------------- moog_vcf(res,fr) ---------------------------
 // Moog "Voltage Controlled Filter" (VCF) in "analog" form
 //
@@ -201,9 +276,7 @@ with {
 moog_vcf_demo = bypass1(bp,vcf) with {
    mvcf_group(x)  = hgroup("MOOG VCF (Voltage Controlled Filter)
       [tooltip: See Faust's effect.lib for info and references]",x);
-
-   meter_group(x) = mvcf_group(vgroup("[0]",x));
-   cb_group(x) = meter_group(hgroup("[0]",x));
+   cb_group(x) = mvcf_group(hgroup("[0]",x));
 
    bp = cb_group(checkbox("[0] Bypass  [tooltip: When this is checked, the Moog VCF has no effect]"));
    archsw = cb_group(checkbox("[1] Use Biquads
@@ -211,7 +284,7 @@ moog_vcf_demo = bypass1(bp,vcf) with {
    bqsw = cb_group(checkbox("[2] Normalized Ladders
    [tooltip: If using biquads, make them normalized ladders (moog_vcf_2bn)]"));
 
-   freq = mvcf_group(hslider("[1] Corner Frequency [unit:PK] [style:knob]
+   freq = mvcf_group(hslider("[1] Corner Frequency [unit:PK]
    [tooltip: The VCF resonates at the corner frequency (specified in PianoKey (PK) units, with A440 = 49 PK).  The VCF response is flat below the corner frequency, and rolls off -24 dB per octave above.]",
    25, 1, 88, 0.01) : pianokey2hz) : smooth(0.999);
 
@@ -219,10 +292,9 @@ moog_vcf_demo = bypass1(bp,vcf) with {
    [tooltip: Amount of resonance near VCF corner frequency (specified between 0 and 1)]",
    0.9, 0, 1, 0.01));
 
-   outgain  = meter_group(hslider("[1] VCF Output Level [unit:dB]
+   outgain  = mvcf_group(hslider("[3] VCF Output Level [unit:dB] [style:knob]
    [tooltip: output level in decibels]",
-   5, -60, 20, 0.1)) : smooth(0.999)
-   : component("music.lib").db2linear;
+   5, -60, 20, 0.1)) : component("music.lib").db2linear : smooth(0.999);
 
    vcfbq =  _ <: select2(bqsw, moog_vcf_2b(res,freq), moog_vcf_2bn(res,freq));
    vcfarch =  _ <: select2(archsw, moog_vcf(res^4,freq), vcfbq);
@@ -244,7 +316,7 @@ wah4_demo = bypass1(bp, wah4(fr)) with {
        [tooltip: Fourth-order wah effect made using moog_vcf]", x);
   bp = wah4_group(checkbox("[0] Bypass
        [tooltip: When this is checked, the wah pedal has no effect]"));
-  fr = wah4_group(hslider("[1] Resonance Frequency
+  fr = wah4_group(hslider("[1] Resonance Frequency [scale:log]
        [tooltip: wah resonance frequency in Hz]",
      200,100,2000,1));
 // Avoid dc with the moog_vcf (amplitude too high when freq comes up from dc)
@@ -518,9 +590,9 @@ phaser2_demo = bypass2(pbp,phaser2_stereo_demo) with {
    depth  = ctl_group(hslider("[2] Notch Depth (Intensity) [style:knob]", 1, 0, 1, 0.001));
    fb     = ctl_group(hslider("[3] Feedback Gain [style:knob]", 0, -0.999, 0.999, 0.001));
 
-   width  = nch_group(hslider("[1] Notch width [unit:Hz] [style:knob]", 1000, 10, 5000, 1));
-   frqmin = nch_group(hslider("[2] Min Notch1 Freq [unit:Hz] [style:knob]", 100, 20, 5000, 1));
-   frqmax = nch_group(hslider("[3] Max Notch1 Freq [unit:Hz] [style:knob]", 800, 20, 10000, 1)) : max(frqmin);
+   width  = nch_group(hslider("[1] Notch width [unit:Hz] [style:knob] [scale:log]", 1000, 10, 5000, 1));
+   frqmin = nch_group(hslider("[2] Min Notch1 Freq [unit:Hz] [style:knob] [scale:log]", 100, 20, 5000, 1));
+   frqmax = nch_group(hslider("[3] Max Notch1 Freq [unit:Hz] [style:knob] [scale:log]", 800, 20, 10000, 1)) : max(frqmin);
    fratio = nch_group(hslider("[4] Notch Freq Ratio: NotchFreq(n+1)/NotchFreq(n)  [style:knob]", 1.5, 1.1, 4, 0.001));
 
    level  = lvl_group(hslider("Phaser Output Level [unit:dB]", 0, -60, 10, 0.1)) : component("music.lib").db2linear;
@@ -528,6 +600,47 @@ phaser2_demo = bypass2(pbp,phaser2_stereo_demo) with {
    mdepth = select2(vibr,depth,2); // Improve "ease of use"
 };
 
+//---------------------------- vocoder -------------------------
+// A very simple vocoder where the spectrum of the modulation signal
+// is analyzed using a filter bank.
+//
+// USAGE: 
+// 		vocoder(nBands,att,rel,BWRatio,source,excitation) : _;
+//
+// where
+// nBands = Number of vocoder bands
+// att = Attack time in seconds
+// rel = Release time in seconds
+// BWRatio = Coefficient to adjust the bandwidth of each band (0.1 - 2)
+// source = Modulation signal
+// excitation = Excitation/Carrier signal
+  
+oneVocoderBand(band,bandsNumb,bwRatio,bandGain,x) = x : resonbp(bandFreq,bandQ,bandGain) with{
+	bandFreq = 25*pow(2,(band+1)*(9/bandsNumb));
+	BW = (bandFreq - 25*pow(2,(band)*(9/bandsNumb)))*bwRatio;
+	bandQ = bandFreq/BW;
+};
+
+vocoder(nBands,att,rel,BWRatio,source,excitation) = source <: par(i,nBands,oneVocoderBand(i,nBands,BWRatio,1) : amp_follower_ar(att,rel) : _,excitation : oneVocoderBand(i,nBands,BWRatio)) :> _ ;
+
+//---------------------------- vocoder_demo -------------------------
+// Use example of the vocoder function where an impulse train is used 
+// as excitation.
+// USAGE: 
+// 		_ : vocoder_demo : _;
+
+vocoder_demo = hgroup("My Vocoder",_,impTrain(freq)*gain : vocoder(bands,att,rel,BWRatio) <: _,_) with{
+	bands = 32;
+	impTrain = component("oscillator.lib").lf_imptrain;
+	vocoderGroup(x) = vgroup("Vocoder",x);
+	att = vocoderGroup(hslider("[0] Attack [style:knob] [tooltip: Attack time in seconds]",5,0.1,100,0.1)*0.001);
+	rel = vocoderGroup(hslider("[1] Release [style:knob] [tooltip: Release time in seconds]",5,0.1,100,0.1)*0.001);
+	BWRatio = vocoderGroup(hslider("[2] BW [style:knob] [tooltip: Coefficient to adjust the bandwidth of each band]",0.5,0.1,2,0.001));
+	excitGroup(x) = vgroup("Excitation",x);
+	freq = excitGroup(hslider("[0] Freq [style:knob]",330,50,2000,0.1));
+	gain = excitGroup(vslider("[1] Gain",0.5,0,1,0.01) : smooth(0.999));
+};
+
 //------------------------- stereo_width(w) ---------------------------
 // Stereo Width effect using the Blumlein Shuffler technique.
 //
@@ -562,15 +675,16 @@ with {
 //
 // REFERENCES:
 //  Musical Engineer's Handbook, Bernie Hutchins, Ithaca NY, 1975
-//  Elecronotes Newsletter, Bernie Hutchins
+//  Electronotes Newsletter, Bernie Hutchins
 
 amp_follower(rel) = abs : env with {
  p = tau2pole(rel);
- env(x) = x * (1.0 - p) : + ~ max(x,_) * p;
+ env(x) = x * (1.0 - p) : (+ : max(x,_)) ~ *(p);
 };
 
 //--------------------------- amp_follower_ud ---------------------------
 // Envelope follower with different up and down time-constants
+// (also called a "peak detector").
 //
 // USAGE:
 //    _ : amp_follower_ud(att,rel) : _
@@ -579,10 +693,77 @@ amp_follower(rel) = abs : env with {
 //  att = attack time = amplitude-envelope time constant (sec) going up
 //  rel = release time = amplitude-envelope time constant (sec) going down
 //
-// For audio, att should be faster (smaller) than rel (e.g., 0.001 and 0.01)
+// NOTE: We assume rel >> att.  Otherwise, consider rel ~ max(rel,att).
+// For audio, att is normally faster (smaller) than rel (e.g., 0.001 and 0.01).
+// Use
+//
+//   _ : amp_follower_ar(att,rel) : _
+//
+// below to remove this restriction.
+//
+// REFERENCE:
+//   "Digital Dynamic Range Compressor Design --- A Tutorial and Analysis", by
+//   Dimitrios Giannoulis, Michael Massberg, and Joshua D. Reiss
+//   http://www.eecs.qmul.ac.uk/~josh/documents/GiannoulisMassbergReiss-dynamicrangecompression-JAES2012.pdf
 
 amp_follower_ud(att,rel) = amp_follower(rel) : smooth(tau2pole(att));
 
+// Begin contributions by Jonatan Liljedahl at http://kymatica.com
+// (in addition to his refinement of amp_follower above)
+
+/*****************************************************
+    _ : amp_follower_ar(att,rel) : _;
+
+Envelope follower with independent attack and release times. The
+release can be shorter than the attack (unlike in amp_follower_ud
+above).
+
+*****************************************************/
+
+amp_follower_ar(att,rel) = abs : lag_ud(att,rel);
+
+/*****************************************************
+    _ : lag_ud(up, dn, signal) : _;
+
+    Lag filter with separate times for up and down.
+*****************************************************/
+
+lag_ud(up,dn) = _ <: ((>,tau2pole(up),tau2pole(dn):select2),_:smooth) ~ _;
+
+/*****************************************************
+    _ : peakhold(mode,sig) : _;
+
+    Outputs current max value above zero.
+    'mode' means:
+    0 - Pass through. A single sample 0 trigger will work as a reset.
+    1 - Track and hold max value.
+*****************************************************/
+
+peakhold = (*,_:max) ~ _;
+
+/*****************************************************
+    sweep(period,run);
+
+    Counts from 0 to 'period' samples repeatedly, while 'run' is 1.
+    Outsputs zero while 'run' is 0.
+*****************************************************/
+
+sweep = %(int(*:max(1)))~+(1);
+
+/*****************************************************
+    peakholder(holdtime, sig);
+
+    Tracks abs peak and holds peak for 'holdtime' samples.
+*****************************************************/
+
+peakholder(holdtime) = peakhold2 ~ reset : (!,_) with {
+    reset = sweep(holdtime) > 0;
+    // first out is gate that is 1 while holding last peak
+    peakhold2 = _,abs <: peakhold,!,_ <: >=,_,!;
+};
+
+// End of contributions (so far) by Jonatan Liljedahl at http://kymatica.com
+
 //=============== Gates, Limiters, and Dynamic Range Compression ============
 
 //----------------- gate_mono, gate_stereo -------------------
@@ -610,17 +791,19 @@ gate_stereo(thresh,att,hold,rel,x,y) = ggm*x, ggm*y with {
   ggm = gate_gain_mono(thresh,att,hold,rel,abs(x)+abs(y));
 };
 
-gate_gain_mono(thresh,att,hold,rel,x) = extendedrawgate : amp_follower_ud(att,rel) with {
-  extendedrawgate = max(rawgatesig,holdsig);
-  rawgatesig = inlevel(x) > db2linear(thresh);
-  inlevel(x) = amp_follower_ud(att/2,rel/2,x);
-  holdsig = ((max(holdreset & holdsamps,_) ~-(1)) > 0);
-  holdreset = rawgatesig > rawgatesig'; // reset hold when raw gate falls
+gate_gain_mono(thresh,att,hold,rel,x) = x : extendedrawgate : amp_follower_ar(att,rel) with {
+  extendedrawgate(x) = max(float(rawgatesig(x)),holdsig(x));
+  rawgatesig(x) = inlevel(x) > db2linear(thresh);
+  minrate = min(att,rel);
+  inlevel = amp_follower_ar(minrate,minrate);
+  holdcounter(x) = (max(holdreset(x) * holdsamps,_) ~-(1));
+  holdsig(x) = holdcounter(x) > 0;
+  holdreset(x) = rawgatesig(x) < rawgatesig(x)'; // reset hold when raw gate falls
   holdsamps = int(hold*SR);
 };
 
 //-------------------- compressor_mono, compressor_stereo ----------------------
-// Mono and stereo dynamic range compressor_s
+// Mono and stereo dynamic range compressors
 //
 // USAGE:
 //    _ : compressor_mono(ratio,thresh,att,rel)   : _
@@ -628,8 +811,8 @@ gate_gain_mono(thresh,att,hold,rel,x) = extendedrawgate : amp_follower_ud(att,re
 //  _,_ : compressor_stereo(ratio,thresh,att,rel) : _,_
 //
 // where
-//  ratio  = compression ratio (1 = no compression, >1 means compression")
-//  thresh = dB level threshold above which compression kicks in
+//  ratio  = compression ratio (1 = no compression, >1 means compression)
+//  thresh = dB level threshold above which compression kicks in (0 dB = max level)
 //  att    = attack time = time constant (sec) when level & compression going up
 //  rel    = release time = time constant (sec) coming out of compression
 //
@@ -646,7 +829,7 @@ compressor_stereo(ratio,thresh,att,rel,x,y) = cgm*x, cgm*y with {
 };
 
 compression_gain_mono(ratio,thresh,att,rel) =
-  amp_follower_ud(att,rel) : linear2db : outminusindb(ratio,thresh) :
+  amp_follower_ar(att,rel) : linear2db : outminusindb(ratio,thresh) :
   kneesmooth(att) : db2linear
 with {
   // kneesmooth(att) installs a "knee" in the dynamic-range compression,
@@ -654,7 +837,7 @@ with {
   // A general 'knee' parameter could be used instead of tying it to att/2:
   kneesmooth(att)  = smooth(tau2pole(att/2.0));
   // compression gain in dB:
-   outminusindb(ratio,thresh,level) = max(level-thresh,0) * (1/float(ratio)-1);
+   outminusindb(ratio,thresh,level) = max(level-thresh,0.0) * (1.0/float(ratio)-1.0);
   // Note: "float(ratio)" REQUIRED when ratio is an integer > 1!
 };
 
@@ -679,14 +862,17 @@ gate_demo = bypass2(gbp,gate_stereo_demo) with {
    gatethr = knob_group(hslider("[1] Threshold [unit:dB] [style:knob]  [tooltip: When the signal level falls below the Threshold (expressed in dB), the signal is muted]",
      -30, -120, 0, 0.1));
 
-   gateatt = knob_group(hslider("[2] Attack [unit:us] [style:knob]  [tooltip: Time constant in MICROseconds (1/e smoothing time) for the gate gain to go (exponentially) from 0 (muted) to 1 (unmuted)]",
-     10, 10, 10000, 1)) : *(0.000001) : max(1/SR);
+   gateatt = knob_group(hslider("[2] Attack [unit:us] [style:knob] [scale:log]
+     [tooltip: Time constant in MICROseconds (1/e smoothing time) for the gate gain to go (exponentially) from 0 (muted) to 1 (unmuted)]",
+     10, 10, 10000, 1)) : *(0.000001) : max(1.0/float(SR));
 
-   gatehold = knob_group(hslider("[3] Hold [unit:ms] [style:knob]  [tooltip: Time in ms to keep the gate open (no muting) after the signal level falls below the Threshold]",
-     200, 0, 1000, 1)) : *(0.001) : max(1/SR);
+   gatehold = knob_group(hslider("[3] Hold [unit:ms] [style:knob] [scale:log]
+     [tooltip: Time in ms to keep the gate open (no muting) after the signal level falls below the Threshold]",
+     200, 1, 1000, 1)) : *(0.001) : max(1.0/float(SR));
 
-   gaterel = knob_group(hslider("[4] Release [unit:ms] [style:knob]  [tooltip: Time constant in ms (1/e smoothing time) for the gain to go (exponentially) from 1 (unmuted) to 0 (muted)]",
-     100, 0, 1000, 1)) : *(0.001) : max(1/SR);
+   gaterel = knob_group(hslider("[4] Release [unit:ms] [style:knob] [scale:log]
+     [tooltip: Time constant in ms (1/e smoothing time) for the gain to go (exponentially) from 1 (unmuted) to 0 (muted)]",
+     100, 1, 1000, 1)) : *(0.001) : max(1.0/float(SR));
 };
 
 //---------------------------- compressor_demo -------------------------
@@ -714,21 +900,26 @@ compressor_demo = bypass2(cbp,compressor_stereo_demo) with {
 
    ctl_group(x)  = knob_group(hgroup("[3] Compression Control", x));
 
-   ratio = ctl_group(hslider("[0] Ratio [style:knob]  [tooltip: A compression Ratio of N means that for each N dB increase in input signal level above Threshold, the output level goes up 1 dB]",
+   ratio = ctl_group(hslider("[0] Ratio [style:knob]
+     [tooltip: A compression Ratio of N means that for each N dB increase in input signal level above Threshold, the output level goes up 1 dB]",
      5, 1, 20, 0.1));
 
-   threshold = ctl_group(hslider("[1] Threshold [unit:dB] [style:knob]  [tooltip: When the signal level exceeds the Threshold (in dB), its level is compressed according to the Ratio]",
+   threshold = ctl_group(hslider("[1] Threshold [unit:dB] [style:knob]
+     [tooltip: When the signal level exceeds the Threshold (in dB), its level is compressed according to the Ratio]",
      -30, -100, 10, 0.1));
 
    env_group(x)  = knob_group(hgroup("[4] Compression Response", x));
 
-   attack = env_group(hslider("[1] Attack [unit:ms] [style:knob]  [tooltip: Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new lower target level (the compression `kicking in')]",
-     50, 0, 500, 0.1)) : *(0.001) : max(1/SR);
+   attack = env_group(hslider("[1] Attack [unit:ms] [style:knob] [scale:log]
+     [tooltip: Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new lower target level (the compression `kicking in')]",
+     50, 1, 1000, 0.1)) : *(0.001) : max(1/SR);
 
-   release = env_group(hslider("[2] Release [unit:ms] [style: knob]  [tooltip: Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new higher target level (the compression 'releasing')]",
-     500, 0, 1000, 0.1)) : *(0.001) : max(1/SR);
+   release = env_group(hslider("[2] Release [unit:ms] [style: knob] [scale:log]
+     [tooltip: Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new higher target level (the compression 'releasing')]",
+     500, 1, 1000, 0.1)) : *(0.001) : max(1/SR);
 
-   makeupgain = comp_group(hslider("[5] Makeup Gain [unit:dB]  [tooltip: The compressed-signal output level is increased by this amount (in dB) to make up for the level lost due to compression]",
+   makeupgain = comp_group(hslider("[5] Makeup Gain [unit:dB]
+     [tooltip: The compressed-signal output level is increased by this amount (in dB) to make up for the level lost due to compression]",
      40, -96, 96, 0.1)) : db2linear;
 };
 
@@ -778,7 +969,7 @@ limiter_1176_R4_stereo = compressor_stereo(4,-6,0.0008,0.5);
 // John Chowning thinks this might be the one that became the
 // well known and often copied JCREV:
 
-jcrev = *(0.06) : allpass_chain <: comb_bank :> _ <: mix_mtx with {
+jcrev = *(0.06) : allpass_chain <: comb_bank : mix_mtx with {
 
   rev1N = component("filter.lib").rev1;
 
@@ -829,9 +1020,66 @@ satrev = *(0.2) <: comb_bank :> allpass_chain <: _,*(-1) with {
     rev2N( 16, 12,0.7);
 };
 
-//-------------------------------- freeverb --------------------------------
-// Freeverb is a widely used, free, open-source Schroeder reverb contributed
-// by ``Jezar at Dreampoint.'' See <faust_distribution>/examples/freeverb.dsp
+//---------------------------- mono_freeverb, stereo_freeverb -------------------------
+// A simple Schroeder reverberator primarily developed by "Jezar at Dreampoint" that 
+// is extensively used in the free-software world. It uses four Schroeder allpasses in 
+// series and eight parallel Schroeder-Moorer filtered-feedback comb-filters for each 
+//audio channel, and is said to be especially well tuned. 
+//
+// USAGE: 
+// 		_ : mono_freeverb(fb1, fb2, damp, spread) : _;
+// or
+// 		_,_ : stereo_freeverb(fb1, fb2, damp, spread) : _,_;
+//
+// where
+// fb1 = coefficient of the lowpass comb filters (0-1)
+// fb2 = coefficient of the allpass comb filters (0-1)
+// damp = damping of the lowpass comb filter (0-1)
+// spread = spatial spread in number of samples (for stereo)
+
+mono_freeverb(fb1, fb2, damp, spread) = _ <: par(i,8,lbcf(combtuningL(i)+spread,fb1,damp)) :> seq(i,4,allpass_comb(1024, allpasstuningL(i)+spread, -fb2))
+with{
+	origSR = 44100;
+	
+	// Filters parameters 
+	combtuningL(0) = 1116*SR/origSR : int;
+	combtuningL(1) = 1188*SR/origSR : int;
+	combtuningL(2) = 1277*SR/origSR : int;
+	combtuningL(3) = 1356*SR/origSR : int;
+	combtuningL(4) = 1422*SR/origSR : int;
+	combtuningL(5) = 1491*SR/origSR : int;
+	combtuningL(6) = 1557*SR/origSR : int;
+	combtuningL(7) = 1617*SR/origSR : int;
+
+	allpasstuningL(0) = 556*SR/origSR : int;
+	allpasstuningL(1) = 441*SR/origSR : int;
+	allpasstuningL(2) = 341*SR/origSR : int;
+	allpasstuningL(3) = 225*SR/origSR : int;
+	// Lowpass Feedback Combfiler: 
+	// https://ccrma.stanford.edu/~jos/pasp/Lowpass_Feedback_Comb_Filter.html
+	lbcf(dt, fb, damp) = (+:@(dt)) ~ (*(1-damp) : (+ ~ *(damp)) : *(fb));
+};
+
+stereo_freeverb(fb1, fb2, damp, spread) =  + <: mono_freeverb(fb1, fb2, damp,0), mono_freeverb(fb1, fb2, damp, spread);
+
+//---------------------------- freeverb_demo -------------------------
+// USAGE: _,_ : freeverb_demo : _,_;
+//
+
+freeverb_demo = _,_ <: (*(g)*fixedgain,*(g)*fixedgain : stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)), *(1-g), *(1-g) :> _,_ with{
+	scaleroom   = 0.28;
+	offsetroom  = 0.7;
+	allpassfeed = 0.5;
+	scaledamp   = 0.4;
+	fixedgain   = 0.1;
+	origSR = 44100;
+	parameters(x) = hgroup("Freeverb",x);
+	knobGroup(x) = parameters(vgroup("[0]",x));
+	damping = knobGroup(vslider("[0] Damp [style: knob] [tooltip: Somehow control the density of the reverb.]",0.5, 0, 1, 0.025)*scaledamp*origSR/SR);
+	combfeed = knobGroup(vslider("[1] RoomSize [style: knob] [tooltip: The room size between 0 and 1 with 1 for the largest room.]", 0.5, 0, 1, 0.025)*scaleroom*origSR/SR + offsetroom);
+	spatSpread = knobGroup(vslider("[2] Stereo Spread [style: knob] [tooltip: Spatial spread between 0 and 1 with 1 for maximum spread.]",0.5,0,1,0.01)*46*SR/origSR : int);
+	g = parameters(vslider("[1] Wet [tooltip: The amount of reverb applied to the signal between 0 and 1 with 1 for the maximum amount of reverb.]", 0.3333, 0, 1, 0.025));
+};
 
 //=============== Feedback Delay Network (FDN) Reverberators  ==============
 
@@ -985,7 +1233,7 @@ with {
   t60_group(x)  = fdn_group(hgroup("[2] Band Decay Times (T60)", x));
   path_group(x)  = fdn_group(vgroup("[3] Room Dimensions", x));
   revin_group(x)  = fdn_group(hgroup("[4] Input Controls", x));
-  nonl_group(x) = revin_group(vgroup("[4] Nonnlinearity",x));
+  nonl_group(x) = revin_group(vgroup("[4] Nonlinearity",x));
   quench_group(x) = revin_group(vgroup("[3] Reverb State",x));
 
   nonl = nonl_group(hslider("[style:knob] [tooltip: nonlinear mode coupling]",
@@ -993,21 +1241,21 @@ with {
   loopgainmax = 1.0-0.5*quench_group(button("[1] Quench
          [tooltip: Hold down 'Quench' to clear the reverberator]"));
 
-  pathmin = path_group(hslider("[1] min acoustic ray length [unit:m]
+  pathmin = path_group(hslider("[1] min acoustic ray length [unit:m] [scale:log]
     [tooltip: This length (in meters) determines the shortest delay-line used in the FDN reverberator.
     	      Think of it as the shortest wall-to-wall separation in the room.]",
 	    46, 0.1, 63, 0.1));
-  pathmax = path_group(hslider("[2] max acoustic ray length [unit:m]
+  pathmax = path_group(hslider("[2] max acoustic ray length [unit:m] [scale:log]
     [tooltip: This length (in meters) determines the longest delay-line used in the FDN reverberator.
     	      Think of it as the largest wall-to-wall separation in the room.]",
 	    63, 0.1, 63, 0.1));
 
-  durvals(i) = t60_group(vslider("[%i] %i [unit:s]
+  durvals(i) = t60_group(vslider("[%i] %i [unit:s] [scale:log]
     [tooltip: T60 is the 60dB decay-time in seconds. For concert halls, an overall reverberation time (T60) near 1.9 seconds is typical [Beranek 2004]. Here we may set T60 independently in each frequency band.  In real rooms, higher frequency bands generally decay faster due to absorption and scattering.]",
-    take(i+1,defdurs), 0.1, 10, 0.1));
+    take(i+1,defdurs), 0.1, 100, 0.1));
   durs = par(i,NB,durvals(NB-1-i));
 
-  freqvals(i) = freq_group(hslider("[%i] Band %i upper edge in Hz [unit:Hz]
+  freqvals(i) = freq_group(hslider("[%i] Band %i upper edge in Hz [unit:Hz] [scale:log]
     [tooltip: Each delay-line signal is split into frequency-bands for separate decay-time control in each band]",
     take(i+1,deffreqs), 100, 10000, 1));
   freqs = par(i,NB-1,freqvals(i));
@@ -1126,13 +1374,13 @@ with {
     [style:knob]
     [tooltip: T60 = time (in seconds) to decay 60dB in low-frequency band]",
     3, 1, 8, 0.1));
-  f1 = fdn_group(vslider("[2] LF X [unit:Hz] [style:knob]
+  f1 = fdn_group(vslider("[2] LF X [unit:Hz] [style:knob] [scale:log]
     [tooltip: Crossover frequency (Hz) separating low and middle frequencies]",
     200, 50, 1000, 1));
-  t60m = fdn_group(vslider("[3] Mid RT60 [unit:s] [style:knob]
+  t60m = fdn_group(vslider("[3] Mid RT60 [unit:s] [style:knob] [scale:log]
     [tooltip: T60 = time (in seconds) to decay 60dB in middle band]",
     2, 1, 8, 0.1));
-  f2 = fdn_group(vslider("[4] HF Damping [unit:Hz] [style:knob]
+  f2 = fdn_group(vslider("[4] HF Damping [unit:Hz] [style:knob] [scale:log]
     [tooltip: Frequency (Hz) at which the high-frequency T60 is half the middle-band's T60]",
     6000, 1500, 0.49*fsmax, 1));
 };
@@ -1214,19 +1462,19 @@ with {
 
   freq_group(x) = fdn_group(hgroup("[2] Decay Times in Bands (see tooltips)", x));
 
-  f1 = freq_group(vslider("[1] LF X [unit:Hz] [style:knob]
+  f1 = freq_group(vslider("[1] LF X [unit:Hz] [style:knob] [scale:log]
        [tooltip: Crossover frequency (Hz) separating low and middle frequencies]",
        200, 50, 1000, 1));
 
-  t60dc = freq_group(vslider("[2] Low RT60 [unit:s] [style:knob]
+  t60dc = freq_group(vslider("[2] Low RT60 [unit:s] [style:knob] [scale:log]
           [style:knob] [tooltip: T60 = time (in seconds) to decay 60dB in low-frequency band]",
 	  3, 1, 8, 0.1));
 
-  t60m = freq_group(vslider("[3] Mid RT60 [unit:s] [style:knob]
+  t60m = freq_group(vslider("[3] Mid RT60 [unit:s] [style:knob] [scale:log]
           [tooltip: T60 = time (in seconds) to decay 60dB in middle band]",
 	  2, 1, 8, 0.1));
 
-  f2 = freq_group(vslider("[4] HF Damping [unit:Hz] [style:knob]
+  f2 = freq_group(vslider("[4] HF Damping [unit:Hz] [style:knob] [scale:log]
        [tooltip: Frequency (Hz) at which the high-frequency T60 is half the middle-band's T60]",
        6000, 1500, 0.49*fsmax, 1));
 
@@ -1243,7 +1491,7 @@ with {
 
   eq1_group(x) = fdn_group(hgroup("[3] RM Peaking Equalizer 1", x));
 
-  eq1f = eq1_group(vslider("[1] Eq1 Freq [unit:Hz] [style:knob]
+  eq1f = eq1_group(vslider("[1] Eq1 Freq [unit:Hz] [style:knob] [scale:log]
        [tooltip: Center-frequency of second-order Regalia-Mitra peaking equalizer section 1]",
        315, 40, 2500, 1));
 
@@ -1257,9 +1505,9 @@ with {
 
   eq2_group(x) = fdn_group(hgroup("[4] RM Peaking Equalizer 2", x));
 
-  eq2f = eq2_group(vslider("[1] Eq2 Freq [unit:Hz] [style:knob]
+  eq2f = eq2_group(vslider("[1] Eq2 Freq [unit:Hz] [style:knob] [scale:log]
        [tooltip: Center-frequency of second-order Regalia-Mitra peaking equalizer section 2]",
-       315, 40, 2500, 1));
+       1500, 160, 10000, 1));
 
   eq2l = eq2_group(vslider("[2] Eq2 Level [unit:dB] [style:knob]
        [tooltip: Peak level in dB of second-order Regalia-Mitra peaking equalizer section 2]",
@@ -1284,7 +1532,7 @@ with {
 
   gain = out_group(vslider("[2] Level [unit:dB] [style:knob]
     [tooltip: Output scale factor]", -20, -70, 40, 0.1))
-    : smooth(0.999) : db2linear;
+    : db2linear : smooth(0.999);
 
 };
 
diff --git a/architecture/faust/au/AUUI.h b/architecture/faust/au/AUUI.h
new file mode 100644
index 0000000..17f1e75
--- /dev/null
+++ b/architecture/faust/au/AUUI.h
@@ -0,0 +1,449 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Audio Unit UI
+ Copyright (C) 2013 Reza Payami
+ All rights reserved.
+ ----------------------------BSD License------------------------------
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Remy Muller nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ ----------------------------Audio Unit SDK----------------------------------
+ In order to compile a AU (TM) Synth plugin with this architecture file
+ you will need the proprietary AU SDK from Apple. Please check
+ the corresponding license.
+ 
+ ************************************************************************/
+#include <set>
+
+#include "faust/gui/UI.h"
+
+using namespace std;
+
+class auUI;
+
+class auUIObject {
+public:
+	string fLabel;
+	float* fZone;
+    
+	float range(float min, float max, float val) { // AU parameters are normalized in the range [0;1]
+		val = min + val * (max - min);
+		return (val < min) ? min : (val > max) ? max : val;
+	}
+    
+public:
+	auUIObject(const char* label, FAUSTFLOAT* zone) :
+    fLabel(label), fZone(zone) {
+	}
+    
+	virtual ~auUIObject() {
+	}
+    
+	virtual void GetName(char *text) {
+		std::strcpy(text, fLabel.c_str());
+	}
+    
+	virtual void SetValue(double f) {
+		*fZone = range(0.0f, 1.0f, (float) f);
+	}
+    
+	virtual float GetValue() {
+		return *fZone;
+	}
+    
+	virtual void GetDisplay(char *text) {
+		std::sprintf(text, "%f", *fZone);
+	}
+    
+	virtual long GetID() { /* returns the sum of all the ASCII characters  contained in the parameter's label */
+		int i;
+		long acc;
+		for (i = 0, acc = 0; i < fLabel.length(); i++)
+			acc += (fLabel.c_str())[i];
+		return acc;
+	}
+};
+
+/**********************************************************************************/
+class auToggleButton: public auUIObject {
+    
+public:
+    
+	auToggleButton(const char* label, FAUSTFLOAT* zone) :
+    auUIObject(label, zone) {
+	}
+    
+	virtual ~auToggleButton() {
+	}
+    
+	virtual float GetValue() {
+		return *fZone;
+	}
+    
+	virtual void SetValue(double f) {
+		*fZone = (f > 0.5f) ? 1.0f : 0.0f;
+	}
+    
+	virtual void GetDisplay(char *text) {
+		(*fZone > 0.5f) ? std::strcpy(text, "ON") : std::strcpy(text, "OFF");
+	}
+};
+
+/**********************************************************************************/
+class auCheckButton: public auUIObject {
+    
+public:
+    
+	auCheckButton(const char* label, FAUSTFLOAT* zone) :
+    auUIObject(label, zone) {
+	}
+    
+	virtual ~auCheckButton() {
+	}
+    
+	virtual float GetValue() {
+		return *fZone;
+	}
+    
+	virtual void SetValue(double f) {
+		*fZone = (f > 0.5f) ? 1.0f : 0.0f;
+	}
+    
+	virtual void GetDisplay(char *text) {
+		(*fZone > 0.5f) ? std::strcpy(text, "ON") : std::strcpy(text, "OFF");
+	}
+};
+
+/**********************************************************************************/
+class auButton: public auUIObject {
+    
+public:
+    
+	auButton(const char* label, FAUSTFLOAT* zone) :
+    auUIObject(label, zone) {
+	}
+    
+	virtual ~auButton() {
+	}
+    
+	virtual float GetValue() {
+		return *fZone;
+	}
+    
+	virtual void SetValue(double f) {
+		*fZone = (f > 0.5f) ? 1.0f : 0.0f;
+	}
+    
+	virtual void GetDisplay(char *text) {
+		(*fZone > 0.5f) ? std::strcpy(text, "ON") : std::strcpy(text, "OFF");
+	}
+};
+
+/**********************************************************************************/
+class auSlider: public auUIObject {
+    
+public:
+	float fInit;
+	float fMin;
+	float fMax;
+	float fStep;
+    bool fIsVertical;
+    
+public:
+    
+	auSlider(const char* label, FAUSTFLOAT* zone, float init, float min, float max,
+             float step, bool isVertical) :
+    auUIObject(label, zone), fInit(init), fMin(min), fMax(max), fStep(step), fIsVertical(isVertical) {
+	}
+    
+	virtual ~auSlider() {
+	}
+    
+	virtual float GetValue() {
+		return (*fZone - fMin) / (fMax - fMin);
+	}	// normalize
+    
+	virtual void SetValue(double f) {
+		*fZone = range(fMin, fMax, (float) f);
+	} // expand
+};
+
+
+/**********************************************************************************/
+
+
+class auBargraph: public auUIObject {
+    
+public:
+	float fInit;
+	float fMin;
+	float fMax;
+	float fStep;
+    bool fIsVertical;
+    
+public:
+    
+	auBargraph(const char* label, FAUSTFLOAT* zone, float min, float max, bool isVertical) :
+    auUIObject(label, zone), fMin(min), fMax(max), fIsVertical(isVertical){
+	}
+    
+	virtual ~auBargraph() {
+	}
+    
+	virtual float GetValue() {
+		return (*fZone - fMin) / (fMax - fMin);
+	}	// normalize
+    
+	virtual void SetValue(double f) {
+		*fZone = range(fMin, fMax, (float) f);
+	} // expand
+};
+
+/**********************************************************************************/
+
+class auBox: public auUIObject {
+    
+public:
+	vector<auUIObject*> children;
+    bool isVertical;
+    auBox* parent;
+    
+public:
+    
+	auBox(const char* label, auBox* inParent, bool inIsVertical) :
+    auUIObject(label, NULL), parent(inParent), isVertical(inIsVertical) {
+	}
+    
+    void add(auUIObject* child) {
+        children.push_back(child);
+    }
+    
+	virtual ~auBox() {
+	}
+    
+};
+
+
+/**********************************************************************************/
+//eunum Direction {HORIZONTAL, VERTICAL}; //TODO
+
+class auUI: public UI {
+public:
+    
+	vector<auUIObject*> fUITable;
+    std::set <float*>knobSet;
+    
+    auBox* currentBox = NULL;
+    auBox* boundingBox = NULL;
+    
+public:
+    
+	auUI() {
+        currentBox = boundingBox = new auBox("", NULL, true);
+	}
+    
+	virtual ~auUI() {
+		for (vector<auUIObject*>::iterator iter = fUITable.begin();
+             iter != fUITable.end(); iter++)
+			delete *iter;
+        //TODO delete boxes
+	}
+    
+    
+    virtual void declare(float* zone, const char* key, const char* value)
+    {
+		if (zone == 0)
+        {
+            if (strcmp(key, "hidden") == 0)
+            {
+
+            }
+		}
+        else
+        {
+			if (strcmp(key,"size") == 0)
+            {
+			}
+			else if (strcmp(key,"tooltip") == 0)
+            {
+			}
+			else if (strcmp(key,"unit") == 0)
+            {
+			}
+            if (strcmp(key,"hidden") == 0)
+            {
+
+            }
+			else if (strcmp(key,"style") == 0)
+            {
+				if (strstr(value, "knob")) //TODO
+                {
+					
+                    knobSet.insert(zone);
+				}
+			}
+            else if (strcmp(key,"color") == 0)
+            {
+            }
+            else if (strcmp(key,"accx") == 0
+                     || strcmp(key,"accy") == 0
+                     || strcmp(key,"accz") == 0
+                     || strcmp(key,"gyrox") == 0
+                     || strcmp(key,"gyroy") == 0
+                     || strcmp(key,"gyroz") == 0
+                     || strcmp(key,"compass") == 0)
+            {
+            }
+            
+		}
+	}
+    
+    
+    void addButton(const char* label, FAUSTFLOAT* zone) {
+        auButton* button = new auButton(label, zone);
+        fUITable.push_back(button);
+        currentBox->add(button);
+    }
+    
+    void openTabBox(const char* label) {
+        
+    }
+    
+    void addCheckButton(const char* label, FAUSTFLOAT* zone) {
+        auCheckButton* checkButton= new auCheckButton(label, zone);
+        fUITable.push_back(checkButton);
+        currentBox->add(checkButton);
+    }
+    
+    void addVerticalSlider(const char* label, FAUSTFLOAT* zone, float init, float min,
+                           float max, float step) {
+        auSlider* slider = new auSlider(label, zone, init, min, max, step, true);
+        fUITable.push_back(slider);
+        currentBox->add(slider);
+    }
+    
+    void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, float init, float min,
+                             float max, float step) {
+        auSlider* slider = new auSlider(label, zone, init, min, max, step, false);
+        fUITable.push_back(slider);
+        currentBox->add(slider);
+    }
+    
+    void addNumEntry(const char* label, FAUSTFLOAT* zone, float init, float min, float max,
+                     float step) {
+        auSlider* slider = new auSlider(label, zone, init, min, max, step, false);
+        fUITable.push_back(slider);
+        currentBox->add(slider);
+    }
+    
+    void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, float min, float max) {
+        auBargraph* bargraph = new auBargraph(label, zone, min, max, false);
+        fUITable.push_back(bargraph);
+        currentBox->add(bargraph);
+    }
+    
+    void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, float min, float max) {
+        auBargraph* bargraph = new auBargraph(label, zone, min, max, true);
+        fUITable.push_back(bargraph);
+        currentBox->add(bargraph);
+    }
+    
+    void openHorizontalBox(const char* label) {
+        auBox* box = new auBox(label, currentBox, false);
+        currentBox->add(box);
+        currentBox = box;
+    }
+    
+    void openVerticalBox(const char* label) {
+        auBox* box = new auBox(label, currentBox, true);
+        currentBox->add(box);
+        currentBox = box;
+    }
+    
+    void closeBox() {
+        if (currentBox) //TODO else?
+            currentBox = currentBox->parent;
+    }
+    
+    void SetValue(int index, double f) {
+        assert(index < fUITable.size());
+        fUITable[index]->SetValue(f);
+    }
+    
+    float GetValue(long index) {
+        assert(index < fUITable.size());
+        return fUITable[index]->GetValue();
+    }
+    
+    void GetDisplay(long index, char *text) {
+        assert(index < fUITable.size());
+        fUITable[index]->GetDisplay(text);
+    }
+    
+    void GetName(long index, char *text) {
+        assert(index < fUITable.size());
+        fUITable[index]->GetName(text);
+    }
+    
+    long GetNumParams() {
+        return fUITable.size();
+    }
+    
+    long makeID()
+    /* Creates a (unique) id by summing all the parameter's labels,
+     * then wrapping it in the range [0;maxNumberOfId] and adding
+     * this number to the offset made by the Four Character ID: 'FAUS'
+     */
+    {
+        const long maxNumberOfId = 128;
+        long baseid = 'FAUS';
+        long id = 0;
+        for (int i = 0; i < fUITable.size(); i++)
+            id += fUITable[i]->GetID();
+        return baseid + id % maxNumberOfId;
+    }
+    
+    void addNumDisplay(char* label, float* zone, int precision) {
+    }
+    
+    void addTextDisplay(char* label, float* zone, char* names[], float min,
+                        float max) {
+    }
+    
+    
+};
+
+
diff --git a/architecture/faust/audio/alsa-dsp.h b/architecture/faust/audio/alsa-dsp.h
new file mode 100644
index 0000000..b31bad5
--- /dev/null
+++ b/architecture/faust/audio/alsa-dsp.h
@@ -0,0 +1,723 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __alsa_dsp__
+#define __alsa_dsp__
+
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <limits.h>
+
+#include <alsa/asoundlib.h>
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp.h"
+
+/**
+DEFAULT ALSA PARAMETERS CONTROLLED BY ENVIRONMENT VARIABLES
+
+Some default parameters of Faust's ALSA applications are controlled by the following environment variables :
+
+    FAUST2ALSA_DEVICE   = "hw:0"
+    FAUST2ALSA_FREQUENCY= 44100
+    FAUST2ALSA_BUFFER   = 512
+    FAUST2ALSA_PERIODS  = 2
+
+*/
+
+//using namespace std;
+
+// handle 32/64 bits int size issues
+
+#ifdef __x86_64__
+
+#define uint32	unsigned int
+#define uint64	unsigned long int
+
+#define int32	int
+#define int64	long int
+
+#else
+
+#define uint32	unsigned int
+#define uint64	unsigned long long int
+
+#define int32	int
+#define int64	long long int
+#endif
+
+// check 32/64 bits issues are correctly handled
+
+#define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); }
+#define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); }
+#define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); }
+
+
+/**
+ * Used to set the priority and scheduling of the audi#include <sys/types.h>
+       #include <pwd.h>
+o thread
+ */
+static bool setRealtimePriority ()
+{
+    struct passwd *         pw;
+    int                     err;
+    uid_t                   uid;
+    struct sched_param      param;
+
+    uid = getuid ();
+    pw = getpwnam ("root");
+    setuid (pw->pw_uid);
+    param.sched_priority = 50; /* 0 to 99  */
+    err = sched_setscheduler(0, SCHED_RR, &param);
+    setuid (uid);
+    return (err != -1);
+}
+
+/******************************************************************************
+*******************************************************************************
+
+								AUDIO INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+enum { kRead = 1, kWrite = 2, kReadWrite = 3 };
+
+/**
+ * A convenient class to pass parameters to AudioInterface
+ */
+class AudioParam
+{
+  public:
+
+	const char*		fCardName;
+	unsigned int	fFrequency;
+	unsigned int	fBuffering;
+	unsigned int	fPeriods;
+
+	unsigned int	fSoftInputs;
+	unsigned int	fSoftOutputs;
+
+  public :
+	AudioParam() :
+		fCardName("hw:0"),
+		fFrequency(44100),
+		fBuffering(512),
+		fPeriods(2),
+		fSoftInputs(2),
+		fSoftOutputs(2)
+	{}
+
+	AudioParam&	cardName(const char* n)	{ fCardName = n; 		return *this; }
+	AudioParam&	frequency(int f)		{ fFrequency = f; 		return *this; }
+	AudioParam&	buffering(int fpb)		{ fBuffering = fpb; 	return *this; }
+	AudioParam&	periods(int p)			{ fPeriods = p; 		return *this; }
+	AudioParam&	inputs(int n)			{ fSoftInputs = n; 		return *this; }
+	AudioParam&	outputs(int n)			{ fSoftOutputs = n; 	return *this; }
+};
+
+/**
+ * An ALSA audio interface
+ */
+class AudioInterface : public AudioParam
+{
+ public :
+	snd_pcm_t*				fOutputDevice ;
+	snd_pcm_t*				fInputDevice ;
+	snd_pcm_hw_params_t* 	fInputParams;
+	snd_pcm_hw_params_t* 	fOutputParams;
+
+	snd_pcm_format_t 		fSampleFormat;
+	snd_pcm_access_t 		fSampleAccess;
+
+	unsigned int			fCardInputs;
+	unsigned int			fCardOutputs;
+
+	unsigned int			fChanInputs;
+	unsigned int			fChanOutputs;
+
+	bool					fDuplexMode;
+
+	// interleaved mode audiocard buffers
+	void*		fInputCardBuffer;
+	void*		fOutputCardBuffer;
+
+	// non interleaved mode audiocard buffers
+	void*		fInputCardChannels[256];
+	void*		fOutputCardChannels[256];
+
+	// non interleaved mod, floating point software buffers
+	float*		fInputSoftChannels[256];
+	float*		fOutputSoftChannels[256];
+
+ public :
+
+	const char*	cardName()				{ return fCardName;  	}
+ 	int			frequency()				{ return fFrequency; 	}
+	int			buffering()				{ return fBuffering;  	}
+	int			periods()				{ return fPeriods;  	}
+
+	float**		inputSoftChannels()		{ return fInputSoftChannels;	}
+	float**		outputSoftChannels()	{ return fOutputSoftChannels;	}
+
+	bool		duplexMode()			{ return fDuplexMode; }
+
+	AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap)
+	{
+
+		fInputDevice 			= 0;
+		fOutputDevice 			= 0;
+		fInputParams			= 0;
+		fOutputParams			= 0;
+	}
+
+	/**
+	 * Open the audio interface
+	 */
+	void open()
+	{
+		int err;
+
+		// try to open output device, quit if fail to open output device
+		err = snd_pcm_open( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ); check_error(err)
+
+		// setup output device parameters
+		err = snd_pcm_hw_params_malloc	( &fOutputParams ); 		check_error(err)
+		setAudioParams(fOutputDevice, fOutputParams);
+
+		fCardOutputs = fSoftOutputs;
+		snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
+		err = snd_pcm_hw_params (fOutputDevice, fOutputParams );	check_error(err);
+
+		// allocate alsa output buffers
+		if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
+			fOutputCardBuffer = calloc(interleavedBufferSize(fOutputParams), 1);
+		} else {
+			for (unsigned int i = 0; i < fCardOutputs; i++) {
+				fOutputCardChannels[i] = calloc(noninterleavedBufferSize(fOutputParams), 1);
+			}
+        }
+
+		// check for duplex mode (if we need and have an input device)
+		if (fSoftInputs == 0) {
+			fDuplexMode = false;
+			fCardInputs = 0;
+		} else {
+			// try to open input device
+			err = snd_pcm_open( &fInputDevice,  fCardName, SND_PCM_STREAM_CAPTURE, 0 );
+			if (err == 0) {
+				fDuplexMode = true;
+			} else {
+				printf("Warning : no input device");
+				fDuplexMode = false;
+				fCardInputs = 0;
+			}
+		}
+
+		if (fDuplexMode) {
+
+			// we have and need an input device
+			// set the number of physical inputs close to what we need
+			err = snd_pcm_hw_params_malloc	( &fInputParams ); 	check_error(err);
+			setAudioParams(fInputDevice, fInputParams);
+			fCardInputs 	= fSoftInputs;
+			snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
+			err = snd_pcm_hw_params (fInputDevice,  fInputParams );	 	check_error(err);
+
+			// allocation of alsa buffers
+			if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
+				fInputCardBuffer = calloc(interleavedBufferSize(fInputParams), 1);
+			} else {
+				for (unsigned int i = 0; i < fCardInputs; i++) {
+					fInputCardChannels[i] = calloc(noninterleavedBufferSize(fInputParams), 1);
+				}
+			}
+        }
+
+		printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs);
+
+		// allocation of floating point buffers needed by the dsp code
+
+		fChanInputs = max(fSoftInputs, fCardInputs);		assert (fChanInputs < 256);
+		fChanOutputs = max(fSoftOutputs, fCardOutputs);		assert (fChanOutputs < 256);
+
+		for (unsigned int i = 0; i < fChanInputs; i++) {
+			fInputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float));
+			for (unsigned int j = 0; j < fBuffering; j++) {
+				fInputSoftChannels[i][j] = 0.0;
+			}
+		}
+
+		for (unsigned int i = 0; i < fChanOutputs; i++) {
+			fOutputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float));
+			for (unsigned int j = 0; j < fBuffering; j++) {
+				fOutputSoftChannels[i][j] = 0.0;
+			}
+		}
+	}
+
+	void setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params)
+	{
+		int	err;
+
+		// set params record with initial values
+		err = snd_pcm_hw_params_any	( stream, params );
+		check_error_msg(err, "unable to init parameters")
+
+		// set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
+
+		err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
+		if (err) {
+			err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED );
+			check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved");
+		}
+		snd_pcm_hw_params_get_access(params, &fSampleAccess);
+
+		// search for 32-bits or 16-bits format
+		err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32);
+		if (err) {
+			err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16);
+		 	check_error_msg(err, "unable to set format to either 32-bits or 16-bits");
+		}
+		snd_pcm_hw_params_get_format(params, &fSampleFormat);
+		// set sample frequency
+		snd_pcm_hw_params_set_rate_near (stream, params, &fFrequency, 0);
+
+		// set period and period size (buffering)
+		err = snd_pcm_hw_params_set_period_size	(stream, params, fBuffering, 0);
+		check_error_msg(err, "period size not available");
+
+		err = snd_pcm_hw_params_set_periods (stream, params, fPeriods, 0);
+		check_error_msg(err, "number of periods not available");
+	}
+
+	ssize_t interleavedBufferSize (snd_pcm_hw_params_t* params)
+	{
+		_snd_pcm_format 	format;  	snd_pcm_hw_params_get_format(params, &format);
+		snd_pcm_uframes_t 	psize;		snd_pcm_hw_params_get_period_size(params, &psize, NULL);
+		unsigned int 		channels; 	snd_pcm_hw_params_get_channels(params, &channels);
+		ssize_t bsize = snd_pcm_format_size (format, psize * channels);
+		return bsize;
+	}
+
+	ssize_t noninterleavedBufferSize (snd_pcm_hw_params_t* params)
+	{
+		_snd_pcm_format 	format;  	snd_pcm_hw_params_get_format(params, &format);
+		snd_pcm_uframes_t 	psize;		snd_pcm_hw_params_get_period_size(params, &psize, NULL);
+		ssize_t bsize = snd_pcm_format_size (format, psize);
+		return bsize;
+	}
+
+	void close()
+	{}
+
+	/**
+	 * Read audio samples from the audio card. Convert samples to floats and take
+	 * care of interleaved buffers
+	 */
+	void read()
+	{
+        if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
+
+			int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering);
+			if (count < 0) {
+				 //display_error_msg(count, "reading samples");
+				 snd_pcm_prepare(fInputDevice);
+				 //check_error_msg(err, "preparing input stream");
+			}
+
+			if (fSampleFormat == SND_PCM_FORMAT_S16) {
+
+				short* buffer16b = (short*)fInputCardBuffer;
+				for (unsigned int s = 0; s < fBuffering; s++) {
+					for (unsigned int c = 0; c < fCardInputs; c++) {
+						fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX));
+					}
+				}
+
+			} else if (fSampleFormat == SND_PCM_FORMAT_S32) {
+
+				int32* buffer32b = (int32*)fInputCardBuffer;
+				for (unsigned int s = 0; s < fBuffering; s++) {
+					for (unsigned int c = 0; c < fCardInputs; c++) {
+						fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(INT_MAX));
+					}
+				}
+			} else {
+
+				printf("unrecognized input sample format : %u\n", fSampleFormat);
+				exit(1);
+			}
+
+		} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
+
+			int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering);
+			if (count < 0) {
+				 //display_error_msg(count, "reading samples");
+				 snd_pcm_prepare(fInputDevice);
+				 //check_error_msg(err, "preparing input stream");
+			}
+
+			if (fSampleFormat == SND_PCM_FORMAT_S16) {
+
+				for (unsigned int c = 0; c < fCardInputs; c++) {
+					short* chan16b = (short*)fInputCardChannels[c];
+					for (unsigned int s = 0; s < fBuffering; s++) {
+						fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX));
+					}
+				}
+
+			} else if (fSampleFormat == SND_PCM_FORMAT_S32) {
+
+				for (unsigned int c = 0; c < fCardInputs; c++) {
+					int32* chan32b = (int32*)fInputCardChannels[c];
+					for (unsigned int s = 0; s < fBuffering; s++) {
+						fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(INT_MAX));
+					}
+				}
+			} else {
+				printf("unrecognized input sample format : %u\n", fSampleFormat);
+				exit(1);
+			}
+
+		} else {
+			check_error_msg(-10000, "unknow access mode");
+		}
+    }
+
+	/**
+	 * write the output soft channels to the audio card. Convert sample
+	 * format and interleaves buffers when needed
+	 */
+	void write()
+	{
+		recovery :
+
+		if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
+
+			if (fSampleFormat == SND_PCM_FORMAT_S16) {
+
+				short* buffer16b = (short*)fOutputCardBuffer;
+				for (unsigned int f = 0; f < fBuffering; f++) {
+					for (unsigned int c = 0; c < fCardOutputs; c++) {
+						float x = fOutputSoftChannels[c][f];
+						buffer16b[c + f*fCardOutputs] = short( max(min(x,1.0f),-1.0f) * float(SHRT_MAX) ) ;
+					}
+				}
+
+			} else if (fSampleFormat == SND_PCM_FORMAT_S32)  {
+
+				int32* buffer32b = (int32*)fOutputCardBuffer;
+				for (unsigned int f = 0; f < fBuffering; f++) {
+					for (unsigned int c = 0; c < fCardOutputs; c++) {
+						float x = fOutputSoftChannels[c][f];
+						buffer32b[c + f*fCardOutputs] = int( max(min(x,1.0f),-1.0f) * float(INT_MAX) ) ;
+					}
+				}
+			} else {
+
+				printf("unrecognized output sample format : %u\n", fSampleFormat);
+				exit(1);
+			}
+
+			int count = snd_pcm_writei(fOutputDevice, fOutputCardBuffer, fBuffering);
+			if (count<0) {
+				//display_error_msg(count, "w3");
+				snd_pcm_prepare(fOutputDevice);
+				//check_error_msg(err, "preparing output stream");
+				goto recovery;
+			}
+
+
+		} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
+
+			if (fSampleFormat == SND_PCM_FORMAT_S16) {
+
+				for (unsigned int c = 0; c < fCardOutputs; c++) {
+					short* chan16b = (short*) fOutputCardChannels[c];
+					for (unsigned int f = 0; f < fBuffering; f++) {
+						float x = fOutputSoftChannels[c][f];
+						chan16b[f] = short( max(min(x,1.0f),-1.0f) * float(SHRT_MAX) ) ;
+					}
+				}
+
+			} else if (fSampleFormat == SND_PCM_FORMAT_S32) {
+
+				for (unsigned int c = 0; c < fCardOutputs; c++) {
+					int32* chan32b = (int32*) fOutputCardChannels[c];
+					for (unsigned int f = 0; f < fBuffering; f++) {
+						float x = fOutputSoftChannels[c][f];
+						chan32b[f] = int( max(min(x,1.0f),-1.0f) * float(INT_MAX) ) ;
+					}
+				}
+
+			} else {
+
+				printf("unrecognized output sample format : %u\n", fSampleFormat);
+				exit(1);
+			}
+
+			int count = snd_pcm_writen(fOutputDevice, fOutputCardChannels, fBuffering);
+			if (count<0) {
+				//display_error_msg(count, "w3");
+				snd_pcm_prepare(fOutputDevice);
+				//check_error_msg(err, "preparing output stream");
+				goto recovery;
+			}
+
+		} else {
+			check_error_msg(-10000, "unknow access mode");
+		}
+	}
+
+	/**
+	 *  print short information on the audio device
+	 */
+	void shortinfo()
+	{
+		int						err;
+		snd_ctl_card_info_t*	card_info;
+    	snd_ctl_t*				ctl_handle;
+		err = snd_ctl_open (&ctl_handle, fCardName, 0);		check_error(err);
+		snd_ctl_card_info_alloca (&card_info);
+		err = snd_ctl_card_info(ctl_handle, card_info);		check_error(err);
+		printf("%s|%d|%d|%d|%d|%s\n",
+				snd_ctl_card_info_get_driver(card_info),
+				fCardInputs, fCardOutputs,
+				fFrequency, fBuffering,
+				snd_pcm_format_name((_snd_pcm_format)fSampleFormat));
+	}
+
+	/**
+	 *  print more detailled information on the audio device
+	 */
+	void longinfo()
+	{
+		int						err;
+		snd_ctl_card_info_t*	card_info;
+    	snd_ctl_t*				ctl_handle;
+
+		printf("Audio Interface Description :\n");
+		printf("Sampling Frequency : %d, Sample Format : %s, buffering : %d\n",
+				fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering);
+		printf("Software inputs : %2d, Software outputs : %2d\n", fSoftInputs, fSoftOutputs);
+		printf("Hardware inputs : %2d, Hardware outputs : %2d\n", fCardInputs, fCardOutputs);
+		printf("Channel inputs  : %2d, Channel outputs  : %2d\n", fChanInputs, fChanOutputs);
+
+		// affichage des infos de la carte
+		err = snd_ctl_open (&ctl_handle, fCardName, 0);		check_error(err);
+		snd_ctl_card_info_alloca (&card_info);
+		err = snd_ctl_card_info(ctl_handle, card_info);		check_error(err);
+		printCardInfo(card_info);
+
+		// affichage des infos liees aux streams d'entree-sortie
+		if (fSoftInputs > 0)	printHWParams(fInputParams);
+		if (fSoftOutputs > 0)	printHWParams(fOutputParams);
+	}
+
+	void printCardInfo(snd_ctl_card_info_t*	ci)
+	{
+		printf("Card info (address : %p)\n", ci);
+		printf("\tID         = %s\n", snd_ctl_card_info_get_id(ci));
+		printf("\tDriver     = %s\n", snd_ctl_card_info_get_driver(ci));
+		printf("\tName       = %s\n", snd_ctl_card_info_get_name(ci));
+		printf("\tLongName   = %s\n", snd_ctl_card_info_get_longname(ci));
+		printf("\tMixerName  = %s\n", snd_ctl_card_info_get_mixername(ci));
+		printf("\tComponents = %s\n", snd_ctl_card_info_get_components(ci));
+		printf("--------------\n");
+	}
+
+	void printHWParams( snd_pcm_hw_params_t* params )
+	{
+		printf("HW Params info (address : %p)\n", params);
+#if 0
+		printf("\tChannels    = %d\n", snd_pcm_hw_params_get_channels(params));
+		printf("\tFormat      = %s\n", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params)));
+		printf("\tAccess      = %s\n", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params)));
+		printf("\tRate        = %d\n", snd_pcm_hw_params_get_rate(params, NULL));
+		printf("\tPeriods     = %d\n", snd_pcm_hw_params_get_periods(params, NULL));
+		printf("\tPeriod size = %d\n", (int)snd_pcm_hw_params_get_period_size(params, NULL));
+		printf("\tPeriod time = %d\n", snd_pcm_hw_params_get_period_time(params, NULL));
+		printf("\tBuffer size = %d\n", (int)snd_pcm_hw_params_get_buffer_size(params));
+		printf("\tBuffer time = %d\n", snd_pcm_hw_params_get_buffer_time(params, NULL));
+#endif
+		printf("--------------\n");
+	}
+
+};
+
+// lopt : Scan Command Line long int Arguments
+long lopt(int argc, char *argv[], const char* longname, const char* shortname, long def)
+{
+	for (int i=2; i<argc; i++)
+		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
+			return atoi(argv[i]);
+	return def;
+}
+
+// sopt : Scan Command Line string Arguments
+const char* sopt(int argc, char *argv[], const char* longname, const char* shortname, const char* def)
+{
+	for (int i=2; i<argc; i++)
+		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
+			return argv[i];
+	return def;
+}
+
+// fopt : Scan Command Line flag option (without argument), return true if the flag
+bool fopt(int argc, char *argv[], const char* longname, const char* shortname)
+{
+	for (int i=1; i<argc; i++)
+		if ( strcmp(argv[i], shortname) == 0 || strcmp(argv[i], longname) == 0 )
+			return true;
+	return false;
+}
+
+/**
+ * Return the value of an environment variable or defval if undefined.
+ */
+static int getDefaultEnv(const char* name, int defval)
+{
+    const char* str = getenv(name);
+    if (str) {
+        return atoi(str);
+    } else {
+        return defval;
+    }
+}
+
+/**
+ * Return the value of an environment variable or defval if undefined.
+ */
+static const char* getDefaultEnv(const char* name, const char* defval)
+{
+    const char* str = getenv(name);
+    if (str) {
+        return str;
+    } else {
+        return defval;
+    }
+}
+
+/******************************************************************************
+*******************************************************************************
+
+							   ALSA audio interface
+
+*******************************************************************************
+*******************************************************************************/
+static void* __run(void* ptr);
+
+class alsaaudio : public audio
+{
+	AudioInterface*	fAudio;
+	dsp* 			fDSP;
+	pthread_t 		fAudioThread;
+	bool 			fRunning;
+
+ public:
+
+	 alsaaudio(int argc, char *argv[], dsp* DSP) : fAudio(0), fDSP(DSP), fRunning(false) {
+			fAudio = new AudioInterface (
+				AudioParam().cardName( sopt(argc, argv, "--device", "-d",  	getDefaultEnv("FAUST2ALSA_DEVICE", "hw:0")  ) )
+				.frequency( lopt(argc, argv, "--frequency", "-f", 			getDefaultEnv("FAUST2ALSA_FREQUENCY",44100) ) )
+				.buffering( lopt(argc, argv, "--buffer", "-b",    			getDefaultEnv("FAUST2ALSA_BUFFER",512)     ) )
+				.periods( lopt(argc, argv, "--periods", "-p",     			getDefaultEnv("FAUST2ALSA_PERIODS",2)       ) )
+				.inputs(DSP->getNumInputs())
+				.outputs(DSP->getNumOutputs()));
+		}
+
+	virtual ~alsaaudio() { stop(); delete fAudio; }
+
+	virtual bool init(const char */*name*/, dsp* DSP) {
+		fAudio->open();
+	    DSP->init(fAudio->frequency());
+ 		return true;
+	}
+
+	virtual bool start() {
+		fRunning = true;
+		if (pthread_create(&fAudioThread, 0, __run, this)) {
+			fRunning = false;
+        }
+		return fRunning;
+	}
+
+	virtual void stop() {
+		if (fRunning) {
+			fRunning = false;
+			pthread_join(fAudioThread, 0);
+		}
+	}
+    
+    virtual int get_buffer_size() { return fAudio->buffering(); }
+    virtual int get_sample_rate() { return fAudio->frequency(); }
+
+	virtual void run() {
+		bool rt = setRealtimePriority();
+		printf(rt ? "RT : ":"NRT: "); fAudio->shortinfo();
+        AVOIDDENORMALS;
+		if (fAudio->duplexMode()) {
+            fAudio->write();
+			fAudio->write();
+			while (fRunning) {
+				fAudio->read();
+				fDSP->compute(fAudio->buffering(), fAudio->inputSoftChannels(), fAudio->outputSoftChannels());
+				fAudio->write();
+			}
+        } else {
+            fAudio->write();
+			while (fRunning) {
+				fDSP->compute(fAudio->buffering(), fAudio->inputSoftChannels(), fAudio->outputSoftChannels());
+				fAudio->write();
+			}
+		}
+	}
+};
+
+void* __run (void* ptr)
+{
+	alsaaudio * alsa = (alsaaudio*)ptr;
+	alsa->run();
+	return 0;
+}
+
+#endif
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/faust/audio/android-dsp.h b/architecture/faust/audio/android-dsp.h
new file mode 100644
index 0000000..c3f183a
--- /dev/null
+++ b/architecture/faust/audio/android-dsp.h
@@ -0,0 +1,442 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ 
+ 
+ ************************************************************************
+ *************************************************************************/
+ 
+#include <android/log.h>
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+#include <pthread.h>
+
+#include "faust/audio/audio.h"
+
+#define CONV16BIT 32767.f
+#define CONVMYFLT (1.f/32767.f)
+
+#define NUM_INPUTS 2
+#define NUM_OUPUTS 2
+
+class androidaudio : public audio {
+    
+    protected:
+    
+        dsp* fDsp;
+        
+        int	fNumInChans;
+        int	fNumOutChans;
+        
+        unsigned int fSampleRate;
+        unsigned int fBufferSize;
+        
+        pthread_mutex_t fMutex;
+    
+        short* fFifobuffer;
+        short* fSilence;
+    
+        float** fInputs;
+        float** fOutputs;
+    
+        SLObjectItf fOpenSLEngine, fOutputMix, fInputBufferQueue, fOutputBufferQueue;
+        SLAndroidSimpleBufferQueueItf fOutputBufferQueueInterface, fInputBufferQueueInterface;
+    
+        SLRecordItf fRecordInterface;
+        SLPlayItf fPlayInterface;
+    
+        int fFifoFirstSample, fFifoLastSample, fLatencySamples, fFifoCapacity;
+    
+        int processAudio(short* audioIO)
+        {
+            for (int chan = 0; chan < NUM_INPUTS; chan++) {
+                for (int i = 0; i < fBufferSize; i++) {
+                    fInputs[chan][i] =  float(audioIO[i * 2 + chan] * CONVMYFLT);
+                }
+            }
+            
+            // computing...
+            fDsp->compute(fBufferSize, fInputs, fOutputs);
+            
+            for (int chan = 0; chan < NUM_OUPUTS; chan++) {
+                for (int i = 0; i < fBufferSize; i++) {
+                    audioIO[i * 2 + chan] = short(min(1.f, max(-1.f, fOutputs[chan][i])) * CONV16BIT);
+                }
+            }
+        }
+    
+        void checkRoom()
+        {
+            if (fFifoLastSample + fBufferSize >= fFifoCapacity) {
+                int samplesInFifo = fFifoLastSample - fFifoFirstSample;
+                if (samplesInFifo > 0) memmove(fFifobuffer, fFifobuffer + fFifoFirstSample * 2, samplesInFifo * 8);
+                fFifoFirstSample = 0;
+                fFifoLastSample = samplesInFifo;
+            };
+        }
+    
+        static void inputCallback(SLAndroidSimpleBufferQueueItf caller, void* arg)
+        {
+            androidaudio* obj = (androidaudio*)arg;
+            obj->inputCallback(caller);
+        }
+    
+        void inputCallback(SLAndroidSimpleBufferQueueItf caller)
+        {
+            pthread_mutex_lock(&fMutex);
+            checkRoom();
+            
+            short* input = fFifobuffer + fFifoLastSample * 2;
+            fFifoLastSample += fBufferSize;
+            
+            if (fNumOutChans > 0) {
+                pthread_mutex_unlock(&fMutex);
+                (*caller)->Enqueue(caller, input, fBufferSize * 4);
+            } else {
+                short* process = fFifobuffer + fFifoFirstSample * 2;
+                fFifoFirstSample += fBufferSize;
+                pthread_mutex_unlock(&fMutex);
+                (*caller)->Enqueue(caller, input, fBufferSize * 4);
+                // Actual processing
+                processAudio(process);
+            };
+        }
+    
+        static void outputCallback(SLAndroidSimpleBufferQueueItf caller, void* arg)
+        {
+            androidaudio* obj = (androidaudio*)arg;
+            obj->outputCallback(caller);
+        }
+    
+        void outputCallback(SLAndroidSimpleBufferQueueItf caller)
+        {
+            pthread_mutex_lock(&fMutex);
+            
+            if (!(fNumInChans > 0)) {
+                checkRoom();
+                short* process = fFifobuffer + fFifoLastSample * 2;
+                fFifoLastSample += fBufferSize;
+                short* output = fFifobuffer + fFifoFirstSample * 2;
+                fFifoFirstSample += fBufferSize;
+                pthread_mutex_unlock(&fMutex);
+                // Actual processing
+                processAudio(process);
+                (*caller)->Enqueue(caller, output, fBufferSize * 4);
+            } else {
+                if (fFifoLastSample - fFifoFirstSample >= fLatencySamples) {
+                    short* output = fFifobuffer + fFifoFirstSample * 2;
+                    fFifoFirstSample += fBufferSize;
+                    pthread_mutex_unlock(&fMutex);
+                    // Actual processing
+                    processAudio(output);
+                    (*caller)->Enqueue(caller, output, fBufferSize * 4);
+                } else {
+                    pthread_mutex_unlock(&fMutex);
+                    (*caller)->Enqueue(caller, fSilence, fBufferSize * 4);
+                };
+            };
+        }
+          
+    public:
+    
+        androidaudio(long srate, long bsize)
+        : fDsp(0), fSampleRate(srate),
+        fBufferSize(bsize), fNumInChans(0), fNumOutChans(0),
+        fFifoFirstSample(0), fFifoLastSample(0),
+        fLatencySamples(0), fFifoCapacity(0),
+        fOpenSLEngine(0), fOutputMix(0), fInputBufferQueue(0), fOutputBufferQueue(0)
+        {
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "Constructor");
+            
+            // Allocating memory for input channels.
+            fInputs = new float*[NUM_INPUTS];
+            for (int i = 0; i < NUM_INPUTS; i++) {
+                fInputs[i] = new float[fBufferSize];
+                memset(fInputs[i], 0, fBufferSize * sizeof(float));
+            }
+    
+            // Allocating memory for output channels.
+            fOutputs = new float*[NUM_OUPUTS];
+            for (int i = 0; i < NUM_OUPUTS; i++) {
+                fOutputs[i] = new float[fBufferSize];
+                memset(fOutputs[i], 0, fBufferSize * sizeof(float));
+            }
+        }
+
+        virtual ~androidaudio()
+        {
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "Destructor");
+            
+            if (fInputBufferQueue) {
+                (*fInputBufferQueue)->Destroy(fInputBufferQueue);
+                fInputBufferQueue = NULL;
+            }
+            
+            if (fOutputBufferQueue) {
+                (*fOutputBufferQueue)->Destroy(fOutputBufferQueue);
+                fOutputBufferQueue = NULL;
+            }
+            
+            if (fOutputMix) {
+                (*fOutputMix)->Destroy(fOutputMix);
+                fOutputMix = NULL;
+            }
+             
+            if (fOpenSLEngine) {
+                (*fOpenSLEngine)->Destroy(fOpenSLEngine);
+                fOpenSLEngine = NULL;
+            }
+            
+            free(fFifobuffer);
+            free(fSilence);
+            
+            for (int i = 0; i < NUM_INPUTS; i++) {
+                delete [] fInputs[i];
+            }
+            delete [] fInputs;
+            
+            for (int i = 0; i < NUM_OUPUTS; i++) {
+                delete [] fOutputs[i];
+            }
+            delete [] fOutputs;
+            
+            pthread_mutex_destroy(&fMutex);
+        }
+    
+        virtual bool init(const char* name, dsp* DSP)
+        {
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "init");
+            
+            fDsp = DSP;
+            fNumInChans = fDsp->getNumInputs();
+            fNumOutChans = fDsp->getNumOutputs();
+            fDsp->init(fSampleRate);
+            if (pthread_mutex_init(&fMutex, NULL) != 0) {
+                return false;
+            }
+            
+            static const SLboolean requireds[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
+            SLresult result;
+            SLuint32 sr;
+            
+            switch (fSampleRate) {
+                    
+                case 8000:
+                    sr = SL_SAMPLINGRATE_8;
+                    break;
+                case 11025:
+                    sr = SL_SAMPLINGRATE_11_025;
+                    break;
+                case 16000:
+                    sr = SL_SAMPLINGRATE_16;
+                    break;
+                case 22050:
+                    sr = SL_SAMPLINGRATE_22_05;
+                    break;
+                case 24000:
+                    sr = SL_SAMPLINGRATE_24;
+                    break;
+                case 32000:
+                    sr = SL_SAMPLINGRATE_32;
+                    break;
+                case 44100:
+                    sr = SL_SAMPLINGRATE_44_1;
+                    break;
+                case 48000:
+                    sr = SL_SAMPLINGRATE_48;
+                    break;
+                case 64000:
+                    sr = SL_SAMPLINGRATE_64;
+                    break;
+                case 88200:
+                    sr = SL_SAMPLINGRATE_88_2;
+                    break;
+                case 96000:
+                    sr = SL_SAMPLINGRATE_96;
+                    break;
+                case 192000:
+                    sr = SL_SAMPLINGRATE_192;
+                    break;
+                default:
+                    return false;
+            }
+            
+            fSilence = (short*)malloc(fBufferSize * 4);
+            memset(fSilence, 0, fBufferSize * 4);
+            fLatencySamples = fLatencySamples < fBufferSize ? fBufferSize : fLatencySamples;
+            
+            fFifoCapacity = fBufferSize * 100;
+            int fifoBufferSizeBytes = fFifoCapacity * 4 + fBufferSize * 4;
+            fFifobuffer = (short*)malloc(fifoBufferSizeBytes);
+            memset(fFifobuffer, 0, fifoBufferSizeBytes);
+            
+            // Create the OpenSL ES engine.
+            result = slCreateEngine(&fOpenSLEngine, 0, NULL, 0, NULL, NULL);
+            if (result != SL_RESULT_SUCCESS) return false;
+            
+            result = (*fOpenSLEngine)->Realize(fOpenSLEngine, SL_BOOLEAN_FALSE);
+            if (result != SL_RESULT_SUCCESS) return false;
+            
+            SLEngineItf openSLEngineInterface = NULL;
+            result = (*fOpenSLEngine)->GetInterface(fOpenSLEngine, SL_IID_ENGINE, &openSLEngineInterface);
+            if (result != SL_RESULT_SUCCESS) return false;
+            
+            // Create the output mix.
+            result = (*openSLEngineInterface)->CreateOutputMix(openSLEngineInterface, &fOutputMix, 0, NULL, NULL);
+            if (result != SL_RESULT_SUCCESS) return false;
+            
+            result = (*fOutputMix)->Realize(fOutputMix, SL_BOOLEAN_FALSE);
+            if (result != SL_RESULT_SUCCESS) return false;
+            
+            SLDataLocator_OutputMix outputMixLocator = { SL_DATALOCATOR_OUTPUTMIX, fOutputMix };
+            
+            if (fNumInChans > 0) {
+                // Create the input buffer queue.
+                SLDataLocator_IODevice deviceInputLocator = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL };
+                SLDataSource inputSource = { &deviceInputLocator, NULL };
+                SLDataLocator_AndroidSimpleBufferQueue inputLocator = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1 };
+                SLDataFormat_PCM inputFormat = { SL_DATAFORMAT_PCM, 2, sr, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, SL_BYTEORDER_LITTLEENDIAN };
+                SLDataSink inputSink = { &inputLocator, &inputFormat };
+                const SLInterfaceID inputInterfaces[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
+                
+                result = (*openSLEngineInterface)->CreateAudioRecorder(openSLEngineInterface, &fInputBufferQueue, &inputSource, &inputSink, 1, inputInterfaces, requireds);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fInputBufferQueue)->Realize(fInputBufferQueue, SL_BOOLEAN_FALSE);
+                if (result != SL_RESULT_SUCCESS) return false;
+            }
+            
+            if (fNumOutChans > 0) {
+                // Create the output buffer queue.
+                SLDataLocator_AndroidSimpleBufferQueue outputLocator = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1 };
+                SLDataFormat_PCM outputFormat = { SL_DATAFORMAT_PCM, 2, sr, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, SL_BYTEORDER_LITTLEENDIAN };
+                SLDataSource outputSource = { &outputLocator, &outputFormat };
+                const SLInterfaceID outputInterfaces[1] = { SL_IID_BUFFERQUEUE };
+                SLDataSink outputSink = { &outputMixLocator, NULL };
+                
+                result = (*openSLEngineInterface)->CreateAudioPlayer(openSLEngineInterface, &fOutputBufferQueue, &outputSource, &outputSink, 1, outputInterfaces, requireds);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fOutputBufferQueue)->Realize(fOutputBufferQueue, SL_BOOLEAN_FALSE);
+                if (result != SL_RESULT_SUCCESS) return false;
+            }
+            
+            if (fNumInChans > 0) { // Initialize
+                result = (*fInputBufferQueue)->GetInterface(fInputBufferQueue, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &fInputBufferQueueInterface);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fInputBufferQueueInterface)->RegisterCallback(fInputBufferQueueInterface, inputCallback, this);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fInputBufferQueue)->GetInterface(fInputBufferQueue, SL_IID_RECORD, &fRecordInterface);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                // init the input buffer queue.
+                result = (*fInputBufferQueueInterface)->Enqueue(fInputBufferQueueInterface, fFifobuffer, fBufferSize * 4);
+                __android_log_print(ANDROID_LOG_ERROR, "Faust", "androidaudio::init Enqueue %d", result);
+                if (result != SL_RESULT_SUCCESS) return false;
+            }
+            
+            if (fNumOutChans > 0) { // Initialize
+                result = (*fOutputBufferQueue)->GetInterface(fOutputBufferQueue, SL_IID_BUFFERQUEUE, &fOutputBufferQueueInterface);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fOutputBufferQueueInterface)->RegisterCallback(fOutputBufferQueueInterface, outputCallback, this);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fOutputBufferQueueInterface)->Enqueue(fOutputBufferQueueInterface, fFifobuffer, fBufferSize * 4);
+                if (result != SL_RESULT_SUCCESS) return false;
+                
+                result = (*fOutputBufferQueue)->GetInterface(fOutputBufferQueue, SL_IID_PLAY, &fPlayInterface);
+                if (result != SL_RESULT_SUCCESS) return false;
+            }
+            
+            return true;
+        }
+    
+        virtual bool start()
+        {
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "start");
+            SLresult result;
+            
+            if (fNumInChans > 0) {
+                // start the inout buffer queue.
+                result = (*fRecordInterface)->SetRecordState(fRecordInterface, SL_RECORDSTATE_RECORDING);
+                if (result != SL_RESULT_SUCCESS) return false;
+            }
+            
+            if (fNumOutChans > 0) {
+                // start the output buffer queue.
+                result = (*fPlayInterface)->SetPlayState(fPlayInterface, SL_PLAYSTATE_PLAYING);
+                if (result != SL_RESULT_SUCCESS) return false;
+            }
+            
+            return true;
+        }
+        
+        virtual void stop()
+        {
+            __android_log_print(ANDROID_LOG_ERROR, "Faust", "stop");
+            SLresult result;
+            
+            if (fNumInChans > 0) {
+                result = (*fRecordInterface)->SetRecordState(fRecordInterface, SL_RECORDSTATE_PAUSED);
+                if (result != SL_RESULT_SUCCESS) __android_log_print(ANDROID_LOG_ERROR, "Faust", "stop: SetRecordState error");
+            }
+            
+            if (fNumOutChans > 0) {
+                result = (*fPlayInterface)->SetPlayState(fPlayInterface, SL_PLAYSTATE_PAUSED);
+                if (result != SL_RESULT_SUCCESS) __android_log_print(ANDROID_LOG_ERROR, "Faust", "stop: SetPlayState error");
+            }
+        }
+    
+        virtual int get_buffer_size()
+        {
+            return fBufferSize;
+        }
+        
+        virtual int get_sample_rate()
+        {
+            return fSampleRate;
+        }
+        
+        virtual int get_num_inputs()
+        {
+            return fNumInChans;
+        }
+        
+        virtual int get_num_outputs()
+        {
+            return fNumOutChans;
+        }
+    
+};
+
diff --git a/architecture/faust/audio/audio.h b/architecture/faust/audio/audio.h
new file mode 100644
index 0000000..7ab0a24
--- /dev/null
+++ b/architecture/faust/audio/audio.h
@@ -0,0 +1,72 @@
+/************************************************************************
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+ 
+/******************************************************************************
+*******************************************************************************
+
+						An abstraction layer over audio layer
+
+*******************************************************************************
+*******************************************************************************/
+
+#ifndef __audio__
+#define __audio__
+			
+class dsp;
+
+typedef void (* shutdown_callback)(const char* message, void* arg);
+
+typedef void (* buffer_size_callback)(int frames, void* arg);
+
+class audio {
+    
+ public:
+			 audio() {}
+	virtual ~audio() {}
+	
+	virtual bool init(const char* name, dsp*)               = 0;
+	virtual bool start()                                    = 0;
+	virtual void stop()                                     = 0;
+    virtual void shutdown(shutdown_callback cb, void* arg)  {}
+    
+    virtual int get_buffer_size() = 0;
+    virtual int get_sample_rate() = 0;
+    
+    virtual int get_num_inputs() { return -1; }
+    virtual int get_num_outputs() { return -1; }
+    
+};
+					
+#endif
diff --git a/architecture/faust/audio/coreaudio-dsp.h b/architecture/faust/audio/coreaudio-dsp.h
new file mode 100644
index 0000000..c1293fe
--- /dev/null
+++ b/architecture/faust/audio/coreaudio-dsp.h
@@ -0,0 +1,1501 @@
+/************************************************************************
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __coreaudio_dsp__
+#define __coreaudio_dsp__
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <vector>
+#include <iostream>
+
+#include <AudioToolbox/AudioConverter.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioUnit/AudioUnit.h>
+#include <CoreServices/CoreServices.h>
+
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp.h"
+
+#include <sys/time.h>
+
+/******************************************************************************
+*******************************************************************************
+
+							COREAUDIO INTERNAL INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+#define OPEN_ERR -1
+#define CLOSE_ERR -1
+#define NO_ERR 0
+
+#define WAIT_NOTIFICATION_COUNTER 60
+
+typedef	UInt8	CAAudioHardwareDeviceSectionID;
+#define	kAudioDeviceSectionInput	((CAAudioHardwareDeviceSectionID)0x01)
+#define	kAudioDeviceSectionOutput	((CAAudioHardwareDeviceSectionID)0x00)
+#define	kAudioDeviceSectionGlobal	((CAAudioHardwareDeviceSectionID)0x00)
+#define	kAudioDeviceSectionWildcard	((CAAudioHardwareDeviceSectionID)0xFF)
+
+class TCoreAudioRenderer;
+typedef TCoreAudioRenderer* TCoreAudioRendererPtr;
+
+static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
+{
+    printf("- - - - - - - - - - - - - - - - - - - -\n");
+    printf("  Sample Rate:%f\n", inDesc->mSampleRate);
+    printf("  Format ID:%.*s\n", (int)sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID);
+    printf("  Format Flags:%lX\n", inDesc->mFormatFlags);
+    printf("  Bytes per Packet:%ld\n", (long)inDesc->mBytesPerPacket);
+    printf("  Frames per Packet:%ld\n", (long)inDesc->mFramesPerPacket);
+    printf("  Bytes per Frame:%ld\n", (long)inDesc->mBytesPerFrame);
+    printf("  Channels per Frame:%ld\n", (long)inDesc->mChannelsPerFrame);
+    printf("  Bits per Channel:%ld\n", (long)inDesc->mBitsPerChannel);
+    printf("- - - - - - - - - - - - - - - - - - - -\n");
+}
+
+static void printError(OSStatus err)
+{
+    switch (err) {
+        case kAudioHardwareNoError:
+            printf("error code : kAudioHardwareNoError\n");
+            break;
+		case kAudioConverterErr_FormatNotSupported:
+            printf("error code : kAudioConverterErr_FormatNotSupported\n");
+            break;
+        case kAudioConverterErr_OperationNotSupported:
+            printf("error code : kAudioConverterErr_OperationNotSupported\n");
+            break;
+        case kAudioConverterErr_PropertyNotSupported:
+            printf("error code : kAudioConverterErr_PropertyNotSupported\n");
+            break;
+        case kAudioConverterErr_InvalidInputSize:
+            printf("error code : kAudioConverterErr_InvalidInputSize\n");
+            break;
+        case kAudioConverterErr_InvalidOutputSize:
+            printf("error code : kAudioConverterErr_InvalidOutputSize\n");
+            break;
+        case kAudioConverterErr_UnspecifiedError:
+            printf("error code : kAudioConverterErr_UnspecifiedError\n");
+            break;
+        case kAudioConverterErr_BadPropertySizeError:
+            printf("error code : kAudioConverterErr_BadPropertySizeError\n");
+            break;
+        case kAudioConverterErr_RequiresPacketDescriptionsError:
+            printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n");
+            break;
+        case kAudioConverterErr_InputSampleRateOutOfRange:
+            printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n");
+            break;
+        case kAudioConverterErr_OutputSampleRateOutOfRange:
+            printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n");
+            break;
+		case kAudioHardwareNotRunningError:
+            printf("error code : kAudioHardwareNotRunningError\n");
+            break;
+        case kAudioHardwareUnknownPropertyError:
+            printf("error code : kAudioHardwareUnknownPropertyError\n");
+            break;
+        case kAudioHardwareIllegalOperationError:
+            printf("error code : kAudioHardwareIllegalOperationError\n");
+            break;
+        case kAudioHardwareBadDeviceError:
+            printf("error code : kAudioHardwareBadDeviceError\n");
+            break;
+        case kAudioHardwareBadStreamError:
+            printf("error code : kAudioHardwareBadStreamError\n");
+            break;
+        case kAudioDeviceUnsupportedFormatError:
+            printf("error code : kAudioDeviceUnsupportedFormatError\n");
+            break;
+        case kAudioDevicePermissionsError:
+            printf("error code : kAudioDevicePermissionsError\n");
+            break;
+        default:
+            printf("error code : err = %d\n", err);
+            break;
+    }
+}
+
+static Float64 GetNominalSampleRate(AudioDeviceID inDevice) 
+{
+    Float64 sampleRate = 0;
+    UInt32 outSize =  sizeof(Float64);
+    OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
+    if (err != noErr) {
+        printf("Cannot get current sample rate\n");
+        printError(err);
+        return -1;
+    } else {
+        return sampleRate;
+    }
+}
+
+static CFStringRef GetDeviceName(AudioDeviceID id)
+{
+    UInt32 size = sizeof(CFStringRef);
+    CFStringRef UIname;
+    OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname);
+    return (err == noErr) ? UIname : NULL;
+}
+
+static bool CheckAvailableDeviceName(const char* device_name, AudioDeviceID* device_id, int len = -1)
+{
+    UInt32 size;
+    Boolean isWritable;
+    int i, deviceNum;
+    OSStatus err;
+
+    err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
+    if (err != noErr) {
+        return false;
+    }
+
+    deviceNum = size / sizeof(AudioDeviceID);
+    AudioDeviceID devices[deviceNum];
+ 
+    err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
+    if (err != noErr) {
+        return false;
+    }
+
+    for (i = 0; i < deviceNum; i++) {
+        char device_name_aux[256];
+    
+        size = 256;
+        err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name_aux);
+        if (err != noErr) {
+            return false;
+        }
+ 
+        if (strncmp(device_name_aux, device_name, (len == -1) ? strlen(device_name) : len) == 0) {
+            *device_id = devices[i];
+            return true;
+        }
+    }
+
+    return false;
+}
+
+class TCoreAudioRenderer
+{
+    
+    protected:
+    
+        AudioDeviceID fAggregateDeviceID;
+        AudioObjectID fAggregatePluginID;    // Used for aggregate device
+     
+        int fDevNumInChans;
+        int fDevNumOutChans;
+        
+        int fPhysicalInputs;
+        int fPhysicalOutputs;
+        
+        float** fInChannel;
+        float** fOutChannel;
+
+        int fBufferSize;
+        int fSampleRate;
+    
+        bool fIsInJackDevice;
+        bool fIsOutJackDevice;
+        
+        dsp* fDSP;
+
+        AudioBufferList* fInputData;
+        AudioDeviceID fDeviceID;
+        AudioUnit fAUHAL;
+        bool fState;
+
+        OSStatus GetDefaultDeviceAndSampleRate(int inChan, int outChan, int& sample_rate, AudioDeviceID* device)
+        {
+            
+            UInt32 theSize = sizeof(UInt32);
+            AudioDeviceID inDefault;
+            AudioDeviceID outDefault;
+            OSStatus res;
+            
+            if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+                                                &theSize, &inDefault)) != noErr) {
+                return res;
+            }
+            
+            if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+                                                &theSize, &outDefault)) != noErr) {
+                return res;
+            }
+            
+            /*
+            // TODO
+            if (inDefault == 0) {
+                printf("Error default input device is 0, will take 'Built-in'...\n");
+                if (CheckAvailableDeviceName("Built-in Microphone", &inDefault) 
+                    || CheckAvailableDeviceName("Built-in Line", &inDefault)) {
+                    printf("GetDefaultInputDevice : output = %ld\n", inDefault);
+                } else {
+                    printf("Cannot find any input device to use...");
+                    return -1;
+                }
+            }
+            
+            if (outDefault == 0) {
+                printf("Error default ouput device is 0, will take 'Built-in'...\n");
+                if (CheckAvailableDeviceName("Built-in Output", &outDefault)) {
+                    printf("GetDefaultOutputDevice : output = %ld\n", outDefault);
+                } else {
+                    printf("Cannot find any output device to use...\n");
+                    return -1;
+                }
+            }  
+            */          
+            
+            printf("GetDefaultDevice : input = %d output = %d\n", inDefault, outDefault);
+            
+            // Duplex mode
+            if (inChan > 0 && outChan > 0) {
+                // Get the device only if default input and output are the same
+                if (inDefault == outDefault) {
+                    *device = inDefault;
+                    goto end;
+                } else {
+                    if (CreateAggregateDevice(inDefault, outDefault, sample_rate) != noErr) {
+                        return kAudioHardwareBadDeviceError;
+                    }
+                    printf("fAggregateDeviceID %d\n", fAggregateDeviceID);
+                    *device = fAggregateDeviceID;
+                    goto end;
+                }
+            } else if (inChan > 0) {
+                *device = inDefault;
+                goto end;
+            } else if (outChan > 0) {
+                *device = outDefault;
+                goto end;
+            } else {
+                return kAudioHardwareBadDeviceError;
+            }
+            
+        end:   
+            
+            if (sample_rate == -1) {
+                // Possible take the current sample rate
+                sample_rate = int(GetNominalSampleRate(*device));
+            } else {
+                // Otherwise force the one we want...
+                SetupSampleRateAux(*device, sample_rate);
+            }
+            printf("samplerate %d\n", sample_rate);
+            fSampleRate = sample_rate;
+            return noErr;
+        }
+
+        OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int& sample_rate)
+        {
+            OSStatus err = noErr;
+            AudioObjectID sub_device[32];
+            UInt32 outSize = sizeof(sub_device);
+            
+            printf("CreateAggregateDevice : input device %d\n", captureDeviceID);
+            
+            err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
+            std::vector<AudioDeviceID> captureDeviceIDArray;
+            
+            if (err != noErr) {
+                printf("Input device does not have subdevices\n");
+                captureDeviceIDArray.push_back(captureDeviceID);
+            } else {
+                int num_devices = outSize / sizeof(AudioObjectID);
+                printf("Input device has %d subdevices\n", num_devices);
+                for (int i = 0; i < num_devices; i++) {
+                    printf("Input sub_device %d\n", sub_device[i]);
+                    captureDeviceIDArray.push_back(sub_device[i]);
+                }
+            }
+            
+            outSize = sizeof(sub_device);
+            err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
+            std::vector<AudioDeviceID> playbackDeviceIDArray;
+            
+            if (err != noErr) {
+                printf("Output device does not have subdevices\n");
+                playbackDeviceIDArray.push_back(playbackDeviceID);
+            } else {
+                int num_devices = outSize / sizeof(AudioObjectID);
+                printf("Output device has %d subdevices\n", num_devices);
+                for (int i = 0; i < num_devices; i++) {
+                    printf("Output sub_device %d\n", sub_device[i]);
+                    playbackDeviceIDArray.push_back(sub_device[i]);
+                }
+            }
+            
+            return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, sample_rate);
+        }
+        
+        OSStatus CreateAggregateDeviceAux(std::vector<AudioDeviceID> captureDeviceID, std::vector<AudioDeviceID> playbackDeviceID, int& sample_rate)
+        {
+            OSStatus osErr = noErr;
+            UInt32 outSize;
+            Boolean outWritable;
+            bool fClockDriftCompensate = true;
+            
+            // Prepare sub-devices for clock drift compensation
+            // Workaround for bug in the HAL : until 10.6.2
+            AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+            AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+            UInt32 theQualifierDataSize = sizeof(AudioObjectID);
+            AudioClassID inClass = kAudioSubDeviceClassID;
+            void* theQualifierData = &inClass;
+            UInt32 subDevicesNum = 0;
+            
+            //---------------------------------------------------------------------------
+            // Setup SR of both devices otherwise creating AD may fail...
+            //---------------------------------------------------------------------------
+            UInt32 keptclockdomain = 0;
+            UInt32 clockdomain = 0;
+            outSize = sizeof(UInt32);
+            bool need_clock_drift_compensation = false;
+            
+            for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
+                if (SetupSampleRateAux(captureDeviceID[i], sample_rate) < 0) {
+                    printf("TCoreAudioRenderer::CreateAggregateDeviceAux : cannot set SR of input device\n");
+                } else  {
+                    // Check clock domain
+                    osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
+                    if (osErr != 0) {
+                        printf("TCoreAudioRenderer::CreateAggregateDeviceAux : kAudioDevicePropertyClockDomain error\n");
+                        printError(osErr);
+                    } else {
+                        keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
+                        //printf("TCoreAudioRenderer::CreateAggregateDevice : input clockdomain = %d\n", clockdomain);
+                        if (clockdomain != 0 && clockdomain != keptclockdomain) {
+                            //printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n");
+                            need_clock_drift_compensation = true;
+                        }
+                    }
+                }
+            }
+            
+            for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
+                if (SetupSampleRateAux(playbackDeviceID[i], sample_rate) < 0) {
+                    printf("TCoreAudioRenderer::CreateAggregateDeviceAux : cannot set SR of output device\n");
+                } else {
+                    // Check clock domain
+                    osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
+                    if (osErr != 0) {
+                        printf("TCoreAudioRenderer::CreateAggregateDeviceAux : kAudioDevicePropertyClockDomain error\n");
+                        printError(osErr);
+                    } else {
+                        keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
+                        //printf("TCoreAudioRenderer::CreateAggregateDevice : output clockdomain = %d", clockdomain);
+                        if (clockdomain != 0 && clockdomain != keptclockdomain) {
+                            //printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n");
+                            need_clock_drift_compensation = true;
+                        }
+                    }
+                }
+            }
+            
+            // If no valid clock domain was found, then assume we have to compensate...
+            if (keptclockdomain == 0) {
+                need_clock_drift_compensation = true;
+            }
+            
+            //---------------------------------------------------------------------------
+            // Start to create a new aggregate by getting the base audio hardware plugin
+            //---------------------------------------------------------------------------
+            
+            char device_name[256];
+            for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
+                GetDeviceNameFromID(captureDeviceID[i], device_name);
+                //printf("Separated input = '%s' \n", device_name);
+            }
+            
+            for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
+                GetDeviceNameFromID(playbackDeviceID[i], device_name);
+                //printf("Separated output = '%s' \n", device_name);
+            }
+            
+            osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable);
+            if (osErr != noErr) {
+                printf("TCoreAudioRenderer::CreateAggregateDeviceAux : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error\n");
+                printError(osErr);
+                return osErr;
+            }
+            
+            AudioValueTranslation pluginAVT;
+            CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio");
+            
+            pluginAVT.mInputData = &inBundleRef;
+            pluginAVT.mInputDataSize = sizeof(inBundleRef);
+            pluginAVT.mOutputData = &fAggregatePluginID;
+            pluginAVT.mOutputDataSize = sizeof(fAggregatePluginID);
+            
+            osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT);
+            if (osErr != noErr) {
+                printf("TCoreAudioRenderer::CreateAggregateDeviceAux : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error\n");
+                printError(osErr);
+                return osErr;
+            }
+            
+            //-------------------------------------------------
+            // Create a CFDictionary for our aggregate device
+            //-------------------------------------------------
+            
+            CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            
+            char buffer1[64];
+            char buffer2[64];
+            
+            // generate "random" name
+            struct timeval fTv1;
+            struct timezone tz;
+            gettimeofday(&fTv1, &tz);
+            
+            sprintf(buffer1, "com.grame.%d", fTv1.tv_sec + fTv1.tv_usec);
+            sprintf(buffer2, "%d", fTv1.tv_sec + fTv1.tv_usec);
+            
+            CFStringRef AggregateDeviceNameRef = CFStringCreateWithCString(kCFAllocatorDefault, buffer1, CFStringGetSystemEncoding());
+            CFStringRef AggregateDeviceUIDRef = CFStringCreateWithCString(kCFAllocatorDefault, buffer2, CFStringGetSystemEncoding());
+            
+            // add the name of the device to the dictionary
+            CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef);
+            
+            // add our choice of UID for the aggregate device to the dictionary
+            CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef);
+            
+            // add a "private aggregate key" to the dictionary
+            int value = 1;
+            CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value);
+            
+            SInt32 system;
+            Gestalt(gestaltSystemVersion, &system);
+            
+            //printf("TCoreAudioRenderer::CreateAggregateDevice : system version = %x limit = %x\n", system, 0x00001054);
+            
+            // Starting with 10.5.4 systems, the AD can be internal... (better)
+            if (system < 0x00001054) {
+                //printf("TCoreAudioRenderer::CreateAggregateDevice : public aggregate device....\n");
+            } else {
+                //printf("TCoreAudioRenderer::CreateAggregateDevice : private aggregate device....\n");
+                CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef);
+            }
+            
+            // Prepare sub-devices for clock drift compensation
+            CFMutableArrayRef subDevicesArrayClock = NULL;
+            
+            /*
+             if (fClockDriftCompensate) {
+                 if (need_clock_drift_compensation) {
+                     jack_info("Clock drift compensation activated...");
+                     subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                     
+                     for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
+                         CFStringRef UID = GetDeviceName(captureDeviceID[i]);
+                         if (UID) {
+                         CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                         CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID);
+                         CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef);
+                         //CFRelease(UID);
+                         CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
+                     }
+                 }
+                 
+                 for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
+                     CFStringRef UID = GetDeviceName(playbackDeviceID[i]);
+                     if (UID) {
+                         CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                         CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID);
+                         CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef);
+                         //CFRelease(UID);
+                         CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
+                     }
+                 }
+                     
+                     // add sub-device clock array for the aggregate device to the dictionary
+                     CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock);
+                     } else {
+                     jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)");
+                 }
+            }
+            */
+            
+            //-------------------------------------------------
+            // Create a CFMutableArray for our sub-device list
+            //-------------------------------------------------
+            
+            // we need to append the UID for each device to a CFMutableArray, so create one here
+            CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+            
+            std::vector<CFStringRef> captureDeviceUID;
+            for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
+                CFStringRef ref = GetDeviceName(captureDeviceID[i]);
+                if (ref == NULL) {
+                    return -1;
+                }
+                captureDeviceUID.push_back(ref);
+                // input sub-devices in this example, so append the sub-device's UID to the CFArray
+                CFArrayAppendValue(subDevicesArray, ref);
+            }
+            
+            std::vector<CFStringRef> playbackDeviceUID;
+            for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
+                CFStringRef ref = GetDeviceName(playbackDeviceID[i]);
+                if (ref == NULL) {
+                    return -1;
+                }
+                playbackDeviceUID.push_back(ref);
+                // output sub-devices in this example, so append the sub-device's UID to the CFArray
+                CFArrayAppendValue(subDevicesArray, ref);
+            }
+            
+            //-----------------------------------------------------------------------
+            // Feed the dictionary to the plugin, to create a blank aggregate device
+            //-----------------------------------------------------------------------
+            
+            AudioObjectPropertyAddress pluginAOPA;
+            pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice;
+            pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
+            pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
+            UInt32 outDataSize;
+            
+            osErr = AudioObjectGetPropertyDataSize(fAggregatePluginID, &pluginAOPA, 0, NULL, &outDataSize);
+            if (osErr != noErr) {
+                printf("TCoreAudioRenderer::CreateAggregateDeviceAux : AudioObjectGetPropertyDataSize error\n");
+                printError(osErr);
+                goto error;
+            }
+            
+            osErr = AudioObjectGetPropertyData(fAggregatePluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, &fAggregateDeviceID);
+            if (osErr != noErr) {
+                printf("TCoreAudioRenderer::CreateAggregateDeviceAux : AudioObjectGetPropertyData error\n");
+                printError(osErr);
+                goto error;
+            }
+            
+            // pause for a bit to make sure that everything completed correctly
+            // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created
+            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
+            
+            //-------------------------
+            // Set the sub-device list
+            //-------------------------
+            
+            pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList;
+            pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
+            pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
+            outDataSize = sizeof(CFMutableArrayRef);
+            osErr = AudioObjectSetPropertyData(fAggregateDeviceID, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray);
+            if (osErr != noErr) {
+                printf("TCoreAudioRenderer::CreateAggregateDeviceAux : AudioObjectSetPropertyData for sub-device list error\n");
+                printError(osErr);
+                goto error;
+            }
+            
+            // pause again to give the changes time to take effect
+            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
+            
+            //-----------------------
+            // Set the master device
+            //-----------------------
+            
+            // set the master device manually (this is the device which will act as the master clock for the aggregate device)
+            // pass in the UID of the device you want to use
+            pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice;
+            pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
+            pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
+            outDataSize = sizeof(CFStringRef);
+            osErr = AudioObjectSetPropertyData(fAggregateDeviceID, &pluginAOPA, 0, NULL, outDataSize, &playbackDeviceUID[0]);  // First playback is master...
+            if (osErr != noErr) {
+                printf("TCoreAudioRenderer::CreateAggregateDeviceAux : AudioObjectSetPropertyData for master device error\n");
+                printError(osErr);
+                goto error;
+            }
+            
+            // pause again to give the changes time to take effect
+            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
+            
+            // Prepare sub-devices for clock drift compensation
+            // Workaround for bug in the HAL : until 10.6.2
+            
+            if (fClockDriftCompensate) {
+                if (need_clock_drift_compensation) {
+                    //printf("Clock drift compensation activated...\n");
+                    
+                    // Get the property data size
+                    osErr = AudioObjectGetPropertyDataSize(fAggregateDeviceID, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize);
+                    if (osErr != noErr) {
+                        printf("TCoreAudioRenderer::CreateAggregateDeviceAux kAudioObjectPropertyOwnedObjects error\n");
+                        printError(osErr);
+                    }
+                    
+                    //	Calculate the number of object IDs
+                    subDevicesNum = outSize / sizeof(AudioObjectID);
+                    //printf("TCoreAudioRenderer::CreateAggregateDevice clock drift compensation, number of sub-devices = %d\n", subDevicesNum);
+                    AudioObjectID subDevices[subDevicesNum];
+                    outSize = sizeof(subDevices);
+                    
+                    osErr = AudioObjectGetPropertyData(fAggregateDeviceID, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices);
+                    if (osErr != noErr) {
+                        printf("TCoreAudioRenderer::CreateAggregateDeviceAux kAudioObjectPropertyOwnedObjects error\n");
+                        printError(osErr);
+                    }
+                    
+                    // Set kAudioSubDevicePropertyDriftCompensation property...
+                    for (UInt32 index = 0; index < subDevicesNum; ++index) {
+                        UInt32 theDriftCompensationValue = 1;
+                        osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue);
+                        if (osErr != noErr) {
+                            printf("TCoreAudioRenderer::CreateAggregateDeviceAux kAudioSubDevicePropertyDriftCompensation error\n");
+                            printError(osErr);
+                        }
+                    }
+                } else {
+                    //printf("Clock drift compensation was asked but is not needed (devices use the same clock domain)\n");
+                }
+            }
+            
+            // pause again to give the changes time to take effect
+            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
+            
+            //----------
+            // Clean up
+            //----------
+            
+            // release the private AD key
+            CFRelease(AggregateDeviceNumberRef);
+            
+            // release the CF objects we have created - we don't need them any more
+            CFRelease(aggDeviceDict);
+            CFRelease(subDevicesArray);
+            
+            if (subDevicesArrayClock)
+                CFRelease(subDevicesArrayClock);
+            
+            // release the device UID
+            for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
+                CFRelease(captureDeviceUID[i]);
+            }
+            
+            for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) {
+                CFRelease(playbackDeviceUID[i]);
+            }
+            
+            //printf("New aggregate device %d\n", fAggregateDeviceID);
+            return noErr;
+            
+        error:
+            DestroyAggregateDevice();
+            return -1;
+        }
+
+        OSStatus DestroyAggregateDevice()
+        {   
+            // No more needed : will be done when process quits...
+            return noErr;
+        }
+
+        OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name)
+        {
+            UInt32 size = 256;
+            return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name);
+        }
+        
+        int SetupBufferSize(int buffer_size)
+        {
+            // Setting buffer size
+            OSStatus err = noErr;
+            UInt32 current_buffer_size = buffer_size;
+            UInt32 outSize; 
+            AudioValueRange buffer_size_range;
+            
+            outSize = sizeof(AudioValueRange);
+            err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSizeRange, &outSize, &buffer_size_range);
+            if (err != noErr) {
+                printf("Cannot get buffer size range\n");
+                printError(err);
+                return -1;
+            } else {
+                printf("SetupBufferSize : buffer size range min = %ld max = %ld\n", (int)buffer_size_range.mMinimum, (int)buffer_size_range.mMaximum);
+            }
+            
+            outSize = sizeof(UInt32);
+            err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &current_buffer_size);
+            if (err != noErr) {
+                printf("Cannot get buffer size\n");
+                printError(err);
+                return -1;
+            } else {
+                printf("SetupBufferSize : current buffer size %ld\n", current_buffer_size);
+            }
+
+            // If needed, set new buffer size
+            if (buffer_size != current_buffer_size && buffer_size >= (int)buffer_size_range.mMinimum && buffer_size <= (int)buffer_size_range.mMaximum) {
+                current_buffer_size = buffer_size;
+
+                // To get BS change notification
+                err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback, this);
+                if (err != noErr) {
+                    printf("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyBufferFrameSize\n");
+                    printError(err);
+                    return -1;
+                }
+
+                // Waiting for BS change notification
+                int count = 0;
+                fState = false;
+
+                err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, outSize, &current_buffer_size);
+                if (err != noErr) {
+                    printf("SetupBufferSize : cannot set buffer size = %ld\n", current_buffer_size);
+                    printError(err);
+                    goto error;
+                }
+
+                while (!fState && count++ < WAIT_NOTIFICATION_COUNTER) {
+                    usleep(100000);
+                    //printf("SetupBufferSize : wait count = %d\n", count);
+                }
+
+                if (count >= WAIT_NOTIFICATION_COUNTER) {
+                    printf("Did not get buffer size notification...\n");
+                    goto error;
+                }
+
+                // Check new buffer size
+                outSize = sizeof(UInt32);
+                err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &current_buffer_size);
+                if (err != noErr) {
+                    printf("Cannot get current buffer size\n");
+                    printError(err);
+                } else {
+                    //printf("SetupBufferSize : checked buffer size = %ld\n", current_buffer_size);
+                }
+
+                // Remove BS change notification
+                AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback);
+            } else {
+                printf("Keep current buffer size = %ld\n", current_buffer_size);
+            }
+            
+            fBufferSize = current_buffer_size;
+            return 0;
+
+        error:
+
+            // Remove BS change notification
+            AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback);
+            return -1;
+        }
+        
+        static OSStatus BSNotificationCallback(AudioDeviceID inDevice,
+                                                         UInt32 inChannel,
+                                                         Boolean isInput,
+                                                         AudioDevicePropertyID inPropertyID,
+                                                         void* inClientData)
+        {
+            TCoreAudioRenderer* driver = (TCoreAudioRenderer*)inClientData;
+        
+            switch (inPropertyID) {
+
+                case kAudioDevicePropertyBufferFrameSize: {
+                    printf("BSNotificationCallback kAudioDevicePropertyBufferFrameSize\n");
+                    // Check new buffer size
+                    UInt32 current_buffer_size;
+                    UInt32 outSize = sizeof(UInt32);
+                    OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &current_buffer_size);
+                    if (err != noErr) {
+                        printf("Cannot get current buffer size\n");
+                        printError(err);
+                    } else {
+                        printf("BSNotificationCallback : checked current buffer size = %d\n", current_buffer_size);
+                    }
+                    driver->fState = true;
+                    break;
+                }
+            }
+
+            return noErr;
+        }
+
+        int SetupSampleRateAux(AudioDeviceID inDevice, int& sample_rate)
+        {
+            OSStatus err = noErr;
+            UInt32 outSize = sizeof(Float64);
+            Float64 sampleRate = GetNominalSampleRate(inDevice);
+            
+            if (sample_rate != -1 && sample_rate != (int)sampleRate) {
+                sampleRate = (Float64)sample_rate;
+                
+                // To get SR change notification
+                err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this);
+                if (err != noErr) {
+                    printf("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate\n");
+                    printError(err);
+                    return -1;
+                }
+                err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate);
+                if (err != noErr) {
+                    printf("Cannot set sample rate = %d\n", sample_rate);
+                    printError(err);
+                    return -1;
+                }
+                
+                // Waiting for SR change notification
+                int count = 0;
+                while (!fState && count++ < WAIT_NOTIFICATION_COUNTER) {
+                    usleep(100000);
+                    //printf("Wait count = %d\n", count);
+                }
+                
+                // Check new sample rate
+                outSize = sizeof(Float64);
+                err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
+                if (err != noErr) {
+                    printf("Cannot get current sample rate\n");
+                    printError(err);
+                } else {
+                    //printf("Checked sample rate = %f\n", sampleRate);
+                }
+                
+                // Remove SR change notification
+                AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
+            }
+            
+            sample_rate = int(sampleRate);
+            return 0;
+        }   
+
+        static OSStatus Render(void *inRefCon,
+                           AudioUnitRenderActionFlags *ioActionFlags,
+                           const AudioTimeStamp *inTimeStamp,
+                           UInt32 inBusNumber,
+                           UInt32 inNumberFrames,
+                           AudioBufferList *ioData)
+        {
+            return static_cast<TCoreAudioRendererPtr>(inRefCon)->Render(ioActionFlags, inTimeStamp, inNumberFrames, ioData);
+        }
+
+        static OSStatus SRNotificationCallback(AudioDeviceID inDevice,
+                                            UInt32 inChannel,
+                                            Boolean	isInput,
+                                            AudioDevicePropertyID inPropertyID,
+                                               void* inClientData)
+        {
+            TCoreAudioRenderer* driver = (TCoreAudioRenderer*)inClientData;
+            
+            switch (inPropertyID) {
+                    
+                case kAudioDevicePropertyNominalSampleRate: {
+                    //printf("SRNotificationCallback kAudioDevicePropertyNominalSampleRate\n");
+                    driver->fState = true;
+                    // Check new sample rate
+                    Float64 sampleRate;
+                    UInt32 outSize = sizeof(Float64);
+                    OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
+                    if (err != noErr) {
+                        printf("Cannot get current sample rate\n");
+                        printError(err);
+                    } else {
+                        //printf("SRNotificationCallback : checked sample rate = %f\n", sampleRate);
+                    }
+                    break;
+                }
+            }
+            
+            return noErr;
+        }
+
+        virtual OSStatus Render(AudioUnitRenderActionFlags *ioActionFlags,
+                            const AudioTimeStamp *inTimeStamp,
+                            UInt32 inNumberFrames,
+                            AudioBufferList *ioData)
+        {
+            OSStatus err = noErr;
+            if (fDevNumInChans > 0) {
+                err = AudioUnitRender(fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, fInputData);
+            }
+            if (err == noErr) {
+                for (int i = 0; i < fDevNumInChans; i++) {
+                    fInChannel[i] = (float*)fInputData->mBuffers[i].mData;
+                }
+                for (int i = 0; i < fDevNumOutChans; i++) {
+                    fOutChannel[i] = (float*)ioData->mBuffers[i].mData;
+                }
+                fDSP->compute(inNumberFrames, fInChannel, fOutChannel);
+            } else {
+                printf("AudioUnitRender error... %x\n", fInputData);
+                printError(err);
+            }
+            return err;
+        }
+    
+        
+        
+    public:
+
+        TCoreAudioRenderer()
+            :fAggregateDeviceID(-1),fAggregatePluginID(-1),
+            fDevNumInChans(0),fDevNumOutChans(0),
+            fPhysicalInputs(0), fPhysicalOutputs(0),
+            fInChannel(0),fOutChannel(0),
+            fBufferSize(0),fSampleRate(0), 
+            fDSP(0),fInputData(0),
+            fDeviceID(0),fAUHAL(0),
+            fState(false), 
+            fIsInJackDevice(false),
+            fIsOutJackDevice(false)
+        {}
+
+        virtual ~TCoreAudioRenderer()
+        {}
+        
+        int GetBufferSize() {return fBufferSize;}
+        int GetSampleRate() {return fSampleRate;}
+        
+        static OSStatus RestartProc(AudioObjectID objectID, UInt32 numberAddresses,
+                                   const AudioObjectPropertyAddress inAddresses[],
+                                   void *clientData) 
+        {
+            /*
+            TCoreAudioRenderer* renderer = (TCoreAudioRenderer*)clientData;
+            AudioDeviceID defaultDevice;
+            UInt32 theSize = sizeof(UInt32);
+            OSStatus res;
+            char device_name[256];
+            
+            // Test if new device is "JackRouter"
+            if (inAddresses[0].mSelector == kAudioHardwarePropertyDefaultInputDevice) {
+                
+                if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+                                                    &theSize, &defaultDevice)) == noErr) {
+                    renderer->GetDeviceNameFromID(defaultDevice, device_name);
+                    renderer->fIsInJackDevice = strcmp(device_name, "JackRouter") == 0;
+                }
+                
+            } else  if (inAddresses[0].mSelector == kAudioHardwarePropertyDefaultOutputDevice) {
+                
+                if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+                                                    &theSize, &defaultDevice)) == noErr) {
+                    renderer->GetDeviceNameFromID(defaultDevice, device_name);
+                    renderer->fIsOutJackDevice = strcmp(device_name, "JackRouter") == 0;
+                }
+                
+            }
+            
+            // Switch only of input and output are "JackRouter"
+            if (renderer->fIsInJackDevice && renderer->fIsOutJackDevice || !renderer->fIsInJackDevice && !renderer->fIsOutJackDevice) {
+                renderer->Stop();
+                renderer->Close();
+                int sampleRate = -1; // Use the current sample rate
+                int bufferSize = (renderer->fBufferSize > 0) ? renderer->fBufferSize : 512; // Use default if needed
+                renderer->OpenDefault(renderer->fDSP, renderer->fDevNumInChans, renderer->fDevNumOutChans, bufferSize, sampleRate);
+                renderer->Start();
+            }
+            */
+            return 0;
+        }
+    
+        int OpenDefault(dsp* DSP, int inChan, int outChan, int bufferSize, int& sampleRate)
+        {
+            fDevNumInChans = 0;
+            fDevNumOutChans = 0;
+            fInChannel = 0;
+            fOutChannel = 0;
+            fBufferSize = 0;
+            fSampleRate = 0;
+            fDSP = 0;
+            fInputData = 0;
+            fDeviceID = 0; 
+            fAUHAL = 0;
+            fState = false;
+            OpenDefault(inChan, outChan, bufferSize, sampleRate);
+            set_dsp(DSP);
+        }
+    
+        int OpenDefault(int inChan, int outChan, int buffer_size, int& sample_rate)
+        {
+            OSStatus err;
+            UInt32 outSize;
+            UInt32 enableIO;
+            Boolean isWritable;
+            AudioStreamBasicDescription srcFormat, dstFormat, sampleRate;
+            
+            fDevNumInChans = inChan;
+            fDevNumOutChans = outChan;
+            
+            fInChannel = new float*[fDevNumInChans];
+            fOutChannel = new float*[fDevNumOutChans];
+            
+            //printf("OpenDefault inChan = %ld outChan = %ld bufferSize = %ld sample_rate = %ld\n", inChan, outChan, bufferSize, sample_rate);
+            
+            SInt32 major;
+            SInt32 minor;
+            Gestalt(gestaltSystemVersionMajor, &major);
+            Gestalt(gestaltSystemVersionMinor, &minor);
+            
+            // Starting with 10.6 systems, the HAL notification thread is created internally
+            if (major == 10 && minor >= 6) {
+                CFRunLoopRef theRunLoop = NULL;
+                AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+                OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
+                if (osErr != noErr) {
+                    printf("TCoreAudioRenderer::Open kAudioHardwarePropertyRunLoop error\n");
+                    printError(osErr);
+                }
+            }
+             
+            if (GetDefaultDeviceAndSampleRate(inChan, outChan, sample_rate, &fDeviceID) != noErr) {
+                printf("Cannot open default device\n");
+                return OPEN_ERR;
+            }
+             
+            // Setting buffer size
+            if (SetupBufferSize(buffer_size) < 0) {
+                return OPEN_ERR;
+            }
+            
+            // fBufferSize now has the real value, either 'bufferSize' (if could be changed) or driver current one
+            
+            // AUHAL
+        
+        #ifdef MAC_OS_X_VERSION_10_5
+            ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
+            Component HALOutput = FindNextComponent(NULL, &cd);
+            err = OpenAComponent(HALOutput, &fAUHAL);
+            if (err != noErr) {
+                printf("Error calling OpenAComponent\n");
+                printError(err);
+                goto error;
+            }
+        #else 
+            AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
+            AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd);
+            err = AudioComponentInstanceNew(HALOutput, &fAUHAL);
+            if (err != noErr) {
+                printf("Error calling AudioComponentInstanceNew\n");
+                printError(err);
+                goto error;
+            }
+        #endif
+            
+            err = AudioUnitInitialize(fAUHAL);
+            if (err != noErr) {
+                printf("Cannot initialize AUHAL unit\n");
+                printError(err);
+                goto error;
+            }
+            
+            if (inChan > 0) {
+                enableIO = 1;
+                printf("OpenAUHAL : setup AUHAL input on\n");
+            } else {
+                enableIO = 0;
+                printf("OpenAUHAL : setup AUHAL input off\n");
+            }
+            
+            err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
+            if (err != noErr) {
+                printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n");
+                printError(err);
+                goto error;
+            }
+                
+            if (outChan > 0) {
+                enableIO = 1;
+                printf("OpenAUHAL : setup AUHAL output on\n");
+            } else {
+                enableIO = 0;
+                printf("OpenAUHAL : setup AUHAL output off\n");
+            }
+            
+            err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
+            if (err != noErr) {
+                printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n");
+                printError(err);
+                goto error;
+            }
+            
+            AudioDeviceID currAudioDeviceID;
+            outSize = sizeof(AudioDeviceID);
+            err = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &outSize);
+            if (err != noErr) {
+                printf("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice\n");
+                printError(err);
+                goto error;
+            } else {
+                printf("AudioUnitGetPropertyCurrentDevice = %d\n", currAudioDeviceID);
+            }
+        
+            // Setup up choosen device, in both input and output cases
+            err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID));
+            printf("fDeviceID %d\n", fDeviceID);
+            if (err != noErr) {
+                printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n");
+                printError(err);
+                goto error;
+            }
+            
+            if (inChan > 0) {
+                err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&fBufferSize, sizeof(UInt32));
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
+                    printError(err);
+                    goto error;
+                }
+            }
+            
+            if (outChan > 0) {
+                err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&fBufferSize, sizeof(UInt32));
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
+                    printError(err);
+                    goto error;
+                }
+            }
+            
+            err = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable);
+            if (err != noErr) {
+                //printf("Error calling AudioUnitGetPropertyInfo - kAudioOutputUnitProperty_ChannelMap 1\n");
+                //printError(err);
+            } else {
+                fPhysicalInputs = (err == noErr) ? outSize / sizeof(SInt32) : 0;
+                printf("fPhysicalInputs = %ld\n", fPhysicalInputs);
+            }
+                    
+            err = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable);
+            if (err != noErr) {
+                //printf("Error calling AudioUnitGetPropertyInfo - kAudioOutputUnitProperty_ChannelMap 0\n");
+                //printError(err);
+            } else {
+                fPhysicalOutputs = (err == noErr) ? outSize / sizeof(SInt32) : 0;
+                printf("fPhysicalOutputs = %ld\n", fPhysicalOutputs);
+            }
+            
+            /*
+             Just ignore this case : seems to work without any further change...
+             
+             if (outChan > fPhysicalOutputs) {
+                printf("This device hasn't required output channels\n");
+                goto error;
+             }
+             if (inChan > fPhysicalInputs) {
+                printf("This device hasn't required input channels\n");
+                goto error;
+             }
+             */
+            
+            if (inChan < fPhysicalInputs) {
+                SInt32 chanArr[fPhysicalInputs];
+                for (int i = 0; i < fPhysicalInputs; i++) {
+                    chanArr[i] = -1;
+                }
+                for (int i = 0; i < inChan; i++) {
+                    chanArr[i] = i;
+                }
+                AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * fPhysicalInputs);
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n");
+                    printError(err);
+                }
+            }
+            
+            if (outChan < fPhysicalOutputs) {
+                SInt32 chanArr[fPhysicalOutputs];
+                for (int i = 0;	i < fPhysicalOutputs; i++) {
+                    chanArr[i] = -1;
+                }
+                for (int i = 0; i < outChan; i++) {
+                    chanArr[i] = i;
+                }
+                err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * fPhysicalOutputs);
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n");
+                    printError(err);
+                }
+            }
+            
+            if (inChan > 0) {
+                outSize = sizeof(AudioStreamBasicDescription);
+                err = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize);
+                if (err != noErr) {
+                    printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
+                    printError(err);
+                }
+                //PrintStreamDesc(&srcFormat);
+                
+                srcFormat.mSampleRate = sample_rate;
+                srcFormat.mFormatID = kAudioFormatLinearPCM;
+                srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
+                srcFormat.mBytesPerPacket = sizeof(float);
+                srcFormat.mFramesPerPacket = 1;
+                srcFormat.mBytesPerFrame = sizeof(float);
+                srcFormat.mChannelsPerFrame = inChan;
+                srcFormat.mBitsPerChannel = 32;
+                
+                //PrintStreamDesc(&srcFormat);
+                
+                err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
+                    printError(err);
+                }
+            }
+            
+            if (outChan > 0) {
+                outSize = sizeof(AudioStreamBasicDescription);
+                err = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize);
+                if (err != noErr) {
+                    printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
+                    printError(err);
+                }
+                //PrintStreamDesc(&dstFormat);
+                
+                dstFormat.mSampleRate = sample_rate;
+                dstFormat.mFormatID = kAudioFormatLinearPCM;
+                dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
+                dstFormat.mBytesPerPacket = sizeof(float);
+                dstFormat.mFramesPerPacket = 1;
+                dstFormat.mBytesPerFrame = sizeof(float);
+                dstFormat.mChannelsPerFrame = outChan;
+                dstFormat.mBitsPerChannel = 32;
+                
+                //PrintStreamDesc(&dstFormat);
+                
+                err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
+                    printError(err);
+                }
+            }
+            
+            if (inChan > 0 && outChan == 0) {
+                AURenderCallbackStruct output;
+                output.inputProc = Render;
+                output.inputProcRefCon = this;
+                err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output));
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n");
+                    printError(err);
+                    goto error;
+                }
+            } else {
+                AURenderCallbackStruct output;
+                output.inputProc = Render;
+                output.inputProcRefCon = this;
+                err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output));
+                if (err != noErr) {
+                    printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n");
+                    printError(err);
+                    goto error;
+                }
+            }
+            
+            if (inChan > 0) {
+                fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inChan * sizeof(AudioBuffer));
+                assert(fInputData);
+                fInputData->mNumberBuffers = inChan;
+                
+                // Prepare buffers
+                for (int i = 0; i < inChan; i++) {
+                    fInputData->mBuffers[i].mNumberChannels = 1;
+                    fInputData->mBuffers[i].mData = malloc(fBufferSize * sizeof(float));
+                    assert(fInputData->mBuffers[i].mData),
+                    fInputData->mBuffers[i].mDataByteSize = fBufferSize * sizeof(float);
+                }
+            }
+            
+            AudioObjectPropertyAddress property_address;
+            property_address.mScope = kAudioObjectPropertyScopeGlobal;
+            property_address.mElement = kAudioObjectPropertyElementMaster;
+            
+            property_address.mSelector = kAudioHardwarePropertyDefaultInputDevice;
+            if (AudioObjectAddPropertyListener(kAudioObjectSystemObject, &property_address, RestartProc, this)) {
+                printf("AudioObjectAddPropertyListener() failed\n");
+                return OPEN_ERR;
+            } else {
+                printf("AudioObjectAddPropertyListener() OK\n");
+            }
+            
+            property_address.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+            if (AudioObjectAddPropertyListener(kAudioObjectSystemObject, &property_address, RestartProc, this)) {
+                printf("AudioObjectAddPropertyListener() failed\n");
+                return OPEN_ERR;
+            } else {
+                printf("AudioObjectAddPropertyListener() OK\n");
+            }
+             
+            return NO_ERR;
+            
+        error:
+            AudioUnitUninitialize(fAUHAL);
+            CloseComponent(fAUHAL);
+            fAUHAL = 0;
+            return OPEN_ERR;
+        }
+        
+        int Close()
+        {
+            if (!fAUHAL) {
+                return CLOSE_ERR;
+            }
+            
+            for (int i = 0; i < fDevNumInChans; i++) {
+                free(fInputData->mBuffers[i].mData);
+            }
+            if (fInputData) {
+                free(fInputData);
+            }
+            AudioUnitUninitialize(fAUHAL);
+            CloseComponent(fAUHAL);
+            DestroyAggregateDevice();
+            
+            delete[] fInChannel;
+            delete[] fOutChannel;
+            
+            AudioObjectPropertyAddress property_address;
+            property_address.mScope = kAudioObjectPropertyScopeGlobal;
+            property_address.mElement = kAudioObjectPropertyElementMaster;
+            
+            property_address.mSelector = kAudioHardwarePropertyDefaultInputDevice;
+            AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &property_address, RestartProc, this);
+            
+            property_address.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+            AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &property_address, RestartProc, this);
+            
+            return NO_ERR;
+        }
+
+        int Start()
+        {
+            if (!fAUHAL) {
+                return OPEN_ERR;
+            }
+            
+            OSStatus err = AudioOutputUnitStart(fAUHAL);
+            
+            if (err != noErr) {
+                printf("Error while opening device : device open error \n");
+                return OPEN_ERR;
+            } else {
+                return NO_ERR;
+            }
+        }
+        
+        int Stop()
+        {
+            if (!fAUHAL) {
+                return OPEN_ERR;
+            }
+            
+            OSStatus err = AudioOutputUnitStop(fAUHAL);
+            
+            if (err != noErr) {
+                printf("Error while closing device : device close error \n");
+                return OPEN_ERR;
+            } else {
+                return NO_ERR;
+            }
+        }
+    
+        void set_dsp(dsp* DSP)
+        {
+            fDSP = DSP;
+        }
+        
+        int GetNumInputs() { return fPhysicalInputs; }
+        int GetNumOutputs() { return fPhysicalOutputs; }
+
+};
+
+/******************************************************************************
+*******************************************************************************
+
+							CORE AUDIO INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+class coreaudio : public audio {
+
+    TCoreAudioRenderer fAudioDevice;
+	int fSampleRate, fBufferSize;
+
+ public:
+  
+    coreaudio(int srate, int fpb) : fSampleRate(srate), fBufferSize(fpb) {}
+    coreaudio(int fpb) : fSampleRate(-1), fBufferSize(fpb) {}
+	virtual ~coreaudio() { fAudioDevice.Close(); }
+
+	virtual bool init(const char* /*name*/, dsp* DSP) 
+    {
+		if (fAudioDevice.OpenDefault(DSP, DSP->getNumInputs(), DSP->getNumOutputs(), fBufferSize, fSampleRate) < 0) {
+			printf("Cannot open CoreAudio device\n");
+			return false;
+		}
+        fAudioDevice.set_dsp(DSP);
+        // If -1 was given, fSampleRate will be changed by OpenDefault
+        DSP->init(fSampleRate);
+        return true;
+    }
+
+	virtual bool start() 
+    {
+		if (fAudioDevice.Start() < 0) {
+			printf("Cannot start CoreAudio device\n");
+			return false;
+		}
+		return true;
+	}
+
+	virtual void stop() 
+    {
+		fAudioDevice.Stop();
+	}
+    
+    virtual int get_buffer_size() { return fAudioDevice.GetBufferSize(); }
+    virtual int get_sample_rate() { return fAudioDevice.GetSampleRate(); }
+    
+    virtual int get_num_inputs() { return fAudioDevice.GetNumInputs(); }
+    virtual int get_num_outputs() { return fAudioDevice.GetNumOutputs(); }
+
+};
+
+#endif
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
diff --git a/architecture/faust/audio/coreaudio-ios-dsp.h b/architecture/faust/audio/coreaudio-ios-dsp.h
new file mode 100644
index 0000000..676ab5e
--- /dev/null
+++ b/architecture/faust/audio/coreaudio-ios-dsp.h
@@ -0,0 +1,755 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+ 
+#ifndef __coreaudio_ios_dsp__
+#define __coreaudio_ios_dsp__
+
+/* link with  */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <errno.h>
+#include <time.h>
+
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp.h"
+
+#include <AudioToolbox/AudioConverter.h>
+#include <AudioToolbox/AudioServices.h>
+#include <AudioUnit/AudioUnit.h>
+
+using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							COREAUDIO INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+#define OPEN_ERR -1
+#define NO_ERR 0
+
+class TiPhoneCoreAudioRenderer
+{
+    
+private:
+
+    AudioUnit fAUHAL;
+
+    int	fDevNumInChans;
+    int	fDevNumOutChans;
+
+    int fHWNumInChans;
+    int fHWNumOutChans;
+    
+    dsp* fDSP;
+
+    AudioBufferList* fCAInputData;
+
+    static OSStatus Render(void *inRefCon,
+                           AudioUnitRenderActionFlags *ioActionFlags,
+                           const AudioTimeStamp *inTimeStamp,
+                           UInt32 inBusNumber,
+                           UInt32 inNumberFrames,
+                           AudioBufferList *ioData);
+
+    static void InterruptionListener(void *inClientData, UInt32 inInterruption);
+    
+    static void AudioSessionPropertyListener(void* inClientData,
+                                             AudioSessionPropertyID inID,
+                                             UInt32 inDataSize,
+                                             const void* inData);
+    
+    OSStatus Render(AudioUnitRenderActionFlags *ioActionFlags,
+                     const AudioTimeStamp *inTimeStamp,
+                     UInt32 inNumberFrames,
+                     AudioBufferList *ioData);
+                     
+    int SetupMixing();
+
+public:
+
+    TiPhoneCoreAudioRenderer()
+        :fAUHAL(0), fDevNumInChans(0), fDevNumOutChans(0),
+        fHWNumInChans(0), fHWNumOutChans(0),
+        fDSP(0), fCAInputData(NULL)
+    {}
+
+    virtual ~TiPhoneCoreAudioRenderer()
+    {
+        if (fCAInputData) {
+            for (int i = 0; i < fDevNumInChans; i++) {
+                free(fCAInputData->mBuffers[i].mData);
+            }
+            free(fCAInputData);
+        }
+    }
+
+    int SetParameters(int bufferSize, int sampleRate);
+
+    int Open(dsp* dsp, int inChan, int outChan, int bufferSize, int sampleRate);
+    int Close();
+
+    int Start();
+    int Stop();
+
+};
+
+typedef TiPhoneCoreAudioRenderer* TiPhoneCoreAudioRendererPtr;
+
+static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
+{
+    printf("- - - - - - - - - - - - - - - - - - - -\n");
+    printf("  Sample Rate:%f\n", inDesc->mSampleRate);
+    printf("  Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID);
+    printf("  Format Flags:%lX\n", inDesc->mFormatFlags);
+    printf("  Bytes per Packet:%ld\n", inDesc->mBytesPerPacket);
+    printf("  Frames per Packet:%ld\n", inDesc->mFramesPerPacket);
+    printf("  Bytes per Frame:%ld\n", inDesc->mBytesPerFrame);
+    printf("  Channels per Frame:%ld\n", inDesc->mChannelsPerFrame);
+    printf("  Bits per Channel:%ld\n", inDesc->mBitsPerChannel);
+    printf("- - - - - - - - - - - - - - - - - - - -\n");
+}
+
+static void printError(OSStatus err)
+{
+    switch (err) {
+      	case kAudioConverterErr_FormatNotSupported:
+            printf("error code : kAudioConverterErr_FormatNotSupported\n");
+            break;
+        case kAudioConverterErr_OperationNotSupported:
+            printf("error code : kAudioConverterErr_OperationNotSupported\n");
+            break;
+        case kAudioConverterErr_PropertyNotSupported:
+            printf("error code : kAudioConverterErr_PropertyNotSupported\n");
+            break;
+        case kAudioConverterErr_InvalidInputSize:
+            printf("error code : kAudioConverterErr_InvalidInputSize\n");
+            break;
+        case kAudioConverterErr_InvalidOutputSize:
+            printf("error code : kAudioConverterErr_InvalidOutputSize\n");
+            break;
+        case kAudioConverterErr_UnspecifiedError:
+            printf("error code : kAudioConverterErr_UnspecifiedError\n");
+            break;
+        case kAudioConverterErr_BadPropertySizeError:
+            printf("error code : kAudioConverterErr_BadPropertySizeError\n");
+            break;
+        case kAudioConverterErr_RequiresPacketDescriptionsError:
+            printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n");
+            break;
+        case kAudioConverterErr_InputSampleRateOutOfRange:
+            printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n");
+            break;
+        case kAudioConverterErr_OutputSampleRateOutOfRange:
+            printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n");
+            break;
+        default:
+            printf("error code : unknown\n");
+            break;
+    }
+}
+
+OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon,
+                                         AudioUnitRenderActionFlags *ioActionFlags,
+                                         const AudioTimeStamp *inTimeStamp,
+                                         UInt32,
+                                         UInt32 inNumberFrames,
+                                         AudioBufferList *ioData)
+{
+    return static_cast<TiPhoneCoreAudioRendererPtr>(inRefCon)->Render(ioActionFlags, inTimeStamp, inNumberFrames, ioData);
+}
+
+OSStatus TiPhoneCoreAudioRenderer::Render(AudioUnitRenderActionFlags *ioActionFlags,
+                                         const AudioTimeStamp *inTimeStamp,
+                                         UInt32 inNumberFrames,
+                                         AudioBufferList *ioData)
+{
+    OSStatus err = noErr;
+    
+    if (fDevNumInChans > 0) {
+        err = AudioUnitRender(fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, fCAInputData);
+    }
+    
+    if (err == noErr) {
+        float* fInChannel[fDevNumInChans];
+        float* fOutChannel[fDevNumOutChans];
+        
+        for (int chan = 0; chan < fDevNumInChans; chan++) {
+            fInChannel[chan] = (float*)fCAInputData->mBuffers[chan].mData;
+        }
+     
+        for (int chan = 0; chan < fDevNumOutChans; chan++) {
+            fOutChannel[chan] = (float*)ioData->mBuffers[chan].mData;
+        }
+        
+        fDSP->compute((int)inNumberFrames, fInChannel, fOutChannel);
+    }
+ 	return err;
+}
+
+void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 inInterruption)
+{
+	TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inClientData;
+	printf("Session interrupted! --- %s ---", (inInterruption == kAudioSessionBeginInterruption) ? "Begin Interruption" : "End Interruption");
+
+	if (inInterruption == kAudioSessionEndInterruption) {
+		// Make sure we are again the active session
+		AudioSessionSetActive(true);
+        obj->SetupMixing();
+        AudioOutputUnitStart(obj->fAUHAL);
+	}
+
+	if (inInterruption == kAudioSessionBeginInterruption) {
+		AudioOutputUnitStop(obj->fAUHAL);
+    }
+}
+
+int TiPhoneCoreAudioRenderer::SetupMixing()
+{
+    OSStatus err;
+    
+    /*
+    01/07/2014 : cause iRig to fail, so deactivated for now...
+    CFStringRef route;
+    UInt32 routesize = sizeof(route);
+    OSStatus err  = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &routesize, &route);
+    if (err == noErr) {
+        if (CFStringCompare(route, CFSTR("ReceiverAndMicrophone"), 0) == kCFCompareEqualTo || CFStringCompare(route,CFSTR("Receiver"), 0) == kCFCompareEqualTo) {
+            // Re-route audio to the speaker (not the receiver, which no music app will ever want)
+            printf("Rerouting audio to speaker\n");
+            UInt32 newRoute = kAudioSessionOverrideAudioRoute_Speaker;
+            AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(newRoute), &newRoute);
+        }
+    }
+    */
+    
+    UInt32 allowMixing = true;
+    err = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
+    if (err != noErr) {
+        printf("Could not set audio session mixing\n");
+        printError(err);
+        return -1;
+    } else {
+        return 0;
+    }
+}
+   
+void TiPhoneCoreAudioRenderer::AudioSessionPropertyListener(void* inClientData,
+                                                             AudioSessionPropertyID inID,
+                                                             UInt32 inDataSize,
+                                                             const void* inData)
+{
+    TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inData;
+    switch (inID) {
+        case kAudioSessionProperty_ServerDied: {
+            printf("kAudioSessionProperty_ServerDied\n");
+            break;
+        }
+        case kAudioSessionProperty_AudioRouteChange: {
+            printf("kAudioSessionProperty_AudioRouteChange\n");
+            obj->SetupMixing();
+            break;
+        }
+        case kAudioSessionProperty_AudioInputAvailable: {
+            printf("kAudioSessionProperty_AudioInputAvailable\n");
+            obj->SetupMixing();
+            break;
+        }
+    }
+}
+
+static int SetAudioCategory(int input, int output)
+{
+    // Set the audioCategory the way Faust DSP wants
+    UInt32 audioCategory;
+    if ((input > 0) && (output > 0)) {
+        audioCategory = kAudioSessionCategory_PlayAndRecord;
+        printf("AudioCategory kAudioSessionCategory_PlayAndRecord\n");
+    } else if (input > 0) {
+        audioCategory = kAudioSessionCategory_RecordAudio;
+        printf("AudioCategory kAudioSessionCategory_RecordAudio\n");
+    } else  if (output > 0) {
+        audioCategory = kAudioSessionCategory_MediaPlayback;
+        printf("AudioCategory kAudioSessionCategory_MediaPlayback\n");
+    }
+    
+    OSStatus err = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
+    if (err != noErr) {
+        printf("Couldn't set audio category\n");
+        printError(err);
+        return OPEN_ERR;
+    }
+     
+    // 09/07/2015 : https://developer.apple.com/library/ios/qa/qa1754/_index.html
+    if (audioCategory == kAudioSessionCategory_PlayAndRecord) {
+        UInt32 overrideAudioRoute = 1;
+        err = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(UInt32), &overrideAudioRoute);
+        if (err != noErr) {
+            printf("Error setting kAudioSessionProperty_OverrideCategoryDefaultToSpeaker\n");
+            printError(err);
+        }
+    }
+    
+#if DISABLE_AGC
+    // If input is used, disable AGC
+    if (audioCategory == kAudioSessionCategory_RecordAudio || audioCategory == kAudioSessionCategory_PlayAndRecord) {
+        
+        UInt32 sessionMode = kAudioSessionMode_Measurement;
+        err = AudioSessionSetProperty(kAudioSessionProperty_Mode, sizeof(sessionMode), &sessionMode);
+        if (err != noErr) {
+            printf("Error setting kAudioSessionMode_Measurement\n");
+            printError(err);
+        }
+        
+        UInt32 availableGain;
+        UInt32 outSize = sizeof(availableGain);
+        err = AudioSessionGetProperty(kAudioSessionProperty_InputGainAvailable, &outSize, &availableGain);
+        if (err != noErr) {
+            printf("Error getting kAudioSessionProperty_InputGainAvailable\n");
+            printError(err);
+        } else {
+            Float32 gain;
+            printf("Getting kAudioSessionProperty_InputGainAvailable OK\n");
+            outSize = sizeof(Float32);
+            AudioSessionGetProperty(kAudioSessionProperty_InputGainScalar, &outSize, &gain);
+            printf("Getting kAudioSessionProperty_InputGainScalar :  %f\n", gain);
+            gain = 1.0f;
+            err = AudioSessionSetProperty(kAudioSessionProperty_InputGainScalar, sizeof(Float32), &gain);
+            if (err != noErr) {
+                printf("Error setting kAudioSessionProperty_InputGainScalar\n");
+                printError(err);
+            } else {
+                printf("Setting kAudioSessionProperty_InputGainAvailable to 1.0 OK\n");
+            }
+        }
+    }
+#endif
+  
+    return NO_ERR;
+}
+
+int TiPhoneCoreAudioRenderer::SetParameters(int bufferSize, int samplerate)
+{
+    OSStatus err;
+    UInt32 outSize;
+    UInt32 enableIO;
+	AudioStreamBasicDescription srcFormat, dstFormat;
+    
+    printf("SetParameters fDevNumInChans = %d fDevNumOutChans = %d bufferSize = %d samplerate = %d\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate);
+    
+    err = AudioSessionSetActive(true);
+    if (err != noErr) {
+        printf("Couldn't set audio session active\n");
+        printError(err);
+        return OPEN_ERR;
+    }
+    
+    AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, AudioSessionPropertyListener, this);
+    AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, AudioSessionPropertyListener, this);
+    AudioSessionAddPropertyListener(kAudioSessionProperty_ServerDied, AudioSessionPropertyListener, this);
+    
+    if (SetAudioCategory(fDevNumInChans, fDevNumOutChans) != NO_ERR) {
+        return OPEN_ERR;
+    }
+    
+    // Scan Hardware
+    outSize = sizeof(fHWNumInChans);
+    err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &fHWNumInChans);
+    if (err != noErr) {
+        fHWNumInChans = 0;
+        printf("Couldn't get hw input channels\n");
+        printError(err);
+    } else {
+        printf("Get hw input channels %d\n", fHWNumInChans);
+    }
+    
+    outSize = sizeof(fHWNumOutChans);
+    err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &fHWNumOutChans);
+    if (err != noErr) {
+        fHWNumOutChans = 0;
+        printf("Couldn't get hw output channels\n");
+        printError(err);
+    } else {
+        printf("Get hw output channels %d\n", fHWNumOutChans);
+    }
+
+    // Possibly reset the audioCategory the way hardware allows
+    if (SetAudioCategory(fHWNumInChans, fHWNumOutChans) != NO_ERR) {
+        return OPEN_ERR;
+    }
+    
+    if (SetupMixing() < 0) {
+        return OPEN_ERR;
+    }
+    
+    Float64 hwSampleRate;
+    outSize = sizeof(hwSampleRate);
+	err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &outSize, &hwSampleRate);
+    if (err != noErr) {
+        printf("Couldn't get hw sample rate\n");
+        printError(err);
+        return OPEN_ERR;
+    } else {
+        printf("Get hw sample rate %f\n", hwSampleRate);
+    }
+    
+    Float32 hwBufferSize;
+    outSize = sizeof(hwBufferSize);
+	err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &outSize, &hwBufferSize);
+    if (err != noErr) {
+        printf("Couldn't get hw buffer duration\n");
+        printError(err);
+        return OPEN_ERR;
+    } else {
+        printf("Get hw buffer duration %f\n", hwBufferSize);
+    }
+    
+    Float32 preferredPeriodDuration = float(bufferSize) / float(samplerate);
+    printf("preferredPeriodDuration %f \n", preferredPeriodDuration);
+    
+	err = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredPeriodDuration), &preferredPeriodDuration);
+    if (err != noErr) {
+        printf("Couldn't set i/o buffer duration\n");
+        printError(err);
+        return OPEN_ERR;
+    }
+    
+    Float32 actualPeriodDuration;
+    outSize = sizeof(actualPeriodDuration);
+    err = AudioSessionGetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, &outSize, &actualPeriodDuration);
+    if (err != noErr) {
+        printf("Couldn't get hw buffer duration\n");
+        printError(err);
+        return OPEN_ERR;
+    }
+    
+    printf("preferredPeriodDuration %f actualPeriodDuration %f\n", preferredPeriodDuration, actualPeriodDuration);
+    if (preferredPeriodDuration != actualPeriodDuration) {
+        printf("Couldn't set hw buffer duration\n");
+        return OPEN_ERR;
+    }
+    
+    Float64 preferredSamplerate = float(samplerate);
+	err = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(preferredSamplerate), &preferredSamplerate);
+    if (err != noErr) {
+        printf("Couldn't set i/o sample rate\n");
+        printError(err);
+        return OPEN_ERR;
+    }
+    
+    Float32 inputLatency;
+    outSize = sizeof(inputLatency);
+    err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputLatency, &outSize, &inputLatency);
+    if (err != noErr) {
+        printf("Couldn't get inputLatency\n");
+        printError(err);
+    } else {
+        printf("inputLatency in sec : %f\n", inputLatency);
+    }
+    
+    Float32 outputLatency;
+    outSize = sizeof(outputLatency);
+    err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputLatency, &outSize, &outputLatency);
+    if (err != noErr) {
+        printf("Couldn't get outputLatency\n");
+        printError(err);
+    } else {
+        printf("outputLatency in sec : %f\n", outputLatency);
+    }
+    
+    // AUHAL
+    AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple, 0, 0};
+    AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd);
+    
+    err = AudioComponentInstanceNew(HALOutput, &fAUHAL);
+    if (err != noErr) {
+		printf("Error calling OpenAComponent\n");
+        printError(err);
+        goto error;
+	}
+    
+    enableIO = 1;
+    err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
+    if (err != noErr) {
+        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n");
+        printError(err);
+        goto error;
+    }
+    
+    enableIO = 1;
+    err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
+    if (err != noErr) {
+        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n");
+        printError(err);
+        goto error;
+    }
+    
+    UInt32 maxFPS;
+    outSize = sizeof(maxFPS);
+    err = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &outSize);
+    if (err != noErr) {
+        printf("Couldn't get kAudioUnitProperty_MaximumFramesPerSlice\n");
+        printError(err);
+        goto error;
+    } else {
+        printf("Get kAudioUnitProperty_MaximumFramesPerSlice %d\n", (unsigned int)maxFPS);
+    }
+    
+    err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32));
+    if (err != noErr) {
+        printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
+        printError(err);
+        goto error;
+    }
+    
+    err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32));
+    if (err != noErr) {
+        printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
+        printError(err);
+        goto error;
+    }
+    
+    err = AudioUnitInitialize(fAUHAL);
+    if (err != noErr) {
+		printf("Cannot initialize AUHAL unit\n");
+		printError(err);
+        goto error;
+	}
+    
+    // Setting format
+    if (fDevNumInChans > 0) {
+        outSize = sizeof(AudioStreamBasicDescription);
+        err = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize);
+        if (err != noErr) {
+            printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
+            printError(err);
+        }
+        PrintStreamDesc(&srcFormat);
+        
+        srcFormat.mFormatID = kAudioFormatLinearPCM;
+        srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
+        srcFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
+        srcFormat.mFramesPerPacket = 1;
+        srcFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
+        srcFormat.mChannelsPerFrame = fDevNumInChans;
+        srcFormat.mBitsPerChannel = 32;
+        
+        PrintStreamDesc(&srcFormat);
+        
+        err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
+        if (err != noErr) {
+            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
+            printError(err);
+        }
+    }
+    
+    if (fDevNumOutChans > 0) {
+        outSize = sizeof(AudioStreamBasicDescription);
+        err = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize);
+        if (err != noErr) {
+            printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n");
+            printError(err);
+        }
+        PrintStreamDesc(&dstFormat);
+        
+        dstFormat.mFormatID = kAudioFormatLinearPCM;
+        dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
+        dstFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
+        dstFormat.mFramesPerPacket = 1;
+        dstFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
+        dstFormat.mChannelsPerFrame = fDevNumOutChans;
+        dstFormat.mBitsPerChannel = 32;
+        
+        PrintStreamDesc(&dstFormat);
+        
+        err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
+        if (err != noErr) {
+            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n");
+            printError(err);
+        }
+    }
+    
+    if (fDevNumInChans > 0 && fDevNumOutChans == 0) {
+        AURenderCallbackStruct output;
+        output.inputProc = Render;
+        output.inputProcRefCon = this;
+        err = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output));
+        if (err != noErr) {
+            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n");
+            printError(err);
+            goto error;
+        }
+    } else {
+        AURenderCallbackStruct output;
+        output.inputProc = Render;
+        output.inputProcRefCon = this;
+        err = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output));
+        if (err != noErr) {
+            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n");
+            printError(err);
+            goto error;
+        }
+    }
+    
+    // Possibly prepare input buffers
+    if (fDevNumInChans > 0) {
+        fCAInputData = (AudioBufferList*)malloc(sizeof(float) + fDevNumInChans * sizeof(AudioBuffer));
+        fCAInputData->mNumberBuffers = fDevNumInChans;
+        for (int i = 0; i < fDevNumInChans; i++) {
+            fCAInputData->mBuffers[i].mNumberChannels = 1;
+            fCAInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(float);
+            fCAInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(float));
+        }
+    }
+    
+    return NO_ERR;
+    
+error:
+    AudioUnitUninitialize(fAUHAL);
+    AudioComponentInstanceDispose(fAUHAL);
+    return OPEN_ERR;
+}
+
+int TiPhoneCoreAudioRenderer::Open(dsp* dsp, int inChan, int outChan, int buffersize, int samplerate)
+{
+    fDSP = dsp;
+    fDevNumInChans = inChan;
+    fDevNumOutChans = outChan;
+    
+    // Initialize and configure the audio session
+    OSStatus err = AudioSessionInitialize(NULL, NULL, InterruptionListener, this);
+    if (err != noErr && err != kAudioSessionAlreadyInitialized) {
+        printf("Couldn't initialize audio session\n");
+        printError(err);
+        return OPEN_ERR;
+    }
+    
+    if (SetParameters(buffersize, samplerate) < 0) {
+        printf("Cannot set parameters to CoreAudio device\n");
+        return OPEN_ERR;
+    }
+    
+    return NO_ERR;
+}
+
+int TiPhoneCoreAudioRenderer::Close()
+{
+ 	AudioUnitUninitialize(fAUHAL);
+    AudioComponentInstanceDispose(fAUHAL);
+    return NO_ERR;
+}
+
+int TiPhoneCoreAudioRenderer::Start()
+{
+    AudioSessionSetActive(true);
+   
+    if (AudioOutputUnitStart(fAUHAL) != noErr) {
+        printf("Error while opening device : device open error\n");
+        return OPEN_ERR;
+    } else {
+        return NO_ERR;
+	}
+}
+
+int TiPhoneCoreAudioRenderer::Stop()
+{
+    AudioSessionSetActive(false);
+    
+    if (AudioOutputUnitStop(fAUHAL) != noErr) {
+        printf("Error while closing device : device close error\n");
+        return OPEN_ERR;
+    } else {
+        return NO_ERR;
+	}
+}
+
+/******************************************************************************
+ *******************************************************************************
+ 
+                                CORE AUDIO INTERFACE
+ 
+ *******************************************************************************
+ *******************************************************************************/
+class iosaudio : public audio {
+
+protected:
+    
+    TiPhoneCoreAudioRenderer fAudioDevice;
+	int fSampleRate, fBufferSize;
+    
+public:
+    iosaudio(int srate, int fpb) : fSampleRate(srate), fBufferSize(fpb) {}
+	virtual ~iosaudio() { fAudioDevice.Close(); }
+    
+	virtual bool init(const char* /*name*/, dsp* DSP) 
+    {
+    	DSP->init(fSampleRate);
+		if (fAudioDevice.Open(DSP, DSP->getNumInputs(), DSP->getNumOutputs(), fBufferSize, fSampleRate) < 0) {
+			printf("Cannot open iOS audio device\n");
+    		return false;
+		}
+        return true;
+    }
+    
+	virtual bool start() 
+    {
+		if (fAudioDevice.Start() < 0) {
+			printf("Cannot start iOS audio device\n");
+			return false;
+		}
+		return true;
+	}
+    
+	virtual void stop() 
+    {
+		fAudioDevice.Stop();
+	}
+    
+    virtual int get_buffer_size() { return fBufferSize; }
+    virtual int get_sample_rate() { return fSampleRate; }
+    
+};
+
+#endif
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
diff --git a/architecture/faust/audio/dsp-adapter.h b/architecture/faust/audio/dsp-adapter.h
new file mode 100644
index 0000000..061d026
--- /dev/null
+++ b/architecture/faust/audio/dsp-adapter.h
@@ -0,0 +1,105 @@
+/************************************************************************
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __dsp_adapter__
+#define __dsp_adapter__
+
+#include <string.h>
+#include "faust/audio/dsp.h"
+
+class dsp_adapter : public dsp {
+    
+private:
+    
+    FAUSTFLOAT** fAdaptedInputs;
+    FAUSTFLOAT** fAdaptedOutputs;
+    int fHardwareInputs;
+    int fHardwareOutputs;
+    dsp* fDsp;
+    
+public:
+    
+    dsp_adapter(dsp* dsp, int hardware_inputs, int hardware_outputs, int buffer_size)
+    {
+        fDsp = dsp;
+        fHardwareInputs = hardware_inputs;
+        fHardwareOutputs = hardware_outputs;
+        
+        fAdaptedInputs = new FAUSTFLOAT*[dsp->getNumInputs()];
+        for (int i = 0; i < dsp->getNumInputs() - hardware_inputs; i++) {
+            fAdaptedInputs[i + hardware_inputs] = new FAUSTFLOAT[buffer_size];
+            memset(fAdaptedInputs[i + hardware_inputs], 0, sizeof(FAUSTFLOAT) * buffer_size);
+        }
+        
+        fAdaptedOutputs = new FAUSTFLOAT*[dsp->getNumOutputs()];
+        for (int i = 0; i < dsp->getNumOutputs() - hardware_outputs; i++) {
+            fAdaptedOutputs[i + hardware_outputs] = new FAUSTFLOAT[buffer_size];
+            memset(fAdaptedOutputs[i + hardware_outputs], 0, sizeof(FAUSTFLOAT) * buffer_size);
+        }
+    }
+    
+    virtual~ dsp_adapter()
+    {
+        for (int i = 0; i < fDsp->getNumInputs() - fHardwareInputs; i++) {
+            delete [] fAdaptedInputs[i + fHardwareInputs];
+        }
+        delete [] fAdaptedInputs;
+        
+        for (int i = 0; i < fDsp->getNumOutputs() - fHardwareOutputs; i++) {
+            delete [] fAdaptedOutputs[i + fHardwareOutputs];
+        }
+        delete [] fAdaptedOutputs;
+        
+        delete fDsp;
+    }
+    
+    int getNumInputs() 	{return fDsp->getNumInputs();}
+    int getNumOutputs() {return fDsp->getNumOutputs();}
+    void buildUserInterface(UI* ui_interface) {return fDsp->buildUserInterface(ui_interface);}
+    void init(int samplingRate) {return fDsp->init(samplingRate);}
+   
+    virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+    {
+        for (int i = 0; i < fHardwareInputs; i++) {
+            fAdaptedInputs[i] = inputs[i];
+        }
+        for (int i = 0; i < fHardwareOutputs; i++) {
+            fAdaptedOutputs[i] = outputs[i];
+        }
+        fDsp->compute(len, fAdaptedInputs, fAdaptedOutputs);
+    }
+};
+
+#endif
diff --git a/architecture/faust/audio/dsp.h b/architecture/faust/audio/dsp.h
new file mode 100644
index 0000000..9b5f9f1
--- /dev/null
+++ b/architecture/faust/audio/dsp.h
@@ -0,0 +1,86 @@
+/************************************************************************
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+ 
+/******************************************************************************
+*******************************************************************************
+
+								FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+#ifndef __dsp__
+#define __dsp__
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+class UI;
+
+//----------------------------------------------------------------
+//  Signal processor definition
+//----------------------------------------------------------------
+
+class dsp {
+
+ protected:
+	int fSamplingFreq;
+    
+ public:
+	dsp() {}
+	virtual ~dsp() {}
+
+	virtual int getNumInputs() 										= 0;
+	virtual int getNumOutputs() 									= 0;
+	virtual void buildUserInterface(UI* ui_interface) 				= 0;
+	virtual void init(int samplingRate) 							= 0;
+ 	virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) 	= 0;
+};
+
+// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
+// flags to avoid costly denormals
+#ifdef __SSE__
+    #include <xmmintrin.h>
+    #ifdef __SSE2__
+        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+    #else
+        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+    #endif
+#else
+    #define AVOIDDENORMALS
+#endif
+
+#endif
diff --git a/architecture/faust/audio/jack-dsp.h b/architecture/faust/audio/jack-dsp.h
new file mode 100644
index 0000000..4438f64
--- /dev/null
+++ b/architecture/faust/audio/jack-dsp.h
@@ -0,0 +1,474 @@
+/************************************************************************
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+ 
+#ifndef __jack_dsp__
+#define __jack_dsp__
+
+#include <stdio.h>
+#include <cstdlib>
+#include <list>
+#include <vector>
+#include <string.h>
+#include <jack/jack.h>
+#ifdef JACK_IOS
+#include <jack/custom.h>
+#endif
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp.h"
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#define snprintf _snprintf_s
+#endif
+
+/******************************************************************************
+*******************************************************************************
+
+							JACK AUDIO INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+class jackaudio : public audio {
+    
+    protected:
+
+        dsp*			fDsp;               // FAUST DSP
+        jack_client_t*	fClient;            // JACK client
+    
+        int				fNumInChans;		// number of input channels
+        int				fNumOutChans;       // number of output channels
+    
+        jack_port_t**	fInputPorts;        // JACK input ports
+        jack_port_t**	fOutputPorts;       // JACK output ports
+        
+        std::vector<char*> fPhysicalInputs;
+        std::vector<char*> fPhysicalOutputs;
+    
+        shutdown_callback fShutdown;        // Shutdown callback to be called by libjack
+        void*           fShutdownArg;       // Shutdown callback data
+        void*           fIconData;          // iOS specific
+        int             fIconSize;          // iOS specific
+        bool            fAutoConnect;       // autoconnect with system in/out ports
+        
+        std::list<std::pair<std::string, std::string> > fConnections;		// Connections list
+    
+        static int _jack_srate(jack_nframes_t nframes, void* arg)
+        {
+            fprintf(stdout, "The sample rate is now %u/sec\n", nframes);
+            return 0;
+        }
+        
+        static void _jack_shutdown(void* arg) 
+        {}
+       
+        static void _jack_info_shutdown(jack_status_t code, const char* reason, void* arg)
+        {
+            fprintf(stderr, "%s\n", reason);
+            static_cast<jackaudio*>(arg)->shutdown(reason);
+        }
+        
+        static int _jack_process(jack_nframes_t nframes, void* arg)
+        {
+            return static_cast<jackaudio*>(arg)->process(nframes);
+        }
+        
+        static int _jack_buffersize(jack_nframes_t nframes, void* arg)
+        {
+            fprintf(stdout, "The buffer size is now %u/sec\n", nframes);
+            return 0;
+        }
+     
+        #ifdef _OPENMP
+        static void* _jack_thread(void* arg)
+        {
+            jackaudio* audio = (jackaudio*)arg;
+            audio->process_thread();
+            return 0;
+        }
+        #endif
+        
+        void shutdown(const char* message)
+        {
+            fClient = NULL;
+            
+            if (fShutdown) {
+                fShutdown(message, fShutdownArg);
+            } else {
+                exit(1); // By default
+            }
+        }
+        
+        // Save client connections
+        void save_connections()
+        {
+            fConnections.clear();
+            
+             for (int i = 0; i < fNumInChans; i++) {
+                const char** connected_port = jack_port_get_all_connections(fClient, fInputPorts[i]);
+                if (connected_port != NULL) {
+                    for (int port = 0; connected_port[port]; port++) {
+                        fConnections.push_back(std::make_pair(connected_port[port], jack_port_name(fInputPorts[i])));
+//                        printf("INPUT %s ==> %s\n", connected_port[port], jack_port_name(fInputPorts[i]));
+                    }
+                    jack_free(connected_port);
+                }
+            }
+       
+            for (int i = 0; i < fNumOutChans; i++) {
+                const char** connected_port = jack_port_get_all_connections(fClient, fOutputPorts[i]);
+                if (connected_port != NULL) {
+                    for (int port = 0; connected_port[port]; port++) {
+                        fConnections.push_back(std::make_pair(jack_port_name(fOutputPorts[i]), connected_port[port]));
+//                        printf("OUTPUT %s ==> %s\n", jack_port_name(fOutputPorts[i]), connected_port[port]);
+                    }
+                    jack_free(connected_port);
+                }
+            }
+        }
+
+        // Load previous client connections
+        void load_connections()
+        {
+            std::list<std::pair<std::string, std::string> >::const_iterator it;
+            for (it = fConnections.begin(); it != fConnections.end(); it++) {
+                std::pair<std::string, std::string> connection = *it;
+                jack_connect(fClient, connection.first.c_str(), connection.second.c_str());
+            }
+        }
+     
+    #ifdef _OPENMP
+        void process_thread() 
+        {
+            jack_nframes_t nframes;
+            while (1) {
+                nframes = jack_cycle_wait(fClient);
+                process(nframes);
+                jack_cycle_signal(fClient, 0);
+            }
+        }
+    #endif
+    
+        // JACK callbacks
+        virtual int	process(jack_nframes_t nframes) 
+        {
+            AVOIDDENORMALS;
+            
+            // Retrieve JACK inputs/output audio buffers
+			float** fInChannel = (float**)alloca(fNumInChans*sizeof(float*));
+            for (int i = 0; i < fNumInChans; i++) {
+                fInChannel[i] = (float*)jack_port_get_buffer(fInputPorts[i], nframes);
+            }
+            
+			float** fOutChannel = (float**)alloca(fNumOutChans*sizeof(float*));
+            for (int i = 0; i < fNumOutChans; i++) {
+                fOutChannel[i] = (float*)jack_port_get_buffer(fOutputPorts[i], nframes);
+            }
+            
+            fDsp->compute(nframes, fInChannel, fOutChannel);
+            return 0;
+        }
+
+    public:
+    
+        jackaudio(const void* icon_data = 0, size_t icon_size = 0, bool auto_connect = true) 
+            : fDsp(0), fClient(0), fNumInChans(0), fNumOutChans(0), 
+            fInputPorts(0), fOutputPorts(0), 
+            fShutdown(0), fShutdownArg(0),
+            fAutoConnect(auto_connect)
+        {
+            if (icon_data) {
+                fIconData = malloc(icon_size);
+                fIconSize = icon_size;
+                memcpy(fIconData, icon_data, icon_size);
+            } else {
+                fIconData = NULL;
+                fIconSize = 0;
+            }
+        }
+        
+        virtual ~jackaudio() 
+        { 
+            if (fClient) {
+                stop();
+                
+                for (int i = 0; i < fNumInChans; i++) {
+                    jack_port_unregister(fClient, fInputPorts[i]);
+                }
+                for (int i = 0; i < fNumOutChans; i++) {
+                    jack_port_unregister(fClient, fOutputPorts[i]);
+                }
+                jack_client_close(fClient);
+                
+                delete[] fInputPorts;
+                delete[] fOutputPorts;
+                
+                if (fIconData) {
+                    free(fIconData);
+                }
+            }
+        }
+        
+        virtual bool init(const char* name, dsp* DSP) 
+        {
+            if (!init(name)) {
+                return false;
+            }
+            if (DSP) set_dsp(DSP);
+            return true;
+        }
+
+        virtual bool init(const char* name) 
+        {
+            if ((fClient = jack_client_open(name, JackNullOption, NULL)) == 0) {
+                fprintf(stderr, "JACK server not running ?\n");
+                return false;
+            }
+        #ifdef JACK_IOS
+            jack_custom_publish_data(fClient, "icon.png", fIconData, fIconSize);
+        #endif
+        
+        #ifdef _OPENMP
+            jack_set_process_thread(fClient, _jack_thread, this);
+        #else
+            jack_set_process_callback(fClient, _jack_process, this);
+        #endif
+        
+            jack_set_sample_rate_callback(fClient, _jack_srate, this);
+            jack_set_buffer_size_callback(fClient, _jack_buffersize, this);
+            jack_on_info_shutdown(fClient, _jack_info_shutdown, this);
+            
+            // Get Physical inputs
+            int inputs = 0;
+            char** physicalInPorts = (char**)jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput);
+            if (physicalInPorts != NULL) {
+                while (physicalInPorts[inputs]) { 
+                    fPhysicalInputs.push_back(physicalInPorts[inputs]);  
+                    printf("physical input %s\n", physicalInPorts[inputs]);
+                    inputs++; 
+                }
+                jack_free(physicalInPorts);
+            }
+            
+            // Get Physical outputs
+            int outputs = 0;
+            char** physicalOutPorts = (char**)jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);
+            if (physicalOutPorts != NULL) {
+                while (physicalOutPorts[outputs]) { 
+                    fPhysicalOutputs.push_back(physicalOutPorts[outputs]); 
+                    printf("physical output %s\n", physicalOutPorts[outputs]);
+                    outputs++; 
+                }
+                jack_free(physicalOutPorts);
+            }
+        
+            return true;
+        }    
+        
+        virtual bool start() 
+        {
+            if (jack_activate(fClient)) {
+                fprintf(stderr, "Cannot activate client");
+                return false;
+            }
+            
+            if (fConnections.size() > 0) {
+                load_connections();
+            } else if (fAutoConnect) {
+                default_connections();
+            }
+            
+            return true;
+        }
+
+        virtual void stop() 
+        {
+            if (fClient) {
+                save_connections();
+                jack_deactivate(fClient);
+            }
+        }
+    
+        virtual void shutdown(shutdown_callback cb, void* arg)
+        {
+            fShutdown = cb;
+            fShutdownArg = arg;
+        }
+        
+        virtual int get_buffer_size() { return jack_get_buffer_size(fClient); }
+        virtual int get_sample_rate() { return jack_get_sample_rate(fClient); }
+                 
+        virtual int get_num_inputs() 
+        { 
+            return fPhysicalInputs.size(); 
+        }
+        
+        virtual int get_num_outputs() 
+        { 
+            return fPhysicalOutputs.size();
+        }
+  
+        // Additional public API
+        
+        jack_client_t* get_client() { return fClient; }
+   
+        // Connect to physical inputs/outputs
+        void default_connections()
+        {
+            // To avoid feedback at launch time, don't connect hardware inputs
+            /*
+            for (int i = 0; i < fNumOutChans && i < fPhysicalOutputs.size(); i++) {
+                jack_connect(fClient, fPhysicalOutputs[i], jack_port_name(fInputPorts[i]));
+            }
+            */
+               
+            for (int i = 0; i < fNumOutChans && i < fPhysicalInputs.size(); i++) {
+                jack_connect(fClient, jack_port_name(fOutputPorts[i]), fPhysicalInputs[i]);
+            }
+        }
+    
+        virtual bool set_dsp(dsp* DSP)
+        {
+            fDsp = DSP;
+            
+            fNumInChans  = fDsp->getNumInputs();
+            fNumOutChans = fDsp->getNumOutputs();
+            
+            fInputPorts = new jack_port_t*[fNumInChans];
+            fOutputPorts = new jack_port_t*[fNumOutChans];
+            
+            for (int i = 0; i < fNumInChans; i++) {
+                char buf[256];
+                snprintf(buf, 256, "in_%d", i);
+                fInputPorts[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
+            }
+            for (int i = 0; i < fNumOutChans; i++) {
+                char buf[256];
+                snprintf(buf, 256, "out_%d", i);
+                fOutputPorts[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+            }
+            
+            fDsp->init(jack_get_sample_rate(fClient));
+            return true;
+        }
+             
+        void connect(jackaudio* driver, int src, int dst, bool reverse)
+        {
+            if (driver) {
+                // Connection between drivers
+                jack_port_t* src_port = get_output_port(src);
+                jack_port_t* dst_port = driver->get_input_port(src);
+                if (src_port && dst_port) {
+                    jack_connect(fClient, jack_port_name(src_port), jack_port_name(dst_port));
+                }
+            } else if (reverse) {
+                // Connection to physical input
+                if (src > fPhysicalInputs.size()) return;
+                jack_port_t* dst_port = get_input_port(dst);
+                if (dst_port) {
+                    jack_connect(fClient, fPhysicalInputs[src], jack_port_name(dst_port));
+                }
+            } else {
+                // Connection to physical output
+                if (dst > fPhysicalOutputs.size()) return;
+                jack_port_t* src_port = get_output_port(src);
+                if (src_port) {
+                    jack_connect(fClient, jack_port_name(src_port), fPhysicalOutputs[dst]);
+                }
+            }
+        }
+        
+        void disconnect(jackaudio* driver, int src, int dst, bool reverse)
+        {
+            if (driver) {
+                // Connection between drivers
+                jack_port_t* src_port = get_output_port(src);
+                jack_port_t* dst_port = driver->get_input_port(src);
+                if (src_port && dst_port) {
+                    jack_disconnect(fClient, jack_port_name(src_port), jack_port_name(dst_port));
+                }
+            } else if (reverse) {
+                // Connection to physical input
+                if (src > fPhysicalInputs.size()) return;
+                jack_port_t* dst_port = get_input_port(dst);
+                if (dst_port) {
+                    jack_disconnect(fClient, fPhysicalInputs[src], jack_port_name(dst_port));
+                }
+            } else {
+                // Connection to physical output
+                if (dst > fPhysicalOutputs.size()) return;
+                jack_port_t* src_port = get_output_port(src);
+                if (src_port) {
+                    jack_disconnect(fClient, jack_port_name(src_port), fPhysicalOutputs[dst]);
+                }
+            }
+        }
+        
+        bool is_connected(jackaudio* driver, int src, int dst, bool reverse)
+        {
+            if (driver) {
+                // Connection between drivers
+                jack_port_t* src_port = get_output_port(src);
+                jack_port_t* dst_port = driver->get_input_port(src);
+                if (src_port && dst_port) {
+                    return jack_port_connected_to(src_port, jack_port_name(dst_port));
+                } else {
+                    return false;
+                }
+            } else if (reverse) {
+                // Connection to physical input
+                if (src > fPhysicalInputs.size()) return false;
+                jack_port_t* dst_port = get_input_port(dst);
+                if (dst_port) {
+                    return jack_port_connected_to(dst_port, fPhysicalInputs[src]);
+                } else {
+                    return false;
+                }
+            } else {
+                // Connection to physical output
+                if (dst > fPhysicalOutputs.size()) return false;
+                jack_port_t* src_port = get_output_port(src);
+                if (src_port) {
+                    return jack_port_connected_to(src_port, fPhysicalOutputs[dst]);
+                } else {
+                    return false;
+                }
+            }
+        }
+        
+        jack_port_t* get_input_port(int port)  { return (port >= 0 && port < fNumInChans) ? fInputPorts[port] : 0; }
+        jack_port_t* get_output_port(int port) { return (port >= 0 && port < fNumOutChans) ? fOutputPorts[port] : 0; }
+     
+};
+
+#endif
diff --git a/architecture/faust/audio/netjack-dsp.h b/architecture/faust/audio/netjack-dsp.h
new file mode 100644
index 0000000..e5310e9
--- /dev/null
+++ b/architecture/faust/audio/netjack-dsp.h
@@ -0,0 +1,344 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __netjack_dsp__
+#define __netjack_dsp__
+
+#include <stdio.h>
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/ControlUI.h"
+#include <jack/net.h>
+#include <string>
+#include <assert.h>
+
+class netjackaudio : public audio
+{
+
+    protected:
+    
+        dsp* fDsp;
+        jack_net_slave_t* fNet;
+        int fNetFormat;
+        std::string fMasterIP;
+        int fMasterPort;
+        int fMTU;
+        int fLatency;
+        jack_master_t fResult;
+
+    #ifdef RESTART_CB_API
+        static int net_restart(void* arg) 
+        {
+            printf("Network failure, restart...\n");
+            return static_cast<netjackaudio*>(arg)->restart_cb();
+        }
+    #else 
+        static void net_shutdown(void* arg) 
+        {
+            printf("Network failure, shutdown...\n");
+            static_cast<netjackaudio*>(arg)->shutdown_cb();
+        }
+    #endif
+    
+        static int net_sample_rate(jack_nframes_t nframes, void* arg) 
+        {
+            return static_cast<netjackaudio*>(arg)->set_sample_rate(nframes);
+        }
+        
+        static int net_buffer_size(jack_nframes_t nframes, void* arg) 
+        {
+            return static_cast<netjackaudio*>(arg)->set_buffer_size(nframes);
+        }
+        
+        static void net_error(int error_code, void* arg)
+        {
+            return static_cast<netjackaudio*>(arg)->error_cb(error_code);
+        }
+        
+        static int net_process(jack_nframes_t buffer_size,
+                               int,
+                               float** audio_inputs,
+                               int,
+                               void** midi_inputs,
+                               int,
+                               float** audio_outputs,
+                               int,
+                               void** midi_outputs,
+                               void* arg) 
+        {
+            static_cast<netjackaudio*>(arg)->process(buffer_size, audio_inputs, audio_outputs, midi_inputs, midi_outputs);
+            return 0;
+        }
+
+        bool init_aux(const char* name, dsp* DSP, int audio_inputs, int audio_outputs, int midi_inputs, int midi_outputs) 
+        {
+            if (init_aux(name, audio_inputs, audio_outputs, midi_inputs, midi_outputs)){
+                set_dsp(DSP);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    
+        bool init_aux(const char* name, int audio_inputs, int audio_outputs, int midi_inputs, int midi_outputs) 
+        {
+            jack_slave_t request = {
+                audio_inputs,
+                audio_outputs,
+                midi_inputs, 
+                midi_outputs,
+                fMTU,
+                2,
+                (fNetFormat > 0) ? JackOpusEncoder : ((fNetFormat == -1) ? JackFloatEncoder : JackIntEncoder),
+                (fNetFormat > 0) ? fNetFormat : 0,
+                fLatency
+            };
+      
+            if ((fNet = jack_net_slave_open(fMasterIP.c_str(), fMasterPort, name, &request, &fResult)) == 0) {
+                printf("jack remote server not running ?\n");
+                return false;
+            }
+
+            jack_set_net_slave_process_callback(fNet, net_process, this);
+        #ifdef RESTART_CB_API
+            jack_set_net_slave_restart_callback(fNet, net_restart, this);
+        #else
+            jack_set_net_slave_shutdown_callback(fNet, net_shutdown, this);
+        #endif
+            jack_set_net_slave_sample_rate_callback(fNet, net_sample_rate, this);
+            
+            jack_set_net_slave_buffer_size_callback(fNet, net_buffer_size, this);
+            
+            jack_set_net_slave_error_callback(fNet, net_error, this);
+
+            return true;
+        }
+    
+        // Possibly to be redefined by subclasses
+        
+        virtual int restart_cb()
+        {
+            return 0;
+        }
+       
+        virtual void shutdown_cb()
+        {}
+        
+        virtual void error_cb(int error_code)
+        {}
+       
+        virtual int set_sample_rate(jack_nframes_t nframes)
+        {
+            return 0;
+        }
+        
+        virtual int set_buffer_size(jack_nframes_t nframes)
+        {
+            return 0;
+        }
+
+        virtual void process(int count, float** audio_inputs, float** audio_outputs, void** midi_inputs, void** midi_outputs)
+        {
+             AVOIDDENORMALS;
+             fDsp->compute(count, audio_inputs, audio_outputs);
+        }
+
+    public:
+
+        netjackaudio(int net_format, const std::string& master_ip, int master_port, int mtu, int latency = 2)
+            : fDsp(0), fNet(0), fNetFormat(net_format), fMasterIP(master_ip), fMasterPort(master_port), fMTU(mtu), fLatency(latency)
+        {}
+        
+        virtual ~netjackaudio() 
+        {
+            if (fNet) {
+                stop();
+                jack_net_slave_close(fNet);
+            }
+        }
+
+        virtual bool init(const char* name, dsp* DSP) 
+        {
+            return init_aux(name, DSP, DSP->getNumInputs(), DSP->getNumOutputs(), 0, 0);
+        }
+
+        virtual bool start() 
+        {
+            if (jack_net_slave_activate(fNet)) {
+                printf("cannot activate net");
+                return false;
+            }
+            return true;
+        }
+
+        virtual void stop() 
+        {
+            if (fNet) {
+                jack_net_slave_deactivate(fNet);
+            }
+        }
+        
+        void set_dsp(dsp* DSP) 
+        {
+            fDsp = DSP;
+            fDsp->init(fResult.sample_rate);
+        }
+        
+        virtual int get_buffer_size() { return fResult.buffer_size; }
+        virtual int get_sample_rate() { return fResult.sample_rate; }
+
+};
+
+/*
+A special NetJack client that uses one more audio input/output to transmit control values.
+*/
+
+class netjackaudio_control : public netjackaudio, public ControlUI {  
+        
+    protected:
+        
+        virtual void process(int count, float** audio_inputs, float** audio_outputs, void** midi_inputs, void** midi_outputs)
+        {
+            AVOIDDENORMALS;
+            
+            float** inputs_tmp = (float**)alloca(fDsp->getNumInputs()*sizeof(float*));
+            float** outputs_tmp = (float**)alloca(fDsp->getNumOutputs()*sizeof(float*));
+            
+            for(int i = 0; i < fDsp->getNumInputs();i++) {
+                inputs_tmp[i] = audio_inputs[i+1];
+            }
+            
+            for(int i = 0; i < fDsp->getNumOutputs();i++) {
+                outputs_tmp[i] = audio_outputs[i+1];
+            }
+            
+            // Control buffer always use buffer_size, even if uncomplete data buffer (count < buffer_size) is received
+            decode_control(audio_inputs[0], fResult.buffer_size);
+            
+            // "count" may be less than buffer_size
+            fDsp->compute(count, inputs_tmp, outputs_tmp);
+            
+            // Control buffer always use buffer_size, even if uncomplete data buffer (count < buffer_size) is received
+            encode_control(audio_outputs[0], fResult.buffer_size);
+        }
+        
+    public:
+        
+        netjackaudio_control(int net_format, const std::string& master_ip, int master_port, int mtu, int latency)
+            :netjackaudio(net_format, master_ip, master_port, mtu, latency)
+        {}
+        
+        virtual ~netjackaudio_control() 
+        {}
+        
+        bool is_connexion_active()
+        {
+            return jack_net_slave_is_active(fNet);
+        }
+    
+        virtual bool init(const char* name, dsp* DSP) 
+        {
+            DSP->buildUserInterface(this);
+            return init_aux(name, DSP, DSP->getNumInputs() + 1, DSP->getNumOutputs() + 1, 0, 0); // One more audio port for control
+        }
+    
+        virtual int restart_cb()
+        {
+            return -1;
+        }
+    
+};
+
+class netjackaudio_midicontrol : public netjackaudio, public ControlUI {  
+        
+    protected:
+        
+        virtual void process(int count, float** audio_inputs, float** audio_outputs, void** midi_inputs, void** midi_outputs)
+        {
+            AVOIDDENORMALS;
+            
+            float** inputs_tmp = (float**)alloca(fDsp->getNumInputs()*sizeof(float*));
+            float** outputs_tmp = (float**)alloca(fDsp->getNumOutputs()*sizeof(float*));
+            
+            for(int i = 0; i < fDsp->getNumInputs();i++) {
+                inputs_tmp[i] = audio_inputs[i];
+            }
+            
+            for(int i = 0; i < fDsp->getNumOutputs();i++) {
+                outputs_tmp[i] = audio_outputs[i];
+            }
+            
+            // Control buffer always use buffer_size, even if uncomplete data buffer (count < buffer_size) is received
+            decode_midi_control(midi_inputs[0], fResult.buffer_size);
+            
+            // "count" may be less than buffer_size
+            fDsp->compute(count, inputs_tmp, outputs_tmp);
+            
+            // Control buffer always use buffer_size, even if uncomplete data buffer (count < buffer_size) is received
+            encode_midi_control(midi_outputs[0], fResult.buffer_size);
+        }
+        
+    public:
+        
+        netjackaudio_midicontrol(int net_format, const std::string& master_ip, int master_port, int mtu, int latency)
+            :netjackaudio(net_format, master_ip, master_port, mtu, latency)
+        {}
+        
+        virtual ~netjackaudio_midicontrol() 
+        {}
+        
+        bool is_connexion_active()
+        {
+            return jack_net_slave_is_active(fNet);
+        }
+    
+        virtual bool init(const char* name, dsp* DSP) 
+        {
+            DSP->buildUserInterface(this);
+            return init_aux(name, DSP, DSP->getNumInputs(), DSP->getNumOutputs(), 1, 1); // One MIDI channel for control in both direction
+        }
+    
+        virtual int restart_cb()
+        {
+            return -1;
+        }
+    
+};
+
+#endif
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/faust/audio/opensles-android-dsp.h b/architecture/faust/audio/opensles-android-dsp.h
new file mode 100644
index 0000000..c9a4feb
--- /dev/null
+++ b/architecture/faust/audio/opensles-android-dsp.h
@@ -0,0 +1,641 @@
+/************************************************************************
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+/*
+* This is an interface for OpenSL ES to make it easier to use with Android
+* devices.  
+*/
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+#include <android/log.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct threadLock_ {
+	pthread_mutex_t m;
+	pthread_cond_t c;
+	unsigned char s;
+} threadLock;
+
+typedef struct opensl_stream {
+
+	// engine interfaces
+	SLObjectItf engineObject;
+	SLEngineItf engineEngine;
+
+	// output mix interfaces
+	SLObjectItf outputMixObject;
+
+	// buffer queue player interfaces
+	SLObjectItf bqPlayerObject;
+	SLPlayItf bqPlayerPlay;
+	SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
+	SLEffectSendItf bqPlayerEffectSend;
+
+	// recorder interfaces
+	SLObjectItf recorderObject;
+	SLRecordItf recorderRecord;
+	SLAndroidSimpleBufferQueueItf recorderBufferQueue;
+
+	// buffer indexes
+	int currentInputIndex;
+	int currentOutputIndex;
+
+	// current buffer half (0, 1)
+	int currentOutputBuffer;
+	int currentInputBuffer;
+
+	// buffers
+	short *outputBuffer[2];
+	short *inputBuffer[2];
+
+	// size of buffers
+	int outBufSamples;
+	int inBufSamples;
+
+	// locks
+	void* inlock;
+	void* outlock;
+
+	double time;
+	int inchannels;
+	int outchannels;
+	int sr;
+
+} OPENSL_STREAM;
+
+#define CONV16BIT 32767.f
+#define CONVMYFLT (1.f/32767.f)
+
+static void* createThreadLock(void);
+static int waitThreadLock(void *lock);
+static void notifyThreadLock(void *lock);
+static void destroyThreadLock(void *lock);
+static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
+static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
+
+// creates the OpenSL ES audio engine
+static SLresult openSLCreateEngine(OPENSL_STREAM *p) {
+	SLresult result;
+	// create engine
+	result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
+	if (result != SL_RESULT_SUCCESS)
+		goto engine_end;
+
+	// realize the engine
+	result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
+	if (result != SL_RESULT_SUCCESS)
+		goto engine_end;
+
+	// get the engine interface, which is needed in order to create other objects
+	result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE,
+			&(p->engineEngine));
+	if (result != SL_RESULT_SUCCESS)
+		goto engine_end;
+
+	engine_end: return result;
+}
+
+// opens the OpenSL ES device for output
+static SLresult openSLPlayOpen(OPENSL_STREAM *p) {
+	SLresult result;
+	SLuint32 sr = p->sr;
+	SLuint32 channels = p->outchannels;
+
+	if (channels) {
+		// configure audio source
+		SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
+				SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
+
+		switch (sr) {
+
+		case 8000:
+			sr = SL_SAMPLINGRATE_8;
+			break;
+		case 11025:
+			sr = SL_SAMPLINGRATE_11_025;
+			break;
+		case 16000:
+			sr = SL_SAMPLINGRATE_16;
+			break;
+		case 22050:
+			sr = SL_SAMPLINGRATE_22_05;
+			break;
+		case 24000:
+			sr = SL_SAMPLINGRATE_24;
+			break;
+		case 32000:
+			sr = SL_SAMPLINGRATE_32;
+			break;
+		case 44100:
+			sr = SL_SAMPLINGRATE_44_1;
+			break;
+		case 48000:
+			sr = SL_SAMPLINGRATE_48;
+			break;
+		case 64000:
+			sr = SL_SAMPLINGRATE_64;
+			break;
+		case 88200:
+			sr = SL_SAMPLINGRATE_88_2;
+			break;
+		case 96000:
+			sr = SL_SAMPLINGRATE_96;
+			break;
+		case 192000:
+			sr = SL_SAMPLINGRATE_192;
+			break;
+		default:
+			return -1;
+		}
+
+		const SLInterfaceID ids[] = { SL_IID_VOLUME };
+		const SLboolean req[] = { SL_BOOLEAN_FALSE };
+		result = (*p->engineEngine)->CreateOutputMix(p->engineEngine,
+				&(p->outputMixObject), 1, ids, req);
+		//if(result != SL_RESULT_SUCCESS) goto end_openaudio;
+
+		// realize the output mix
+		result = (*p->outputMixObject)->Realize(p->outputMixObject,
+				SL_BOOLEAN_FALSE);
+
+		int speakers;
+		if (channels > 1)
+			speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+		else
+			speakers = SL_SPEAKER_FRONT_CENTER;
+		SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM, channels, sr,
+				SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
+				speakers, SL_BYTEORDER_LITTLEENDIAN };
+
+		SLDataSource audioSrc = { &loc_bufq, &format_pcm };
+
+		// configure audio sink
+		SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX,
+				p->outputMixObject };
+		SLDataSink audioSnk = { &loc_outmix, NULL };
+
+		// create audio player
+		const SLInterfaceID ids1[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
+		const SLboolean req1[] = { SL_BOOLEAN_TRUE };
+		result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine,
+				&(p->bqPlayerObject), &audioSrc, &audioSnk, 1, ids1, req1);
+		if (result != SL_RESULT_SUCCESS)
+			goto end_openaudio;
+
+		// realize the player
+		result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject,
+				SL_BOOLEAN_FALSE);
+		if (result != SL_RESULT_SUCCESS)
+			goto end_openaudio;
+
+		// get the play interface
+		result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject,
+				SL_IID_PLAY, &(p->bqPlayerPlay));
+		if (result != SL_RESULT_SUCCESS)
+			goto end_openaudio;
+
+		// get the buffer queue interface
+		result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject,
+				SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(p->bqPlayerBufferQueue));
+		if (result != SL_RESULT_SUCCESS)
+			goto end_openaudio;
+
+		// register callback on the buffer queue
+		result = (*p->bqPlayerBufferQueue)->RegisterCallback(
+				p->bqPlayerBufferQueue, bqPlayerCallback, p);
+		if (result != SL_RESULT_SUCCESS)
+			goto end_openaudio;
+
+		// set the player's state to playing
+		result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay,
+				SL_PLAYSTATE_PLAYING);
+
+		end_openaudio: return result;
+	}
+	return SL_RESULT_SUCCESS;
+}
+
+// Open the OpenSL ES device for input
+static SLresult openSLRecOpen(OPENSL_STREAM *p) {
+
+	SLresult result;
+	SLuint32 sr = p->sr;
+	SLuint32 channels = p->inchannels;
+
+	if (channels) {
+
+		switch (sr) {
+
+		case 8000:
+			sr = SL_SAMPLINGRATE_8;
+			break;
+		case 11025:
+			sr = SL_SAMPLINGRATE_11_025;
+			break;
+		case 16000:
+			sr = SL_SAMPLINGRATE_16;
+			break;
+		case 22050:
+			sr = SL_SAMPLINGRATE_22_05;
+			break;
+		case 24000:
+			sr = SL_SAMPLINGRATE_24;
+			break;
+		case 32000:
+			sr = SL_SAMPLINGRATE_32;
+			break;
+		case 44100:
+			sr = SL_SAMPLINGRATE_44_1;
+			break;
+		case 48000:
+			sr = SL_SAMPLINGRATE_48;
+			break;
+		case 64000:
+			sr = SL_SAMPLINGRATE_64;
+			break;
+		case 88200:
+			sr = SL_SAMPLINGRATE_88_2;
+			break;
+		case 96000:
+			sr = SL_SAMPLINGRATE_96;
+			break;
+		case 192000:
+			sr = SL_SAMPLINGRATE_192;
+			break;
+		default:
+			return -1;
+		}
+
+		// configure audio source
+		SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE,
+				SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL };
+		SLDataSource audioSrc = { &loc_dev, NULL };
+
+		// configure audio sink
+		int speakers;
+		if (channels > 1)
+			speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+		else
+			speakers = SL_SPEAKER_FRONT_CENTER;
+		SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
+				SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
+		SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM, channels, sr,
+				SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
+				speakers, SL_BYTEORDER_LITTLEENDIAN };
+		SLDataSink audioSnk = { &loc_bq, &format_pcm };
+
+		// create audio recorder
+		// (requires the RECORD_AUDIO permission)
+		const SLInterfaceID id[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
+		const SLboolean req[1] = { SL_BOOLEAN_TRUE };
+		result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine,
+				&(p->recorderObject), &audioSrc, &audioSnk, 1, id, req);
+		if (SL_RESULT_SUCCESS != result)
+			goto end_recopen;
+
+		// realize the audio recorder
+		result = (*p->recorderObject)->Realize(p->recorderObject,
+				SL_BOOLEAN_FALSE);
+		if (SL_RESULT_SUCCESS != result)
+			goto end_recopen;
+
+		// get the record interface
+		result = (*p->recorderObject)->GetInterface(p->recorderObject,
+				SL_IID_RECORD, &(p->recorderRecord));
+		if (SL_RESULT_SUCCESS != result)
+			goto end_recopen;
+
+		// get the buffer queue interface
+		result = (*p->recorderObject)->GetInterface(p->recorderObject,
+				SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(p->recorderBufferQueue));
+		if (SL_RESULT_SUCCESS != result)
+			goto end_recopen;
+
+		// register callback on the buffer queue
+		result = (*p->recorderBufferQueue)->RegisterCallback(
+				p->recorderBufferQueue, bqRecorderCallback, p);
+		if (SL_RESULT_SUCCESS != result)
+			goto end_recopen;
+		result = (*p->recorderRecord)->SetRecordState(p->recorderRecord,
+				SL_RECORDSTATE_RECORDING);
+
+		end_recopen: return result;
+	} else
+		return SL_RESULT_SUCCESS;
+
+}
+
+// close the OpenSL IO and destroy the audio engine
+static void openSLDestroyEngine(OPENSL_STREAM *p) {
+
+	// destroy buffer queue audio player object, and invalidate all associated interfaces
+	if (p->bqPlayerObject != NULL) {
+		(*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
+		p->bqPlayerObject = NULL;
+		p->bqPlayerPlay = NULL;
+		p->bqPlayerBufferQueue = NULL;
+		p->bqPlayerEffectSend = NULL;
+	}
+
+	// destroy audio recorder object, and invalidate all associated interfaces
+	if (p->recorderObject != NULL) {
+		(*p->recorderObject)->Destroy(p->recorderObject);
+		p->recorderObject = NULL;
+		p->recorderRecord = NULL;
+		p->recorderBufferQueue = NULL;
+	}
+
+	// destroy output mix object, and invalidate all associated interfaces
+	if (p->outputMixObject != NULL) {
+		(*p->outputMixObject)->Destroy(p->outputMixObject);
+		p->outputMixObject = NULL;
+	}
+
+	// destroy engine object, and invalidate all associated interfaces
+	if (p->engineObject != NULL) {
+		(*p->engineObject)->Destroy(p->engineObject);
+		p->engineObject = NULL;
+		p->engineEngine = NULL;
+	}
+
+}
+
+// close the android audio device
+void android_CloseAudioDevice(OPENSL_STREAM *p) {
+
+	if (p == NULL)
+		return;
+
+	openSLDestroyEngine(p);
+
+	if (p->inlock != NULL) {
+		notifyThreadLock(p->inlock);
+		destroyThreadLock(p->inlock);
+		p->inlock = NULL;
+	}
+
+	if (p->outlock != NULL) {
+		notifyThreadLock(p->outlock);
+		destroyThreadLock(p->outlock);
+		p->inlock = NULL;
+	}
+
+	if (p->outputBuffer[0] != NULL) {
+		free(p->outputBuffer[0]);
+		p->outputBuffer[0] = NULL;
+	}
+
+	if (p->outputBuffer[1] != NULL) {
+		free(p->outputBuffer[1]);
+		p->outputBuffer[1] = NULL;
+	}
+
+	if (p->inputBuffer[0] != NULL) {
+		free(p->inputBuffer[0]);
+		p->inputBuffer[0] = NULL;
+	}
+
+	if (p->inputBuffer[1] != NULL) {
+		free(p->inputBuffer[1]);
+		p->inputBuffer[1] = NULL;
+	}
+
+	free(p);
+}
+
+// open the android audio device for input and/or output
+OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels,
+		int bufferframes) {
+
+	OPENSL_STREAM *p;
+	p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM), 1);
+
+	p->inchannels = inchannels;
+	p->outchannels = outchannels;
+	p->sr = sr;
+	p->inlock = createThreadLock();
+	p->outlock = createThreadLock();
+
+	if ((p->outBufSamples = bufferframes * outchannels) != 0) {
+		if ((p->outputBuffer[0] = (short *) calloc(p->outBufSamples,
+				sizeof(short))) == NULL || (p->outputBuffer[1] =
+				(short *) calloc(p->outBufSamples, sizeof(short))) == NULL) {
+			android_CloseAudioDevice(p);
+			return NULL;
+		}
+	}
+
+	if ((p->inBufSamples = bufferframes * inchannels) != 0) {
+		if ((p->inputBuffer[0] = (short *) calloc(p->inBufSamples,
+				sizeof(short))) == NULL || (p->inputBuffer[1] =
+				(short *) calloc(p->inBufSamples, sizeof(short))) == NULL) {
+			android_CloseAudioDevice(p);
+			return NULL;
+		}
+	}
+
+	p->currentInputIndex = 0;
+	p->currentOutputBuffer = 0;
+	p->currentInputIndex = p->inBufSamples;
+	p->currentInputBuffer = 0;
+
+	if (openSLCreateEngine(p) != SL_RESULT_SUCCESS) {
+		android_CloseAudioDevice(p);
+		return NULL;
+	}
+
+	if (openSLRecOpen(p) != SL_RESULT_SUCCESS) {
+		android_CloseAudioDevice(p);
+		return NULL;
+	}
+
+	if (openSLPlayOpen(p) != SL_RESULT_SUCCESS) {
+		android_CloseAudioDevice(p);
+		return NULL;
+	}
+
+	notifyThreadLock(p->outlock);
+	notifyThreadLock(p->inlock);
+
+	p->time = 0.;
+	return p;
+}
+
+// returns timestamp of the processed stream
+double android_GetTimestamp(OPENSL_STREAM *p) {
+	return p->time;
+}
+
+// this callback handler is called every time a buffer finishes recording
+void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
+	OPENSL_STREAM *p = (OPENSL_STREAM *) context;
+	notifyThreadLock(p->inlock);
+}
+
+// gets a buffer of size samples from the device
+int android_AudioIn(OPENSL_STREAM *p, float *buffer, int size) {
+	short *inBuffer;
+	int i, bufsamps = p->inBufSamples, index = p->currentInputIndex;
+	if (p == NULL || bufsamps == 0)
+		return 0;
+
+	inBuffer = p->inputBuffer[p->currentInputBuffer];
+	for (i = 0; i < size; i++) {
+		if (index >= bufsamps) {
+			waitThreadLock(p->inlock);
+			(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, inBuffer,
+					bufsamps * sizeof(short));
+			p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1);
+			index = 0;
+			inBuffer = p->inputBuffer[p->currentInputBuffer];
+		}
+		buffer[i] = (float) inBuffer[index++] * CONVMYFLT;
+		// TODO: the output buffer should be clicked
+		//buffer[i] = min(1.f,max(-1.f,buffer[i]));
+	}
+	p->currentInputIndex = index;
+	if (p->outchannels == 0)
+		p->time += (double) size / (p->sr * p->inchannels);
+	return i;
+}
+
+// this callback handler is called every time a buffer finishes playing
+void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
+	OPENSL_STREAM *p = (OPENSL_STREAM *) context;
+	notifyThreadLock(p->outlock);
+}
+
+// puts a buffer of size samples to the device
+int android_AudioOut(OPENSL_STREAM *p, float **buffer, int size) {
+
+	short *outBuffer;
+	int i, bufsamps = p->outBufSamples, index = p->currentOutputIndex;
+	if (p == NULL || bufsamps == 0)
+		return 0;
+    
+    __android_log_write(ANDROID_LOG_INFO, "FaustCPP", "Error");
+    
+	outBuffer = p->outputBuffer[p->currentOutputBuffer];
+    if (p->outchannels == 1) {
+        for (i = 0; i < size; i++) {
+            outBuffer[index++] = (short) (min(1.f, max(-1.f, buffer[0][i]))
+                                          * CONV16BIT);
+            if (index >= p->outBufSamples) {
+                waitThreadLock(p->outlock);
+                (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue,
+                                                   outBuffer, bufsamps * sizeof(short));
+                p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1);
+                index = 0;
+                outBuffer = p->outputBuffer[p->currentOutputBuffer];
+            }
+        }
+    } else {
+        for (i = 0; i < size; i++) {
+            outBuffer[index++] = (short) (min(1.f, max(-1.f, buffer[0][i]))
+                                          * CONV16BIT);
+            outBuffer[index++] = (short) (min(1.f, max(-1.f, buffer[1][i]))
+                                          * CONV16BIT);
+            if (index >= p->outBufSamples) {
+                waitThreadLock(p->outlock);
+                (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue,
+                                                   outBuffer, bufsamps * sizeof(short));
+                p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1);
+                index = 0;
+                outBuffer = p->outputBuffer[p->currentOutputBuffer];
+            }
+        }
+    }
+	p->currentOutputIndex = index;
+	p->time += (double) size * p->outchannels/ (p->sr * p->outchannels);
+	return i;
+}
+
+//----------------------------------------------------------------------
+// thread Locks
+// to ensure synchronisation between callbacks and processing code
+void* createThreadLock(void) {
+	threadLock *p;
+	p = (threadLock*) malloc(sizeof(threadLock));
+	if (p == NULL)
+		return NULL;
+	memset(p, 0, sizeof(threadLock));
+	if (pthread_mutex_init(&(p->m), (pthread_mutexattr_t*) NULL) != 0) {
+		free((void*) p);
+		return NULL;
+	}
+	if (pthread_cond_init(&(p->c), (pthread_condattr_t*) NULL) != 0) {
+		pthread_mutex_destroy(&(p->m));
+		free((void*) p);
+		return NULL;
+	}
+	p->s = (unsigned char) 1;
+
+	return p;
+}
+
+int waitThreadLock(void *lock) {
+	threadLock *p;
+	int retval = 0;
+	p = (threadLock*) lock;
+	pthread_mutex_lock(&(p->m));
+	while (!p->s) {
+		pthread_cond_wait(&(p->c), &(p->m));
+	}
+	p->s = (unsigned char) 0;
+	pthread_mutex_unlock(&(p->m));
+}
+
+void notifyThreadLock(void *lock) {
+	threadLock *p;
+	p = (threadLock*) lock;
+	pthread_mutex_lock(&(p->m));
+	p->s = (unsigned char) 1;
+	pthread_cond_signal(&(p->c));
+	pthread_mutex_unlock(&(p->m));
+}
+
+void destroyThreadLock(void *lock) {
+	threadLock *p;
+	p = (threadLock*) lock;
+	if (p == NULL)
+		return;
+	notifyThreadLock(p);
+	pthread_cond_destroy(&(p->c));
+	pthread_mutex_destroy(&(p->m));
+	free(p);
+}
\ No newline at end of file
diff --git a/architecture/faust/audio/osc-dsp.h b/architecture/faust/audio/osc-dsp.h
new file mode 100644
index 0000000..743708d
--- /dev/null
+++ b/architecture/faust/audio/osc-dsp.h
@@ -0,0 +1,89 @@
+
+#ifndef __osc_dsp__
+#define __osc_dsp__
+
+#include <stdio.h>
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp.h"
+#include "OSCIO.h"
+
+/******************************************************************************
+*******************************************************************************
+
+							OSC AUDIO INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+#define kMaxBuffer 4096
+
+class oscdsp : public audio, public oscfaust::OSCIO {
+	dsp*	 fDsp;
+	float ** fInBuffers, **fOutBuffers;
+
+ public:
+    oscdsp(const char * dst, int argc, char *argv[]) : OSCIO(dst), fDsp(0), fInBuffers(0), fOutBuffers(0)
+    {
+        for (int i = 1; i < argc-1; i++) {
+            if (!strcmp(argv[i], "-iodst")) setDest (argv[i+1]);
+        }
+    }
+	virtual ~oscdsp() 
+    { 
+        stop(); 
+        for (int i = 0; i < numInputs(); i++) {
+            delete [] fInBuffers[i];
+        }
+        for (int i = 0; i < numOutputs(); i++) {
+            delete [] fOutBuffers[i];
+        }
+        delete [] fInBuffers;
+        delete [] fOutBuffers;
+    }
+
+	virtual bool init(const char*name, dsp* DSP) 
+    {
+		fDsp = DSP;
+		fDsp->init(44100);
+		fInBuffers  = new float*[numInputs()];
+		fOutBuffers = new float*[numOutputs()];
+		for (int i = 0; i < numInputs(); i++) {
+			fInBuffers[i] = new float[kMaxBuffer];
+        }
+		for (int i = 0; i < numOutputs(); i++) {
+			fOutBuffers [i] = new float[kMaxBuffer];
+        }
+		return true;
+	}
+
+	virtual bool start()	{ return true; }
+	virtual void stop()		{}
+
+	void compute(int nframes) 
+    {
+		fDsp->compute(nframes, fInBuffers, fOutBuffers);
+		for (int i= 0; i < numOutputs(); i++) {
+			send( nframes, fOutBuffers [i], i);
+        }
+	}
+
+	void receive(int nvalues, float* val) 
+    {
+		int inChans = numInputs();
+		if (!inChans) {
+			compute(nvalues);
+			return;
+		}
+
+		for (int i=0; i < nvalues; i++) {
+			int c = i % inChans;
+			int frame = i / inChans;
+			fInBuffers[c][frame] = val[i];
+		}
+		compute (nvalues / inChans);
+	}
+	int	numOutputs() const	{ return fDsp ? fDsp->getNumOutputs() : 0; }
+	int	numInputs() const	{ return fDsp ? fDsp->getNumInputs() : 0; }
+};
+
+#endif
diff --git a/architecture/faust/audio/portaudio-dsp.h b/architecture/faust/audio/portaudio-dsp.h
new file mode 100644
index 0000000..c9403ea
--- /dev/null
+++ b/architecture/faust/audio/portaudio-dsp.h
@@ -0,0 +1,232 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ 
+ 
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __portaudio_dsp__
+#define __portaudio_dsp__
+
+#include <stdio.h>
+#include <assert.h>
+#include <portaudio.h>
+#include <stdlib.h>
+
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp-adapter.h"
+
+static bool pa_error(int err)
+{
+	if (err != paNoError) {
+		printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/******************************************************************************
+ *******************************************************************************
+ 
+ PORT AUDIO INTERFACE
+ 
+ *******************************************************************************
+ *******************************************************************************/
+
+class portaudio : public audio {
+    
+    protected:
+        
+        dsp* fDsp;
+        PaStream* fAudioStream;
+        long fSampleRate;
+        long fBufferSize;
+        PaStreamParameters fInputParameters;
+        PaStreamParameters fOutputParameters;
+        
+        //----------------------------------------------------------------------------
+        // 	Number of physical input and output channels of the PA device
+        //----------------------------------------------------------------------------
+        int	fDevNumInChans;
+        int	fDevNumOutChans;
+        
+        static int audioCallback(const void* ibuf, void* obuf, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* drv)
+        {
+            portaudio* pa = (portaudio*)drv;
+            return pa->processAudio((float**)ibuf, (float**)obuf, frames);
+        }
+        
+        virtual int processAudio(float** ibuf, float** obuf, unsigned long frames) 
+        {
+            // process samples
+            fDsp->compute(frames, ibuf, obuf);
+            return paContinue;
+        }
+        
+    public:
+        
+        portaudio(long srate, long bsize) : 
+            fDsp(0), fAudioStream(0),
+            fSampleRate(srate), fBufferSize(bsize), 
+            fDevNumInChans(0), fDevNumOutChans(0) {}
+        virtual ~portaudio() 
+        {   
+            stop(); 
+            Pa_Terminate();
+        }
+        
+        virtual bool init(const char* name, dsp* DSP)
+        {
+            if (init(name, DSP->getNumInputs(), DSP->getNumOutputs())) {
+                set_dsp(DSP);
+                return true;
+            } else {
+                return false;
+            }
+        }
+        
+        bool init(const char* /*name*/, int numInputs, int numOutputs)
+        {            
+            if (pa_error(Pa_Initialize())) {
+                return false;
+            }
+            
+            const PaDeviceInfo*	idev = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice());
+            const PaDeviceInfo*	odev = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
+            
+            printf("DEVICE = %p || %p\n", idev, odev);
+            
+            //In case there is no audio device, the function fails
+            
+            if(idev == NULL) {
+                fDevNumInChans = 0;
+            } else {
+                fDevNumInChans = idev->maxInputChannels;
+                
+                fInputParameters.device = Pa_GetDefaultInputDevice();
+                fInputParameters.sampleFormat = paFloat32 | paNonInterleaved;
+                fInputParameters.channelCount = fDevNumInChans;
+                fInputParameters.hostApiSpecificStreamInfo = 0;
+            }
+            
+            if (odev == NULL) {
+                fDevNumOutChans = 0;
+            } else{
+                fDevNumOutChans = odev->maxOutputChannels;
+                
+                fOutputParameters.device = Pa_GetDefaultOutputDevice();
+                fOutputParameters.sampleFormat = paFloat32 | paNonInterleaved;;
+                fOutputParameters.channelCount = fDevNumOutChans;
+                fOutputParameters.hostApiSpecificStreamInfo = 0;
+            }
+            
+            // A DSP that has only outputs or only inputs forces the presence of an output or input device
+            if (numInputs == 0 && numOutputs != 0 && fDevNumOutChans == 0) {
+                printf("Devices not adaptated to DSP\n");
+                return false;
+            }
+            
+            if (numInputs != 0 && numOutputs == 0 && fDevNumInChans == 0) {
+                printf("Devices not adaptated to DSP\n");
+                return false;
+            }
+            
+            // If no device exists : the function fails
+            PaError err;
+            if ((err = Pa_IsFormatSupported(((fDevNumInChans > 0) ? &fInputParameters : 0),
+                                            ((fDevNumOutChans > 0) ? &fOutputParameters : 0), fSampleRate)) != 0) {
+                printf("stream format is not supported err = %d\n", err);
+                return false;
+            }
+            
+            return true;
+        }
+        
+        void set_dsp(dsp* DSP) 
+        {
+            fDsp = DSP;
+            if (fDsp->getNumInputs() > fDevNumInChans || fDsp->getNumOutputs() > fDevNumOutChans) {
+                printf("DSP has %d inputs and %d outputs, physical inputs = %d physical outputs = %d \n", 
+                       fDsp->getNumInputs(), fDsp->getNumOutputs(), 
+                       fDevNumInChans, fDevNumOutChans);
+                fDsp = new dsp_adapter(fDsp, fDevNumInChans, fDevNumOutChans, fBufferSize);
+                printf("adapter\n");
+            }
+            
+            fDsp->init(fSampleRate);
+        }
+        
+        virtual bool start() 
+        {
+            if (pa_error(Pa_OpenStream(&fAudioStream, ((fDevNumInChans > 0) ? &fInputParameters : 0),
+                                       ((fDevNumOutChans > 0) ? &fOutputParameters : 0), fSampleRate, fBufferSize, paNoFlag, audioCallback, this))) {
+                return false;
+            }    
+            
+            if (pa_error(Pa_StartStream(fAudioStream))) {
+                return false;
+            }
+            return true;
+        }
+        
+        virtual void stop() 
+        {
+            if (fAudioStream) {
+                Pa_StopStream(fAudioStream);
+                Pa_CloseStream(fAudioStream);
+                fAudioStream = 0;
+            }
+        }
+        
+        virtual int get_buffer_size() 
+        { 
+            return fBufferSize; 
+        }
+        
+        virtual int get_sample_rate() 
+        { 
+            return fSampleRate; 
+        }
+        
+        virtual int get_num_inputs() 
+        {
+            return fDevNumInChans;
+        }
+        
+        virtual int get_num_outputs() 
+        {
+            return fDevNumOutChans;
+        }
+};
+
+#endif
diff --git a/architecture/faust/audio/rtaudio-dsp.h b/architecture/faust/audio/rtaudio-dsp.h
new file mode 100644
index 0000000..eb8f6c5
--- /dev/null
+++ b/architecture/faust/audio/rtaudio-dsp.h
@@ -0,0 +1,211 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ 
+ 
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __rtaudio_dsp__
+#define __rtaudio_dsp__
+
+#include <stdio.h>
+#include <assert.h>
+#include <RtAudio.h>
+#include <stdlib.h>
+
+#include "faust/audio/audio.h"
+#include "faust/audio/dsp-adapter.h"
+
+#define FORMAT RTAUDIO_FLOAT32
+
+
+/******************************************************************************
+ *******************************************************************************
+ 
+ RTAUDIO INTERFACE
+ 
+ *******************************************************************************
+ *******************************************************************************/
+
+class rtaudio : public audio {
+    
+    protected:
+        
+        dsp* fDsp;
+        RtAudio fAudioDAC;
+        unsigned int fSampleRate;
+        unsigned int fBufferSize;
+         
+        //----------------------------------------------------------------------------
+        // 	number of physical input and output channels of the PA device
+        //----------------------------------------------------------------------------
+        int	fDevNumInChans;
+        int	fDevNumOutChans;
+        
+        virtual int processAudio(void* ibuf, void* buf, unsigned long frames) 
+        {
+            float* inputs[fDsp->getNumInputs()];
+            float* outputs[fDsp->getNumOutputs()];
+            
+            for (int i = 0; i < fDsp->getNumInputs(); i++) {
+                inputs[i] = &((float*)ibuf)[i * frames];
+            }
+            for (int i = 0; i < fDsp->getNumOutputs(); i++) {
+                outputs[i] = &((float*)buf)[i * frames];
+            }
+
+            // process samples
+            fDsp->compute(frames, inputs, outputs);
+            return 0;
+        }
+        
+        static int audioCallback(void* outputBuffer, void* inputBuffer, 
+                        unsigned int nBufferFrames,
+                        double streamTime, RtAudioStreamStatus status, 
+                        void* data)
+        {
+            rtaudio* ra = (rtaudio*)data;
+            return ra->processAudio(inputBuffer, outputBuffer, nBufferFrames);
+        }
+      
+    public:
+        
+        rtaudio(long srate, long bsize) : fDsp(0),
+            fSampleRate(srate), fBufferSize(bsize), fDevNumInChans(0), fDevNumOutChans(0) {}
+        virtual ~rtaudio() 
+        {   
+            stop(); 
+        }
+        
+        virtual bool init(const char* name, dsp* DSP)
+        {
+            if (init(name, DSP->getNumInputs(), DSP->getNumOutputs())) {
+                set_dsp(DSP);
+                return true;
+            } else {
+                return false;
+            }
+        }
+        
+        bool init(const char* /*name*/, int numInputs, int numOutputs)
+        {           
+            if (fAudioDAC.getDeviceCount() < 1) {
+                std::cout << "No audio devices found!\n";
+                return false;
+            }
+            
+            RtAudio::DeviceInfo info_in = fAudioDAC.getDeviceInfo(fAudioDAC.getDefaultInputDevice());
+            RtAudio::DeviceInfo info_out = fAudioDAC.getDeviceInfo(fAudioDAC.getDefaultOutputDevice());
+            RtAudio::StreamParameters iParams, oParams;
+            
+            iParams.deviceId = fAudioDAC.getDefaultInputDevice();
+            fDevNumInChans = info_in.inputChannels;
+            iParams.nChannels = fDevNumInChans;
+            iParams.firstChannel = 0;
+            
+            oParams.deviceId = fAudioDAC.getDefaultOutputDevice();
+            fDevNumOutChans = info_out.outputChannels;
+            oParams.nChannels = fDevNumOutChans;
+            oParams.firstChannel = 0;
+            
+            RtAudio::StreamOptions options;
+            options.flags |= RTAUDIO_NONINTERLEAVED;
+         
+            try {
+                fAudioDAC.openStream(((numOutputs > 0) ? &oParams : NULL), 
+                    ((numInputs > 0) ? &iParams : NULL), FORMAT, 
+                    fSampleRate, &fBufferSize, audioCallback, this, &options);
+            } catch (RtAudioError& e) {
+                std::cout << '\n' << e.getMessage() << '\n' << std::endl;
+                return false;
+            }
+               
+            return true;
+        }
+        
+        void set_dsp(dsp* DSP)
+        {
+            fDsp = DSP;
+            if (fDsp->getNumInputs() > fDevNumInChans || fDsp->getNumOutputs() > fDevNumOutChans) {
+                printf("DSP has %d inputs and %d outputs, physical inputs = %d physical outputs = %d \n", 
+                       fDsp->getNumInputs(), fDsp->getNumOutputs(), 
+                       fDevNumInChans, fDevNumOutChans);
+                fDsp = new dsp_adapter(fDsp, fDevNumInChans, fDevNumOutChans, fBufferSize);
+                printf("adapter\n");
+            }
+            
+            fDsp->init(fSampleRate);
+        }
+        
+        virtual bool start() 
+        {
+           try {
+                fAudioDAC.startStream();
+            } catch (RtAudioError& e) {
+                std::cout << '\n' << e.getMessage() << '\n' << std::endl;
+                return false;
+            }
+            return true;
+        }
+        
+        virtual void stop() 
+        {
+            try {
+                fAudioDAC.stopStream();
+                fAudioDAC.closeStream();
+            } catch (RtAudioError& e) {
+                std::cout << '\n' << e.getMessage() << '\n' << std::endl;
+            }
+        }
+        
+        virtual int get_buffer_size() 
+        { 
+            return fBufferSize; 
+        }
+        
+        virtual int get_sample_rate() 
+        { 
+            return fSampleRate; 
+        }
+        
+        virtual int get_num_inputs() 
+        {
+            return fDevNumInChans;
+        }
+        
+        virtual int get_num_outputs() 
+        {
+            return fDevNumOutChans;
+        }
+};
+
+#endif
diff --git a/architecture/faust/dsp/poly-dsp.h b/architecture/faust/dsp/poly-dsp.h
new file mode 100644
index 0000000..2facbc3
--- /dev/null
+++ b/architecture/faust/dsp/poly-dsp.h
@@ -0,0 +1,466 @@
+/************************************************************************
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ 
+ 
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __poly_dsp__
+#define __poly_dsp__
+
+#include <stdio.h>
+#include <string>
+#include <math.h>
+#include <algorithm>
+#include <ostream>
+#include <sstream>
+
+#include "faust/gui/JSONUI.h"
+#include "faust/gui/MapUI.h"
+#include "faust/audio/dsp.h"
+#include "faust/midi/midi.h"
+
+#define kFreeVoice        -2
+#define kReleaseVoice     -1
+
+#define VOICE_STOP_LEVEL  0.001
+#define MIX_BUFFER_SIZE   16384
+
+// ends_with(<str>,<end>) : returns true if <str> ends with <end>
+static bool ends_with(std::string const& str, std::string const& end)
+{
+	unsigned int l1 = str.length();
+	unsigned int l2 = end.length();
+    return (l1 >= l2) && (0 == str.compare(l1 - l2, l2, end));
+}
+
+// One voice of polyphony
+struct dsp_voice : public MapUI, public dsp {
+       
+    int fNote;
+
+    dsp_voice()
+    {
+        fNote = kFreeVoice;
+    }
+    
+    virtual void metadata(Meta* meta) = 0;
+ 
+};
+
+struct voice_factory {
+
+    virtual dsp_voice* create() = 0;
+};
+
+struct mydsp_voice : public dsp_voice {
+
+    mydsp fVoice;
+     
+    mydsp_voice():dsp_voice()
+    {
+        fVoice.buildUserInterface(this);
+    }
+    
+    virtual int getNumInputs() { return fVoice.getNumInputs(); }
+    virtual int getNumOutputs() { return fVoice.getNumOutputs(); }
+    virtual void buildUserInterface(UI* ui_interface) { fVoice.buildUserInterface(ui_interface); }
+    virtual void init(int samplingRate) { fVoice.init(samplingRate); }
+    virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fVoice.compute(len, inputs, outputs); }
+
+    virtual void metadata(Meta* meta) { mydsp::metadata(meta); }
+
+};
+
+struct mydsp_voice_factory : public voice_factory {
+
+    virtual dsp_voice* create() { return new mydsp_voice(); }
+};
+
+// Polyphonic DSP
+class mydsp_poly : public dsp, public midi
+{
+
+    private:
+  
+        std::string fJSON;
+        
+        dsp_voice** fVoiceTable;
+        
+        std::string fGateLabel;
+        std::string fGainLabel;
+        std::string fFreqLabel;
+        
+        int fMaxPolyphony;
+        bool fVoiceControl;
+        
+        FAUSTFLOAT** fMixBuffer;
+        int fNumOutputs;
+        
+        inline FAUSTFLOAT mixVoice(int count, FAUSTFLOAT** outputBuffer, FAUSTFLOAT** mixBuffer) 
+        {
+            FAUSTFLOAT level = 0;
+            // Normalize sample by the max polyphony (as in vst.cpp file)
+            FAUSTFLOAT gain_level = 1./sqrt(fMaxPolyphony);
+            for (int i = 0; i < fNumOutputs; i++) {
+                FAUSTFLOAT* mixChannel = mixBuffer[i];
+                FAUSTFLOAT* outChannel = outputBuffer[i];
+                for (int j = 0; j < count; j++) {
+                    level = std::max(level, (FAUSTFLOAT)fabs(outChannel[j]));
+                    mixChannel[j] += outChannel[j] * gain_level;
+                }
+            }
+            return level;
+        }
+        
+        inline double midiToFreq(double note) 
+        {
+            return 440.0 * pow(2.0, (note-69.0)/12.0);
+        }
+        
+        inline void clearOutput(int count, FAUSTFLOAT** mixBuffer) 
+        {
+            for (int i = 0; i < fNumOutputs; i++) {
+                memset(mixBuffer[i], 0, count * sizeof(FAUSTFLOAT));
+            }
+        }
+        
+        inline int getVoice(int note)
+        {
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                if (fVoiceTable[i]->fNote == note) return i;
+            }
+            return kReleaseVoice;
+        }
+        
+        inline void init(int max_polyphony, voice_factory* factory)
+        {
+            fMaxPolyphony = max_polyphony;
+            fVoiceTable = new dsp_voice*[fMaxPolyphony];
+            
+             // Init it with supplied sample_rate 
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                fVoiceTable[i] = factory->create();
+            }
+            
+            // Init audio output buffers
+            fNumOutputs = fVoiceTable[0]->getNumOutputs();
+            fMixBuffer = new FAUSTFLOAT*[fNumOutputs];
+            for (int i = 0; i < fNumOutputs; i++) {
+                fMixBuffer[i] = new FAUSTFLOAT[MIX_BUFFER_SIZE];
+            }
+        }
+    
+    public: 
+    
+        mydsp_poly(int max_polyphony, bool control, int buffer_size = 8192)  // Second argument to remove ASAP
+        {
+            fVoiceControl = control;
+            mydsp_voice_factory factory;
+            init(max_polyphony, &factory);
+        }
+        
+        mydsp_poly(int max_polyphony, int buffer_size = 8192)  // Second argument to remove ASAP
+        {
+            fVoiceControl = false;
+            mydsp_voice_factory factory;
+            init(max_polyphony, &factory);
+        }
+          
+        virtual ~mydsp_poly()
+        {
+            for (int i = 0; i < fNumOutputs; i++) {
+                delete[] fMixBuffer[i];
+            }
+            delete[] fMixBuffer;
+            
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                delete fVoiceTable[i];
+            }
+            delete[] fVoiceTable;
+        }
+        
+        void init(int sample_rate) 
+        {
+            // Init voices
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                fVoiceTable[i]->init(sample_rate);
+            }
+            
+            // Creates JSON
+            JSONUI builder(fVoiceTable[0]->getNumInputs(), fVoiceTable[0]->getNumOutputs());
+            fVoiceTable[0]->metadata(&builder);
+            builder.openTabBox("Polyphonic instrument");
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                std::stringstream voice; voice << "Voice" << i;
+                builder.openHorizontalBox(voice.str().c_str());
+                fVoiceTable[i]->buildUserInterface(&builder);
+                builder.closeBox();
+            }
+            builder.closeBox();
+            fJSON = builder.JSON();
+            
+            // Keep gain, freq and gate labels
+            std::map<std::string, FAUSTFLOAT*>::iterator it;
+            
+            for (it = fVoiceTable[0]->getMap().begin(); it != fVoiceTable[0]->getMap().end(); it++) {
+                std::string label = (*it).first;
+                if (ends_with(label, "/gate")) {
+                    fGateLabel = label;
+                } else if (ends_with(label, "/freq")) {
+                    fFreqLabel = label;
+                } else if (ends_with(label, "/gain")) {
+                    fGainLabel = label;
+                }
+            }
+        }
+        
+        void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) 
+        {
+            assert(count < MIX_BUFFER_SIZE);
+            
+            // First clear the outputs
+            clearOutput(count, outputs);
+            
+            if (fVoiceControl) {
+                // Mix all playing voices
+                for (int i = 0; i < fMaxPolyphony; i++) {
+                    if (fVoiceTable[i]->fNote != kFreeVoice) {
+                        fVoiceTable[i]->compute(count, inputs, fMixBuffer);
+                        FAUSTFLOAT level = mixVoice(count, fMixBuffer, outputs);
+                        if ((level < VOICE_STOP_LEVEL) && (fVoiceTable[i]->fNote == kReleaseVoice)) {
+                            fVoiceTable[i]->fNote = kFreeVoice;
+                        }
+                    }
+                }
+            } else {
+                // Mix all voices
+                for (int i = 0; i < fMaxPolyphony; i++) {
+                    fVoiceTable[i]->compute(count, inputs, fMixBuffer);
+                    mixVoice(count, fMixBuffer, outputs);
+                }
+            }
+        }
+        
+        int getNumInputs()
+        {
+            return fVoiceTable[0]->getNumInputs();
+        }
+        
+        int getNumOutputs()
+        {
+            return fVoiceTable[0]->getNumOutputs();
+        }
+        
+        void buildUserInterface(UI* ui_interface) 
+        {   
+            if (fMaxPolyphony > 1) {
+                ui_interface->openTabBox("Polyphonic instrument");
+                for (int i = 0; i < fMaxPolyphony; i++) {
+                    std::stringstream voice; voice << "Voice" << i;
+                    ui_interface->openHorizontalBox(voice.str().c_str());
+                    fVoiceTable[i]->buildUserInterface(ui_interface);
+                    ui_interface->closeBox();
+                }
+                ui_interface->closeBox();
+            } else {
+                fVoiceTable[0]->buildUserInterface(ui_interface);
+            }
+        }
+        
+        // Pure MIDI control
+        void keyOn(int channel, int pitch, int velocity)
+        {
+            int voice = getVoice(kFreeVoice);
+            if (voice == kReleaseVoice) voice = getVoice(kReleaseVoice);  // Gets a free voice
+            
+            if (voice >= 0) {
+                fVoiceTable[voice]->setValue(fFreqLabel, midiToFreq(pitch));
+                fVoiceTable[voice]->setValue(fGainLabel, float(velocity)/127.f);
+                fVoiceTable[voice]->setValue(fGateLabel, 1.0f);
+                fVoiceTable[voice]->fNote = pitch;
+            } else {
+                printf("No more free voice...\n");
+            }
+        }
+        
+        void keyOff(int channel, int pitch, int velocity = 127)
+        {
+            int voice = getVoice(pitch);
+            if (voice >= 0) {
+                fVoiceTable[voice]->setValue(fGainLabel, float(velocity)/127.f);
+                fVoiceTable[voice]->setValue(fGateLabel, 0.0f);
+                fVoiceTable[voice]->fNote = kReleaseVoice;
+            } else {
+                printf("Playing voice not found...\n");
+            }
+        }
+        
+        void pitchWheel(int channel, int wheel)
+        {}
+        
+        void ctrlChange(int channel, int ctrl, int value)
+        {}
+        
+        void progChange(int channel, int pgm)
+        {}
+
+        // Additional API
+        void allNotesOff()
+        {
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                fVoiceTable[i]->setValue(fGateLabel, 0.0f);
+                fVoiceTable[i]->fNote = kReleaseVoice;
+            }
+        }
+        
+        void pitchBend(int channel, int refPitch, float pitch)
+        {
+            int voice = getVoice(refPitch);
+            if (voice >= 0) {
+                fVoiceTable[voice]->setValue(fFreqLabel, midiToFreq(pitch));
+            } else {
+                printf("Playing voice not found...\n");
+            }
+        }
+        
+        void setValue(const char* path, float value)
+        {
+            for (int i = 0; i < fMaxPolyphony; i++) {
+                fVoiceTable[i]->setValue(path, value);
+            }
+        }
+        
+        void setValue(const char* path, int pitch, float value)
+        {
+            int voice = getVoice(pitch);
+            if (voice >= 0) {
+                fVoiceTable[voice]->setValue(path, value);
+            }
+        }
+        
+        float getValue(const char* path)
+        {
+            return fVoiceTable[0]->getValue(path);
+        }
+        
+        void setVoiceGain(int pitch, float value)
+        {   
+            int voice = getVoice(pitch);
+            if (voice >= 0) {
+                fVoiceTable[voice]->setValue(fGainLabel, value);
+            }
+        }
+        
+        const char* getJSON()
+        {
+            return fJSON.c_str();
+        }
+    
+};
+   
+extern "C" {
+    
+    // C like API
+    mydsp_poly* mydsp_poly_constructor(int sample_rate, int max_polyphony) 
+    {
+        mydsp_poly* poly = new mydsp_poly(max_polyphony);
+        if (poly) poly->init(sample_rate);
+        return poly;
+    }
+
+    void mydsp_poly_destructor(mydsp_poly* poly) 
+    {
+        delete poly;
+    }
+
+    const char* mydsp_poly_getJSON(mydsp_poly* poly)
+    {
+        return poly->getJSON();
+    }
+  
+    void mydsp_poly_compute(mydsp_poly* poly, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) 
+    {
+        poly->compute(count, inputs, outputs);
+    }
+
+    int mydsp_poly_getNumInputs(mydsp_poly* poly)
+    {
+        return poly->getNumInputs();
+    }
+
+    int mydsp_poly_getNumOutputs(mydsp_poly* poly)
+    {
+        return poly->getNumOutputs();
+    }
+
+    void mydsp_poly_keyOn(mydsp_poly* poly, int channel, int pitch, int velocity)
+    {
+        poly->keyOn(channel, pitch, velocity);
+    }
+
+    void mydsp_poly_keyOff(mydsp_poly* poly, int channel, int pitch, int velocity)
+    {
+        poly->keyOff(channel, pitch, velocity);
+    }
+    
+    void mydsp_poly_allNotesOff(mydsp_poly* poly)
+    {
+        poly->allNotesOff();
+    }
+    
+    void mydsp_poly_ctrlChange(mydsp_poly* poly, int channel, int ctrl, int value)
+    {
+        poly->ctrlChange(channel, ctrl, value);
+    }
+    
+    void mydsp_poly_pitchWheel(mydsp_poly* poly, int channel, int wheel)
+    {
+        poly->pitchWheel(channel, wheel);
+    }
+    
+    void mydsp_poly_pitchBend(mydsp_poly* poly, int channel, int refPitch, float pitch)
+    {
+        poly->pitchBend(channel, refPitch, pitch);
+    }
+    
+    void mydsp_poly_setValue(mydsp_poly* poly, const char* path, float value)
+    {
+        poly->setValue(path, value);
+    }
+
+    float mydsp_poly_getValue(mydsp_poly* poly, const char* path)
+    {
+        return poly->getValue(path);
+    }
+        
+}
+
+#endif
diff --git a/architecture/faust/gui/APIUI.h b/architecture/faust/gui/APIUI.h
new file mode 100644
index 0000000..f25eac1
--- /dev/null
+++ b/architecture/faust/gui/APIUI.h
@@ -0,0 +1,332 @@
+#ifndef API_UI_H
+#define API_UI_H
+
+#include "faust/misc.h"
+#include "faust/gui/meta.h"
+#include "faust/gui/PathUI.h"
+#include "faust/gui/ValueConverter.h"
+#include <sstream>
+#include <string>
+#include <vector>
+#include <map>
+
+using namespace std;
+
+enum { kLin = 0, kLog = 1, kExp = 2 };
+
+class APIUI : public PathUI, public Meta
+{
+    protected:
+    
+        int	fNumParameters;
+        vector<string>			fName;
+        map<string, int>		fMap;
+        vector<ValueConverter*>	fConversion;
+        vector<FAUSTFLOAT*>		fZone;
+        vector<FAUSTFLOAT>		fInit;
+        vector<FAUSTFLOAT>		fMin;
+        vector<FAUSTFLOAT>		fMax;
+        vector<FAUSTFLOAT>		fStep;        
+        vector<string>			fUnit; 
+        vector<ZoneControl*>	fAcc[3];
+        vector<ZoneControl*>	fGyr[3]; 
+    
+        // Current values controlled by metadata
+        string	fCurrentUnit;     
+        int     fCurrentScale;
+        string	fCurrentAcc; 
+        string	fCurrentGyr;     
+
+        // Add a generic parameter
+        virtual void addParameter(const char* label, 
+                                FAUSTFLOAT* zone, 
+                                FAUSTFLOAT init, 
+                                FAUSTFLOAT min, 
+                                FAUSTFLOAT max, 
+                                FAUSTFLOAT step)
+        {
+            string name = buildPath(label);
+
+            fMap[name] = fNumParameters++;
+            fName.push_back(name);
+            fZone.push_back(zone);
+            fInit.push_back(init);
+            fMin.push_back(min);
+            fMax.push_back(max);
+            fStep.push_back(step);
+
+            //handle unit metadata
+            fUnit.push_back(fCurrentUnit); 
+            fCurrentUnit = "";
+
+            //handle scale metadata
+            switch (fCurrentScale) {
+                case kLin : fConversion.push_back(new LinearValueConverter(0,1, min, max)); break;
+                case kLog : fConversion.push_back(new LogValueConverter(0,1, min, max)); break;							
+                case kExp : fConversion.push_back(new ExpValueConverter(0,1, min, max)); break;
+            }
+            fCurrentScale  = kLin;
+        
+            // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+            if (fCurrentAcc.size() > 0) {
+                istringstream iss(fCurrentAcc); 
+                int axe, curve;
+                double amin, amid, amax;
+                iss >> axe >> curve >> amin >> amid >> amax;
+                
+                if ((0 <= axe) && (axe < 3) && 
+                    (0 <= curve) && (curve < 4) &&
+                    (amin < amax) && (amin <= amid) && (amid <= amax)) 
+                {
+                    fAcc[axe].push_back(new CurveZoneControl(zone, amin, amid, amax, min, init, max));
+                } else {
+                    cerr << "incorrect acc metadata : " << fCurrentAcc << endl;
+                }
+            }
+            fCurrentAcc = "";
+            
+            // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+            if (fCurrentGyr.size() > 0) {
+                istringstream iss(fCurrentGyr); 
+                int axe, curve;
+                double amin, amid, amax;
+                iss >> axe >> curve >> amin >> amid >> amax;
+                
+                if ((0 <= axe) && (axe < 3) && 
+                    (0 <= curve) && (curve < 4) &&
+                    (amin < amax) && (amin <= amid) && (amid <= amax)) 
+                {
+                    fGyr[axe].push_back(new CurveZoneControl(zone, amin, amid, amax, min, init, max));
+                } else {
+                    cerr << "incorrect gyr metadata : " << fCurrentGyr << endl;
+                }
+            }
+            fCurrentGyr = "";
+        }
+    
+        int getAccZoneIndex(int p, int acc)
+        {
+            FAUSTFLOAT* zone = fZone[p];
+            for (int i = 0; i < fAcc[acc].size(); i++) {
+                if (zone == fAcc[acc][i]->getZone()) return i;
+            }
+            return -1;
+        }
+    
+     public:
+    
+        APIUI() : fNumParameters(0) {}
+        virtual ~APIUI()
+        {
+            vector<ValueConverter*>::iterator it1;
+            for (it1 = fConversion.begin(); it1 != fConversion.end(); it1++) {
+                delete(*it1);
+            }
+            
+            vector<ZoneControl*>::iterator it2;
+            for (int i = 0; i < 3; i++) {
+                for (it2 = fAcc[i].begin(); it2 != fAcc[i].end(); it2++) {
+                    delete(*it2);
+                }
+                for (it2 = fGyr[i].begin(); it2 != fGyr[i].end(); it2++) {
+                    delete(*it2);
+                }
+            }
+        }
+
+        // -- widget's layouts
+    
+        virtual void openTabBox(const char* label)			{ fControlsLevel.push_back(label); 	}    
+        virtual void openHorizontalBox(const char* label)	{ fControlsLevel.push_back(label); 	} 
+        virtual void openVerticalBox(const char* label)		{ fControlsLevel.push_back(label); 	}
+        virtual void closeBox()								{ fControlsLevel.pop_back();		}
+    
+        // -- active widgets
+
+        virtual void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addParameter(label, zone, 0, 0, 1, 1);
+        }
+    
+        virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addParameter(label, zone, 0, 0, 1, 1);
+        }
+    
+        virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step);
+        }
+    
+        virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step);
+        }
+    
+        virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step);
+        }
+
+        // -- passive widgets
+    
+        virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            addParameter(label, zone, min, min, max, (max-min)/1000.0);
+        }
+    
+        virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addParameter(label, zone, min, min, max, (max-min)/1000.0);
+        }
+
+        // -- metadata declarations
+
+        virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {
+			if (strcmp(key, "scale") == 0) {
+                if (strcmp(val, "log") == 0) {
+                    fCurrentScale = kLog;
+                } else if (strcmp(val, "exp") == 0) {
+                    fCurrentScale = kExp;
+                } else {
+                    fCurrentScale = kLin;
+                }
+			} else if (strcmp(key, "unit") == 0) {
+				fCurrentUnit = val;
+			} else if (strcmp(key, "acc") == 0) {
+				fCurrentAcc = val;
+			} else if (strcmp(key, "gyr") == 0) {
+				fCurrentGyr = val;
+			}
+        }
+
+        virtual void declare(const char* key, const char* val)
+        {}
+
+		//-------------------------------------------------------------------------------
+		// Simple API part
+		//-------------------------------------------------------------------------------
+		int getParamsCount()				{ return fNumParameters; }
+		int getParamIndex(const char* n) 	{ return (fMap.count(n)>0) ? fMap[n] : -1; }
+		const char* getParamName(int p)		{ return fName[p].c_str(); }
+		const char* getParamUnit(int p)		{ return fUnit[p].c_str(); }
+		FAUSTFLOAT getParamMin(int p)		{ return fMin[p]; }
+		FAUSTFLOAT getParamMax(int p)		{ return fMax[p]; }
+		FAUSTFLOAT getParamStep(int p)		{ return fStep[p]; }
+	
+		FAUSTFLOAT getParamValue(int p)         { return *fZone[p]; }
+		void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+	
+		double getParamRatio(int p)         { return fConversion[p]->faust2ui(*fZone[p]); }
+		void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+	
+		double value2ratio(int p, double r)	{ return fConversion[p]->faust2ui(r); }
+		double ratio2value(int p, double r)	{ return fConversion[p]->ui2faust(r); }
+    
+        /**
+         * Set a new value coming from an accelerometer, propagate it to all relevant float* zones.
+         * 
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+         * @param value - the new value
+         *
+         */
+        void propagateAcc(int acc, double value)
+        {
+            for (int i = 0; i < fAcc[acc].size(); i++) {
+                fAcc[acc][i]->update(value);
+            }
+        }
+
+        /**
+         * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
+         * 
+         * @param p - the UI parameter index
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
+         * @param curve - between 0 and 3
+         * @param amin - mapping 'min' point
+         * @param amid - mapping 'middle' point
+         * @param amax - mapping 'max' point
+         *
+         */
+        void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+        {
+            int id1 = getAccZoneIndex(p, 0);
+            int id2 = getAccZoneIndex(p, 1);
+            int id3 = getAccZoneIndex(p, 2);
+            
+            // Deactivates everywhere..
+            if (id1 != -1) fAcc[0][id1]->setActive(false);
+            if (id2 != -1) fAcc[1][id2]->setActive(false);
+            if (id3 != -1) fAcc[2][id3]->setActive(false);
+            
+            if (acc == -1) { // Means: no more mapping...
+                // So stay all deactivated...
+            } else {
+                int id4 = getAccZoneIndex(p, acc);
+                if (id4 != -1) {
+                    // Reactivate the one we edit...
+                    fAcc[acc][id4]->setMappingValues(curve, amin, amid, amax, fMin[p], fInit[p], fMax[p]);
+                    fAcc[acc][id4]->setActive(true);
+                } else {
+                    // Allocate a new CurveZoneControl which is 'active' by default
+                    FAUSTFLOAT* zone = fZone[p];
+                    fAcc[acc].push_back(new CurveZoneControl(zone, amin, amid, amax, fMin[p], fInit[p], fMax[p]));
+                    //__android_log_print(ANDROID_LOG_ERROR, "Faust", "setAccConverter new CurveZoneControl %d", acc);
+                }
+            }
+        }
+         
+         /**
+         * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
+         * 
+         * @param p - the UI parameter index
+         * @param acc - the acc value to be retrieved (-1 means "no mapping")
+         * @param curve - the curve value to be retrieved
+         * @param amin - the amin value to be retrieved
+         * @param amid - the amid value to be retrieved
+         * @param amax - the amax value to be retrieved
+         *
+         */
+        void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
+        {
+            int id1 = getAccZoneIndex(p, 0);
+            int id2 = getAccZoneIndex(p, 1);
+            int id3 = getAccZoneIndex(p, 2);
+            
+            if (id1 != 1) {
+                acc = 0;
+                curve = fAcc[acc][id1]->getCurve();
+                fAcc[acc][id1]->getMappingValues(amin, amid, amax);
+            } else if (id2 != 1) {
+                acc = 1;
+                curve = fAcc[acc][id2]->getCurve();
+                fAcc[acc][id2]->getMappingValues(amin, amid, amax);
+            } else if (id3 != 1) {
+                acc = 2;
+                curve = fAcc[acc][id3]->getCurve();
+                fAcc[acc][id3]->getMappingValues(amin, amid, amax);
+            } else {
+                acc = -1; // No mapping 
+                curve = 0;
+                amin = -100.;
+                amid = 0.;
+                amax = 100.;
+            }
+        }
+        
+        // TODO
+        void propagateGyr(int gyr, double value) 
+        {
+            for (int i = 0; i < fGyr[gyr].size(); i++) {
+                fGyr[gyr][i]->update(value);
+            }
+        }
+        
+        void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax) {}
+        
+        void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax) {}
+   
+};
+
+#endif
diff --git a/architecture/faust/gui/ControlUI.h b/architecture/faust/gui/ControlUI.h
new file mode 100644
index 0000000..2b4d5f2
--- /dev/null
+++ b/architecture/faust/gui/ControlUI.h
@@ -0,0 +1,104 @@
+#ifndef CONTROL_UI_H
+#define CONTROL_UI_H
+
+#include "faust/gui/UI.h"
+#include <jack/midiport.h>
+#include <vector>
+#include <assert.h>
+
+class ControlUI : public UI {  
+
+    protected:
+    
+        std::vector<FAUSTFLOAT*> fControlIn;
+        std::vector<FAUSTFLOAT*> fControlOut;
+     
+         // -- widget's layouts
+
+        void openTabBox(const char* label) {}
+        void openHorizontalBox(const char* label) {}
+        void openVerticalBox(const char* label) {};
+        void closeBox() {}
+
+        // -- active widgets
+
+        void addButton(const char* label, FAUSTFLOAT* zone) { fControlIn.push_back(zone); }
+        void addCheckButton(const char* label, FAUSTFLOAT* zone) { fControlIn.push_back(zone); }
+        void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fControlIn.push_back(zone); };
+        void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fControlIn.push_back(zone); };
+
+        void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fControlIn.push_back(zone); };
+
+        // -- passive widgets
+
+        void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { fControlOut.push_back(zone); };
+        void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { fControlOut.push_back(zone); };
+        
+    public:
+       
+        void encode_control(float* control_buffer, unsigned int frames)
+        { 
+            assert(fControlOut.size() < frames);
+            
+            for (unsigned int i = 0; i < fControlOut.size(); i++) {
+                control_buffer[i] = *fControlOut[i];
+            }
+        }
+        
+        void decode_control(float* control_buffer, unsigned int frames)
+        {
+            assert(fControlIn.size() < frames);
+            
+            for (unsigned int i = 0; i < fControlIn.size(); i++) {
+               *fControlIn[i] = control_buffer[i];
+            }
+        }
+        
+        void encode_midi_control(void* midi_control_buffer, unsigned int count)
+        { 
+            assert(fControlOut.size() < count);
+            jack_midi_reset_buffer(midi_control_buffer);
+          
+            for (unsigned int i = 0; i < fControlOut.size(); i++) {
+                jack_midi_data_t* buffer = jack_midi_event_reserve(midi_control_buffer, i, 4);
+                assert(buffer);
+                *((float*)buffer) = *fControlOut[i];
+            }
+        }
+    
+        static void encode_midi_control(void* midi_control_buffer, float* control_buffer, int count)
+        {
+            jack_midi_reset_buffer(midi_control_buffer);
+            
+            for (unsigned int i = 0; i < count; i++) {
+                jack_midi_data_t* buffer = jack_midi_event_reserve(midi_control_buffer, i, 4);
+                assert(buffer);
+                *((float*)buffer) = control_buffer[i];
+            }
+        }
+        
+        void decode_midi_control(void* midi_control_buffer, unsigned int count)
+        {
+            assert(jack_midi_get_event_count(midi_control_buffer) <= count);
+            
+            for (int i = 0; i < jack_midi_get_event_count(midi_control_buffer); i++) {
+                jack_midi_event_t in_event;
+                jack_midi_event_get(&in_event, midi_control_buffer, i);
+                *fControlIn[i] = *((float*)in_event.buffer);
+            }
+        }
+        
+        static void decode_midi_control(void* midi_control_buffer, float* control_buffer, int count)
+        {
+            assert(jack_midi_get_event_count(midi_control_buffer) <= count);
+            
+            for (int i = 0; i < jack_midi_get_event_count(midi_control_buffer); i++) {
+                jack_midi_event_t in_event;
+                jack_midi_event_get(&in_event, midi_control_buffer, i);
+                control_buffer[i] = *((float*)(in_event.buffer));
+            }
+        }
+        
+};
+
+#endif
diff --git a/architecture/faust/gui/FUI.h b/architecture/faust/gui/FUI.h
new file mode 100644
index 0000000..b51c841
--- /dev/null
+++ b/architecture/faust/gui/FUI.h
@@ -0,0 +1,144 @@
+#ifndef FAUST_FUI_H
+#define FAUST_FUI_H
+
+#include "faust/gui/UI.h"
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+#include <stack>
+
+#include <iostream>
+#include <fstream>
+
+//using namespace std;
+
+#if 1
+
+/*******************************************************************************
+ * FUI : used to save and recall the state of the user interface
+ * This class provides essentially two new methods saveState() and recallState()
+ * used to save on file and recall from file the state of the user interface.
+ * The file is human readble and editable
+ ******************************************************************************/
+
+class FUI : public UI
+{
+    
+    std::stack<std::string>             fGroupStack;
+	std::vector<std::string>            fNameList;
+	std::map<std::string, FAUSTFLOAT*>	fName2Zone;
+
+ protected:
+
+ 	// labels are normalized by replacing white spaces by underscores and by
+ 	// removing parenthesis
+	std::string normalizeLabel(const char* label)
+	{
+		std::string 	s;
+		char 	c;
+
+		while ((c=*label++)) {
+			if (isspace(c)) 				{ s += '_'; }
+			//else if ((c == '(') | (c == ')') ) 	{ }
+			else 							{ s += c; }
+		}
+		return s;
+	}
+
+	// add an element by relating its full name and memory zone
+	virtual void addElement(const char* label, FAUSTFLOAT* zone)
+	{
+		std::string fullname (fGroupStack.top() + '/' + normalizeLabel(label));
+		fNameList.push_back(fullname);
+		fName2Zone[fullname] = zone;
+	}
+
+	// keep track of full group names in a stack
+	virtual void pushGroupLabel(const char* label)
+	{
+		if (fGroupStack.empty()) {
+			fGroupStack.push(normalizeLabel(label));
+		} else {
+			fGroupStack.push(fGroupStack.top() + '/' + normalizeLabel(label));
+		}
+	}
+
+	virtual void popGroupLabel()
+	{
+		fGroupStack.pop();
+	};
+
+ public:
+
+	FUI() 			{}
+	virtual ~FUI() 	{}
+
+	// -- Save and recall methods
+
+	// save the zones values and full names
+	virtual void saveState(const char* filename)
+	{
+		std::ofstream f(filename);
+
+		for (unsigned int i=0; i<fNameList.size(); i++) {
+			std::string	n = fNameList[i];
+			FAUSTFLOAT*	z = fName2Zone[n];
+			f << *z << ' ' << n.c_str() << std::endl;
+		}
+
+		f << std::endl;
+		f.close();
+	}
+
+	// recall the zones values and full names
+	virtual void recallState(const char* filename)
+	{
+		std::ifstream f(filename);
+		FAUSTFLOAT	v;
+		std::string	n;
+
+		while (f.good()) {
+			f >> v >> n;
+			if (fName2Zone.count(n)>0) {
+				*(fName2Zone[n]) = v;
+			} else {
+				std::cerr << "recallState : parameter not found : " << n.c_str() << " with value : " << v << std::endl;
+			}
+		}
+		f.close();
+	}
+
+
+    // -- widget's layouts (just keep track of group labels)
+
+    virtual void openTabBox(const char* label) 			{ pushGroupLabel(label); }
+    virtual void openHorizontalBox(const char* label) 	{ pushGroupLabel(label); }
+    virtual void openVerticalBox(const char* label)  	{ pushGroupLabel(label); }
+    virtual void closeBox() 							{ popGroupLabel(); };
+
+    // -- active widgets (just add an element)
+
+    virtual void addButton(const char* label, FAUSTFLOAT* zone) 		{ addElement(label, zone); }
+    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) 	{ addElement(label, zone); }
+    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT)
+    																{ addElement(label, zone); }
+    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT)
+    																{ addElement(label, zone); }
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT)
+    																{ addElement(label, zone); }
+
+    // -- passive widgets (are ignored)
+
+    virtual void addHorizontalBargraph(const char*, FAUSTFLOAT*, FAUSTFLOAT, FAUSTFLOAT) {};
+    virtual void addVerticalBargraph(const char*, FAUSTFLOAT*, FAUSTFLOAT, FAUSTFLOAT) {};
+
+	// -- metadata are not used
+
+    virtual void declare(FAUSTFLOAT*, const char*, const char*) {}
+};
+#endif
+
+#endif
+
diff --git a/architecture/faust/gui/GUI.h b/architecture/faust/gui/GUI.h
new file mode 100644
index 0000000..b0639bf
--- /dev/null
+++ b/architecture/faust/gui/GUI.h
@@ -0,0 +1,184 @@
+#ifndef FAUST_GUI_H
+#define FAUST_GUI_H
+
+#include "faust/gui/UI.h"
+#include <list>
+#include <map>
+
+/*******************************************************************************
+ * GUI : Abstract Graphic User Interface
+ * Provides additional macchanismes to synchronize widgets and zones. Widgets
+ * should both reflect the value of a zone and allow to change this value.
+ ******************************************************************************/
+
+class uiItem;
+typedef void (*uiCallback)(FAUSTFLOAT val, void* data);
+
+class clist : public std::list<uiItem*>
+{
+    public:
+    
+        virtual ~clist();
+        
+};
+
+class GUI : public UI
+{
+    
+	typedef std::map<FAUSTFLOAT*, clist*> zmap;
+	
+    private:
+     
+        static std::list<GUI*>  fGuiList;
+        zmap                    fZoneMap;
+        bool                    fStopped;
+        
+     public:
+            
+        GUI() : fStopped(false) 
+        {	
+            fGuiList.push_back(this);
+        }
+        
+        virtual ~GUI() 
+        {   
+            // delete all 
+            zmap::iterator g;
+            for (g = fZoneMap.begin(); g != fZoneMap.end(); g++) {
+                delete (*g).second;
+            }
+            // suppress 'this' in static fGuiList
+            fGuiList.remove(this);
+        }
+
+        // -- registerZone(z,c) : zone management
+        
+        void registerZone(FAUSTFLOAT* z, uiItem* c)
+        {
+            if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist();
+            fZoneMap[z]->push_back(c);
+        } 	
+
+        void updateAllZones();
+        
+        void updateZone(FAUSTFLOAT* z);
+        
+        static void updateAllGuis()
+        {
+            std::list<GUI*>::iterator g;
+            for (g = fGuiList.begin(); g != fGuiList.end(); g++) {
+                (*g)->updateAllZones();
+            }
+        }
+        void addCallback(FAUSTFLOAT* zone, uiCallback foo, void* data);
+        virtual void show() {};	
+        virtual void run() {};
+        
+        virtual void stop()		{ fStopped = true; }
+        bool stopped() 	{ return fStopped; }
+
+        virtual void declare(FAUSTFLOAT* , const char* , const char*) {}
+};
+
+/**
+ * User Interface Item: abstract definition
+ */
+
+class uiItem
+{
+    protected:
+          
+        GUI*            fGUI;
+        FAUSTFLOAT*     fZone;
+        FAUSTFLOAT      fCache;
+
+        uiItem(GUI* ui, FAUSTFLOAT* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321) 
+        { 
+            ui->registerZone(zone, this); 
+        }
+
+    public:
+
+        virtual ~uiItem() 
+        {}
+
+        void modifyZone(FAUSTFLOAT v) 	
+        { 
+            fCache = v;
+            if (*fZone != v) {
+                *fZone = v;
+                fGUI->updateZone(fZone);
+            }
+        }
+                
+        FAUSTFLOAT		cache()	{ return fCache; }
+        virtual void 	reflectZone() = 0;	
+};
+
+/**
+ * Callback Item
+ */
+
+struct uiCallbackItem : public uiItem
+{
+	uiCallback	fCallback;
+	void*		fData;
+	
+	uiCallbackItem(GUI* ui, FAUSTFLOAT* zone, uiCallback foo, void* data) 
+			: uiItem(ui, zone), fCallback(foo), fData(data) {}
+	
+	virtual void reflectZone() 
+    {		
+		FAUSTFLOAT 	v = *fZone;
+		fCache = v; 
+		fCallback(v, fData);	
+	}
+};
+
+// en cours d'installation de callback : a finir!!!!!
+
+/**
+ * Update all user items reflecting zone z
+ */
+
+inline void GUI::updateZone(FAUSTFLOAT* z)
+{
+	FAUSTFLOAT v = *z;
+	clist* l = fZoneMap[z];
+	for (clist::iterator c = l->begin(); c != l->end(); c++) {
+		if ((*c)->cache() != v) (*c)->reflectZone();
+	}
+}
+
+/**
+ * Update all user items not up to date
+ */
+
+inline void GUI::updateAllZones()
+{
+	for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) {
+		FAUSTFLOAT* z = m->first;
+		clist*	l = m->second;
+        if (z) {
+            FAUSTFLOAT	v = *z;
+            for (clist::iterator c = l->begin(); c != l->end(); c++) {
+                if ((*c)->cache() != v) (*c)->reflectZone();
+            }
+        }
+	}
+}
+
+inline void GUI::addCallback(FAUSTFLOAT* zone, uiCallback foo, void* data) 
+{ 
+	new uiCallbackItem(this, zone, foo, data); 
+};
+
+inline clist::~clist() 
+{
+    std::list<uiItem*>::iterator it;
+    for (it = begin(); it != end(); it++) {
+        delete (*it);
+    }
+}
+
+#endif
diff --git a/architecture/faust/gui/JSONUI.h b/architecture/faust/gui/JSONUI.h
new file mode 100644
index 0000000..b405f2c
--- /dev/null
+++ b/architecture/faust/gui/JSONUI.h
@@ -0,0 +1,287 @@
+#ifndef FAUST_JSONUI_H
+#define FAUST_JSONUI_H
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#include "faust/gui/PathUI.h"
+#include "faust/gui/meta.h"
+
+#include <vector>
+#include <map>
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#include <assert.h>
+
+/*******************************************************************************
+ * JSONUI : Faust User Interface
+ * This class produce a complete JSON decription of the DSP instance.
+ ******************************************************************************/
+
+class JSONUI : public PathUI, public Meta
+{
+
+    protected:
+    
+        std::stringstream fJSON;
+        std::stringstream fUI;
+        std::stringstream fMeta;
+        std::vector<std::pair <std::string, std::string> > fMetaAux;
+        std::string fName;
+        std::string fExpandedCode;
+        std::string fSHAKey;
+    
+        char fCloseUIPar;
+        char fCloseMetaPar;
+        int fTab;
+    
+        int fInputs, fOutputs;
+         
+        void tab(int n, std::ostream& fout)
+        {
+            fout << '\n';
+            while (n-- > 0) {
+                fout << '\t';
+            }
+        }
+    
+        void addMeta(int tab_val, bool quote = true)
+        {
+            if (fMetaAux.size() > 0) {
+                tab(tab_val, fUI); fUI << "\"meta\": [";
+                std::string sep = "";
+                for (size_t i = 0; i < fMetaAux.size(); i++) {
+                    fUI << sep;
+                    tab(tab_val + 1, fUI); fUI << "{ \"" << fMetaAux[i].first << "\": \"" << fMetaAux[i].second << "\" }";
+                    sep = ",";
+                }
+                tab(tab_val, fUI); fUI << ((quote) ? "],": "]");
+                fMetaAux.clear();
+            }
+        }
+        
+        void init(const std::string& name, int inputs, int outputs, const std::string& sha_key, const std::string& dsp_code)
+        {
+            fTab = 1;
+            
+            // Start Meta generation
+            tab(fTab, fMeta); fMeta << "\"meta\": [";
+            fCloseMetaPar = ' ';
+            
+            // Start UI generation
+            tab(fTab, fUI); fUI << "\"ui\": [";
+            fCloseUIPar = ' ';
+            fTab += 1;
+            
+            fName = name;
+            fInputs = inputs;
+            fOutputs = outputs;
+            fExpandedCode = dsp_code;
+            fSHAKey = sha_key;
+        }
+        
+        inline std::string flatten(const std::string& src)
+        {
+            std::stringstream dst;
+            for (size_t i = 0; i < src.size(); i++) {
+                switch (src[i]) {
+                    case '\n':
+                    case '\t':
+                        dst << ' ';
+                        break;
+                    case '"':
+                        dst << "\\" << '"';
+                        break;
+                    default:
+                        dst << src[i];
+                        break;
+                }
+            }
+            return dst.str();
+        }
+      
+     public:
+     
+        JSONUI(const std::string& name, int inputs, int outputs, const std::string& sha_key, const std::string& dsp_code)
+        {
+            init(name, inputs, outputs, sha_key, dsp_code);
+        }
+
+        JSONUI(const std::string& name, int inputs, int outputs)
+        {
+            init(name, inputs, outputs, "", "");
+        }
+
+        JSONUI(int inputs, int outputs)
+        {
+            init("", inputs, outputs, "", "");
+        }
+ 
+        virtual ~JSONUI() {}
+
+        // -- widget's layouts
+    
+        virtual void openGenericGroup(const char* label, const char* name)
+        {
+            fControlsLevel.push_back(label);
+            fUI << fCloseUIPar;
+            tab(fTab, fUI); fUI << "{";
+            fTab += 1;
+            tab(fTab, fUI); fUI << "\"type\": \"" << name << "\",";
+            tab(fTab, fUI); fUI << "\"label\": \"" << label << "\",";
+            addMeta(fTab + 1);
+            tab(fTab, fUI); fUI << "\"items\": [";
+            fCloseUIPar = ' ';
+            fTab += 1;
+        }
+
+        virtual void openTabBox(const char* label)
+        {
+            openGenericGroup(label, "tgroup");
+        }
+    
+        virtual void openHorizontalBox(const char* label)
+        {
+            openGenericGroup(label, "hgroup");
+        }
+    
+        virtual void openVerticalBox(const char* label)
+        {
+            openGenericGroup(label, "vgroup");
+        }
+    
+        virtual void closeBox()
+        {
+            fControlsLevel.pop_back();
+            fTab -= 1;
+            tab(fTab, fUI); fUI << "]";
+            fTab -= 1;
+            tab(fTab, fUI); fUI << "}";
+            fCloseUIPar = ',';
+        }
+    
+        // -- active widgets
+    
+        virtual void addGenericButton(const char* label, const char* name)
+        {
+            fUI << fCloseUIPar;
+            tab(fTab, fUI); fUI << "{";
+            tab(fTab + 1, fUI); fUI << "\"type\": \"" << name << "\",";
+            tab(fTab + 1, fUI); fUI << "\"label\": \"" << label << "\"" << ",";
+            tab(fTab + 1, fUI); fUI << "\"address\": \"" << buildPath(label) << "\"" << ((fMetaAux.size() > 0) ? "," : "");
+            addMeta(fTab + 1, false);
+            tab(fTab, fUI); fUI << "}";
+            fCloseUIPar = ',';
+        }
+
+        virtual void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addGenericButton(label, "button");
+        }
+    
+        virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addGenericButton(label, "checkbox");
+        }
+
+        virtual void addGenericEntry(const char* label, const char* name, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            fUI << fCloseUIPar;
+            tab(fTab, fUI); fUI << "{";
+            tab(fTab + 1, fUI); fUI << "\"type\": \"" << name << "\",";
+            tab(fTab + 1, fUI); fUI << "\"label\": \"" << label << "\"" << ",";
+            tab(fTab + 1, fUI); fUI << "\"address\": \"" << buildPath(label) << "\"" << ",";
+            addMeta(fTab + 1);
+            tab(fTab + 1, fUI); fUI << "\"init\": \"" << init << "\",";
+            tab(fTab + 1, fUI); fUI << "\"min\": \"" << min << "\",";
+            tab(fTab + 1, fUI); fUI << "\"max\": \"" << max << "\",";
+            tab(fTab + 1, fUI); fUI << "\"step\": \"" << step << "\"";
+            tab(fTab, fUI); fUI << "}";
+            fCloseUIPar = ',';
+        }
+    
+        virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addGenericEntry(label, "vslider", init, min, max, step);
+        }
+    
+        virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addGenericEntry(label, "hslider", init, min, max, step);
+        }
+    
+        virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addGenericEntry(label, "nentry", init, min, max, step);
+        }
+
+        // -- passive widgets
+    
+        virtual void addGenericBargraph(const char* label, const char* name, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            fUI << fCloseUIPar;
+            tab(fTab, fUI); fUI << "{";
+            tab(fTab + 1, fUI); fUI << "\"type\": \"" << name << "\",";
+            tab(fTab + 1, fUI); fUI << "\"label\": \"" << label << "\"" << ",";
+            tab(fTab + 1, fUI); fUI << "\"address\": \"" << buildPath(label) << "\"" << ",";
+            addMeta(fTab + 1);
+            tab(fTab + 1, fUI); fUI << "\"min\": \"" << min << "\",";
+            tab(fTab + 1, fUI); fUI << "\"max\": \"" << max << "\"";
+            tab(fTab, fUI); fUI << "}";
+            fCloseUIPar = ',';
+        }
+
+        virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            addGenericBargraph(label, "hbargraph", min, max);
+        }
+    
+        virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addGenericBargraph(label, "vbargraph", min, max);
+        }
+
+        // -- metadata declarations
+
+        virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {
+            fMetaAux.push_back(std::make_pair(key, val));
+        }
+    
+        // Meta interface
+        virtual void declare(const char* key, const char* value)
+        {
+            fMeta << fCloseMetaPar;
+            if ((strcmp(key, "name") == 0) && (fName == "")) fName = value;
+            tab(fTab, fMeta); fMeta << "{ " << "\"" << key << "\"" << ": " << "\"" << value << "\" }";
+            fCloseMetaPar = ',';
+        }
+    
+        std::string JSON(bool flat = false)
+        {
+            fTab = 0;
+            fJSON << "{";
+            fTab += 1;
+            tab(fTab, fJSON); fJSON << "\"name\": \"" << fName << "\",";
+            if (fSHAKey != "") { tab(fTab, fJSON); fJSON << "\"sha_key\": \"" << fSHAKey << "\","; }
+            if (fExpandedCode != "") { tab(fTab, fJSON); fJSON << "\"code\": \"" << fExpandedCode << "\","; }
+            if (fInputs > 0) { tab(fTab, fJSON); fJSON << "\"inputs\": \"" << fInputs << "\","; }
+            if (fOutputs > 0) { tab(fTab, fJSON); fJSON << "\"outputs\": \"" << fOutputs << "\","; }
+            tab(fTab, fMeta); fMeta << "],";
+            tab(fTab, fUI); fUI << "]";
+            fTab -= 1;
+            if (fCloseMetaPar == ',') { // If "declare" has been called, fCloseMetaPar state is now ','
+                fJSON << fMeta.str() << fUI.str();
+            } else {
+                fJSON << fUI.str();
+            }
+            tab(fTab, fJSON); fJSON << "}" << std::endl;
+            return (flat) ? flatten(fJSON.str()) : fJSON.str();
+        }
+    
+};
+
+#endif
diff --git a/architecture/faust/gui/MapUI.h b/architecture/faust/gui/MapUI.h
new file mode 100644
index 0000000..0f270b2
--- /dev/null
+++ b/architecture/faust/gui/MapUI.h
@@ -0,0 +1,113 @@
+#ifndef FAUST_MapUI_H
+#define FAUST_MapUI_H
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#include "faust/gui/PathUI.h"
+#include <vector>
+#include <map>
+#include <string>
+
+/*******************************************************************************
+ * MapUI : Faust User Interface
+ * This class creates a map of complete path and zones for each UI item.
+ ******************************************************************************/
+
+class MapUI : public PathUI
+{
+    
+    protected:
+        
+        std::map<std::string, FAUSTFLOAT*> fZoneMap;
+           
+    public:
+        
+        MapUI() {};
+        virtual ~MapUI() {};
+        
+        // -- widget's layouts
+        void openTabBox(const char* label)
+        {
+            fControlsLevel.push_back(label);
+        }
+        void openHorizontalBox(const char* label)
+        {
+            fControlsLevel.push_back(label);
+        }
+        void openVerticalBox(const char* label)
+        {
+            fControlsLevel.push_back(label);
+        }
+        void closeBox()
+        {
+            fControlsLevel.pop_back();
+        }
+        
+        // -- active widgets
+        void insertMap(std::string label, FAUSTFLOAT* zone)
+        {
+            fZoneMap[label] = zone;
+        }
+        
+        void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT fmin, FAUSTFLOAT fmax, FAUSTFLOAT step)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT fmin, FAUSTFLOAT fmax, FAUSTFLOAT step)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT fmin, FAUSTFLOAT fmax, FAUSTFLOAT step)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        
+        // -- passive widgets
+        void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT fmin, FAUSTFLOAT fmax)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT fmin, FAUSTFLOAT fmax)
+        {
+            insertMap(buildPath(label), zone);
+        }
+        
+        // -- metadata declarations
+        void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {}
+        
+        // set/get
+        void setValue(const std::string& path, float value)
+        {
+            *fZoneMap[path] = value;
+        }
+        
+        float getValue(const std::string& path)
+        {
+            return *fZoneMap[path];
+        }
+    
+        // map access 
+        std::map<std::string, FAUSTFLOAT*>& getMap() { return fZoneMap; }
+        
+        int getParamsCount() { return fZoneMap.size(); }
+        
+        std::string getParamPath(int index) 
+        { 
+            std::map<std::string, FAUSTFLOAT*>::iterator it = fZoneMap.begin();
+            while (index-- > 0 && it++ != fZoneMap.end()) {}
+            return (*it).first;
+        }
+};
+
+#endif
diff --git a/architecture/faust/gui/MidiUI.h b/architecture/faust/gui/MidiUI.h
new file mode 100644
index 0000000..cfe679d
--- /dev/null
+++ b/architecture/faust/gui/MidiUI.h
@@ -0,0 +1,222 @@
+/************************************************************************
+    FAUST Architecture File
+    Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+    EXCEPTION : As a special exception, you may create a larger work
+    that contains this FAUST architecture section and distribute
+    that work under terms of your choice, so long as this FAUST
+    architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef FAUST_MIDIUI_H
+#define FAUST_MIDIUI_H
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#include "faust/gui/GUI.h"
+#include "faust/midi/midi.h"
+#include "faust/midi/rt-midi.h"
+#include "faust/gui/ValueConverter.h"
+#include <vector>
+#include <string>
+
+/*******************************************************************************
+ * MidiUI : Faust User Interface
+ * This class decode MIDI meta data and maps incoming MIDI messages to them
+ ******************************************************************************/
+
+class uiMidiPgm : public uiItem
+{
+    private:
+        
+        midi* fMidiOut;
+        int fPgm;
+  
+    public:
+    
+        uiMidiPgm(midi* midi_out, int pgm, GUI* ui, FAUSTFLOAT* zone)
+            :uiItem(ui, zone), fMidiOut(midi_out), fPgm(pgm)
+        {}
+        virtual ~uiMidiPgm()
+        {}
+        
+        virtual void reflectZone()
+        {
+            FAUSTFLOAT v = *fZone;
+            fCache = v;
+            if (v != 0.) {
+                fMidiOut->progChange(0, fPgm);
+            }
+        }
+        
+};
+
+class uiMidiCtrl : public uiItem
+{
+    private:
+    
+        midi* fMidiOut;
+        int fCtrl;
+        LinearValueConverter fConverter;
+ 
+    public:
+    
+        uiMidiCtrl(midi* midi_out, int ctrl, GUI* ui, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+            :uiItem(ui, zone), fMidiOut(midi_out), fCtrl(ctrl), fConverter(0., 127., double(min), double(max))
+        {}
+        virtual ~uiMidiCtrl()
+        {}
+        
+        virtual void reflectZone()
+        {
+            FAUSTFLOAT v = *fZone;
+            fCache = v;
+            fMidiOut->ctrlChange(0, fCtrl, fConverter.faust2ui(v));
+        }
+        
+        void modifyZone(int v) 	
+        { 
+            uiItem::modifyZone(FAUSTFLOAT(fConverter.ui2faust(v)));
+        }
+ 
+};
+
+class MidiUI : public GUI, public midi
+{
+
+    private:
+    
+        std::map <int, std::vector<uiMidiCtrl*> > fCtrlChangeTable;
+        std::map <int, std::vector<uiMidiPgm*> > fProgChangeTable;
+        
+        std::vector<std::pair <std::string, std::string> > fMetaAux;
+        
+        rtmidi fMIDI;
+        midi* fMidiOut;
+  
+    public:
+
+        MidiUI(const string& name = "RTMidi"):fMIDI(name), fMidiOut(&fMIDI) { fMIDI.addMidiIn(this); }
+
+        virtual ~MidiUI() {}
+        
+        virtual void run() { fMIDI.start(); }
+        virtual void stop() { fMIDI.stop(); }
+      
+        // -- widget's layouts
+
+        virtual void openTabBox(const char* label)
+        {}
+        virtual void openHorizontalBox(const char* label)
+        {}
+        virtual void openVerticalBox(const char* label)
+        {}
+        virtual void closeBox()
+        {}
+
+        // -- active widgets
+        
+        void addGenericZone(FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            if (fMetaAux.size() > 0) {
+                for (size_t i = 0; i < fMetaAux.size(); i++) {
+                    unsigned num;
+                    if (fMetaAux[i].first == "midi") {
+                        if (sscanf(fMetaAux[i].second.c_str(), "ctrl %u", &num) == 1) {
+                            fCtrlChangeTable[num].push_back(new uiMidiCtrl(fMidiOut, num, this, zone, min, max));
+                        } else if (sscanf(fMetaAux[i].second.c_str(), "pgm %u", &num) == 1) {
+                            fProgChangeTable[num].push_back(new uiMidiPgm(fMidiOut, num, this, zone));
+                        }
+                    }
+                }
+            }
+            fMetaAux.clear();
+        }
+
+        virtual void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addGenericZone(zone, 0, 0);
+        }
+        virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addGenericZone(zone, 0, 0);
+        }
+        
+        virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addGenericZone(zone, min, max);
+        }
+        virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addGenericZone(zone, min, max);
+        }
+        virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addGenericZone(zone, min, max);
+        }
+
+        // -- passive widgets
+
+        virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            addGenericZone(zone, 0, 0);
+        }
+        virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addGenericZone(zone, 0, 0);
+        }
+
+        // -- metadata declarations
+
+        virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {
+            fMetaAux.push_back(std::make_pair(key, val));
+        }
+        
+        // -- MIDI API 
+        
+        void keyOn(int channel, int note, int velocity) {}
+        
+        void keyOff(int channel, int note, int velocity) {}
+           
+        void ctrlChange(int channel, int ctrl, int value)
+        {
+            if (fCtrlChangeTable.find(ctrl) != fCtrlChangeTable.end()) {
+                for (int i = 0; i < fCtrlChangeTable[ctrl].size(); i++) {
+                    fCtrlChangeTable[ctrl][i]->modifyZone(value);
+                }
+            } 
+        }
+        
+        void progChange(int channel, int pgm)
+        {
+            if (fProgChangeTable.find(pgm) != fProgChangeTable.end()) {
+                for (int i = 0; i < fProgChangeTable[pgm].size(); i++) {
+                    fProgChangeTable[pgm][i]->modifyZone(1.f);
+                }
+            } 
+        }
+        
+        void pitchWheel(int channel, int wheel) {}
+
+};
+
+#endif
diff --git a/architecture/faust/gui/OCVUI.h b/architecture/faust/gui/OCVUI.h
new file mode 100644
index 0000000..5438e61
--- /dev/null
+++ b/architecture/faust/gui/OCVUI.h
@@ -0,0 +1,689 @@
+#ifndef _OCVUI_H
+#define _OCVUI_H
+
+/******************************************************************************
+*******************************************************************************
+
+                                OPENCV USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+/**
+ * \file OCVUI.h
+ * \brief OpenCV user interface
+ * \author GRAME, Centre National de Création Musicale
+ * \date 26/01/2015
+ * 
+ * This architecture file allows the user to use the OpenCV library in order to perform
+ *	image processing and use the result to control audio parameters.
+ *								
+ * To use this mode, just add the option -ocv with your faust2jack tool.
+ * 				
+ */
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+// OpenCV includes
+#include "opencv2/video/tracking.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/highgui/highgui.hpp"
+
+// Basic includes
+#include <iostream>
+#include <ctype.h>
+
+// std::thread
+#include <pthread.h>
+
+// OpenCV Main Loop Function Prototype
+
+static void* ocvLoop(void*);
+
+//********	OpenCV User Interface CLASS DEFINITION ********//
+class OCVUI : public UI
+{
+    
+    public :
+    
+	// STRUCTURES
+	
+	/**
+	 * \struct object
+	 * \brief parameters of an object detected in the image
+	 * 
+	 * An object is assimilated to a circle, and characterised by 
+	 * its color, its center, its area, and its radius.
+	 * 
+	 */
+	
+	struct object
+	{
+		int color;		/*!< Object's color				*/
+		float centerX;	/*!< Object's center's abscissa */
+		float centerY;	/*!< Object's center's ordinate */
+		float area;		/*!< Object's area 				*/
+		int radius;		/*!< Object's radius 			*/
+	};
+	
+	/**
+	 * \struct metadata
+	 * \brief metadata for audio parameters
+	 *
+	 * OpenCV metadata specify which object's characteristics you
+	 * want for an audio parameter.
+	 *
+	 */
+	struct metadata
+	{
+		FAUSTFLOAT* zone;	/*!< Audio parameter's address 	*/
+		int color;			/*!< Object's color 			*/
+		std::string param;	/*!< Object's parameter 		*/
+		bool used;			/*!< Bool variable				*/
+	};
+	
+
+	// FUNCTIONS
+	
+	//-- UI Functions Redefinition
+		// Functions inherited from the UI class
+	
+    // Constructor
+	OCVUI() : objects_storage_(0), parameters_storage_(0), height_(0), width_(0){};
+	
+	// Destructor
+	~OCVUI() 
+	{
+	exit_=true;
+	pthread_join(loop_, NULL);	
+	};
+	
+	
+	// -- WIDGETS LAYOUTS
+	void openTabBox(const char* label){}
+	void openHorizontalBox(const char* label){}
+	void openVerticalBox(const char* label){}
+	void closeBox(){}
+
+	// -- ACTIVE WIDGETS
+	void addButton(const char* label, FAUSTFLOAT* zone){}
+	void addCheckButton(const char* label, FAUSTFLOAT* zone){}
+	void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min,
+	FAUSTFLOAT max, FAUSTFLOAT step){}
+	void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, 
+	FAUSTFLOAT max, FAUSTFLOAT step){}
+	void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, 
+	FAUSTFLOAT max, FAUSTFLOAT step){}
+	
+	// -- PASSIVE WIDGETS
+	void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max){}
+	void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max){}
+
+
+	// -- METADATA DECLARATION
+	
+	
+	/**
+	 * \fn bool parser(std::string string2parse, metadata *pmeta)
+	 * \brief Parsing Function
+	 * 
+	 * \param string2parse A string to parse
+	 * \param pmeta Pointer on a metadata structure
+	 *
+	 * This function parses the metadata string, and puts the parameters 
+	 * in a metadata structure.
+	 */
+		
+	bool parser(std::string string2parse, metadata *pmeta)
+	{
+	    int SPACE = 32; // Parameters separator
+	    std::vector<std::string> parameters(0);
+	    
+	    // String analysis 
+	    for (int i = 0 ; i < string2parse.size() ; i++)
+	    {
+	    	if (string2parse[i]==SPACE)
+	    	{
+	    	    std::string oneParameter= string2parse.substr(0,i);
+	    	    parameters.push_back(oneParameter);
+	    	    string2parse.erase(string2parse.begin(), string2parse.begin()+i+1);
+	    	    i=0;
+	    	}	
+	    }
+	    std::string lastParameter = string2parse;
+	    
+	    parameters.push_back(lastParameter);
+	    	    
+	    // Store Parameters in a Metadata Structure
+	    
+	    // Parameters count must be 2
+	    if (parameters.size()==2)
+	    {
+	    	/**
+	    	 * \enum color
+	    	 * \brief color indexes
+	    	 *
+	    	 * Colors are indexed
+	    	 */
+	    	
+	    		
+	    	if (parameters[0]=="red")			/*!< red = 1		*/
+	    	{
+	    		pmeta->color = 1;
+	    	}
+	    	else if (parameters[0]=="yellow")	/*!< yellow = 2		*/
+	    	{
+	    		pmeta->color = 2;
+	    	}
+	    	else if (parameters[0]=="green")	/*!< green = 3 		*/
+	    	{
+	    		pmeta->color = 3;
+	    	}
+	    	else if (parameters[0]=="cyan")		/*!< cyan = 4 		*/
+	    	{
+	    		pmeta->color = 4;
+	    	}
+	    	else if (parameters[0]=="blue")		/*!< blue = 5 		*/
+	    	{
+	    		pmeta->color = 5;
+	    	}
+	    	else if (parameters[0]=="magenta")	/*!< magenta = 6	*/
+	    	{
+	    		pmeta->color = 6;
+	    	}
+	    	pmeta->param = parameters[1];
+	    	pmeta->used = false;
+	    	return true;
+	    }
+	    else
+	    {
+	    	std::cout<<"Wrong count of parameters. Please check if the OpenCV"
+	    			 <<"metadata is correctly defined"<<std::endl;
+	    	return false;
+	    }
+	}
+	/**
+	 * \fn void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+	 * \brief metadata declaration
+	 *
+	 * \param zone audio parameter's address
+	 * \param key metadata key/type (here, it must be ocv)
+	 * \param val metadata value
+	 * 
+	 * This function gives the metadata string, which will be analysed.
+	 */
+	void declare(FAUSTFLOAT* zone, const char* key, const char* val) 
+	{
+		if (key=="ocv")
+		{
+			metadata newMeta;
+			bool string_parsed = false;
+						
+			if (zone != 0)
+			{
+				newMeta.zone = zone;
+			}
+			string_parsed = parser(val, &newMeta);
+			
+			if (string_parsed)
+			{
+				parameters_storage_.push_back(newMeta);
+			}
+		}
+	}
+	
+	// Image Processing Functions
+       
+    /** 
+     * \fn void contoursProcess(std::vector<std::vector<cv::Point>> contours, int color)
+     * \brief Contours processing
+     *
+     * \param contours contours of an object
+     * \param color color of this object
+     * 
+     * This function approximates contours to rectangles, 
+     * and stores the bigest one as a new object.
+     */  
+	
+    void contoursProcess(std::vector<std::vector<cv::Point> > contours, int color)
+	{
+		int tempArea=0;
+		cv::Rect myRect;
+		for (int j=0 ; j<contours.size() ; j++)
+		{
+			std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
+			std::vector<cv::Rect> boundRect( contours.size() );
+		
+			if (contours[j].size()>40)										// Do not take care about small
+																				// contours
+			{
+				approxPolyDP( cv::Mat(contours[j]), contours_poly[j], 3, true );// Approximate contours to 
+																				// a polygone
+				boundRect[j] = cv::boundingRect( cv::Mat(contours_poly[j]) );		// Bound a contour in a 
+																				// rectangle
+				if ((int)boundRect[j].area()>tempArea)	
+				{
+					tempArea=(int)boundRect[j].area();
+					myRect = boundRect[j];
+				}
+			}	
+		}
+		if (tempArea != 0)
+		{
+			// Create a new object structure to store the object properties
+			object newObject;
+			newObject.color = color;
+			newObject.centerX = myRect.x+myRect.width/2;
+			newObject.centerY = myRect.y+myRect.height/2;
+			newObject.area = 1.5*(float)tempArea/(width_*height_);
+			newObject.radius= (int)MIN(myRect.width/2, myRect.height/2);
+				
+			// Put the new object in the objects storage.
+			objects_storage_.push_back(newObject);
+		}
+	}
+	/**
+	 * \fn void erodeAndDilate(cv::Mat image)
+	 * \brief Morphological Opening (Erosion and Dilatation)
+	 * 
+	 * \param image mask produced with the "cv::inRange" function.
+	 *
+	 * This function improves a mask shape
+	 * See OpenCV documentation for more informations :
+	 * http://docs.opencv.org/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html
+	 */
+	
+	void erodeAndDilate(cv::Mat image)
+	{
+		cv::Mat element;
+		element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
+		
+		// Erase small alone pixels
+			// http://docs.opencv.org/modules/imgproc/doc/filtering.html#dilate
+		for (int i = 0; i<2 ; i++)
+		{
+			cv::erode(image, image, element);
+		}
+		
+		// Enlarge blocks of pixels
+			// http://docs.opencv.org/modules/imgproc/doc/filtering.html#erode
+		for (int i = 0; i<10 ; i++)
+		{
+			cv::dilate(image, image, element);
+		}
+	}
+	
+	/**
+	 * \fn void drawCircle(object my_object, cv::Mat my_image)
+	 * \brief Draws circles around chosen objects
+	 *
+	 * \param my_object Detected and specified object
+	 * \param my_image image on which to draw
+	 *
+	 * This function draws circles around the objects specified in the metadata
+	 * declaration and detected in the image.
+	 * Note that the circle color depends on the object color.
+	 */
+	
+	void drawCircle(object my_object, cv::Mat my_image)
+	{
+		cv::Scalar bgr_color;
+		switch (my_object.color)
+		{
+			case 1: // RED
+				bgr_color = cv::Scalar (0,0,255); 
+			
+				break;
+				
+			case 2: //YELLOW
+				bgr_color = cv::Scalar (0, 255, 255); 
+				
+				break;
+			
+			case 3: // GREEN
+				bgr_color = cv::Scalar (0, 255, 0);
+			
+				break;
+			case 4: // CYAN
+				bgr_color = cv::Scalar (255, 255, 0);
+				
+				break;
+			
+			case 5: // BLUE
+				bgr_color = cv::Scalar (255,0,0);
+							
+				break;
+			
+			case 6: // MAGENTA
+				bgr_color = cv::Scalar (255, 0, 255);
+					
+				break;
+	
+			default: // Add a color !
+	
+				break;
+		}
+		// draw circle
+		cv::circle(my_image, cv::Point(my_object.centerX, my_object.centerY),
+				   my_object.radius, bgr_color, 2, 8, 0);
+	}
+
+	
+	/**
+	 * \fn imageProcessing(cv::Mat BGRImage)
+	 * \brief Image Processing function for objects detection
+	 *
+	 * \param BGRImage image in BGR color scale, from camera
+	 *
+	 * This function processes a BGR image. 
+	 * It converts it into an HSV image, opens it (erodes and dilates), extracts contours from image
+	 * and extracts objects from contours. The objects are stored and circled.
+	 */
+	
+	void imageProcessing(cv::Mat BGRImage)
+	{	
+		height_ = BGRImage.rows;
+		width_ = BGRImage.cols;
+		
+		cv::Mat HsvImage;
+		
+		cv::cvtColor(BGRImage, HsvImage, CV_BGR2HSV);	// Convert frame to HSV format 
+   	    												// in order to use "inRange"
+   	    
+		// Mask matrices (red, yellow, green, cyan, blue and magenta)
+		cv::Mat r_mask, y_mask, g_mask, c_mask, b_mask, m_mask;
+	
+		// Objects contours
+		std::vector<std::vector<cv::Point> > r_contours, y_contours, g_contours, 
+											 c_contours, b_contours, m_contours;
+		std::vector<cv::Vec4i> hierarchy;
+		
+		// Get every pixel whose value is between _min and _max
+			// and put it into a mask
+		cv::inRange(BGRImage, red_min, red_max, r_mask);
+		cv::inRange(BGRImage, yellow_min, yellow_max, y_mask);
+		cv::inRange(BGRImage, green_min, green_max, g_mask);
+		cv::inRange(BGRImage, cyan_min, cyan_max, c_mask);
+		cv::inRange(BGRImage, blue_min, blue_max, b_mask);
+		cv::inRange(BGRImage, magenta_min, magenta_max, m_mask);
+		
+		// Improve masks shapes
+		erodeAndDilate(r_mask);
+		erodeAndDilate(y_mask);
+		erodeAndDilate(g_mask);
+		erodeAndDilate(c_mask);
+		erodeAndDilate(b_mask);
+		erodeAndDilate(m_mask);
+	
+		// Get the shapes contours from masks
+		cv::findContours(r_mask, r_contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
+		cv::findContours(y_mask, y_contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
+		cv::findContours(g_mask, g_contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
+		cv::findContours(c_mask, c_contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
+		cv::findContours(b_mask, b_contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
+		cv::findContours(m_mask, m_contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
+	
+		// Process every contour. Note that color is taken in account.
+		for (int i=1 ; i<=6 ; i++)
+		{
+			switch (i)
+			{
+			case 1:		// RED
+				contoursProcess(r_contours, 1);
+			
+				break;
+			
+			case 2:		// YELLOW
+				contoursProcess(y_contours, 2);
+			
+				break;
+			
+			case 3:		// GREEN
+				contoursProcess(g_contours, 3);
+			
+				break;
+			
+			case 4:		// CYAN
+				contoursProcess(c_contours, 4);
+			
+				break;
+		
+			case 5:		// BLUE
+				contoursProcess(b_contours, 5);
+			
+				break;
+			
+			case 6:		// MAGENTA
+				contoursProcess(m_contours, 6);
+			
+				break;
+		
+			default:	// You'll have to add a new color...
+				break;
+			}
+		}
+		
+		// Audio parameters setting
+		for (int i=0 ; i<objects_storage_.size() ; i++)
+		{
+			for (int j=0 ; j<parameters_storage_.size() ; j++)
+			{
+				if(objects_storage_[i].color==parameters_storage_[j].color
+					&& !parameters_storage_[j].used)
+				{
+					if (parameters_storage_[j].param=="color")
+					{
+						*parameters_storage_[j].zone=(float)objects_storage_[i].color;
+					}
+					else if (parameters_storage_[j].param=="x")
+					{
+						*parameters_storage_[j].zone=objects_storage_[i].centerX/width_;
+					}
+					else if (parameters_storage_[j].param=="y")
+					{
+						*parameters_storage_[j].zone=1-(objects_storage_[i].centerY/height_);
+					}
+					else if (parameters_storage_[j].param=="area")
+					{
+						*parameters_storage_[j].zone=(float)objects_storage_[i].area;
+					}
+					parameters_storage_[j].used=true;
+					
+					drawCircle(objects_storage_[i], BGRImage);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * \fn void empty()
+	 * \brief Empties the object's storage
+	 *
+	 * This function empties the object's storage, and resets the parameters storage
+	 */
+
+	void empty()
+    {
+    	while (objects_storage_.size()>0)
+    	{
+    		objects_storage_.pop_back();
+    	}
+		
+		for(int l=0 ; l<parameters_storage_.size() ; l++)
+		{
+			parameters_storage_[l].used=false;
+		}
+	}
+	
+	/**
+	 * \fn bool exit()
+	 * \brief Return the exit member parameter.
+	 */
+	bool exit()
+	{
+		return exit_;
+	}
+	
+	/**
+	 * \fn void exitThread()
+	 * \brief Exit from thread
+	 *
+	 * \param This function exits from thread
+	 */
+	void exitThread()
+	{
+		pthread_exit(NULL);
+	}
+	
+	/**
+	 * \fn void run()
+	 * \brief Creates and runs the thread
+	 *
+	 * This function creates the image processing thread
+	 */
+	void run()
+	{		
+		exit_=false;
+		int create_thread = 1;
+	
+		create_thread = pthread_create(&loop_, NULL, ocvLoop, (void *) this);
+		
+		if (create_thread)
+		{
+			std::cout<<"Could not create thread. Thread Creation failed."<< std::endl;
+		}
+
+	}
+       	
+    ////////////////////////////////////////////
+	////									////
+	////		  MEMBER VARIABLES  		////
+	////									////
+	////////////////////////////////////////////
+	
+    private :
+    	
+	// HSV min and max values variables
+	// #1 : RED
+	static cv::Scalar red_min;
+	static cv::Scalar red_max;
+	
+	// #2 : YELLOW
+	static cv::Scalar yellow_min;
+	static cv::Scalar yellow_max;
+	
+	// #3 : GREEN
+	static cv::Scalar green_min;
+	static cv::Scalar green_max;
+	
+	// #4 : CYAN
+	static cv::Scalar cyan_min;
+	static cv::Scalar cyan_max;
+	
+	// #5 : BLUE
+	static cv::Scalar blue_min;	
+	static cv::Scalar blue_max;
+	
+	// #6 : MAGENTA
+	static cv::Scalar magenta_min;
+	static cv::Scalar magenta_max;
+
+	// Objects Storage
+		// Where all the objects are stored
+	std::vector<object> objects_storage_;
+	
+	// Parameters Storage
+		// Where all the "ocv" metadata parameters are stored
+	std::vector<metadata> parameters_storage_;
+	
+	// Matrix height and width
+	int height_, width_;
+	
+	// Loop thread;
+	pthread_t loop_;
+	
+	// Thread EXIT variable
+	bool exit_;
+		
+};
+
+// HSV min and max values
+	// Note that H is between 0 and 180 
+	// in openCV
+	
+// #1 = RED
+cv::Scalar OCVUI::red_min = cv::Scalar (0,200,55);
+cv::Scalar OCVUI::red_max = cv::Scalar (1,255,255);
+
+// #2 = YELLOW
+cv::Scalar OCVUI::yellow_min = cv::Scalar (25, 200, 55);
+cv::Scalar OCVUI::yellow_max = cv::Scalar (35, 255, 255);
+
+// #3 = GREEN
+cv::Scalar OCVUI::green_min = cv::Scalar (20,155,55);
+cv::Scalar OCVUI::green_max = cv::Scalar (50,255,255);
+
+// #4 = CYAN
+cv::Scalar OCVUI::cyan_min = cv::Scalar (85,200,55);
+cv::Scalar OCVUI::cyan_max = cv::Scalar (95,200,55);
+
+// #5 = BLUE
+cv::Scalar OCVUI::blue_min = cv::Scalar (115,155,55);
+cv::Scalar OCVUI::blue_max = cv::Scalar (125,255,255);
+
+// #6 = MAGENTA
+cv::Scalar OCVUI::magenta_min = cv::Scalar (145,200,55);
+cv::Scalar OCVUI::magenta_max = cv::Scalar (155,255,255);
+
+
+// OpenCV Main Loop Function Implementation
+	// This function is a loop that gets every frame from a camera
+	// and calls the image processing functions.
+	// This is the OCVUI.h main function.
+/**
+ * \fn void* ocvLoop(void* ocv_object)
+ * \brief Loop function for image processing
+ */
+void* ocvLoop(void* ocv_object)
+{
+	// The camera index allows to select the camera.
+		// 0 stands for the default camera.
+	int camIndex=1;
+	//std::cout<<"camera index ?"<<std::endl;
+	//std::cin>>camIndex;
+
+	cv::Mat frame, hsv;
+	OCVUI* ocv = (OCVUI*) ocv_object;
+	cv::VideoCapture cap(camIndex);
+	std::cout<<"Video Capture from camera n°"<<camIndex<<std::endl;
+	
+	if(!cap.isOpened())  // check if we succeeded to read frames
+						 // from camera
+	{
+		std::cout<<"Could not open camera n°"<<camIndex<<" !"<<std::endl;
+		
+	}
+    	  
+	cap.set(CV_CAP_PROP_FPS, 60); 	// Set frames rate
+		
+	cv::namedWindow( "Tracking", 1 );	// Create a window
+
+	while(!ocv->exit())
+   	{
+
+   	    cap >> frame;							// Get frame from camera
+       														
+		ocv->imageProcessing(frame);				// Objects Detection function
+	
+   		/*** Show image ***/
+   		cv::imshow("Tracking", frame);
+
+   		ocv->empty();								// Empty the objects and parameters storages
+   	}
+   	
+   	ocv->exitThread();
+
+}
+
+#endif
diff --git a/architecture/faust/gui/OSCUI.h b/architecture/faust/gui/OSCUI.h
new file mode 100644
index 0000000..0d6f691
--- /dev/null
+++ b/architecture/faust/gui/OSCUI.h
@@ -0,0 +1,143 @@
+/*
+   Copyright (C) 2011 Grame - Lyon
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted.
+*/
+
+#ifndef __OSCUI__
+#define __OSCUI__
+
+#include "faust/gui/OSCControler.h"
+#include "faust/gui/GUI.h"
+#include <vector>
+
+/******************************************************************************
+*******************************************************************************
+
+					OSC (Open Sound Control) USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+/*
+
+Note about the OSC addresses and the Faust UI names:
+----------------------------------------------------
+There are potential conflicts between the Faust UI objects naming scheme and 
+the OSC address space. An OSC symbolic names is an ASCII string consisting of
+printable characters other than the following:
+	space 
+#	number sign
+*	asterisk
+,	comma
+/	forward
+?	question mark
+[	open bracket
+]	close bracket
+{	open curly brace
+}	close curly brace
+
+a simple solution to address the problem consists in replacing 
+space or tabulation with '_' (underscore)
+all the other osc excluded characters with '-' (hyphen)
+
+This solution is implemented in the proposed OSC UI;
+*/
+
+///using namespace std;
+
+//class oscfaust::OSCIO;
+
+class OSCUI : public GUI 
+{
+     
+	oscfaust::OSCControler*	fCtrl;
+	std::vector<const char*> fAlias;
+	
+	const char* tr(const char* label) const;
+	
+	// add all accumulated alias
+	void addalias(FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, const char* label)
+	{
+		for (unsigned int i=0; i<fAlias.size(); i++) {
+			fCtrl->addAlias(fAlias[i], zone, (FAUSTFLOAT)0, (FAUSTFLOAT)1, init, min, max, label);
+		}
+		fAlias.clear();
+	}
+	
+ public:
+
+    OSCUI(const char* /*applicationname*/, int argc, char *argv[], oscfaust::OSCIO* io=0, ErrorCallback errCallback = NULL, void* arg = NULL, bool init = true) : GUI() 
+    { 
+		fCtrl = new oscfaust::OSCControler(argc, argv, this, io, errCallback, arg, init); 
+        //		fCtrl->opengroup(applicationname);
+	}
+    
+	virtual ~OSCUI() { delete fCtrl; }
+    
+    // -- widget's layouts
+    
+  	virtual void openTabBox(const char* label) 			{ fCtrl->opengroup( tr(label)); }
+	virtual void openHorizontalBox(const char* label) 	{ fCtrl->opengroup( tr(label)); }
+	virtual void openVerticalBox(const char* label) 	{ fCtrl->opengroup( tr(label)); }
+	virtual void closeBox() 							{ fCtrl->closegroup(); }
+
+	
+	// -- active widgets
+	virtual void addButton(const char* label, FAUSTFLOAT* zone) 		{ const char* l= tr(label); addalias(zone, 0, 0, 1, l); fCtrl->addnode( l, zone, (FAUSTFLOAT)0, (FAUSTFLOAT)0, (FAUSTFLOAT)1); }
+	virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) 	{ const char* l= tr(label); addalias(zone, 0, 0, 1, l); fCtrl->addnode( l, zone, (FAUSTFLOAT)0, (FAUSTFLOAT)0, (FAUSTFLOAT)1); }
+	virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/)
+																		{ const char* l= tr(label); addalias(zone, init, min, max, l); fCtrl->addnode( l, zone, init, min, max); }
+	virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/)
+																		{ const char* l= tr(label); addalias(zone, init, min, max, l); fCtrl->addnode( l, zone, init, min, max); }
+	virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/)
+																		{ const char* l= tr(label); addalias(zone, init, min, max, l); fCtrl->addnode( l, zone, init, min, max); }
+	
+	// -- passive widgets
+	
+	virtual void addHorizontalBargraph(const char* /*label*/, FAUSTFLOAT* /*zone*/, FAUSTFLOAT /*min*/, FAUSTFLOAT /*max*/) {}
+	virtual void addVerticalBargraph(const char* /*label*/, FAUSTFLOAT* /*zone*/, FAUSTFLOAT /*min*/, FAUSTFLOAT /*max*/) {}
+		
+	// -- metadata declarations
+    
+	virtual void declare(FAUSTFLOAT* , const char* key , const char* alias) 
+	{ 
+		if (strcasecmp(key,"OSC")==0) fAlias.push_back(alias);
+	}
+
+	virtual void show() {}
+
+	void run()
+    {
+        fCtrl->run(); 
+    }
+	const char* getRootName()		{ return fCtrl->getRootName(); }
+    int getUDPPort()                { return fCtrl->getUDPPort(); }
+    int	getUDPOut()                 { return fCtrl->getUDPOut(); }
+    int	getUDPErr()                 { return fCtrl->getUDPErr(); }
+    const char* getDestAddress()    {return fCtrl->getDestAddress();}
+};
+
+const char* OSCUI::tr(const char* label) const
+{
+	static char buffer[1024];
+	char * ptr = buffer; int n=1;
+	while (*label && (n++ < 1024)) {
+		switch (*label) {
+			case ' ': case '	':
+				*ptr++ = '_';
+				break;
+			case '#': case '*': case ',': case '/': case '?':
+			case '[': case ']': case '{': case '}': case '(': case ')':
+				*ptr++ = '_';
+				break;
+			default: 
+				*ptr++ = *label;
+		}
+		label++;
+	}
+	*ptr = 0;
+	return buffer;
+}
+
+#endif
diff --git a/architecture/faust/gui/PathUI.h b/architecture/faust/gui/PathUI.h
new file mode 100644
index 0000000..d9a56e4
--- /dev/null
+++ b/architecture/faust/gui/PathUI.h
@@ -0,0 +1,37 @@
+#ifndef FAUST_PathUI_H
+#define FAUST_PathUI_H
+
+#include "faust/gui/UI.h"
+#include <vector>
+#include <string>
+#include <algorithm>
+
+/*******************************************************************************
+ * PathUI : Faust User Interface
+ * Helper class to build complete path for items.
+ ******************************************************************************/
+
+class PathUI : public UI
+{
+
+    protected:
+    
+        std::vector<std::string> fControlsLevel;
+       
+    public:
+    
+        std::string buildPath(const std::string& label) 
+        {
+            std::string res = "/";
+            for (size_t i = 0; i < fControlsLevel.size(); i++) {
+                res += fControlsLevel[i];
+                res += "/";
+            }
+            res += label;
+            replace(res.begin(), res.end(), ' ', '_');
+            return res;
+        }
+    
+};
+
+#endif
diff --git a/architecture/faust/gui/PrintUI.h b/architecture/faust/gui/PrintUI.h
new file mode 100644
index 0000000..fe3813f
--- /dev/null
+++ b/architecture/faust/gui/PrintUI.h
@@ -0,0 +1,92 @@
+#ifndef FAUST_PUI_H
+#define FAUST_PUI_H
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#include "faust/gui/PathUI.h"
+#include <vector>
+#include <string>
+
+/*******************************************************************************
+ * PrintUI : Faust User Interface
+ * This class print arguments given to calls to UI methods and build complete path for labels.
+ ******************************************************************************/
+
+class PrintUI : public PathUI
+{
+
+    public:
+
+        PrintUI() {}
+
+        virtual ~PrintUI() {}
+
+        // -- widget's layouts
+
+        virtual void openTabBox(const char* label)
+        {
+            fControlsLevel.push_back(label);
+            std::cout << "openTabBox label : " << label << std::endl;
+        }
+        virtual void openHorizontalBox(const char* label)
+        {
+            fControlsLevel.push_back(label);
+            std::cout << "openHorizontalBox label : " << label << std::endl;
+        }
+        virtual void openVerticalBox(const char* label)
+        {
+            fControlsLevel.push_back(label);
+            std::cout << "openVerticalBox label : " << label << std::endl;
+        }
+        virtual void closeBox()
+        {
+            fControlsLevel.pop_back();
+            std::cout << "closeBox" << std::endl;
+        }
+
+        // -- active widgets
+
+        virtual void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            std::cout << "addButton label : " << buildPath(label) << std::endl;
+        }
+        virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            std::cout << "addCheckButton label : " << buildPath(label) << std::endl;
+        }
+        virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            std::cout << "addVerticalSlider label : " << buildPath(label) << " init : " << init << " min : " << min << " max : " << max << " step : " << step << std::endl;
+        }
+        virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            std::cout << "addHorizontalSlider label : " << buildPath(label) << " init : " << init << " min : " << min << " max : " << max << " step : " << step << std::endl;
+        }
+        virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            std::cout << "addNumEntry label : " << buildPath(label) << " init : " << init << " min : " << min << " max : " << max << " step : " << step << std::endl;
+        }
+
+        // -- passive widgets
+
+        virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            std::cout << "addHorizontalBargraph label : " << buildPath(label) << " min : " << min << " max : " << max << std::endl;
+        }
+        virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            std::cout << "addVerticalBargraph label : " << buildPath(label) << " min : " << min << " max : " << max << std::endl;
+        }
+
+        // -- metadata declarations
+
+        virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {
+            std::cout << "declare key : " << key << " val : " << val << std::endl;
+        }
+    
+};
+
+#endif
diff --git a/architecture/faust/gui/RosCI.h b/architecture/faust/gui/RosCI.h
new file mode 100644
index 0000000..3508336
--- /dev/null
+++ b/architecture/faust/gui/RosCI.h
@@ -0,0 +1,490 @@
+/**********************************************
+* 			ROS Callbacks Interface
+*
+* This interface allows the user to use ROS 
+* 	metadata
+* It handles ROS metadata, and writes the 
+*	callbacks directly in the .cpp file.
+*
+**********************************************/
+
+#ifndef FAUST_RosCI_H
+#define FAUST_RosCI_H
+
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#include "faust/gui/UI.h"
+
+#include <algorithm>
+#include <vector>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <sstream>
+
+class RosCI : public UI
+{
+    
+    public :
+    
+	RosCI() : count_(0), use_slider_values_(false), meta_(false)
+	{};
+	
+	//~RosCI() {}
+	
+	// String processing function
+	std::string strProcess(std::string label)
+    {
+        int count = label.size();
+        bool ok = false;
+        int FORWARD_SLASH = 47;
+        int TILDE = 126;
+        int UNDERSCORE = 95;
+        int SPACE = 32;
+        int LEFT_BRACKET = 40;
+        int RIGHT_BRACKET = 41;
+        
+        do
+        {
+            if ((label[0]<65)  // before "A" in ASCII
+                || (label[0]<=96 && label[0]>=91) // After "Z" and before "a" in ASCII
+                || (label[0] > 122) // After "z" in ASCII
+                && (label[0] != FORWARD_SLASH) // not "/"
+                && (label[0] != TILDE) // not "~"
+              )
+            {
+                label.erase(0,1);
+                count = label.size();
+            }
+            else if(count < 1)
+            {
+                label = "/topic";
+                count = label.size();
+                ok=true;
+            }
+            else
+            {
+                ok=true;
+            }
+        }
+        while (!ok);
+
+        for (int i=0 ; i<count ; i++)
+        {
+
+            if ((label[i]<=90 && label[i]>=65) // A-Z
+                    || (label[i]<=122 && label[i]>=97) // a-z
+                    || (label[i]<=57 && label[i]>=47) // 0-9
+                    || label[i]==UNDERSCORE 
+               )
+            {
+            }
+            else if (label[i]==SPACE) 
+            {
+                if(label[i-1]==UNDERSCORE)
+                {
+                    label.erase(i,1);
+                    i=i-1;
+                    count = label.size();
+                }
+                else
+                    label[i]='_';
+            }
+
+            else if(label[i]== LEFT_BRACKET) // in case of '('
+            {
+                if(label[i-1]==95) 
+                {
+                    label.erase(i,1);
+                    i=i-1;
+                    count = label.size();
+                }
+                else		   
+                    label[i]='_';
+            }
+            else if (label[i]==RIGHT_BRACKET) // in case of ')'
+            {
+                label.erase(i,1);
+                i=i-1;
+                count = label.size();
+            }
+            else
+            {
+                label.erase(i, 1);
+                i=i-1;
+                count = label.size();
+            }
+
+        }
+        return (label);
+    }
+	
+	
+	
+	
+    	// -- widget's layouts
+
+	void openTabBox(const char* label)
+	{
+	}
+	void openHorizontalBox(const char* label)
+	{
+	}
+	void openVerticalBox(const char* label)
+	{
+	}
+	void closeBox()
+	{
+	}
+
+
+	// -- active widgets
+
+	void addButton(const char* label, FAUSTFLOAT* zone)
+	{ 	
+	}
+	void addCheckButton(const char* label, FAUSTFLOAT* zone)
+	{
+	}
+	void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min,
+	FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		*zone=init;
+		if (meta_)
+		{
+			if (use_slider_values_)
+			{
+				callbacks_parameters_[count_-1].min_value = min;
+				callbacks_parameters_[count_-1].max_value = max;
+				use_slider_values_ = false;
+			}
+			callbacks_parameters_[count_-1].slider_min = min;
+			callbacks_parameters_[count_-1].slider_max = max;
+			meta_=false;
+		}
+	}
+	void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, 
+	FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		*zone=init;
+		if (meta_)
+		{
+			if (use_slider_values_)
+			{
+				callbacks_parameters_[count_-1].min_value = min;
+				callbacks_parameters_[count_-1].max_value = max;
+				use_slider_values_ = false;
+			}
+			callbacks_parameters_[count_-1].slider_min = min;
+			callbacks_parameters_[count_-1].slider_max = max;
+			meta_=false;
+		}
+	}
+	void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, 
+	FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		*zone=init;
+		if (meta_)
+		{
+			if (use_slider_values_)
+			{
+				callbacks_parameters_[count_-1].min_value = min;
+				callbacks_parameters_[count_-1].max_value = max;
+				use_slider_values_ = false;
+			}
+			callbacks_parameters_[count_-1].slider_min = min;
+			callbacks_parameters_[count_-1].slider_max = max;
+			meta_=false;
+		}
+	}
+	
+	// -- passive widgets
+
+	void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+	{
+	}
+	void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+	{
+	}
+
+	// -- metadata declarations
+
+	// Structure containing a callback parameters
+	struct CallbackParams
+	{
+	    std::string topic_name;
+	    std::string msg_type;
+	    std::string msg_name;
+	    std::string field_name;
+	    FAUSTFLOAT min_value;
+	    FAUSTFLOAT max_value;
+	    FAUSTFLOAT slider_min;
+	    FAUSTFLOAT slider_max;
+	};
+	
+	// Callback writing the callbacks filekeyboard's arrows
+		// num is the number of ROS declared metadata
+		// param_vector is a callbacks parameters structure container 
+		// name is the application name
+	void callbacksWriter(int num, std::vector<RosCI::CallbackParams> param_vector, std::string name)
+	{
+		// Get file name
+		name = name + ".cpp";
+		const char* file_name = name.c_str();
+		std::fstream file (file_name);
+		
+		if (!file.is_open())
+		{
+			std::cout<<"unable to open"<<file_name<<std::endl;
+			return;
+		}
+		
+		std::string line, test_line;
+		bool search_RosUI = true;
+		std::streampos begin = 0;
+		std::streampos end=0;
+		int block_size;
+		char * memblock;
+		
+		test_line = "class RosUI : public UI";  // This is the line we look for
+													// in the file so that we can
+													// write callbacks before this line
+		
+		while( search_RosUI )
+		{
+			std::getline(file,line);
+			if(line==test_line)
+			{
+				search_RosUI=false;
+			}
+			else 
+			{
+			// Get the searched line position
+			begin += (std::streampos)line.size() +(std::streampos)1;	
+			}		
+		}
+		// Get the end of file position
+		file.seekp(0,std::ios::end);
+		end=file.tellp();
+		
+		block_size = end-begin;
+		
+		memblock = new char[block_size];
+
+		// puts the end of the file in a memory block
+			// in order to overwrite without deleting information
+		file.seekp(begin, std::ios::beg);
+		file.read(memblock, block_size);
+		file.seekp(begin,std::ios::beg);
+
+		file <<"/*****************************"<<std::endl
+			 <<"* Code generated automatically"<<std::endl
+			 <<"* "<<std::endl
+			 <<"* See the RosCI.h file"<<std::endl
+			 <<"* \tCallbacksWriter function"<<std::endl
+			 <<"* \tfor more informations"<<std::endl
+			 <<"* "<<std::endl
+			 <<"*****************************/\n"<<std::endl;
+		
+		// Include messages files if they are different
+		bool include = true;
+		for (int i = 0 ; i<num ; i++)
+		{
+			RosCI::CallbackParams parameters = param_vector[i];
+			if (i!=0)
+			{
+				for (int j=0 ; j<i ; j++)
+				{
+					if(parameters.msg_type == param_vector[j].msg_type)
+					{
+						if (parameters.msg_name == param_vector[j].msg_name)
+						{
+							include = false;
+						}
+					}
+				}
+			}
+				
+			if (include)
+			{
+				file << "#include \""<< parameters.msg_type<<"/"
+					 << parameters.msg_name<<".h\""<<std::endl;
+			}
+			
+		}
+
+				
+		// New class
+		file << "class RosCallbacks"<< std::endl
+			 << "{" << std::endl
+			 << "\tpublic : \n" << std::endl
+			 << "\tRosCallbacks(ros::NodeHandle n) : nh_(n)"<<std::endl
+			 << "\t{};\n"<<std::endl;
+		
+		// Ranging Function
+		file << "\tfloat rangeAndConvert(FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT slider_min, "<< std::endl
+			 << "\t\tFAUSTFLOAT slider_max, float value)" << std::endl
+			 << "\t{" << std::endl
+			 << "\t\tif (value < min)" << std::endl
+			 << "\t\t{" << std::endl
+			 << "\t\t\tvalue = min;" << std::endl
+			 << "\t\t}" << std::endl
+			 << "\t\telse if (value > max)" << std::endl
+			 << "\t\t{" << std::endl
+			 << "\t\t\tvalue = max ;" << std::endl
+			 << "\t\t}" << std::endl
+			 << "\t\tfloat a = (slider_max - slider_min)/(max-min);" << std::endl
+			 << "\t\tfloat b = (slider_max + slider_min - a*(max+min))/2;" << std::endl
+			 << "\t\tvalue = a*value + b;\n" << std::endl
+			 << "\t\treturn value;" << std::endl
+			 << "\t}" << std::endl;
+		
+		// ROS specific callbacks
+		for (int i = 0 ; i<num ; i++)
+		{
+			RosCI::CallbackParams parameters = param_vector[i];
+			file << "\tvoid callback"<<i<<"(const "<< parameters.msg_type<<"::"
+				 << parameters.msg_name<<"ConstPtr& msg, FAUSTFLOAT* zone)"<<std::endl
+				 << "\t{"<<std::endl
+				 << "\t\t FAUSTFLOAT min"<<i<<" = "<<parameters.min_value<<";"<<std::endl
+				 << "\t\t FAUSTFLOAT max"<<i<<" = "<<parameters.max_value<<";"<<std::endl
+				 << "\t\t FAUSTFLOAT smin"<<i<<" = "<<parameters.slider_min<<";"<<std::endl
+				 << "\t\t FAUSTFLOAT smax"<<i<<" = "<<parameters.slider_max<<";\n"<<std::endl
+				 << "\t\t *zone =  rangeAndConvert(min"<<i<<", max"<<i<<", smin"<<i<<", smax"<<i
+				 << ", (float) msg->"<<parameters.field_name<<");"<<std::endl
+				 << "\t}\n"<<std::endl;
+		}	
+		
+		// RosCallbacks class main function :
+			// When called, it subscribes to all the predefined callbacks
+		file << "\n\tvoid subscribe(std::vector<FAUSTFLOAT*> zones)\n"<<std::endl
+			 << "\t{" <<std::endl;
+		
+		// Declaring subscribers and subscribing	 
+		for (int i = 0 ; i<num ; i++)
+		{
+			RosCI::CallbackParams parameters = param_vector[i];
+			file << "\t\tros::Subscriber* my_sub"<<i<<" = new ros::Subscriber();"<<std::endl
+				 << "\t\t*my_sub"<<i<<" = nh_.subscribe<"<<parameters.msg_type<<"::"<<parameters.msg_name
+				 << ">(\"" <<parameters.topic_name
+				 << "\", 1,"<<std::endl
+				 << "\t\t\tboost::bind(&RosCallbacks::callback"<<i
+				 << ", this, _1, zones["<<i<<"]));\n"<<std::endl;
+		}
+		
+		file << "\t}\n"<<std::endl;
+		
+		// RosCallbacks class private parameter
+		file << "\tprivate :\n"<<std::endl
+			 << "\tros::NodeHandle nh_;"<<std::endl;
+		
+		file << "};\n" << std::endl;
+		
+		file << memblock;
+		
+		file.close();
+	}
+	
+	// String parsing function, which detects every callback parameter
+		// Separators must be spaces, and there must be 4 or 6 arguments
+	void stringParser(std::string string2parse)
+	{
+	    int SPACE = 32;
+	    
+	    for (int i = 0 ; i < string2parse.size() ; i++)
+	    {
+	    	if (string2parse[i]==SPACE)
+	    	{
+	    	    std::string param= string2parse.substr(0,i);
+	    	    topic_params_.push_back(param);
+	    	    string2parse.erase(string2parse.begin(), string2parse.begin()+i+1);
+	    	    i=-1;
+
+	    	}
+	    	
+	    }
+	    
+	    topic_params_.push_back(string2parse);
+	}
+	
+	// Function declaring metadata
+	void declare(FAUSTFLOAT* zone, const char* key, const char* val) 
+	{
+		if (key=="ros") // We do not care if key is not "ros" here
+		{
+			stringParser(val); // Parsing the string corresponding to a callback parameters
+			CallbackParams params;
+			if (topic_params_.size() == 4 
+				||
+				topic_params_.size() == 6  )
+			{
+				// Storing the parameters in a structure...
+				params.topic_name=strProcess(topic_params_[0]);
+				params.msg_type=topic_params_[1];
+				params.msg_name=topic_params_[2];
+				params.field_name=topic_params_[3];
+				
+				if (topic_params_.size() == 6)
+				{
+					std::stringstream smin, smax;
+					smin.str(topic_params_[4]);
+					smin >> params.min_value;
+					smax.str(topic_params_[5]);
+					smax >> params.max_value;
+				}
+				else 
+				{
+					use_slider_values_ = true;
+				}
+					
+				// ... and the structure in a vector 
+				callbacks_parameters_.push_back(params);
+				
+				count_++;
+				meta_=true;
+			}
+			else
+			{
+				std::cout<<"Wrong number of parameters in ros metadata declaration !"<<std::endl;
+				std::cout<<"It should look like : [ros:/my/topic/name msg_type msg_name"
+						 <<" field_name]"<<std::endl;
+				std::cout<<"Example : [ros:/topic/level std_msgs Float32 data]"<<std::endl;
+			}
+			
+			do
+			{
+			    topic_params_.pop_back();
+			}
+			while ( !topic_params_.empty());
+			
+		}
+	}
+    
+    // Function returning the number of metadata declared, 
+    	//which means the number of callbacks to call
+    int getParamsCount()
+    {
+        return count_;
+    }
+    
+    // Function returning a vector containing ROS Callbacks parameters structures	
+    std::vector<CallbackParams> getCallbacksParameters()
+    {
+        return callbacks_parameters_;
+    }
+    
+    private :
+    
+	int count_;
+	bool use_slider_values_;
+	bool meta_;
+	
+	std::vector<std::string> topic_params_;
+	std::vector<CallbackParams> callbacks_parameters_;
+		
+};
+
+#endif
diff --git a/architecture/faust/gui/RosUI.h b/architecture/faust/gui/RosUI.h
new file mode 100644
index 0000000..30885d1
--- /dev/null
+++ b/architecture/faust/gui/RosUI.h
@@ -0,0 +1,485 @@
+/**********************************************
+* 			ROS User Interface
+*
+* This interface  creates default callbacks 
+*	with default messages types
+* It also returns parameters for specific ROS
+*  callbacks, defined in the RosCallbacks class
+*	thanks to the RosCI.h and ros-callbacks.cpp
+* 	architecture files
+**********************************************/
+#ifndef FAUST_RosUI_H
+#define FAUST_RosUI_H
+
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#include "faust/gui/UI.h"
+#include "ros/ros.h"
+#include "std_msgs/Bool.h"
+#include "std_msgs/Float32.h"
+
+#include <algorithm>
+#include <vector>
+
+class RosUI : public UI
+{
+    
+    public :
+    
+	RosUI(ros::NodeHandle nh, std::string nspace) : nh_(nh), queue_(10), count_(0), meta_(false), box_names_(0), zones_(0) 
+	{
+	   // Get the namespace's name for default topics
+	   box_names_.push_back(nspace);
+	};
+	
+	//~RosUI() {}
+	
+	// String processing function for topics names
+	std::string strProcess(std::string label)
+    {
+        int count = label.size();
+        bool ok = false;
+        int FORWARD_SLASH = 47;
+        int TILDE = 126;
+        int UNDERSCORE = 95;
+        int SPACE = 32;
+        int LEFT_BRACKET = 40;
+        int RIGHT_BRACKET = 41;
+        
+        do
+        {
+            if ((label[0]<65)  // before "A" in ASCII
+                || (label[0]<=96 && label[0]>=91) // After "Z" and before "a" in ASCII
+                || (label[0] > 122) // After "z" in ASCII
+                && (label[0] != FORWARD_SLASH) // not "/"
+                && (label[0] != TILDE) // not "~"
+              )
+            {
+                label.erase(0,1);
+                count = label.size();
+            }
+            else if(count <= 1)
+            {
+                label = "/topic";
+                count = label.size();
+                ok=true;
+            }
+            else
+            {
+                ok=true;
+            }
+        }
+        while (!ok);
+
+        for (int i=0 ; i<count ; i++)
+        {
+
+            if ((label[i]<=90 && label[i]>=65) // A-Z
+                    || (label[i]<=122 && label[i]>=97) // a-z
+                    || (label[i]<=57 && label[i]>=47) // 0-9
+                    || label[i]==UNDERSCORE 
+               )
+            {
+            }
+            else if (label[i]==SPACE) 
+            {
+                if(label[i-1]==UNDERSCORE)
+                {
+                    label.erase(i,1);
+                    i=i-1;
+                    count = label.size();
+                }
+                else
+                    label[i]='_';
+            }
+
+            else if(label[i]== LEFT_BRACKET) // in case of '('
+            {
+                if(label[i-1]==95) 
+                {
+                    label.erase(i,1);
+                    i=i-1;
+                    count = label.size();
+                }
+                else		   
+                    label[i]='_';
+            }
+            else if (label[i]==RIGHT_BRACKET) // in case of ')'
+            {
+                label.erase(i,1);
+                i=i-1;
+                count = label.size();
+            }
+            else
+            {
+                label.erase(i, 1);
+                i=i-1;
+                count = label.size();
+            }
+
+        }
+        return (label);
+    }
+	
+	
+	// -- default callbacks
+	
+	// Default Callbacks :
+		// Buttons widgets use the std_msgs/Bool message type
+		// Sliders and Numerical entries use the std_msgs/Float32 message type
+	
+	void buttonCallback(const std_msgs::BoolConstPtr& msg, FAUSTFLOAT* zone)
+	{
+	    
+	    *zone=msg->data;
+
+	}
+	
+	void cButtonCallback(const std_msgs::BoolConstPtr& msg, FAUSTFLOAT* zone)
+	{
+	    
+	    *zone=msg->data;
+	    
+	}
+	
+	void sliderCallback(const std_msgs::Float32ConstPtr& msg, FAUSTFLOAT* zone)
+	{
+	    
+	    *zone=msg->data;
+	    
+	}
+	
+	void numEntryCallback(const std_msgs::Float32ConstPtr& msg, FAUSTFLOAT* zone)
+	{
+	    
+	    *zone=msg->data;
+	    
+	}	
+	
+	// -- widget's layouts
+		// Boxes names are stored in a vector so that the default topics names
+		// fit to the graphic interface
+
+	void openTabBox(const char* label)
+	{
+		std::string L = (std::string)label;
+		if(L == "0x00") // no box name
+		{
+			L="";
+		}
+	    
+		box_names_.push_back(L);	    
+	}
+	
+	void openHorizontalBox(const char* label)
+	{
+		std::string L = (std::string)label;
+		if(L == "0x00") // no box name
+		{
+			L="";
+		}
+	    
+		box_names_.push_back(L);	    
+	}
+	
+	void openVerticalBox(const char* label)
+	{
+		std::string L = (std::string)label;
+		if(L == "0x00") // no box name
+		{
+			L="";
+		}
+	    
+		box_names_.push_back(L);	    
+	}
+	
+	void closeBox()
+	{
+	    box_names_.pop_back();
+	}
+
+	// -- active widgets
+		// Adding a widget is translated into subscribing to a topic
+		// For each widget, we use default messages types
+		// Buttons							: std_msgs/Bool
+		// Sliders and Numerical Entries	: std_msgs/Float32
+
+	void addButton(const char* label, FAUSTFLOAT* zone)
+	{
+	    // Gets the button name and processes it to fit to ROS naming conventions
+	    std::string str = (std::string)label;
+	    
+	    std::string my_string = strProcess(str);
+	    
+	    // Builds the topic name from boxes and button names
+	    if (! box_names_.empty())
+	    {
+		
+			std::string my_name = "";
+		
+			for (int i = 0 ; i<box_names_.size() ; i++)
+			{
+			    if (box_names_[i] != "")
+			    {
+					my_name += "/" + strProcess(box_names_[i]); 
+		    	}   
+		    	else 
+		    	{
+					box_names_.erase(box_names_.begin()+i);
+		    	}
+			}
+			
+			my_string = my_name + "/" + my_string;
+
+	    }
+	    else
+	    {
+	    	ROS_ERROR("RosUI.h - function addButton : No box name to use ! ");
+	    	ROS_INFO("Button's callback will not be subscribed");
+	    	return;
+	    }
+  		
+  		// Subscription to buttons callback
+	    ros::Subscriber* button_sub = new ros::Subscriber();
+	    
+	    *button_sub = nh_.subscribe<std_msgs::Bool>(my_string, queue_, 
+	    boost::bind(&RosUI::buttonCallback, this, _1, zone));
+	    
+	    count_++;
+	}
+	void addCheckButton(const char* label, FAUSTFLOAT* zone)
+	{
+	    // Gets the check button name and processes it to fit to ROS naming conventions
+	    std::string str = (std::string)label;
+	    
+	    std::string my_string = strProcess(str);
+	    
+	    // Builds the topic name from boxes and check button names
+	    if (! box_names_.empty())
+	    {
+			std::string my_name = "";
+		
+			for (int i = 0 ; i<box_names_.size() ; i++)
+			{
+			    if (box_names_[i] != "")
+			    {
+					my_name += "/" + strProcess(box_names_[i]); 
+		    	}   
+		    	else 
+		    	{
+					box_names_.erase(box_names_.begin()+i);
+		    	}
+			}
+			
+			my_string = my_name + "/" + my_string;
+
+	    }
+	    else
+	    {
+	    	ROS_ERROR("RosUI.h - function addCheckButton : No box name to use ! ");
+	    	ROS_INFO("Check button's callback will not be subscribed");
+	    	return;
+	    }
+	    
+	    // Subscription to check buttons callback
+	    ros::Subscriber* c_button_sub = new ros::Subscriber();
+	    
+	    *c_button_sub = nh_.subscribe<std_msgs::Bool>(my_string, queue_, 
+	    boost::bind(&RosUI::cButtonCallback, this, _1, zone));
+	    
+	    count_++;
+	}
+	void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min,
+	FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+	     // Gets the vertical slider name and processes it to fit to ROS naming conventions
+	    std::string str = (std::string)label;
+	    
+	    std::string my_string = strProcess(str);
+	    
+	    // Builds the topic name from boxes and vertical slider names
+
+	    if (! box_names_.empty())
+	    {
+			std::string my_name = "";
+		
+			for (int i = 0 ; i<box_names_.size() ; i++)
+			{
+			    if (box_names_[i] != "")
+			    {
+					my_name += "/" + strProcess(box_names_[i]); 
+			    }   
+			    else 
+			    {
+					box_names_.erase(box_names_.begin()+i);
+				}
+			}
+			
+			my_string = my_name + "/" + my_string;
+	    }
+	    else
+	    {
+	    	ROS_ERROR("RosUI.h - function addVerticalSlider : No box name to use ! ");
+	    	ROS_INFO("Vertical slider's callback will not be subscribed");
+	    	return;
+	    }
+	    
+	    // Subscription to sliders callback
+	    ros::Subscriber* v_slider = new ros::Subscriber();
+	    
+	    *v_slider = nh_.subscribe<std_msgs::Float32>(my_string, queue_, 
+	    boost::bind(&RosUI::sliderCallback, this, _1, zone));
+	    
+	    count_++;
+	}
+	void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, 
+	FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+	    // Gets the horizontal slider name and processes it to fit to ROS naming conventions
+	    std::string str = (std::string)label;
+	    
+	    std::string my_string = strProcess(str);
+	    
+	    // Builds the topic name from boxes and horizontal slider names	    
+	    if (! box_names_.empty())
+	    {
+			std::string my_name = "";
+		
+			for (int i = 0 ; i<box_names_.size() ; i++)
+			{
+			    if (box_names_[i] != "")
+			    {
+					my_name += "/" + strProcess(box_names_[i]); 
+		    	}   
+		    	else 
+		    	{
+					box_names_.erase(box_names_.begin()+i);
+		    	}
+			}
+			
+			my_string = my_name + "/" + my_string;
+	    }
+	    else
+	    {
+	    	ROS_ERROR("RosUI.h - function addVerticalSlider : No box name to use ! ");
+	    	ROS_INFO("Vertical slider's callback will not be subscribed");
+	    	return;
+	    }
+	    
+	    // Subscription to sliders callback
+	    ros::Subscriber* h_slider = new ros::Subscriber();
+	    
+	    *h_slider = nh_.subscribe<std_msgs::Float32>
+	    (my_string, queue_, boost::bind(&RosUI::sliderCallback, this, _1, zone));
+	    
+	    count_++;
+		
+	}
+	void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, 
+	FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+	    // Gets the numerical entry name and processes it to fit to ROS naming conventions
+	    std::string str = (std::string)label;
+	    
+	    std::string my_string = strProcess(str);
+	    
+	    // Builds the topic name from boxes and numerical entry names
+	    
+	    if (! box_names_.empty())
+	    {
+			std::string my_name = "";
+		
+			for (int i = 0 ; i<box_names_.size() ; i++)
+			{
+			    if (box_names_[i] != "")
+		    	{
+					my_name += "/" + strProcess(box_names_[i]); 
+		    	}   
+		    	else 
+		    	{
+					box_names_.erase(box_names_.begin()+i);
+				}
+			}
+		
+			my_string = my_name + "/" + my_string;
+	    }
+	    else
+	    {
+		    ROS_ERROR("RosUI.h - function addVerticalSlider : No box name to use ! ");
+	    	ROS_INFO("Vertical slider's callback will not be subscribed");
+	    	return;
+	    }
+	    
+	    // Subscription to numerical entries callback
+	    ros::Subscriber* num_entry = new ros::Subscriber();
+	    *num_entry = nh_.subscribe<std_msgs::Float32>(my_string, queue_, 
+	    boost::bind(&RosUI::numEntryCallback, this, _1, zone));
+	    
+		count_++;
+ 	
+	}
+	
+	// -- passive widgets
+		// Nothing to say - not used
+
+	void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+	{
+	}
+	void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+	{
+	}
+
+	// -- metadata declarations
+
+	void declare(FAUSTFLOAT* zone, const char* key, const char* val) 
+	{
+		if (key=="ros") // We do not care if key is not "ros" here
+		{
+			// Adds the Faust parameter's address (zone) to a zone vector
+	    		// if a ros metadata has been declared
+			zones_.push_back(zone);
+		}
+	}
+    
+    // Function returning the number of widgets added
+	int getParamsCount()
+	{
+		return count_;
+	}
+	
+	// Function saying if, yes or no, there is any ROS metadata declared
+	bool isTrue()
+    {
+    	if (!zones_.empty())
+    	{
+    		return true; // yes
+    	}
+    	else
+    	{
+    		return false; // no
+    	}
+    }
+	
+	// Function returning the Faust parameters addresses (zones)
+		// if these zones correspond to metadata declared topics
+	std::vector<FAUSTFLOAT*> getZones()
+	{
+		return zones_;
+	}
+    
+    private :
+    
+	ros::NodeHandle nh_;
+	int queue_;
+	int count_;
+	bool meta_;
+	
+	std::vector<std::string> box_names_;
+	std::vector<FAUSTFLOAT*> zones_;
+		
+};
+
+#endif
diff --git a/architecture/faust/gui/SimpleParser.h b/architecture/faust/gui/SimpleParser.h
new file mode 100644
index 0000000..953d8b1
--- /dev/null
+++ b/architecture/faust/gui/SimpleParser.h
@@ -0,0 +1,233 @@
+#ifndef SIMPLEPARSER_H
+#define SIMPLEPARSER_H
+
+// ---------------------------------------------------------------------
+//                          Simple Parser
+// A parser returns true if it was able to parse what it is
+// supposed to parse and advance the pointer. Otherwise it returns false
+// and the pointer is not advanced so that another parser can be tried.
+// ---------------------------------------------------------------------
+
+#include <vector>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <ctype.h>
+
+using namespace std;
+
+bool parseMenuList(const char*& p, vector<string>& names, vector<double>& values);
+bool parseMenuItem(const char*& p, string& name, double& value);
+
+void skipBlank(const char*& p);
+bool parseChar(const char*& p, char x);
+bool parseWord(const char*& p, const char* w);
+bool parseString(const char*& p, char quote, string& s);
+bool parseSQString(const char*& p, string& s);
+bool parseDQString(const char*& p, string& s);
+bool parseDouble(const char*& p, double& x);
+
+// ---------------------------------------------------------------------
+//
+//                          IMPLEMENTATION
+// 
+// ---------------------------------------------------------------------
+
+/**
+ * @brief parseMenuList, parse a menu list {'low' : 440.0; 'mid' : 880.0; 'hi' : 1760.0}...
+ * @param p the string to parse, then the remaining string
+ * @param names the vector of names found
+ * @param values the vector of values found
+ * @return true if a menu list was found
+ */
+inline bool parseMenuList(const char*& p, vector<string>& names, vector<double>& values)
+{
+    vector<string> tmpnames;
+    vector<double> tmpvalues;
+
+    const char* saved=p;
+
+    if (parseChar(p,'{')) {
+        do {
+            string n;
+            double v;
+            if (parseMenuItem(p,n,v)) {
+                tmpnames.push_back(n);
+                tmpvalues.push_back(v);
+            } else {
+                p = saved;
+                return false;
+            }
+        } while ( parseChar(p,';') );
+        if (parseChar(p,'}')) {
+            // we suceeded
+            names = tmpnames;
+            values = tmpvalues;
+            return true;
+        }
+    }
+    p = saved;
+    return false;
+}
+
+/**
+ * @brief parseMenuItem, parse a menu item ...'low':440.0...
+ * @param p the string to parse, then the remaining string
+ * @param name the name found
+ * @param value the value found
+ * @return true if a nemu item was found
+ */
+inline bool parseMenuItem(const char*& p, string& name, double& value)
+{
+    const char* saved=p;
+    if (parseSQString(p,name) && parseChar(p,':') && parseDouble(p,value)) {
+        return true;
+    } else {
+        p=saved;
+        return false;
+    }
+}
+
+// ---------------------------------------------------------------------
+//                          Elementary parsers
+// ---------------------------------------------------------------------
+
+/**
+ * @brief skipBlank : advance pointer p to the first non blank character
+ * @param p the string to parse, then the remaining string
+ */
+inline void skipBlank(const char*& p)
+{
+    while (isspace(*p)) { p++; }
+}
+
+/**
+ * @brief parseChar : parse a specific character x
+ * @param p the string to parse, then the remaining string
+ * @param x the character to recognize
+ * @return true if x was found at the begin of p
+ */
+inline bool parseChar(const char*& p, char x)
+{
+    skipBlank(p);
+    if (x == *p) {
+        p++;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * @brief parseWord : parse a specific string w
+ * @param p the string to parse, then the remaining string
+ * @param w the string to recognize
+ * @return true if string w was found at the begin of p
+ */
+inline bool parseWord(const char*& p, const char* w)
+{
+    skipBlank(p);
+    const char* saved = p;
+    while ((*w == *p) && (*w)) {++w; ++p;}
+    if (*w) {
+        p = saved;
+        return false;
+    } else {
+        return true;
+    }
+}
+
+/**
+ * @brief parseDouble : parse number [s]dddd[.dddd] and store the result in x
+ * @param p the string to parse, then the remaining string
+ * @param x the float number found if any
+ * @return true if a float number was found at the begin of p
+ */
+inline bool parseDouble(const char*& p, double& x)
+{
+    double sign = +1.0;    // sign of the number
+    double ipart = 0;      // integral part of the number
+    double dpart = 0;      // decimal part of the number before division
+    double dcoef = 1.0;    // division factor for the decimal part
+
+    bool valid = false;   // true if the number contains at least one digit
+
+    skipBlank(p);
+
+    const char* saved = p;  // to restore position if we fail
+
+    if (parseChar(p,'+')) {
+        sign = 1.0;
+    } else if (parseChar(p,'-')) {
+        sign = -1.0;
+    }
+    while (isdigit(*p)) {
+        valid = true;
+        ipart = ipart*10 + (*p - '0');
+        p++;
+    }
+    if (parseChar(p,'.')) {
+        while (isdigit(*p)) {
+            valid = true;
+            dpart = dpart*10 + (*p - '0');
+            dcoef *= 10.0;
+            p++;
+        }
+    }
+    if (valid)  {
+        x = sign*(ipart + dpart/dcoef);
+    } else {
+        p = saved;
+    }
+    return valid;
+}
+
+/**
+ * @brief parseString, parse an arbitrary quoted string q...q and store the result in s
+ * @param p the string to parse, then the remaining string
+ * @param quote the character used to quote the string
+ * @param s the (unquoted) string found if any
+ * @return true if a string was found at the begin of p
+ */
+inline bool parseString(const char*& p, char quote, string& s)
+{
+    string str;
+    skipBlank(p);
+
+    const char* saved = p;
+    if (*p++ == quote) {
+        while ((*p != 0) && (*p != quote)) {
+            str += *p++;
+        }
+        if (*p++ == quote) {
+            s = str;
+            return true;
+        }
+    }
+    p = saved;
+    return false;
+}
+
+/**
+ * @brief parseSQString, parse a single quoted string '...' and store the result in s
+ * @param p the string to parse, then the remaining string
+ * @param s the (unquoted) string found if any
+ * @return true if a string was found at the begin of p
+ */
+inline bool parseSQString(const char*& p, string& s)
+{
+    return parseString(p, '\'', s);
+}
+
+/**
+ * @brief parseDQString, parse a double quoted string "..." and store the result in s
+ * @param p the string to parse, then the remaining string
+ * @param s the (unquoted) string found if any
+ * @return true if a string was found at the begin of p
+ */
+inline bool parseDQString(const char*& p, string& s)
+{
+    return parseString(p, '"', s);
+}
+
+#endif // SIMPLEPARSER_H
diff --git a/architecture/faust/gui/Styles/Blue.qrc b/architecture/faust/gui/Styles/Blue.qrc
new file mode 100644
index 0000000..aeacc80
--- /dev/null
+++ b/architecture/faust/gui/Styles/Blue.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>Blue.qss</file>
+</qresource>
+</RCC>
diff --git a/architecture/faust/gui/Styles/Blue.qss b/architecture/faust/gui/Styles/Blue.qss
new file mode 100644
index 0000000..c175752
--- /dev/null
+++ b/architecture/faust/gui/Styles/Blue.qss
@@ -0,0 +1,177 @@
+QPushButton{
+min-width : 80px;
+border: 2px solid grey;
+border-radius: 6px;
+margin-top: 1ex;
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #811453, stop: 1 #702963);
+color: white;
+}
+
+QPushButton:hover{
+border: 2px solid orange;
+}
+
+QPushButton:pressed{
+background-color: orange;
+border-color: grey;
+}
+
+QGroupBox{
+subcontrol: .QGroupBox;
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #003366, stop: 1 #22427C);
+margin-top: 3ex;
+border-radius: 5px;
+font-size: 10pt;
+font-weight: bold;
+color: white;
+}
+
+QGroupBox::title {
+subcontrol-origin: margin;
+subcontrol-position: top center;
+padding: 0 5px;
+color: white;
+}
+
+QMainWindow, QDialog{
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #003366, stop: 1 #22427C);
+border-radius: 5px;
+margin-top: 3ex;
+font-size:10pt;
+font-weight:bold;
+color: white;
+}  
+
+QPlainTextEdit, QTextEdit{
+background-color: transparent;
+border: 2px solid #702963;
+border-radius: 5px;
+top: 3px;
+margin-top: 3ex;
+font-size:12pt;
+font-weight:bold;
+color: white;
+}
+
+QTextBrowser {
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #003366, stop: 1 #22427C);
+	color: white;
+}
+    
+QTextBrowser:document{
+	text-decoration: underline;
+	color: white;
+	font: Menlo;
+	font-size: 14px
+}
+
+QLabel{
+color : white;
+background: transparent;
+}
+
+QSlider::groove:vertical {
+background: red;
+position: absolute; 
+left: 13px; right: 13px;
+}
+
+QSlider::handle:vertical {
+height: 40px;
+width: 30px;
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);
+margin: 0 -5px;
+border-radius: 5px;
+} 
+
+QSlider::add-page:vertical {
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 yellow, stop : 0.5 orange);
+}
+
+QSlider::sub-page:vertical {
+background: grey;
+}
+
+QSlider::groove:horizontal {
+background: red;
+position: absolute;
+top: 14px; bottom: 14px;
+}
+
+QSlider::handle:horizontal {
+width: 40px;
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #6A455D, stop : 0.05 #811453, stop: 0.3 #811453, stop : 0.90 #6A455D, stop: 0.91 #702963);
+margin: -5px 0;
+border-radius: 5px;
+}
+    
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 yellow, stop : 0.5 orange);
+}
+
+QSlider::add-page:horizontal {
+background: grey;
+}
+
+QTabWidget::pane {
+color : white;
+border-top: 2px #702963;
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 1.0 #22427C);
+}
+    
+QTabWidget::tab-bar {
+left: 5px;
+}
+    
+QTabBar::tab {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C);
+border: 2px solid #808080;
+color : white;
+border-bottom-color: #702963;
+border-top-left-radius: 4px;
+border-top-right-radius: 4px;
+min-width: 8ex;
+padding: 2px;
+}
+    
+QTabBar::tab:selected, QTabBar::tab:hover {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C);
+color : white;
+}
+    
+QTabBar::tab:selected {
+color : white;
+border-color: #702963;
+border-bottom-color: #22427C;
+}
+    
+QTabBar::tab:!selected {
+margin-top: 2px;
+}
+
+QListWidget{
+background-color: transparent;
+}
+
+QListWidget::item{                
+	color: white;
+}
+
+QStatusBar{
+	background-color: transparent;
+	border: 0px; 
+	padding:0px 0px 0px 0px; 
+	margin:0px;
+}
+
+QScrollArea > QWidget > QWidget{
+	background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C);
+}
+
+QScrollArea > QWidget {
+	background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C);
+}
+
+QScrollArea {
+	background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C);
+}
\ No newline at end of file
diff --git a/architecture/faust/gui/Styles/Default.qrc b/architecture/faust/gui/Styles/Default.qrc
new file mode 100644
index 0000000..59a63a5
--- /dev/null
+++ b/architecture/faust/gui/Styles/Default.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>Default.qss</file>
+</qresource>
+</RCC>
diff --git a/architecture/faust/gui/Styles/Default.qss b/architecture/faust/gui/Styles/Default.qss
new file mode 100644
index 0000000..58ee6e6
--- /dev/null
+++ b/architecture/faust/gui/Styles/Default.qss
@@ -0,0 +1,117 @@
+QPushButton{
+min-width : 80px;
+border: 2px solid grey;
+border-radius: 6px;
+margin-top: 1ex;
+border-color: #811453;
+background-color: transparent;
+}
+
+QPushButton:hover{
+border: 2px;
+border-radius: 6px;
+border-color: #811453;
+background-color: #6A455D;
+}
+
+QPushButton:pressed{
+background-color: #6A455D;
+border-radius: 6px;
+border-color: #811453;
+}
+
+QGroupBox{
+subcontrol: .QGroupBox;
+margin-top: 3ex;
+font-size: 10pt;
+font-weight: bold;
+color: black;
+}
+
+QGroupBox::title {
+subcontrol-origin: margin;
+subcontrol-position: top center;
+padding: 0 5px;
+color: black;
+}
+
+QMainWindow {
+margin-top: 3ex;
+font-size:10pt;
+font-weight:bold;
+color: black;
+}
+
+QPlainTextEdit, QTextEdit{
+background-color: transparent;
+border: 2px solid gray;
+border-radius: 5px;
+top: 3px;
+margin-top: 3ex;
+font-size:12pt;
+font-weight:bold;
+color: black;
+}
+
+QTextBrowser {
+color: black;
+}
+QTextBrowser:document{
+text-decoration: underline;
+color: black;
+font: Menlo;
+font-size: 14px
+}
+
+QLabel{
+color : black;
+background: transparent;
+}
+
+QSlider::groove:vertical {
+background: red;
+position: absolute; 
+left: 13px; right: 13px;
+}
+
+QSlider::handle:vertical {
+height: 40px;
+width: 30px;
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E67E30, stop : 0.05 #AD4F09, stop: 0.3 #E67E30, stop : 0.90 #AD4F09, stop: 0.91 #AD4F09);
+margin: 0 -5px;
+border-radius: 5px;
+}
+
+QSlider::add-page:vertical {
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
+stop: 0 #6A455D, stop : 0.5 #6A455D);
+}
+
+QSlider::sub-page:vertical {
+background: grey;
+}
+
+QSlider::groove:horizontal {
+background: red;
+position: absolute;
+top: 14px; bottom: 14px;
+}
+
+QSlider::handle:horizontal {
+width: 40px;
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #E67E30, stop : 0.05 #AD4F09, stop: 0.3 #E67E30, stop : 0.90 #AD4F09, stop: 0.91 #AD4F09);
+margin: -5px 0;
+border-radius: 5px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6A455D, stop : 0.5 #6A455D);
+}
+
+QSlider::add-page:horizontal {
+background: grey;
+}
+
+QListWidget{
+background-color: transparent;
+}
\ No newline at end of file
diff --git a/architecture/faust/gui/Styles/Grey.qrc b/architecture/faust/gui/Styles/Grey.qrc
new file mode 100644
index 0000000..b3f2ec8
--- /dev/null
+++ b/architecture/faust/gui/Styles/Grey.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>Grey.qss</file>
+</qresource>
+</RCC>
diff --git a/architecture/faust/gui/Styles/Grey.qss b/architecture/faust/gui/Styles/Grey.qss
new file mode 100644
index 0000000..baa10cd
--- /dev/null
+++ b/architecture/faust/gui/Styles/Grey.qss
@@ -0,0 +1,174 @@
+QPushButton {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8,
+stop: 0 #B0B0B0, stop: 1 #404040);
+min-width : 80px;
+border: 2px solid grey;
+border-radius: 6px;
+margin-top: 1ex;
+color:white
+}
+    
+QPushButton:hover {
+border: 2px solid orange;
+}
+    
+QPushButton:pressed {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #404040, stop: 1 #B0B0B0);
+}
+    
+QGroupBox {
+subcontrol: .QGroupBox
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020);
+margin-top: 3ex;
+border-radius: 5px;
+font-size:10pt;
+font-weight:bold;
+color: white;
+}
+    
+QGroupBox::title {
+subcontrol-origin: margin;
+subcontrol-position: top center;
+padding: 0 5px;
+color : white;
+}
+
+QMainWindow, QDialog {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020);
+border-radius: 5px;
+margin-top: 3ex;
+font-size:10pt;
+font-weight:bold;
+color: white;
+}    
+    
+QPlainTextEdit, QTextEdit{
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020);
+border-color: yellow;
+border-radius: 5px;
+top: 3px;
+margin-top: 3ex;
+font-size:12pt;
+font-weight:bold;
+color: white;
+}
+    
+QTextBrowser {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020);
+color: white;
+}
+    
+QTextDocument{
+text-decoration: underline;
+color: white;
+font: Menlo;
+font-size: 14px
+}
+
+QLabel{
+	color : white;
+	background: transparent;
+}
+    
+QSlider::groove:vertical {
+background: red;
+position: absolute;
+left: 13px; right: 13px;
+}
+ 
+QSlider::handle:vertical {
+height: 40px;
+width: 30px;
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);
+margin: 0 -5px;
+border-radius: 5px;
+}
+
+QSlider::add-page:vertical {
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 yellow, stop : 0.5 orange);
+}
+
+QSlider::sub-page:vertical {
+background: grey;
+}
+    
+QSlider::groove:horizontal {
+background: red;
+position: absolute;
+top: 14px; bottom: 14px;
+}
+
+QSlider::handle:horizontal {
+width: 40px;
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);
+margin: -5px 0;
+border-radius: 5px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 yellow, stop : 0.5 orange);
+}
+    
+QSlider::add-page:horizontal {
+background: grey;
+}
+    
+QTabWidget::pane {
+border-top: 2px solid orange;
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020);
+}
+
+QTabWidget::tab-bar {
+left: 5px;
+}
+        
+QTabBar::tab {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #909090, stop: 0.4 #888888, stop: 0.5 #808080, stop: 1.0 #909090);
+border: 2px solid #808080;
+border-bottom-color: orange;
+border-top-left-radius: 4px;
+border-top-right-radius: 4px;
+min-width: 8ex;
+padding: 2px;
+}
+
+QTabBar::tab:selected, QTabBar::tab:hover {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D0D0D0, stop: 0.4 #A0A0A0, stop: 0.5 #808080, stop: 1.0 #A0A0A0);
+}
+
+QTabBar::tab:selected {
+border-color: orange;
+border-bottom-color: #A0A0A0;
+}
+    
+QTabBar::tab:!selected {
+margin-top: 2px;
+}
+    
+QListWidget{
+background-color: transparent;
+}
+
+
+QListWidget::item{                
+	color: white;
+}
+
+QStatusBar{
+	background-color: transparent;
+	border: 0px; 
+	padding:0px 0px 0px 0px; 
+	margin:0px;
+}
+
+QScrollArea > QWidget > QWidget{
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020);
+}
+
+QScrollArea > QWidget {
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020);
+}
+
+QScrollArea {
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020);
+}
\ No newline at end of file
diff --git a/architecture/faust/gui/Styles/Salmon.qrc b/architecture/faust/gui/Styles/Salmon.qrc
new file mode 100644
index 0000000..e301d9c
--- /dev/null
+++ b/architecture/faust/gui/Styles/Salmon.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>Salmon.qss</file>
+</qresource>
+</RCC>
diff --git a/architecture/faust/gui/Styles/Salmon.qss b/architecture/faust/gui/Styles/Salmon.qss
new file mode 100644
index 0000000..2abcfa2
--- /dev/null
+++ b/architecture/faust/gui/Styles/Salmon.qss
@@ -0,0 +1,171 @@
+QPushButton{
+background-color:#FF5E4D;
+min-width : 80px;
+border: 2px solid grey;
+border-radius: 6px;
+margin-top: 1ex;
+}
+    
+QPushButton:hover{
+border: 2px ;
+}
+    
+QPushButton:pressed{
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FFE4C4, stop: 1 #FEC3AC);
+}
+
+QGroupBox{
+subcontrol: .QGroupBox
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4, stop: 1 #FEC3AC);
+border-radius: 5px;
+margin-top: 3ex;
+font-size:10pt;
+font-weight:bold;
+color: dark grey;
+color: white;
+}
+    
+QGroupBox::title {
+subcontrol-origin: margin;
+subcontrol-position: top center;
+padding: 0 5px;
+color: black;
+}
+    
+QMainWindow, QDialog {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+border-radius: 5px;
+margin-top: 3ex;
+font-size:10pt;
+font-weight:bold;
+color: dark grey;
+color: white;
+}
+    
+QPlainTextEdit, QTextEdit {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+border: 2px solid gray;
+border-radius: 5px;
+top: 3px;
+margin-top: 3ex;
+font-size:12pt;
+font-weight:bold;
+color: black;
+}
+
+QTextBrowser {
+background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+color: black;
+}
+    
+QTextBrowser:document{
+text-decoration: underline;
+color: white;
+font: Menlo;
+font-size: 14px
+}
+      
+QLabel{
+	color : black;
+	background: transparent;
+}
+  
+QSlider::groove:vertical {
+background: red;
+position: absolute;
+left: 13px; right: 13px;
+}
+    
+QSlider::handle:vertical {
+height: 40px;
+width: 30px;
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #4E3D28, stop : 0.05 #856D4D, stop: 0.1 #4E3D28, stop : 0.15 #856D4D, stop: 0.2 #4E3D28, stop : 0.25 #856D4D, stop: 0.3 #4E3D28, stop : 0.35 #856D4D, stop: 0.4 #4E3D28, stop : 0.45 #856D4D, stop: 0.5 #4E3D28, stop : 0.55 #856D4D, stop: 0.6 #4E3D28, stop : 0.65 #856D4D, stop: 0.7 #4E3D28, stop : 0.75 #856D4D, stop: 0.8 #4E3D28, stop : 0.85 #856D4D, stop: 0.95 #4E3D28);
+margin: 0 -5px;
+border-radius: 5px;
+}
+    
+QSlider::add-page:vertical {
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF5E4D, stop : 0.5 #FF5E4D);
+}
+    
+QSlider::sub-page:vertical {
+background: #CECECE;
+}
+
+QSlider::groove:horizontal {
+background: red;
+position: absolute;
+top: 14px; bottom: 14px;
+}
+    
+QSlider::handle:horizontal {
+width: 40px;
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #4E3D28, stop : 0.05 #856D4D, stop: 0.1 #4E3D28, stop : 0.15 #856D4D, stop: 0.2 #4E3D28, stop : 0.25 #856D4D, stop: 0.3 #4E3D28, stop : 0.35 #856D4D, stop: 0.4 #4E3D28, stop : 0.45 #856D4D, stop: 0.5 #4E3D28, stop : 0.55 #856D4D, stop: 0.6 #4E3D28, stop : 0.65 #856D4D, stop: 0.7 #4E3D28, stop : 0.75 #856D4D, stop: 0.8 #4E3D28, stop : 0.85 #856D4D, stop: 0.95 #4E3D28);
+margin: -5px 0;
+border-radius: 5px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF5E4D stop : 0.5 #FF5E4D);
+}
+
+QSlider::add-page:horizontal {
+background: #CECECE;
+}
+    
+QTabWidget::pane {
+color : black;
+border-top: 2px #FF5E4D;
+background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+}
+
+QTabWidget::tab-bar {
+left: 5px;
+}
+    
+QTabBar::tab {
+background: #FFE4C4;
+border: 2px solid #FF5E4D;
+color : black;
+border-bottom-color: #FF5E4D;
+border-top-left-radius: 4px;
+border-top-right-radius: 4px;
+min-width: 8ex;
+padding: 2px;
+}
+
+QTabBar::tab:selected, QTabBar::tab:hover {
+background: #FEC3AC;
+color : white;
+}
+
+QTabBar::tab:!selected {
+margin-top: 2px;
+}
+    
+QListWidget{     
+background-color: transparent;
+}
+
+QListWidget::item{                
+	color: color;
+}
+
+QStatusBar{
+	background-color: transparent;
+	border: 0px; 
+	padding:0px 0px 0px 0px; 
+	margin:0px;
+}
+
+QScrollArea > QWidget > QWidget{
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+}
+
+QScrollArea > QWidget {
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+}
+
+QScrollArea {
+	background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #FFE4C4,stop: 1 #FEC3AC);
+}
\ No newline at end of file
diff --git a/architecture/faust/gui/UI.h b/architecture/faust/gui/UI.h
new file mode 100644
index 0000000..78b7436
--- /dev/null
+++ b/architecture/faust/gui/UI.h
@@ -0,0 +1,48 @@
+#ifndef FAUST_UI_H
+#define FAUST_UI_H
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+/*******************************************************************************
+ * UI : Faust User Interface
+ * This abstract class contains only the method that the faust compiler can
+ * generate to describe a DSP interface.
+ ******************************************************************************/
+
+class UI
+{
+
+ public:
+
+	UI() {}
+
+	virtual ~UI() {}
+
+    // -- widget's layouts
+
+    virtual void openTabBox(const char* label) = 0;
+    virtual void openHorizontalBox(const char* label) = 0;
+    virtual void openVerticalBox(const char* label) = 0;
+    virtual void closeBox() = 0;
+
+    // -- active widgets
+
+    virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
+    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
+    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
+    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
+
+    // -- passive widgets
+
+    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
+    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
+
+	// -- metadata declarations
+
+    virtual void declare(FAUSTFLOAT*, const char*, const char*) {}
+};
+
+#endif
diff --git a/architecture/faust/gui/ValueConverter.h b/architecture/faust/gui/ValueConverter.h
new file mode 100644
index 0000000..79badff
--- /dev/null
+++ b/architecture/faust/gui/ValueConverter.h
@@ -0,0 +1,483 @@
+#ifndef __ValueConverter__
+#define __ValueConverter__
+
+/***************************************************************************************
+								ValueConverter.h
+							    (GRAME, © 2015)
+
+Set of conversion objects used to map user interface values (for example a gui slider 
+delivering values between 0 and 1) to faust values (for example a vslider between
+20 and 20000) using a log scale.
+
+-- Utilities
+
+Range(lo,hi) : clip a value x between lo and hi
+Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
+Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
+
+-- Value Converters
+
+ValueConverter::ui2faust(x)
+ValueConverter::faust2ui(x)
+
+-- ValueConverters used for sliders depending of the scale
+
+LinearValueConverter(umin, umax, fmin, fmax)
+LogValueConverter(umin, umax, fmin, fmax)
+ExpValueConverter(umin, umax, fmin, fmax)
+
+-- ValueConverters used for accelerometers based on 3 points
+
+AccUpConverter(amin, amid, amax, fmin, fmid, fmax)		-- curve 0
+AccDownConverter(amin, amid, amax, fmin, fmid, fmax)	-- curve 1
+AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)	-- curve 2
+AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)	-- curve 3
+
+-- lists of ZoneControl are used to implement accelerometers metadata for each axes
+
+ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter 
+
+****************************************************************************************/
+
+
+#include <float.h>
+#include <algorithm>    // std::max
+#include <cmath>
+#include <vector>
+
+//--------------------------------------------------------------------------------------
+// Range(lo,hi) clip a value between lo and hi
+//--------------------------------------------------------------------------------------
+struct Range
+{
+    double fLo;
+    double fHi;
+
+    Range(double x, double y) : fLo(std::min(x,y)), fHi(std::max(x,y)) {}
+    double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
+};
+
+
+//--------------------------------------------------------------------------------------
+// Interpolator(lo,hi,v1,v2) 
+// Maps a value x between lo and hi to a value y between v1 and v2
+// y = v1 + (x-lo)/(hi-lo)*(v2-v1)
+// y = v1 + (x-lo) * coef   		with coef = (v2-v1)/(hi-lo)
+// y = v1 + x*coef - lo*coef
+// y = v1 - lo*coef + x*coef
+// y = offset + x*coef				with offset = v1 - lo*coef
+//--------------------------------------------------------------------------------------
+class Interpolator
+{
+    
+    private:
+
+        Range fRange;
+        double fCoef;
+        double fOffset;
+
+    public:
+
+        Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
+        { 
+            if (hi != lo) { 
+                // regular case
+                fCoef = (v2-v1)/(hi-lo); 
+                fOffset = v1 - lo*fCoef; 
+            } else {
+                // degenerate case, avoids division by zero
+                fCoef = 0;
+                fOffset = (v1+v2)/2;
+            }
+        }
+        double operator()(double v) 
+        {
+            double x = fRange(v);
+            return  fOffset + x*fCoef;
+        }
+        
+        void getLowHigh(double& amin, double& amax)
+        {
+            amin = fRange.fLo;
+            amax = fRange.fHi;
+        }
+};
+
+
+//--------------------------------------------------------------------------------------
+// Interpolator3pt(lo,mi,hi,v1,vm,v2) 
+// Map values between lo mid hi to values between v1 vm v2
+//--------------------------------------------------------------------------------------
+class Interpolator3pt
+{
+
+    private:
+
+        Interpolator fSegment1;
+        Interpolator fSegment2;
+        double fMid;
+
+    public:
+
+        Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
+            fSegment1(lo, mi, v1, vm),
+            fSegment2(mi, hi, vm, v2),
+            fMid(mi) {}
+        double operator()(double x) { return  (x < fMid) ? fSegment1(x) : fSegment2(x); }
+        
+        void getMappingValues(double& amin, double& amid, double& amax) 
+        {
+            fSegment1.getLowHigh(amin, amid);
+            fSegment2.getLowHigh(amid, amax);
+        }
+};
+
+
+//--------------------------------------------------------------------------------------
+// Abstract ValueConverter class. Converts values between UI and Faust representations
+//--------------------------------------------------------------------------------------
+class ValueConverter 
+{
+    
+    public:
+    
+        virtual ~ValueConverter() {}
+        virtual double ui2faust(double x) = 0;
+        virtual double faust2ui(double x) = 0;
+};
+
+
+//--------------------------------------------------------------------------------------
+// Linear conversion between ui and faust values
+//--------------------------------------------------------------------------------------
+class LinearValueConverter : public ValueConverter
+{
+    
+    private:
+
+        Interpolator fUI2F;
+        Interpolator fF2UI;
+
+    public:
+
+        LinearValueConverter(double umin, double umax, double fmin, double fmax) :
+            fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
+        {}
+
+        LinearValueConverter() :
+            fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
+        {}
+        virtual double ui2faust(double x) {	return fUI2F(x); }
+        virtual double faust2ui(double x) {	return fF2UI(x); }
+
+};
+
+
+//--------------------------------------------------------------------------------------
+// Logarithmic conversion between ui and faust values
+//--------------------------------------------------------------------------------------
+class LogValueConverter : public LinearValueConverter
+{
+    
+    public:
+
+        LogValueConverter(double umin, double umax, double fmin, double fmax) :
+            LinearValueConverter(umin, umax, log(std::max(DBL_MIN,fmin)), log(std::max(DBL_MIN,fmax))) 
+        {}
+
+        virtual double ui2faust(double x) 	{ return exp(LinearValueConverter::ui2faust(x)); }
+        virtual double faust2ui(double x)	{ return LinearValueConverter::faust2ui(log(std::max(x, DBL_MIN))); }
+        
+};
+
+
+//--------------------------------------------------------------------------------------
+// Exponential conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class ExpValueConverter : public LinearValueConverter
+{
+    
+    public:
+
+        ExpValueConverter(double umin, double umax, double fmin, double fmax) :
+            LinearValueConverter(umin, umax, exp(fmin), exp(fmax)) 
+        {}
+
+        virtual double ui2faust(double x) { return log(LinearValueConverter::ui2faust(x)); }
+        virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(exp(x)); }
+        
+};
+
+//--------------------------------------------------------------------------------------
+// A converter than can be updated
+//--------------------------------------------------------------------------------------
+
+class UpdatableValueConverter : public ValueConverter {
+    
+    protected:
+    
+        bool fActive;
+
+    public:
+    
+        UpdatableValueConverter():fActive(true)
+        {}
+        virtual ~UpdatableValueConverter()
+        {}
+
+        virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
+        virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+    
+        void setActive(bool on_off) { fActive = on_off; }
+        bool getActive() { return fActive; }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using an Up curve (curve 0)
+//--------------------------------------------------------------------------------------
+class AccUpConverter : public UpdatableValueConverter
+{
+    
+    private:
+
+        Interpolator3pt fA2F;
+        Interpolator3pt fF2A;
+
+    public:
+
+        AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmin,fmid,fmax),
+            fF2A(fmin,fmid,fmax,amin,amid,amax)
+        {}
+
+        virtual double ui2faust(double x)	{ return fA2F(x); }
+        virtual double faust2ui(double x)	{ return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin,amid,amax,fmin,fmid,fmax);
+            fF2A = Interpolator3pt(fmin,fmid,fmax,amin,amid,amax);
+        }
+        
+        virtual void getMappingValues(double& amin, double& amid, double& amax) 
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+    
+};
+
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using a Down curve (curve 1)
+//--------------------------------------------------------------------------------------
+class AccDownConverter : public UpdatableValueConverter
+{
+    
+    private:
+        
+        Interpolator3pt	fA2F;
+        Interpolator3pt	fF2A;
+
+    public:
+
+        AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmax,fmid,fmin),
+            fF2A(fmin,fmid,fmax,amax,amid,amin)
+        {}
+
+        virtual double ui2faust(double x)	{ return fA2F(x); }
+        virtual double faust2ui(double x)	{ return fF2A(x); }
+        
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+             //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin,amid,amax,fmax,fmid,fmin);
+            fF2A = Interpolator3pt(fmin,fmid,fmax,amax,amid,amin);
+        }
+        
+        virtual void getMappingValues(double& amin, double& amid, double& amax) 
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using an Up-Down curve (curve 2)
+//--------------------------------------------------------------------------------------
+class AccUpDownConverter : public UpdatableValueConverter
+{
+    
+    private:
+        
+        Interpolator3pt	fA2F;
+        Interpolator fF2A;
+
+    public:
+
+        AccUpDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmin,fmax,fmin),
+            fF2A(fmin,fmax,amin,amax)				// Special, pseudo inverse of a non monotone function 
+        {}
+
+        virtual double ui2faust(double x)	{ return fA2F(x); }
+        virtual double faust2ui(double x)	{ return fF2A(x); }
+        
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+             //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin,amid,amax,fmin,fmax,fmin);
+            fF2A = Interpolator(fmin,fmax,amin,amax);
+        }
+        
+        virtual void getMappingValues(double& amin, double& amid, double& amax) 
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using a Down-Up curve (curve 3)
+//--------------------------------------------------------------------------------------
+class AccDownUpConverter : public UpdatableValueConverter
+{
+    
+    private:
+        
+        Interpolator3pt	fA2F;
+        Interpolator fF2A;
+
+    public:
+
+        AccDownUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmax,fmin,fmax),
+            fF2A(fmin,fmax,amin,amax)				// Special, pseudo inverse of a non monotone function 
+        {}
+
+        virtual double ui2faust(double x)	{ return fA2F(x); }
+        virtual double faust2ui(double x)	{ return fF2A(x); }
+        
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin,amid,amax,fmax,fmin,fmax);
+            fF2A = Interpolator(fmin,fmax,amin,amax);
+        }
+        
+        virtual void getMappingValues(double& amin, double& amid, double& amax) 
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+
+//--------------------------------------------------------------------------------------
+// Base class for ZoneControl
+//--------------------------------------------------------------------------------------
+class ZoneControl
+{
+    
+    protected:
+        
+        FAUSTFLOAT*	fZone;
+        
+    public:
+        
+        ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+        virtual ~ZoneControl() {}
+        
+        virtual void update(double v) {}
+        
+        virtual void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max) {}
+        virtual void getMappingValues(double& amin, double& amid, double& amax) {}
+        
+        FAUSTFLOAT* getZone() { return fZone; }
+    
+        virtual void setActive(bool on_off) {}
+        virtual bool getActive() { return false; }
+        
+        int getCurve() { return -1; }
+
+};
+
+//--------------------------------------------------------------------------------------
+//  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
+//--------------------------------------------------------------------------------------
+class ConverterZoneControl : public ZoneControl
+{
+    
+    private:
+        
+        ValueConverter* fValueConverter;
+        
+    public:
+        
+        ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* valueConverter) : ZoneControl(zone), fValueConverter(valueConverter) {}
+        virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
+
+        void update(double v) { *fZone = fValueConverter->ui2faust(v); }
+
+        ValueConverter* getConverter() { return fValueConverter; }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Association of a zone and a four value converter, each one for each possible curve. 
+// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
+//--------------------------------------------------------------------------------------
+class CurveZoneControl : public ZoneControl
+{
+    
+    private:
+
+        std::vector<UpdatableValueConverter*> fValueConverters;
+        int fCurve;
+
+    public:
+
+        CurveZoneControl(FAUSTFLOAT* zone, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
+        {
+            fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
+        }
+        virtual ~CurveZoneControl()
+        {
+            std::vector<UpdatableValueConverter*>::iterator it;
+            for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
+                delete(*it);
+            }
+        }
+        void update(double v) { if (fValueConverters[fCurve]->getActive()) *fZone = fValueConverters[fCurve]->ui2faust(v); }
+
+        void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
+        {
+            fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+            fCurve = curve;
+        }
+        
+        void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+        }
+    
+        void setActive(bool on_off)
+        {
+            std::vector<UpdatableValueConverter*>::iterator it;
+            for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
+                (*it)->setActive(on_off);
+            }
+        }
+        
+        int getCurve() { return fCurve; }
+};
+
+#endif
diff --git a/architecture/faust/gui/console.h b/architecture/faust/gui/console.h
new file mode 100644
index 0000000..ff6b095
--- /dev/null
+++ b/architecture/faust/gui/console.h
@@ -0,0 +1,289 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+#ifndef __faustconsole__
+#define __faustconsole__
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stack>
+#include <string>
+#include <map>
+#include <vector>
+#include <iostream>
+
+#include "faust/gui/UI.h"
+
+//using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+								USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+struct param {
+	FAUSTFLOAT* fZone; FAUSTFLOAT fMin; FAUSTFLOAT fMax;
+	param(FAUSTFLOAT* z, FAUSTFLOAT init, FAUSTFLOAT a, FAUSTFLOAT b) : fZone(z), fMin(a), fMax(b) { *z = init; }
+};
+
+class CMDUI : public UI
+{
+    int                             fArgc;
+    char**                          fArgv;
+    std::vector<char*>              fFiles;
+    std::stack<std::string>         fPrefix;
+	std::map<std::string, param>	fKeyParam;
+
+	void openAnyBox(const char* label)
+	{
+		std::string prefix;
+
+		if (label && label[0]) {
+			prefix = fPrefix.top() + "-" + label;
+		} else {
+			prefix = fPrefix.top();
+		}
+		fPrefix.push(prefix);
+	}
+
+	std::string simplify(const std::string& src)
+	{
+		int		i=0;
+		int		level=0;
+		std::string	dst;
+
+		while (src[i] ) {
+
+			switch (level) {
+
+				case 0 :
+				case 1 :
+				case 2 :
+					// Skip the begin of the label "--foo-"
+					// until 3 '-' have been read
+					if (src[i]=='-') { level++; }
+					break;
+
+				case 3 :
+					// copy the content, but skip non alphnum
+					// and content in parenthesis
+					switch (src[i]) {
+						case '(' :
+						case '[' :
+							level++;
+							break;
+
+						case '-' :
+							dst += '-';
+							break;
+
+						default :
+							if (isalnum(src[i])) {
+								dst+= tolower(src[i]);
+							}
+
+					}
+					break;
+
+				default :
+					// here we are inside parenthesis and
+					// we skip the content until we are back to
+					// level 3
+					switch (src[i]) {
+
+						case '(' :
+						case '[' :
+							level++;
+							break;
+
+						case ')' :
+						case ']' :
+							level--;
+							break;
+
+						default :
+							break;
+					}
+
+			}
+			i++;
+		}
+		return dst;
+	}
+
+public:
+
+	CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("-"); }
+	virtual ~CMDUI() {}
+
+	void addOption(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max)
+	{
+		std::string fullname = "-" + simplify(fPrefix.top() + "-" + label);
+		fKeyParam.insert(make_pair(fullname, param(zone, init, min, max)));
+	}
+
+	virtual void addButton(const char* label, FAUSTFLOAT* zone)
+	{
+		addOption(label,zone,0,0,1);
+	}
+
+	virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+	{
+		addOption(label,zone,0,0,1);
+	}
+
+	virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		addOption(label,zone,init,min,max);
+	}
+
+	virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		addOption(label,zone,init,min,max);
+	}
+
+	virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		addOption(label,zone,init,min,max);
+	}
+
+	// -- passive widgets
+
+	virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 		{}
+	virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 			{}
+
+	virtual void openTabBox(const char* label)			{ openAnyBox(label); }
+	virtual void openHorizontalBox(const char* label)	{ openAnyBox(label); }
+	virtual void openVerticalBox(const char* label)		{ openAnyBox(label); }
+
+	virtual void closeBox() 							{ fPrefix.pop(); }
+
+	virtual void show() {}
+	virtual void run()
+	{
+		char c;
+		printf("Type 'q' to quit\n");
+		while ((c = getchar()) != 'q') {
+			sleep(1);
+		}
+	}
+
+	void printhelp_command()
+	{
+		std::map<std::string, param>::iterator i;
+		std::cout << fArgc << "\n";
+		std::cout << fArgv[0] << " option list : ";
+		for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
+			std::cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
+		}
+		std::cout << " infile outfile\n";
+	}
+    
+    void printhelp_init()
+	{
+		std::map<std::string, param>::iterator i;
+		std::cout << fArgc << "\n";
+		std::cout << fArgv[0] << " option list : ";
+		for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
+			std::cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
+		}
+		std::cout << std::endl;
+	}
+
+	void process_command()
+	{
+		std::map<std::string, param>::iterator p;
+		for (int i = 1; i < fArgc; i++) {
+			if (fArgv[i][0] == '-') {
+				if ((strcmp(fArgv[i], "-help") == 0)
+                    || (strcmp(fArgv[i], "-h") == 0)
+                    || (strcmp(fArgv[i], "--help") == 0)) 	{
+					printhelp_command();
+					exit(1);
+				}
+				p = fKeyParam.find(fArgv[i]);
+				if (p == fKeyParam.end()) {
+					std::cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
+					printhelp_command();
+					exit(1);
+				}
+				char* end;
+				*(p->second.fZone) = FAUSTFLOAT(strtod(fArgv[i+1], &end));
+				i++;
+			} else {
+				fFiles.push_back(fArgv[i]);
+			}
+		}
+	}
+
+	int 	files()         { return fFiles.size(); }
+	char* 	file (int n)	{ return fFiles[n]; }
+
+	char* input_file ()     { std::cout << "input file " << fFiles[0] << "\n"; return fFiles[0]; }
+	char* output_file() 	{ std::cout << "output file " << fFiles[1] << "\n"; return fFiles[1]; }
+
+	void process_init()
+	{
+		std::map<std::string, param>::iterator p;
+		for (int i = 1; i < fArgc; i++) {
+			if (fArgv[i][0] == '-') {
+                if ((strcmp(fArgv[i], "-help") == 0)
+                    || (strcmp(fArgv[i], "-h") == 0)
+                    || (strcmp(fArgv[i], "--help") == 0)) 	{
+					printhelp_init();
+					exit(1);
+				}
+				p = fKeyParam.find(fArgv[i]);
+				if (p == fKeyParam.end()) {
+					std::cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
+                    printhelp_init();
+					exit(1);
+				}
+				char* end;
+				*(p->second.fZone) = FAUSTFLOAT(strtod(fArgv[i+1], &end));
+				i++;
+			}
+		}
+	}
+};
+
+#endif
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
diff --git a/architecture/faust/gui/faustgtk.h b/architecture/faust/gui/faustgtk.h
new file mode 100644
index 0000000..6d44ef0
--- /dev/null
+++ b/architecture/faust/gui/faustgtk.h
@@ -0,0 +1,1524 @@
+#ifndef FAUST_GTKUI_H
+#define FAUST_GTKUI_H
+
+#include "faust/gui/GUI.h"
+
+/******************************************************************************
+*******************************************************************************
+
+                                GRAPHIC USER INTERFACE
+                                  gtk interface
+
+*******************************************************************************
+*******************************************************************************/
+#include <string>
+#include <set>
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <assert.h>
+
+#define stackSize 256
+
+// Insertion modes
+
+#define kSingleMode 0
+#define kBoxMode 1
+#define kTabMode 2
+
+static inline bool startWith(const std::string& str, const std::string& prefix)
+{
+    return (str.substr(0, prefix.size()) == prefix);
+}
+
+//------------ calculate needed precision
+static int precision(double n)
+{
+	if (n < 0.009999) return 3;
+	else if (n < 0.099999) return 2;
+	else if (n < 0.999999) return 1;
+	else return 0;
+}
+
+namespace gtk_knob
+{
+
+class GtkKnob
+{
+private:
+	double start_x, start_y, max_value;
+public:
+	GtkRange parent;
+	int last_quadrant;
+	GtkKnob();
+	~GtkKnob();
+	GtkWidget* gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment);
+	
+};
+
+#define GTK_TYPE_KNOB          (gtk_knob_get_type())
+#define GTK_KNOB(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_KNOB, GtkKnob))
+#define GTK_IS_KNOB(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_KNOB))
+#define GTK_KNOB_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),  GTK_TYPE_KNOB, GtkKnobClass))
+#define GTK_IS_KNOB_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GTK_TYPE_KNOB))
+
+GtkKnob::GtkKnob()
+// GtkKnob constructor
+{}
+
+GtkKnob::~GtkKnob()
+{
+	// Nothing specific to do...
+}
+
+struct GtkKnobClass {
+	GtkRangeClass parent_class;
+	int knob_x;
+	int knob_y;
+	int knob_step;
+	int button_is;
+
+};
+
+//------forward declaration
+GType gtk_knob_get_type ();
+
+/****************************************************************
+ ** calculate the knop pointer with dead zone
+ */
+
+const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs
+
+static void knob_expose(GtkWidget* widget, int knob_x, int knob_y, GdkEventExpose *event, int arc_offset)
+{
+	/** check resize **/
+	int grow;
+	if(widget->allocation.width > widget->allocation.height) {
+		grow = widget->allocation.height;
+	} else {
+		grow =  widget->allocation.width;
+	}
+	knob_x = grow-4;
+	knob_y = grow-4;
+	/** get values for the knob **/
+	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
+	int knobx = (widget->allocation.x+2 + (widget->allocation.width-4 - knob_x) * 0.5);
+	int knoby = (widget->allocation.y+2 + (widget->allocation.height-4 - knob_y) * 0.5);
+	int knobx1 = (widget->allocation.x+2 + (widget->allocation.width-4)* 0.5);
+	int knoby1 = (widget->allocation.y+2 + (widget->allocation.height-4) * 0.5);
+	double knobstate = (adj->value - adj->lower) / (adj->upper - adj->lower);
+	double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero);
+	double knobstate1 = (0. - adj->lower) / (adj->upper - adj->lower);
+	double pointer_off = knob_x/6;
+	double radius = std::min(knob_x-pointer_off, knob_y-pointer_off) / 2;
+	double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle);
+	double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle);
+	double radius1 = std::min(knob_x, knob_y) / 2 ;
+
+	/** get widget forground color convert to cairo **/
+	GtkStyle *style = gtk_widget_get_style (widget);
+	double r = std::min(0.6,style->fg[gtk_widget_get_state(widget)].red/65535.0),
+		   g = std::min(0.6,style->fg[gtk_widget_get_state(widget)].green/65535.0),
+		   b = std::min(0.6,style->fg[gtk_widget_get_state(widget)].blue/65535.0);
+
+	/** paint focus **/
+	if (GTK_WIDGET_HAS_FOCUS(widget)== TRUE) {
+		gtk_paint_focus(widget->style, widget->window, GTK_STATE_NORMAL, NULL, widget, NULL,
+		                knobx-2, knoby-2, knob_x+4, knob_y+4);
+	}
+	/** create clowing knobs with cairo **/
+	cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
+	GdkRegion *region;
+	region = gdk_region_rectangle (&widget->allocation);
+	gdk_region_intersect (region, event->region);
+	gdk_cairo_region (cr, region);
+	cairo_clip (cr);
+	
+	cairo_arc(cr,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI );
+	cairo_pattern_t*pat =
+		cairo_pattern_create_radial (knobx1+arc_offset-knob_x/6,knoby1+arc_offset-knob_x/6, 1,knobx1+arc_offset,knoby1+arc_offset,knob_x/2.1 );
+	if(adj->lower<0 && adj->value>0.) {
+		cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 + knobstate-knobstate1, b+0.4);
+		cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + (knobstate-knobstate1)*0.5, b+0.15);
+		cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
+	} else if(adj->lower<0 && adj->value<=0.) {
+		cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4 +knobstate1- knobstate, g+0.4, b+0.4);
+		cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15 +(knobstate1- knobstate)*0.5, g+0.15, b+0.15);
+		cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
+	} else {
+		cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 +knobstate, b+0.4);
+		cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + knobstate*0.5, b+0.15);
+		cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
+	}
+	cairo_set_source (cr, pat);
+	cairo_fill_preserve (cr);
+	gdk_cairo_set_source_color(cr, gtk_widget_get_style (widget)->fg);
+	cairo_set_line_width(cr, 2.0);
+	cairo_stroke(cr);
+
+	/** create a rotating pointer on the kob**/
+	cairo_set_source_rgb(cr,  0.1, 0.1, 0.1);
+	cairo_set_line_width(cr,std::max(3, std::min(7, knob_x/15)));
+	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); 
+	cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
+	cairo_move_to(cr, knobx+radius1, knoby+radius1);
+	cairo_line_to(cr,lengh_x,lengh_y);
+	cairo_stroke(cr);
+	cairo_set_source_rgb(cr,  0.9, 0.9, 0.9);
+	cairo_set_line_width(cr,std::min(5, std::max(1,knob_x/30)));
+	cairo_move_to(cr, knobx+radius1, knoby+radius1);
+	cairo_line_to(cr,lengh_x,lengh_y);
+	cairo_stroke(cr);
+	cairo_pattern_destroy (pat);
+	gdk_region_destroy (region);
+	cairo_destroy(cr);
+}
+
+/****************************************************************
+ ** general expose events for all "knob" controllers
+ */
+
+//----------- draw the Knob when moved
+static gboolean gtk_knob_expose (GtkWidget* widget, GdkEventExpose *event)
+{
+	g_assert(GTK_IS_KNOB(widget));
+	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
+	knob_expose(widget, klass->knob_x, klass->knob_y, event, 0);
+	return TRUE;
+}
+
+/****************************************************************
+ ** set initial size for GdkDrawable per type
+ */
+
+static void gtk_knob_size_request (GtkWidget* widget, GtkRequisition *requisition)
+{
+	g_assert(GTK_IS_KNOB(widget));
+	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
+	requisition->width = klass->knob_x;
+	requisition->height = klass->knob_y;
+}
+
+/****************************************************************
+ ** set value from key bindings
+ */
+
+static void gtk_knob_set_value (GtkWidget* widget, int dir_down)
+{
+	g_assert(GTK_IS_KNOB(widget));
+
+	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
+
+	int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment);
+	int step;
+	int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment);
+	if (dir_down)
+		step = oldstep - 1;
+	else
+		step = oldstep + 1;
+	FAUSTFLOAT value = adj->lower + step * double(adj->upper - adj->lower) / nsteps;
+	gtk_widget_grab_focus(widget);
+	gtk_range_set_value(GTK_RANGE(widget), value);
+}
+
+/****************************************************************
+ ** keyboard bindings
+ */
+
+static gboolean gtk_knob_key_press (GtkWidget* widget, GdkEventKey *event)
+{
+	g_assert(GTK_IS_KNOB(widget));
+
+	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
+	switch (event->keyval) {
+	case GDK_Home:
+		gtk_range_set_value(GTK_RANGE(widget), adj->lower);
+		return TRUE;
+	case GDK_End:
+		gtk_range_set_value(GTK_RANGE(widget), adj->upper);
+		return TRUE;
+	case GDK_Up:
+		gtk_knob_set_value(widget, 0);
+		return TRUE;
+	case GDK_Right:
+		gtk_knob_set_value(widget, 0);
+		return TRUE;
+	case GDK_Down:
+		gtk_knob_set_value(widget, 1);
+		return TRUE;
+	case GDK_Left:
+		gtk_knob_set_value(widget, 1);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/****************************************************************
+ ** alternative (radial) knob motion mode (ctrl + mouse pressed)
+ */
+
+static void knob_pointer_event(GtkWidget* widget, gdouble x, gdouble y, int knob_x, int knob_y,
+                               bool drag, int state)
+{
+	static double last_y = 2e20;
+	GtkKnob *knob = GTK_KNOB(widget);
+	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
+	double radius =  std::min(knob_x, knob_y) / 2;
+	int  knobx = (widget->allocation.width - knob_x) / 2;
+	int  knoby = (widget->allocation.height - knob_y) / 2;
+	double posx = (knobx + radius) - x; // x axis right -> left
+	double posy = (knoby + radius) - y; // y axis top -> bottom
+	double value;
+	if (!drag) {
+		if (state & GDK_CONTROL_MASK) {
+			last_y = 2e20;
+			return;
+		} else {
+			last_y = posy;
+		}
+	}
+	if (last_y < 1e20) { // in drag started with Control Key
+		const double scaling = 0.005;
+		double scal = (state & GDK_SHIFT_MASK ? scaling*0.1 : scaling);
+		value = (last_y - posy) * scal;
+		last_y = posy;
+		gtk_range_set_value(GTK_RANGE(widget), adj->value - value * (adj->upper - adj->lower));
+		return;
+	}
+
+	double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI
+	if (drag) {
+		// block "forbidden zone" and direct moves between quadrant 1 and 4
+		int quadrant = 1 + int(angle/M_PI_2);
+		if (knob->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) {
+			angle = scale_zero;
+		} else if (knob->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) {
+			angle = 2*M_PI - scale_zero;
+		} else {
+			if (angle < scale_zero) {
+				angle = scale_zero;
+			} else if (angle > 2*M_PI - scale_zero) {
+				angle = 2*M_PI - scale_zero;
+			}
+			knob->last_quadrant = quadrant;
+		}
+	} else {
+		if (angle < scale_zero) {
+			angle = scale_zero;
+		} else if (angle > 2*M_PI - scale_zero) {
+			angle = 2*M_PI - scale_zero;
+		}
+		knob->last_quadrant = 0;
+	}
+	angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1
+	gtk_range_set_value(GTK_RANGE(widget), adj->lower + angle * (adj->upper - adj->lower));
+}
+
+/****************************************************************
+ ** mouse button pressed set value
+ */
+
+static gboolean gtk_knob_button_press (GtkWidget* widget, GdkEventButton *event)
+{
+	g_assert(GTK_IS_KNOB(widget));
+	
+	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
+	
+
+	switch (event->button) {
+	case 1:  // left button
+		gtk_widget_grab_focus(widget);
+		gtk_widget_grab_default (widget);
+		gtk_grab_add(widget);
+		klass->button_is = 1;
+		knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y,
+						   false, event->state);
+		break;
+	case 2: //wheel
+		klass->button_is = 2;
+		break;
+	case 3:  // right button 
+		klass->button_is = 3;
+		break;
+	default: // do nothing
+		break;
+	}
+	return TRUE;
+}
+
+/****************************************************************
+ ** mouse button release
+ */
+
+static gboolean gtk_knob_button_release (GtkWidget* widget, GdkEventButton *event)
+{
+	g_assert(GTK_IS_KNOB(widget));
+	GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget))->button_is = 0;
+	if (GTK_WIDGET_HAS_GRAB(widget))
+		gtk_grab_remove(widget);
+	return FALSE;
+}
+
+/****************************************************************
+ ** set the value from mouse movement
+ */
+
+static gboolean gtk_knob_pointer_motion (GtkWidget* widget, GdkEventMotion *event)
+{
+	g_assert(GTK_IS_KNOB(widget));
+	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
+	
+	gdk_event_request_motions (event);
+	
+	if (GTK_WIDGET_HAS_GRAB(widget)) {
+		knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y,
+						   true, event->state);
+	}
+	return FALSE;
+}
+
+/****************************************************************
+ ** set value from mouseweel
+ */
+
+static gboolean gtk_knob_scroll (GtkWidget* widget, GdkEventScroll *event)
+{
+	usleep(5000);
+	gtk_knob_set_value(widget, event->direction);
+	return FALSE;
+}
+
+/****************************************************************
+ ** init the GtkKnobClass
+ */
+
+static void gtk_knob_class_init (GtkKnobClass *klass)
+{
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+	/** set here the sizes and steps for the used knob **/
+//--------- small knob size and steps
+	
+	klass->knob_x = 30;
+	klass->knob_y = 30;
+	klass->knob_step = 86;
+
+//--------- event button
+	klass->button_is = 0;
+
+//--------- connect the events with funktions
+	widget_class->expose_event = gtk_knob_expose;
+	widget_class->size_request = gtk_knob_size_request;
+	widget_class->button_press_event = gtk_knob_button_press;
+	widget_class->button_release_event = gtk_knob_button_release;
+	widget_class->motion_notify_event = gtk_knob_pointer_motion;
+	widget_class->key_press_event = gtk_knob_key_press;
+	widget_class->scroll_event = gtk_knob_scroll;
+}
+
+/****************************************************************
+ ** init the Knob type/size
+ */
+
+static void gtk_knob_init (GtkKnob *knob)
+{
+	GtkWidget* widget = GTK_WIDGET(knob);
+	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
+
+	GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_FOCUS);
+	GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_DEFAULT);
+
+	widget->requisition.width = klass->knob_x;
+	widget->requisition.height = klass->knob_y;
+}
+
+/****************************************************************
+ ** redraw when value changed
+ */
+
+static gboolean gtk_knob_value_changed(gpointer obj)
+{
+	GtkWidget* widget = (GtkWidget* )obj;
+	gtk_widget_queue_draw(widget);
+	return FALSE;
+}
+
+/****************************************************************
+ ** create small knob
+ */
+
+GtkWidget* GtkKnob::gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment)
+{
+	GtkWidget* widget = GTK_WIDGET( g_object_new (GTK_TYPE_KNOB, NULL ));
+	GtkKnob *knob = GTK_KNOB(widget);
+	knob->last_quadrant = 0;
+	if (widget) {
+		gtk_range_set_adjustment(GTK_RANGE(widget), _adjustment);
+		g_signal_connect(GTK_OBJECT(widget), "value-changed",
+		                 G_CALLBACK(gtk_knob_value_changed), widget);
+	}
+	return widget;
+}
+
+/****************************************************************
+ ** get the Knob type
+ */
+
+GType gtk_knob_get_type (void)
+{
+	static GType kn_type = 0;
+	if (!kn_type) {
+		static const GTypeInfo kn_info = {
+			sizeof(GtkKnobClass), NULL,  NULL, (GClassInitFunc)gtk_knob_class_init, NULL, NULL, sizeof(GtkKnob), 0, (GInstanceInitFunc)gtk_knob_init, NULL
+		};
+		kn_type = g_type_register_static(GTK_TYPE_RANGE,  "GtkKnob", &kn_info, (GTypeFlags)0);
+	}
+	return kn_type;
+}
+}/* end of gtk_knob namespace */
+
+gtk_knob::GtkKnob myGtkKnob;
+
+/**
+ * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string
+ * (but not those in the middle of the string)
+ */
+static std::string rmWhiteSpaces(const std::string& s)
+{
+    size_t i = s.find_first_not_of(" \t");
+    size_t j = s.find_last_not_of(" \t");
+
+    if (i != std::string::npos & j != std::string::npos) {
+        return s.substr(i, 1+j-i);
+    } else {
+        return "";
+    }
+}
+
+/**
+ * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata
+ */
+static void extractMetadata(const std::string& fulllabel, std::string& label, std::map<std::string, std::string>& metadata)
+{
+    enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
+    int state = kLabel; int deep = 0;
+    std::string key, value;
+
+    for (unsigned int i=0; i < fulllabel.size(); i++) {
+        char c = fulllabel[i];
+        switch (state) {
+            case kLabel :
+                assert (deep == 0);
+                switch (c) {
+                    case '\\' : state = kEscape1; break;
+                    case '[' : state = kKey; deep++; break;
+                    default : label += c;
+                }
+                break;
+
+            case kEscape1 :
+                label += c;
+                state = kLabel;
+                break;
+
+            case kEscape2 :
+                key += c;
+                state = kKey;
+                break;
+
+            case kEscape3 :
+                value += c;
+                state = kValue;
+                break;
+
+            case kKey :
+                assert (deep > 0);
+                switch (c) {
+                    case '\\' :  state = kEscape2;
+                                break;
+
+                    case '[' :  deep++;
+                                key += c;
+                                break;
+
+                    case ':' :  if (deep == 1) {
+                                    state = kValue;
+                                } else {
+                                    key += c;
+                                }
+                                break;
+                    case ']' :  deep--;
+                                if (deep < 1) {
+                                    metadata[rmWhiteSpaces(key)] = "";
+                                    state = kLabel;
+                                    key="";
+                                    value="";
+                                } else {
+                                    key += c;
+                                }
+                                break;
+                    default :   key += c;
+                }
+                break;
+
+            case kValue :
+                assert (deep > 0);
+                switch (c) {
+                    case '\\' : state = kEscape3;
+                                break;
+
+                    case '[' :  deep++;
+                                value += c;
+                                break;
+
+                    case ']' :  deep--;
+                                if (deep < 1) {
+                                    metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value);
+                                    state = kLabel;
+                                    key="";
+                                    value="";
+                                } else {
+                                    value += c;
+                                }
+                                break;
+                    default :   value += c;
+                }
+                break;
+
+            default :
+                std::cerr << "ERROR unrecognized state " << state << std::endl;
+        }
+    }
+    label = rmWhiteSpaces(label);
+}
+
+class GTKUI : public GUI
+{
+ private :
+    static bool                         		fInitialized;
+    static std::map<FAUSTFLOAT*, FAUSTFLOAT> 	fGuiSize;       // map widget zone with widget size coef
+    static std::map<FAUSTFLOAT*, std::string>   fTooltip;       // map widget zone with tooltip strings
+    static std::set<FAUSTFLOAT*>             	fKnobSet;       // set of widget zone to be knobs
+	std::string									gGroupTooltip;
+    
+    bool isKnob(FAUSTFLOAT* zone) {return fKnobSet.count(zone) > 0;}
+    
+ protected :
+    GtkWidget*  fWindow;
+    int         fTop;
+    GtkWidget*  fBox[stackSize];
+    int         fMode[stackSize];
+    bool        fStopped;
+
+    GtkWidget* addWidget(const char* label, GtkWidget* w);
+    virtual void pushBox(int mode, GtkWidget* w);
+
+        
+ public :
+    static const gboolean expand = TRUE;
+    static const gboolean fill = TRUE;
+    static const gboolean homogene = FALSE;
+         
+    GTKUI(char * name, int* pargc, char*** pargv);
+
+    // -- Labels and metadata
+
+    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value);
+    virtual int  checkLabelOptions(GtkWidget* widget, const std::string& fullLabel, std::string& simplifiedLabel);
+    virtual void checkForTooltip(FAUSTFLOAT* zone, GtkWidget* widget);
+    
+    // -- layout groups
+    
+    virtual void openTabBox(const char* label = "");
+    virtual void openHorizontalBox(const char* label = "");
+    virtual void openVerticalBox(const char* label = "");
+    virtual void closeBox();
+
+    // -- active widgets
+    
+    virtual void addButton(const char* label, FAUSTFLOAT* zone);
+    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone);
+    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);   
+    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); 
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+
+    // -- passive display widgets
+    
+    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max);
+    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max);
+    
+    // -- layout groups - internal
+    
+    virtual void openFrameBox(const char* label);   
+   
+    // -- extra widget's layouts
+
+    virtual void openDialogBox(const char* label, FAUSTFLOAT* zone);
+    virtual void openEventBox(const char* label = "");
+    virtual void openHandleBox(const char* label = "");
+    virtual void openExpanderBox(const char* label, FAUSTFLOAT* zone);
+    
+    virtual void adjustStack(int n);
+    
+    // -- active widgets - internal
+    virtual void addToggleButton(const char* label, FAUSTFLOAT* zone);
+    virtual void addKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+    
+    // -- passive display widgets - internal
+    
+    virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision);
+    virtual void addTextDisplay(const char* label, FAUSTFLOAT* zone, const char* names[], FAUSTFLOAT min, FAUSTFLOAT max);
+   
+    virtual void show();
+    virtual void run();
+    
+};
+
+/******************************************************************************
+*******************************************************************************
+
+                                GRAPHIC USER INTERFACE (v2)
+                                  gtk implementation
+
+*******************************************************************************
+*******************************************************************************/
+
+// global static fields
+
+bool                             GTKUI::fInitialized = false;
+std::map<FAUSTFLOAT*, FAUSTFLOAT>     GTKUI::fGuiSize;
+std::map<FAUSTFLOAT*, std::string>    GTKUI::fTooltip;
+std::set<FAUSTFLOAT*>                 GTKUI::fKnobSet;       // set of widget zone to be knobs
+
+/**
+* Format tooltip string by replacing some white spaces by 
+* return characters so that line width doesn't exceed n.
+* Limitation : long words exceeding n are not cut 
+*/
+static std::string formatTooltip(unsigned int n, const std::string& tt)
+{
+	std::string  ss = tt;	// ss string we are going to format
+	unsigned int lws = 0;	// last white space encountered
+	unsigned int lri = 0;	// last return inserted
+	for (unsigned int i = 0; i < tt.size(); i++) {
+		if (tt[i] == ' ') lws = i;
+		if (((i-lri) >= n) && (lws > lri)) {
+			// insert return here
+			ss[lws] = '\n';
+			lri = lws;
+		}
+	}
+	//std::cout << ss;
+	return ss;
+}
+
+static gint delete_event(GtkWidget* widget, GdkEvent *event, gpointer data)
+{
+    return FALSE; 
+}
+
+static void destroy_event(GtkWidget* widget, gpointer data)
+{
+    gtk_main_quit ();
+}
+
+GTKUI::GTKUI(char * name, int* pargc, char*** pargv) 
+{
+    if (!fInitialized) {
+        gtk_init(pargc, pargv);
+        fInitialized = true;
+    }
+    
+    fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    //gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10);
+    gtk_window_set_title (GTK_WINDOW (fWindow), name);
+    gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);
+    gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL);
+
+    fTop = 0;
+    fBox[fTop] = gtk_vbox_new (homogene, 4);
+    fMode[fTop] = kBoxMode;
+    gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]);
+    fStopped = false;
+}
+
+// empilement des boites
+
+void GTKUI::pushBox(int mode, GtkWidget* w)
+{
+    ++fTop;
+    assert(fTop < stackSize);
+    fMode[fTop] = mode;
+    fBox[fTop] = w;
+}
+
+/**
+ * Remove n levels from the stack S before the top level
+ * adjustStack(n): S -> S' with S' = S(0),S(n+1),S(n+2),...
+ */
+void GTKUI::adjustStack(int n)
+{
+    if (n > 0) {
+        assert(fTop >= n);
+        fTop -= n; 
+        fMode[fTop] = fMode[fTop+n];
+        fBox[fTop] = fBox[fTop+n];
+    }
+}
+
+void GTKUI::closeBox()
+{
+    --fTop;
+    assert(fTop >= 0);
+}
+
+/**
+ * Analyses the widget zone metadata declarations and takes
+ * appropriate actions 
+ */
+void GTKUI::declare(FAUSTFLOAT* zone, const char* key, const char* value)
+{
+	if (zone == 0) {
+		// special zone 0 means group metadata
+		if (strcmp(key,"tooltip") == 0) {
+			// only group tooltip are currently implemented
+			gGroupTooltip = formatTooltip(30, value);
+		}
+	} else {
+		if (strcmp(key,"size")==0) {
+			fGuiSize[zone] = atof(value);
+		}
+		else if (strcmp(key,"tooltip") == 0) {
+			fTooltip[zone] = formatTooltip(30,value) ;
+		}
+		else if (strcmp(key,"style") == 0) {
+			if (strcmp(value,"knob") == 0) {
+				fKnobSet.insert(zone);
+			}
+		}
+	}
+}
+    
+/**
+ * Analyses a full label and activates the relevant options. returns a simplified
+ * label (without options) and an amount of stack adjustement (in case additional
+ * containers were pushed on the stack). 
+ */
+
+int GTKUI::checkLabelOptions(GtkWidget* widget, const std::string& fullLabel, std::string& simplifiedLabel)
+{   
+    std::map<std::string, std::string> metadata;
+    extractMetadata(fullLabel, simplifiedLabel, metadata);
+
+    if (metadata.count("tooltip")) {
+        gtk_tooltips_set_tip (gtk_tooltips_new (), widget, metadata["tooltip"].c_str(), NULL);
+    }
+    if (metadata["option"] == "detachable") {
+        openHandleBox(simplifiedLabel.c_str());
+        return 1;
+    }
+
+	//---------------------
+	if (gGroupTooltip != std::string()) {
+		gtk_tooltips_set_tip (gtk_tooltips_new (), widget, gGroupTooltip.c_str(), NULL);
+		gGroupTooltip = std::string();
+	}
+	
+	//----------------------
+    // no adjustement of the stack needed
+    return 0;
+}
+
+/**
+ * Check if a tooltip is associated to a zone and add it to the corresponding widget
+ */
+void GTKUI::checkForTooltip(FAUSTFLOAT* zone, GtkWidget* widget)
+{
+    if (fTooltip.count(zone)) {
+        gtk_tooltips_set_tip (gtk_tooltips_new (), widget, fTooltip[zone].c_str(), NULL);
+    }
+}
+
+// The different boxes
+
+void GTKUI::openFrameBox(const char* label)
+{
+    GtkWidget* box = gtk_frame_new (label);
+    //gtk_container_set_border_width (GTK_CONTAINER (box), 10);
+            
+    pushBox(kSingleMode, addWidget(label, box));
+}
+
+void GTKUI::openTabBox(const char* fullLabel)
+{
+    std::string label;
+    GtkWidget* widget = gtk_notebook_new();
+
+    int adjust = checkLabelOptions(widget, fullLabel, label);
+    
+    pushBox(kTabMode, addWidget(label.c_str(), widget));
+
+    // adjust stack because otherwise Handlebox will remain open
+    adjustStack(adjust);
+}
+
+void GTKUI::openHorizontalBox(const char* fullLabel)
+{   
+    std::string label;
+    GtkWidget* box = gtk_hbox_new (homogene, 4);
+    int adjust = checkLabelOptions(box, fullLabel, label);
+
+    gtk_container_set_border_width (GTK_CONTAINER (box), 10);
+    label = startWith(label, "0x") ? "" : label;
+            
+    if (fMode[fTop] != kTabMode && label[0] != 0) {
+        GtkWidget* frame = addWidget(label.c_str(), gtk_frame_new (label.c_str()));
+        gtk_container_add (GTK_CONTAINER(frame), box);
+        gtk_widget_show(box);
+        pushBox(kBoxMode, box);
+    } else {
+        pushBox(kBoxMode, addWidget(label.c_str(), box));
+    }
+
+    // adjust stack because otherwise Handlebox will remain open
+    adjustStack(adjust);
+}
+
+void GTKUI::openVerticalBox(const char* fullLabel)
+{
+    std::string label;
+    GtkWidget* box = gtk_vbox_new (homogene, 4);
+    int adjust = checkLabelOptions(box, fullLabel, label);
+
+    gtk_container_set_border_width (GTK_CONTAINER (box), 10);
+    label = startWith(label, "0x") ? "" : label;
+            
+    if (fMode[fTop] != kTabMode && label[0] != 0) {
+        GtkWidget* frame = addWidget(label.c_str(), gtk_frame_new (label.c_str()));
+        gtk_container_add (GTK_CONTAINER(frame), box);
+        gtk_widget_show(box);
+        pushBox(kBoxMode, box);
+    } else {
+        pushBox(kBoxMode, addWidget(label.c_str(), box));
+    }
+
+    // adjust stack because otherwise Handlebox will remain open
+    adjustStack(adjust);
+}
+
+void GTKUI::openHandleBox(const char* label)
+{
+    GtkWidget* box = gtk_hbox_new (homogene, 4);
+    gtk_container_set_border_width (GTK_CONTAINER (box), 2);
+    label = startWith(label, "0x") ? "" : label;
+    if (fMode[fTop] != kTabMode && label[0] != 0) {
+        GtkWidget* frame = addWidget(label, gtk_handle_box_new ());
+        gtk_container_add (GTK_CONTAINER(frame), box);
+        gtk_widget_show(box);
+        pushBox(kBoxMode, box);
+    } else {
+        pushBox(kBoxMode, addWidget(label, box));
+    }
+}
+
+void GTKUI::openEventBox(const char* label)
+{
+    GtkWidget* box = gtk_hbox_new (homogene, 4);
+    gtk_container_set_border_width (GTK_CONTAINER (box), 2);
+    label = startWith(label, "0x") ? "" : label;
+    if (fMode[fTop] != kTabMode && label[0] != 0) {
+        GtkWidget* frame = addWidget(label, gtk_event_box_new ());
+        gtk_container_add (GTK_CONTAINER(frame), box);
+        gtk_widget_show(box);
+        pushBox(kBoxMode, box);
+    } else {
+        pushBox(kBoxMode, addWidget(label, box));
+    }
+}
+
+struct uiExpanderBox : public uiItem
+{
+    GtkExpander* fButton;
+    uiExpanderBox(GUI* ui, FAUSTFLOAT* zone, GtkExpander* b) : uiItem(ui, zone), fButton(b) {}
+    static void expanded (GtkWidget* widget, gpointer data)
+    {
+        FAUSTFLOAT v = gtk_expander_get_expanded  (GTK_EXPANDER(widget));
+        if (v == 1.000000) {
+            v = 0;
+        } else {
+            v = 1;
+        }
+        ((uiItem*)data)->modifyZone(v);
+    }
+
+    virtual void reflectZone()
+    {
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        gtk_expander_set_expanded(GTK_EXPANDER(fButton), v);
+    }
+};
+
+void GTKUI::openExpanderBox(const char* label, FAUSTFLOAT* zone)
+{
+    *zone = 0.0;
+    GtkWidget* box = gtk_hbox_new (homogene, 4);
+    gtk_container_set_border_width (GTK_CONTAINER (box), 2);
+    label = startWith(label, "0x") ? "" : label;
+    if (fMode[fTop] != kTabMode && label[0] != 0) {
+        GtkWidget* frame = addWidget(label, gtk_expander_new (label));
+        gtk_container_add (GTK_CONTAINER(frame), box);
+        uiExpanderBox* c = new uiExpanderBox(this, zone, GTK_EXPANDER(frame));
+        gtk_signal_connect (GTK_OBJECT (frame), "activate", GTK_SIGNAL_FUNC (uiExpanderBox::expanded), (gpointer)c);
+        gtk_widget_show(box);
+        pushBox(kBoxMode, box);
+    } else {
+        pushBox(kBoxMode, addWidget(label, box));
+    }
+}
+
+GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w)
+{ 
+    switch (fMode[fTop]) {
+        case kSingleMode    : gtk_container_add (GTK_CONTAINER(fBox[fTop]), w);                             break;
+        case kBoxMode       : gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0);                 break;
+        case kTabMode       : gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break;
+    }
+    gtk_widget_show (w);
+    return w;
+}
+
+// --------------------------- Press button ---------------------------
+
+struct uiButton : public uiItem
+{
+    GtkButton*  fButton;
+    
+    uiButton(GUI* ui, FAUSTFLOAT* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {}
+    
+    static void pressed(GtkWidget* widget, gpointer data)
+    {
+        uiItem* c = (uiItem*) data;
+        c->modifyZone(1.0);
+    }
+
+    static void released(GtkWidget* widget, gpointer data)
+    {
+        uiItem* c = (uiItem*) data;
+        c->modifyZone(0.0);
+    }
+
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v; 
+        if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton);
+    }
+};
+
+void GTKUI::addButton(const char* label, FAUSTFLOAT* zone)
+{
+    *zone = 0.0;
+    GtkWidget* button = gtk_button_new_with_label (label);
+    addWidget(label, button);
+    
+    uiButton* c = new uiButton(this, zone, GTK_BUTTON(button));
+    
+    gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c);
+    gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c);
+
+    checkForTooltip(zone, button);
+}
+
+// ---------------------------  Toggle Buttons ---------------------------
+
+struct uiToggleButton : public uiItem
+{
+    GtkToggleButton* fButton;
+    
+    uiToggleButton(GUI* ui, FAUSTFLOAT* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
+    
+    static void toggled (GtkWidget* widget, gpointer data)
+    {
+        FAUSTFLOAT v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; 
+        ((uiItem*)data)->modifyZone(v);
+    }
+
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v; 
+        gtk_toggle_button_set_active(fButton, v > 0.0); 
+    }
+};
+
+void GTKUI::addToggleButton(const char* label, FAUSTFLOAT* zone)
+{
+    *zone = 0.0;
+    GtkWidget* button = gtk_toggle_button_new_with_label (label);
+    addWidget(label, button);
+    
+    uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button));
+    gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c);
+
+    checkForTooltip(zone, button);
+}
+
+void show_dialog(GtkWidget* widget, gpointer data)
+{
+    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == TRUE)
+    {
+        gtk_widget_show(GTK_WIDGET(data));
+        gint root_x, root_y;
+        gtk_window_get_position (GTK_WINDOW(data), &root_x, &root_y);
+        root_y -= 120;
+        gtk_window_move(GTK_WINDOW(data), root_x, root_y);
+    }
+    else gtk_widget_hide(GTK_WIDGET(data));
+}
+
+static gboolean deleteevent( GtkWidget* widget, gpointer   data )
+{
+    return TRUE;
+} 
+
+void GTKUI::openDialogBox(const char* label, FAUSTFLOAT* zone)
+{
+    // create toplevel window and set properties
+    GtkWidget* dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_decorated(GTK_WINDOW(dialog), TRUE);
+    gtk_window_set_deletable(GTK_WINDOW(dialog), FALSE);
+    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+    gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_SOUTH);
+    gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(fWindow));
+    gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
+    gtk_window_set_keep_below (GTK_WINDOW(dialog), FALSE);
+    gtk_window_set_title (GTK_WINDOW (dialog), label);
+    g_signal_connect (G_OBJECT (dialog), "delete_event", G_CALLBACK (deleteevent), NULL); 
+    gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
+
+    GtkWidget* box = gtk_hbox_new (homogene, 4);
+ 
+    *zone = 0.0;
+    GtkWidget* button = gtk_toggle_button_new ();
+    gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (show_dialog), (gpointer) dialog);
+ 
+    gtk_container_add (GTK_CONTAINER(fBox[fTop]), button);
+    gtk_container_add (GTK_CONTAINER(dialog), box);
+    gtk_widget_show (button);
+    gtk_widget_show(box);
+    pushBox(kBoxMode, box);
+}
+
+// ---------------------------  Check Button ---------------------------
+
+struct uiCheckButton : public uiItem
+{
+    GtkToggleButton* fButton;
+    
+    uiCheckButton(GUI* ui, FAUSTFLOAT* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
+    
+    static void toggled (GtkWidget* widget, gpointer data)
+    {
+        FAUSTFLOAT v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; 
+        ((uiItem*)data)->modifyZone(v);
+    }
+
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v; 
+        gtk_toggle_button_set_active(fButton, v > 0.0); 
+    }
+};
+
+void GTKUI::addCheckButton(const char* label, FAUSTFLOAT* zone)
+{
+    *zone = 0.0;
+    GtkWidget* button = gtk_check_button_new_with_label (label);
+    addWidget(label, button);
+    
+    uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button));
+    gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c);
+
+    checkForTooltip(zone, button);
+}
+
+// ---------------------------  Adjustmenty based widgets ---------------------------
+
+struct uiAdjustment : public uiItem
+{
+    GtkAdjustment* fAdj;
+    
+    uiAdjustment(GUI* ui, FAUSTFLOAT* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {}
+    
+    static void changed (GtkWidget* widget, gpointer data)
+    {
+        FAUSTFLOAT v = GTK_ADJUSTMENT (widget)->value; 
+        ((uiItem*)data)->modifyZone(v);
+    }
+
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v; 
+        gtk_adjustment_set_value(fAdj, v);  
+    }
+};
+
+// --------------------------- format knob value display ---------------------------
+
+struct uiValueDisplay : public uiItem
+{
+	GtkLabel* fLabel;
+	int	fPrecision ;
+
+	uiValueDisplay(GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, int precision)
+		: uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
+
+	virtual void reflectZone()
+		{
+			FAUSTFLOAT v = *fZone;
+			fCache = v;
+			char s[64];
+			if (fPrecision <= 0)
+				snprintf(s, 63, "%d", int(v));
+
+			else if (fPrecision > 3)
+				snprintf(s, 63, "%f", v);
+
+			else if (fPrecision == 1)
+			{
+				const char* format[] = {"%.1f", "%.2f", "%.3f"};
+				snprintf(s, 63, format[1-1], v);
+			}
+			else if (fPrecision == 2)
+			{
+				const char* format[] = {"%.1f", "%.2f", "%.3f"};
+				snprintf(s, 63, format[2-1], v);
+			}
+			else
+			{
+				const char* format[] = {"%.1f", "%.2f", "%.3f"};
+				snprintf(s, 63, format[3-1], v);
+			}
+			gtk_label_set_text(fLabel, s);
+		}
+};
+
+// ------------------------------- Knob -----------------------------------------
+
+void GTKUI::addKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+	*zone = init;
+    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
+    
+    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
+
+    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
+    
+	GtkWidget* slider = gtk_vbox_new (FALSE, 0);
+	GtkWidget* fil = gtk_vbox_new (FALSE, 0);
+	GtkWidget* rei = gtk_vbox_new (FALSE, 0);
+	GtkWidget* re = myGtkKnob.gtk_knob_new_with_adjustment(GTK_ADJUSTMENT(adj));
+	GtkWidget* lw = gtk_label_new("");
+	new uiValueDisplay(this, zone, GTK_LABEL(lw),precision(step));
+	gtk_container_add (GTK_CONTAINER(rei), re);
+	if(fGuiSize[zone]) {
+		FAUSTFLOAT size = 30 * fGuiSize[zone];
+		gtk_widget_set_size_request(rei, size, size );
+		gtk_box_pack_start (GTK_BOX(slider), fil, TRUE, TRUE, 0);
+		gtk_box_pack_start (GTK_BOX(slider), rei, FALSE, FALSE, 0);
+	} else {
+		gtk_container_add (GTK_CONTAINER(slider), fil);
+		gtk_container_add (GTK_CONTAINER(slider), rei);
+	}
+	gtk_container_add (GTK_CONTAINER(slider), lw);
+	gtk_widget_show_all(slider);
+	
+    label = startWith(label, "0x") ? "" : label;
+	if (label && label[0] != 0) {
+        openFrameBox(label);
+        addWidget(label, slider);
+        closeBox();
+    } else {
+        addWidget(label, slider);
+    }
+
+    checkForTooltip(zone, slider);
+}
+
+// -------------------------- Vertical Slider -----------------------------------
+
+void GTKUI::addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+	if (isKnob(zone)) { 
+		addKnob(label, zone, init, min, max, step);
+		return;
+	} 
+    *zone = init;
+    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
+    
+    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
+
+    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
+    
+	GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj));
+	gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
+	FAUSTFLOAT size = 160;
+	if(fGuiSize[zone]) {
+		size = 160 * fGuiSize[zone];
+	}
+	gtk_widget_set_size_request(slider, -1, size);
+	
+    gtk_range_set_inverted (GTK_RANGE(slider), TRUE);
+    
+    label = startWith(label, "0x") ? "" : label;
+    if (label && label[0] != 0) {
+        openFrameBox(label);
+        addWidget(label, slider);
+        closeBox();
+    } else {
+        addWidget(label, slider);
+    }
+
+    checkForTooltip(zone, slider);
+}
+
+// -------------------------- Horizontal Slider -----------------------------------
+
+void GTKUI::addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+	if (isKnob(zone)) { 
+		addKnob(label, zone, init, min, max, step);
+		return;
+	} 
+    *zone = init;
+    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
+    
+    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
+
+    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
+    
+    GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj));
+	gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
+	FAUSTFLOAT size = 160;
+	if(fGuiSize[zone]) {
+		size = 160 * fGuiSize[zone];
+	}
+	gtk_widget_set_size_request(slider, size, -1);
+    
+    label = startWith(label, "0x") ? "" : label;
+    if (label && label[0] != 0) {
+        openFrameBox(label);
+        addWidget(label, slider);
+        closeBox();
+    } else {
+        addWidget(label, slider);
+    }             
+
+    checkForTooltip(zone, slider);
+}
+
+// ------------------------------ Num Entry -----------------------------------
+
+void GTKUI::addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+	if (isKnob(zone)) { 
+		addKnob(label, zone, init, min, max, step);
+		return;
+	} 
+    *zone = init;
+    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step);
+    
+    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
+    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
+    GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step));
+    
+    label = startWith(label, "0x") ? "" : label;
+    if (label && label[0] != 0) {
+        openFrameBox(label);
+        addWidget(label, spinner);
+        closeBox();
+    } else {
+        addWidget(label, spinner);
+    }
+
+    checkForTooltip(zone, spinner);
+}
+
+// ==========================   passive widgets ===============================
+
+// ------------------------------ Progress Bar -----------------------------------
+
+struct uiBargraph : public uiItem
+{
+    GtkProgressBar*     fProgressBar;
+    FAUSTFLOAT          fMin;
+    FAUSTFLOAT          fMax;
+    
+    uiBargraph(GUI* ui, FAUSTFLOAT* zone, GtkProgressBar* pbar, FAUSTFLOAT lo, FAUSTFLOAT hi) 
+            : uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {}
+
+    FAUSTFLOAT scale(FAUSTFLOAT v)        { return (v-fMin)/(fMax-fMin); }
+    
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v; 
+        gtk_progress_bar_set_fraction(fProgressBar, scale(v));  
+    }
+};
+
+void GTKUI::addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi)
+{
+    GtkWidget* pb = gtk_progress_bar_new();
+    gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP);
+    gtk_widget_set_size_request(pb, 8, -1);
+    new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
+    
+    label = startWith(label, "0x") ? "" : label;
+    if (label && label[0] != 0) {
+        openFrameBox(label);
+        addWidget(label, pb);
+        closeBox();
+    } else {
+        addWidget(label, pb);
+    }
+
+    checkForTooltip(zone, pb);
+}
+    
+void GTKUI::addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi)
+{
+    GtkWidget* pb = gtk_progress_bar_new();
+    gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT);
+    gtk_widget_set_size_request(pb, -1, 8);
+    new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
+    
+    label = startWith(label, "0x") ? "" : label;
+    if (label && label[0] != 0) {
+        openFrameBox(label);
+        addWidget(label, pb);
+        closeBox();
+    } else {
+        addWidget(label, pb);
+    }
+
+    checkForTooltip(zone, pb);
+}
+
+// ------------------------------ Num Display -----------------------------------
+
+struct uiNumDisplay : public uiItem
+{
+    GtkLabel* fLabel;
+    int fPrecision;
+    
+    uiNumDisplay(GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, int precision) 
+            : uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
+
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        char s[64]; 
+        if (fPrecision <= 0) { 
+            snprintf(s, 63, "%d", int(v)); 
+        } else if (fPrecision>3) {
+            snprintf(s, 63, "%f", v);
+        } else {
+            const char* format[] = {"%.1f", "%.2f", "%.3f"};
+            snprintf(s, 63, format[fPrecision-1], v);
+        }
+        gtk_label_set_text(fLabel, s);
+    }
+};
+
+void GTKUI::addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision)
+{
+    GtkWidget* lw = gtk_label_new("");
+    new uiNumDisplay(this, zone, GTK_LABEL(lw), precision);
+    openFrameBox(label);
+    addWidget(label, lw);
+    closeBox();
+
+    checkForTooltip(zone, lw);
+}
+
+// ------------------------------ Text Display -----------------------------------
+
+struct uiTextDisplay : public uiItem
+{
+    GtkLabel*       fLabel;
+    const char**    fNames;
+    FAUSTFLOAT      fMin;
+    FAUSTFLOAT      fMax;
+    int             fNum;
+    
+    uiTextDisplay (GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, const char* names[], FAUSTFLOAT lo, FAUSTFLOAT hi)
+                    : uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi)
+    {
+        fNum = 0;
+        while (fNames[fNum] != 0) fNum++;
+    }
+
+    virtual void reflectZone()  
+    { 
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        
+        int idx = int(fNum*(v-fMin)/(fMax-fMin));
+        
+        if      (idx < 0)       idx = 0; 
+        else if (idx >= fNum)   idx = fNum-1;
+                
+        gtk_label_set_text(fLabel, fNames[idx]); 
+    }
+};
+    
+void GTKUI::addTextDisplay(const char* label, FAUSTFLOAT* zone, const char* names[], FAUSTFLOAT lo, FAUSTFLOAT hi)
+{
+    GtkWidget* lw = gtk_label_new("");
+    new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi);
+    openFrameBox(label);
+    addWidget(label, lw);
+    closeBox();
+
+    checkForTooltip(zone, lw);
+}
+
+void GTKUI::show() 
+{
+    assert(fTop == 0);
+    gtk_widget_show  (fBox[0]);
+    gtk_widget_show  (fWindow);
+}
+
+/**
+ * Update all user items reflecting zone z
+ */
+    
+static gboolean callUpdateAllGuis(gpointer)
+{ 
+    GUI::updateAllGuis(); 
+    return TRUE;
+}
+
+void GTKUI::run() 
+{
+    assert(fTop == 0);
+    gtk_widget_show  (fBox[0]);
+    gtk_widget_show  (fWindow);
+    gtk_timeout_add(40, callUpdateAllGuis, 0);
+    gtk_main ();
+    stop();
+}
+
+#endif
+
diff --git a/architecture/faust/gui/faustqt.h b/architecture/faust/gui/faustqt.h
new file mode 100644
index 0000000..96e9b02
--- /dev/null
+++ b/architecture/faust/gui/faustqt.h
@@ -0,0 +1,2109 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+ 
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __faustqt__
+#define __faustqt__
+
+#include <cassert>
+#include <cmath>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+#include <stack>
+
+#if defined(HTTPCTRL) && defined(QRCODECTRL) 
+
+#ifdef _WIN32
+#include <winsock2.h>
+#undef min
+#undef max
+#else
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#endif
+
+#include <QtNetwork>
+#include <qrencode.h>
+
+#endif
+
+#include <QtGlobal>
+#include <QtGui>
+#if QT_VERSION >= 0x050000
+#include <QtWidgets>
+#endif
+#include <QApplication>
+#include <QLabel>
+#include <QComboBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
+#include "faust/gui/GUI.h"
+#include "faust/gui/ValueConverter.h"
+#include "faust/gui/SimpleParser.h"
+
+#include <sstream>
+
+//#define STYLESHEET "QPushButton {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #B0B0B0, stop: 1 #404040); border: 2px solid grey; border-radius: 6px; margin-top: 1ex; } QPushButton:hover { border: 2px solid orange; } QPushButton:pressed { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #404040, stop: 1 #B0B0B0); } QGroupBox, QMainWindow { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020); border: 2px solid gray; border-radius: 5px; margin-top: 3ex; font-size:10pt; font-weight:bold; color: white; } QGroupBox::title, QMainWindow::title { subcontrol-origin: margin; subcontrol-position: top center; padding: 0 5px; } QSlider::groove:vertical { background: red; position: absolute; left: 13px; right: 13px; } QSlider::handle:vertical { height: 40px; width: 30px; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000); margin: 0 -5px; /* expand outside the groove */ border-radius: 5px; } QSlider::add-page:vertical { background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 yellow, stop : 0.5 orange); } QSlider::sub-page:vertical { background: grey; }  QSlider::groove:horizontal { background: red; position: absolute; top: 14px; bottom: 14px; }  QSlider::handle:horizontal { width: 40px; background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000); margin: -5px 0; border-radius: 5px; } QSlider::sub-page:horizontal { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 yellow, stop : 0.5 orange); } QSlider::add-page:horizontal { background: grey; }QTabWidget::pane {border-top: 2px solid orange; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020); } QTabWidget::tab-bar { left: 5px; }  QTabBar::tab { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #909090, stop: 0.4 #888888, stop: 0.5 #808080, stop: 1.0 #909090); border: 2px solid #808080; border-bottom-color: orange; border-top-left-radius: 4px; border-top-right-radius: 4px; min-width: 8ex; padding: 2px; }  QTabBar::tab:selected, QTabBar::tab:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D0D0D0, stop: 0.4 #A0A0A0, stop: 0.5 #808080, stop: 1.0 #A0A0A0); } QTabBar::tab:selected { border-color: orange; border-bottom-color: #A0A0A0; } QTabBar::tab:!selected { margin-top: 2px; }"
+//#define STYLESHEET ""
+//----------------------------------
+
+// for compatibility
+#define minValue minimum
+#define maxValue maximum
+
+static inline bool startWith(const std::string& str, const std::string& prefix)
+{
+    return (str.substr(0, prefix.size()) == prefix);
+}
+
+//==============================BEGIN QSYNTHKNOB=====================================
+//
+//   qsynthknob and qsynthDialVokiStyle borrowed from qsynth-0.3.3 by Rui Nuno Capela
+//   This widget is based on a design by Thorsten Wilms,
+//   implemented by Chris Cannam in Rosegarden,
+//   adapted for QSynth by Pedro Lopez-Cabanillas,
+//   improved for Qt4 by David Garcia Garzon.
+//
+
+#define DIAL_MIN      (0.25 * M_PI)
+#define DIAL_MAX      (1.75 * M_PI)
+#define DIAL_RANGE    (DIAL_MAX - DIAL_MIN)
+
+class qsynthDialVokiStyle : public QCommonStyle
+{
+public:
+	qsynthDialVokiStyle() {};
+	virtual ~qsynthDialVokiStyle() {};
+    
+    virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget = 0) const
+	{
+		if (cc != QStyle::CC_Dial)
+		{
+			QCommonStyle::drawComplexControl(cc, opt, p, widget);
+			return;
+		}
+        
+		const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt);
+		if (dial == NULL)
+			return;
+        
+		double angle = DIAL_MIN // offset
+        + (DIAL_RANGE *
+           (double(dial->sliderValue - dial->minimum) /
+            (double(dial->maximum - dial->minimum))));
+		int degrees = int(angle * 180.0 / M_PI);
+		int side = dial->rect.width() < dial->rect.height() ? dial->rect.width() : dial->rect.height();
+		int xcenter = dial->rect.width() / 2;
+		int ycenter = dial->rect.height() / 2;
+		int notchWidth   = 1 + side / 400;
+		int pointerWidth = 2 + side / 30;
+		int scaleShadowWidth = 1 + side / 100;
+		int knobBorderWidth = 0;
+		int ns = dial->tickInterval;
+		int numTicks = 1 + (dial->maximum + ns - dial->minimum) / ns;
+		int indent = int(0.15 * side) + 2;
+		int knobWidth = side - 2 * indent;
+		int shineFocus = knobWidth / 4;
+		int shineCenter = knobWidth / 5;
+		int shineExtension = shineCenter * 4;
+		int shadowShift = shineCenter * 2;
+		int meterWidth = side - 2 * scaleShadowWidth;
+        
+		QPalette pal = opt->palette;
+		QColor knobColor = pal.mid().color();
+		QColor borderColor = knobColor.light();
+		QColor meterColor = (dial->state & State_Enabled) ?
+        QColor("orange") : pal.mid().color();
+        // pal.highlight().color() : pal.mid().color();
+		QColor background = pal.window().color();
+        
+		p->save();
+		p->setRenderHint(QPainter::Antialiasing, true);
+        
+		// The bright metering bit...
+        
+		QConicalGradient meterShadow(xcenter, ycenter, -90);
+		meterShadow.setColorAt(0, meterColor.dark());
+		meterShadow.setColorAt(0.5, meterColor);
+		meterShadow.setColorAt(1.0, meterColor.light().light());
+		p->setBrush(meterShadow);
+		p->setPen(Qt::transparent);
+		p->drawPie(xcenter - meterWidth / 2, ycenter - meterWidth / 2,
+                   meterWidth, meterWidth, (180 + 45) * 16, -(degrees - 45) * 16);
+        
+		// Knob projected shadow
+		QRadialGradient projectionGradient(
+                                           xcenter + shineCenter, ycenter + shineCenter,
+                                           shineExtension,	xcenter + shadowShift, ycenter + shadowShift);
+		projectionGradient.setColorAt(0, QColor(  0, 0, 0, 100));
+		projectionGradient.setColorAt(1, QColor(200, 0, 0,  10));
+		QBrush shadowBrush(projectionGradient);
+		p->setBrush(shadowBrush);
+		p->drawEllipse(xcenter - shadowShift, ycenter - shadowShift,
+                       knobWidth, knobWidth);
+        
+		// Knob body and face...
+        
+		QPen pen;
+		pen.setColor(knobColor);
+		pen.setWidth(knobBorderWidth);
+		p->setPen(pen);
+        
+		QRadialGradient gradient(
+                                 xcenter - shineCenter, ycenter - shineCenter,
+                                 shineExtension,	xcenter - shineFocus, ycenter - shineFocus);
+		gradient.setColorAt(0.2, knobColor.light().light());
+		gradient.setColorAt(0.5, knobColor);
+		gradient.setColorAt(1.0, knobColor.dark(150));
+		QBrush knobBrush(gradient);
+		p->setBrush(knobBrush);
+		p->drawEllipse(xcenter - knobWidth / 2, ycenter - knobWidth / 2,
+                       knobWidth, knobWidth);
+        
+		// Tick notches...
+        
+		p->setBrush(Qt::NoBrush);
+        
+		if (dial->subControls & QStyle::SC_DialTickmarks)
+		{
+			pen.setColor(pal.dark().color());
+			pen.setWidth(notchWidth);
+			p->setPen(pen);
+			double hyp = double(side - scaleShadowWidth) / 2.0;
+			double len = hyp / 4;
+			for (int i = 0; i < numTicks; ++i) {
+				int div = numTicks;
+				if (div > 1) --div;
+				bool internal = (i != 0 && i != numTicks - 1);
+				double angle = DIAL_MIN
+                + (DIAL_MAX - DIAL_MIN) * i / div;
+				double dir = (internal ? -1 : len);
+				double sinAngle = sin(angle);
+				double cosAngle = cos(angle);
+				double x0 = xcenter - (hyp - len) * sinAngle;
+				double y0 = ycenter + (hyp - len) * cosAngle;
+				double x1 = xcenter - (hyp + dir) * sinAngle;
+				double y1 = ycenter + (hyp + dir) * cosAngle;
+				p->drawLine(QLineF(x0, y0, x1, y1));
+			}
+		}
+        
+		// Shadowing...
+        
+		// Knob shadow...
+		if (knobBorderWidth > 0) {
+			QLinearGradient inShadow(xcenter - side / 4, ycenter - side / 4,
+                                     xcenter + side / 4, ycenter + side / 4);
+			inShadow.setColorAt(0.0, borderColor.light());
+			inShadow.setColorAt(1.0, borderColor.dark());
+			p->setPen(QPen(QBrush(inShadow), knobBorderWidth * 7 / 8));
+			p->drawEllipse(xcenter - side / 2 + indent,
+                           ycenter - side / 2 + indent,
+                           side - 2 * indent, side - 2 * indent);
+		}
+        
+		// Scale shadow...
+		QLinearGradient outShadow(xcenter - side / 3, ycenter - side / 3,
+                                  xcenter + side / 3, ycenter + side / 3);
+		outShadow.setColorAt(0.0, background.dark().dark());
+		outShadow.setColorAt(1.0, background.light().light());
+		p->setPen(QPen(QBrush(outShadow), scaleShadowWidth));
+		p->drawArc(xcenter - side / 2 + scaleShadowWidth / 2,
+                   ycenter - side / 2 + scaleShadowWidth / 2,
+                   side - scaleShadowWidth, side - scaleShadowWidth, -45 * 16, 270 * 16);
+        
+		// Pointer notch...
+        
+		double hyp = double(side) / 2.0;
+		double len = hyp - indent - 1;
+        
+		double x = xcenter - len * sin(angle);
+		double y = ycenter + len * cos(angle);
+        
+		QColor pointerColor = pal.dark().color();
+		pen.setColor((dial->state & State_Enabled) ? pointerColor.dark(140) : pointerColor);
+		pen.setWidth(pointerWidth + 2);
+		p->setPen(pen);
+		p->drawLine(QLineF(xcenter, ycenter, x, y));
+		pen.setColor((dial->state & State_Enabled) ? pointerColor.light() : pointerColor.light(140));
+		pen.setWidth(pointerWidth);
+		p->setPen(pen);
+		p->drawLine(QLineF(xcenter - 1, ycenter - 1, x - 1, y - 1));
+        
+		// done
+		p->restore();
+	}
+    
+};
+
+//
+//===============================END QSYNTHKNOB======================================
+
+
+//==============================BEGIN DISPLAYS===================================
+//
+// This section constains displays, passive QT widgets that displays values in
+// different ways, in particular bargraphs
+//
+
+/**
+ * An abstract widget that display a value in a range
+ */
+class AbstractDisplay : public QWidget
+{
+    protected :
+    
+    FAUSTFLOAT fMin;
+    FAUSTFLOAT fMax;
+    FAUSTFLOAT fValue;
+    
+public:
+    
+    AbstractDisplay(FAUSTFLOAT lo, FAUSTFLOAT hi) : fMin(lo), fMax(hi), fValue(lo)
+    {}
+    
+    /**
+     * set the range of displayed values
+     */
+    virtual void setRange(FAUSTFLOAT lo, FAUSTFLOAT hi)
+    {
+        fMin = lo;
+        fMax = hi;
+    }
+    
+    /**
+     * set the value to be displayed
+     */
+    virtual void setValue(FAUSTFLOAT v)
+    {
+        if (v < fMin)       v = fMin;
+        else if (v > fMax)  v = fMax;
+        
+        if (v != fValue) {
+            fValue = v;
+            update();
+        }
+    }
+};
+
+/**
+ * Displays dB values using a scale of colors
+ */
+class dbAbstractDisplay : public AbstractDisplay
+{
+    protected :
+    
+    FAUSTFLOAT      fScaleMin;
+    FAUSTFLOAT      fScaleMax;
+    std::vector<int>     fLevel;
+    std::vector<QBrush>  fBrush;
+    
+    
+    /**
+     * Convert a dB value into a scale between 0 and 1 (following IEC standard ?)
+     */
+    FAUSTFLOAT dB2Scale(FAUSTFLOAT dB) const
+    {
+        FAUSTFLOAT fScale = 1.0;
+        
+        /*if (dB < -70.0f)
+         fScale = 0.0f;
+         else*/ if (dB < -60.0)
+             fScale = (dB + 70.0) * 0.0025;
+         else if (dB < -50.0)
+             fScale = (dB + 60.0) * 0.005 + 0.025;
+         else if (dB < -40.0)
+             fScale = (dB + 50.0) * 0.0075 + 0.075;
+         else if (dB < -30.0)
+             fScale = (dB + 40.0) * 0.015 + 0.15;
+         else if (dB < -20.0)
+             fScale = (dB + 30.0) * 0.02 + 0.3;
+         else if (dB < -0.001 || dB > 0.001)  /* if (dB < 0.0) */
+             fScale = (dB + 20.0f) * 0.025 + 0.5;
+        
+        return fScale;
+    }
+    
+    /**
+     * Create the scale of colors used to paint the bargraph in relation to the levels
+     * The parameter x indicates the direction of the gradient. x=1 means an horizontal
+     * gradient typically used by a vertical bargraph, and x=0 a vertical gradient.
+     */
+    void initLevelsColors(int x)
+    {
+        int alpha = 200;
+        { // level until -10 dB
+            QColor c(40, 160, 40, alpha);
+            QLinearGradient g(0,0,x,1-x);
+            g.setCoordinateMode(QGradient::ObjectBoundingMode);
+            g.setColorAt(0.0,   c.lighter());
+            g.setColorAt(0.2,   c);
+            g.setColorAt(0.8,   c);
+            g.setColorAt(0.9,   c.darker(120));
+            
+            fLevel.push_back(-10);
+            fBrush.push_back(QBrush(g));
+        }
+        
+        { // level until -6 dB
+            QColor c(160, 220, 20, alpha);
+            QLinearGradient g(0,0,x,1-x);
+            g.setCoordinateMode(QGradient::ObjectBoundingMode);
+            g.setColorAt(0.0,   c.lighter());
+            g.setColorAt(0.2,   c);
+            g.setColorAt(0.8,   c);
+            g.setColorAt(0.9,   c.darker(120));
+            
+            fLevel.push_back(-6);
+            fBrush.push_back(QBrush(g));
+        }
+        
+        { // level until -3 dB
+            QColor c(220, 220, 20, alpha);
+            QLinearGradient g(0,0,x,1-x);
+            g.setCoordinateMode(QGradient::ObjectBoundingMode);
+            g.setColorAt(0.0,   c.lighter());
+            g.setColorAt(0.2,   c);
+            g.setColorAt(0.8,   c);
+            g.setColorAt(0.9,   c.darker(120));
+            
+            fLevel.push_back(-3);
+            fBrush.push_back(QBrush(g));
+        }
+        
+        { // level until -0 dB
+            QColor c(240, 160, 20, alpha);
+            QLinearGradient g(0,0,x,1-x);
+            g.setCoordinateMode(QGradient::ObjectBoundingMode);
+            g.setColorAt(0.0,   c.lighter());
+            g.setColorAt(0.2,   c);
+            g.setColorAt(0.8,   c);
+            g.setColorAt(0.9,   c.darker(120));
+            
+            fLevel.push_back(0);
+            fBrush.push_back(QBrush(g));
+        }
+        
+        { // until 10 dB (and over because last one)
+            QColor c(240,  0, 20, alpha);   // ColorOver
+            QLinearGradient g(0,0,x,1-x);
+            g.setCoordinateMode(QGradient::ObjectBoundingMode);
+            g.setColorAt(0.0,   c.lighter());
+            g.setColorAt(0.2,   c);
+            g.setColorAt(0.8,   c);
+            g.setColorAt(0.9,   c.darker(120));
+            
+            fLevel.push_back(+10);
+            fBrush.push_back(QBrush(g));
+        }
+        
+    }
+    
+public:
+    
+    dbAbstractDisplay(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo, hi)
+    {}
+    
+    /**
+     * set the range of displayed values
+     */
+    virtual void setRange(FAUSTFLOAT lo, FAUSTFLOAT hi)
+    {
+        AbstractDisplay::setRange(lo, hi);
+        fScaleMin = dB2Scale(fMin);
+        fScaleMax = dB2Scale(fMax);
+    }
+};
+
+/**
+ * Small rectangular LED display which color changes with the level in dB
+ */
+class dbLED : public dbAbstractDisplay
+{
+protected:
+    
+    /**
+     * Draw the LED using a color depending of its value in dB
+     */
+    virtual void paintEvent ( QPaintEvent *)
+    {
+        QPainter painter(this);
+        painter.drawRect(rect());
+        
+        if (fValue <= fLevel[0]) {
+            
+            // interpolate the first color on the alpha channel
+            QColor c(40, 160, 40) ;
+            FAUSTFLOAT a = (fValue-fMin)/(fLevel[0]-fMin);
+            c.setAlphaF(a);
+            painter.fillRect(rect(), c);
+            
+        } else {
+            
+            // find the minimal level > value
+            int l = fLevel.size()-1; while (fValue < fLevel[l] && l > 0) l--;
+            painter.fillRect(rect(), fBrush[l]);
+        }
+    }
+    
+public:
+    
+    dbLED(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbAbstractDisplay(lo,hi)
+    {
+        setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+        initLevelsColors(1);
+    }
+    
+    virtual QSize sizeHint () const
+    {
+        return QSize(16, 8);
+    }
+};
+
+/**
+ * Small rectangular LED display which intensity (alpha channel) changes according to the value
+ */
+class LED : public AbstractDisplay
+{
+    QColor  fColor;
+    
+protected:
+    
+    /**
+     * Draw the LED using a transparency depending of its value
+     */
+    virtual void paintEvent ( QPaintEvent *)
+    {
+        QPainter painter(this);
+        painter.drawRect(rect());
+        // interpolate the first color on the alpha channel
+        QColor c = fColor ;
+        FAUSTFLOAT a = (fValue-fMin)/(fMax-fMin);
+        c.setAlphaF(a);
+        painter.fillRect(rect(), c);
+    }
+    
+public:
+    
+    LED(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo,hi), fColor("yellow")
+    {
+        setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+    }
+    
+    virtual QSize sizeHint () const
+    {
+        return QSize(16, 8);
+    }
+};
+
+/**
+ * A simple bargraph that detect automatically its direction
+ */
+class linBargraph : public AbstractDisplay
+{
+    protected :
+    QBrush  fBrush;
+    
+    /**
+     * No scale implemented yet
+     */
+    void paintScale(QPainter* painter) const
+    {
+        painter->drawRect(0,0,width(),height());
+    }
+    
+    /**
+     * The length of the rectangle is proportional to the value
+     */
+    void paintContent (QPainter* painter) const
+    {
+        int     w = width();
+        int     h = height();
+        FAUSTFLOAT   v = (fValue-fMin)/(fMax-fMin);
+        
+        if (h>w) {
+            // draw vertical rectangle
+            painter->fillRect(0,(1-v)*h,w, v*h, fBrush);
+        } else {
+            // draw horizontal rectangle
+            painter->fillRect(0, 0, v*w, h, fBrush);
+        }
+        
+    }
+    
+    virtual void paintEvent ( QPaintEvent *)
+    {
+        QPainter painter(this);
+        paintContent(&painter);
+        paintScale(&painter);
+    }
+    
+public:
+    
+    linBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo,hi)
+    {
+        // compute the brush that will be used to
+        // paint the value
+        QColor c(0xffa500);                 // orange
+        int x = int(height() < width());    // gradient direction
+        QLinearGradient g(0,0,x,1-x);
+        g.setCoordinateMode(QGradient::ObjectBoundingMode);
+        g.setColorAt(0.0,   c.lighter());
+        g.setColorAt(0.2,   c);
+        g.setColorAt(0.8,   c);
+        g.setColorAt(0.9,   c.darker(120));
+        fBrush = QBrush(g);
+    }
+};
+
+/**
+ * A simple vertical bargraph
+ */
+class linVerticalBargraph : public linBargraph
+{
+public:
+    
+    linVerticalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : linBargraph(lo,hi)
+    {
+        setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+    }
+    
+    virtual QSize sizeHint () const
+    {
+        return QSize(16, 128);
+    }
+};
+
+/**
+ * A simple horizontal bargraph
+ */
+class linHorizontalBargraph : public linBargraph
+{
+public:
+    
+    linHorizontalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : linBargraph(lo,hi)
+    {
+        setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+    }
+    
+    virtual QSize sizeHint () const
+    {
+        return QSize(128, 16);
+    }
+};
+
+/**
+ * A dB Bargraph with a scale of colors
+ */
+class dbBargraph : public dbAbstractDisplay
+{
+    QBrush  fBackColor;
+    
+    protected :
+    
+    // These two abstract methods are implemented
+    // according to the vertical or horizontal direction
+    // in dbVerticalBargraph and dbHorizontalBargraph
+    virtual void paintMark(QPainter* painter, FAUSTFLOAT v) const = 0;
+    virtual int paintSegment (QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const = 0;
+    
+    /**
+     * Draw the logarithmic scale
+     */
+    void paintScale(QPainter* painter) const
+    {
+        painter->fillRect(0,0,width(),height(), fBackColor);
+        painter->save();
+        painter->setPen(QColor(0x6699aa)); //0xffa500));
+        for (FAUSTFLOAT v = -10; v > fMin; v -= 10) paintMark(painter, v);
+        for (FAUSTFLOAT v = -6; v < fMax; v += 3) paintMark(painter, v);
+        painter->restore();
+    }
+    
+    /**
+     * Draw the content using colored segments
+     */
+    void paintContent (QPainter* painter) const
+    {
+        int   l = fLevel.size();
+        
+        FAUSTFLOAT   p = -1;   // fake value indicates to start from border
+        int     n = 0;
+        // paint all the full segments < fValue
+        for (n=0; (n < l) && (fValue > fLevel[n]); n++) {
+            p = paintSegment(painter, p, fLevel[n], fBrush[n]);
+        }
+        // paint the last segment
+        if (n == l) n = n-1;
+        p=paintSegment(painter, p, fValue, fBrush[n]);
+        
+        painter->drawRect(0,0,width(),height());
+    }
+    
+    
+    virtual void paintEvent ( QPaintEvent *)
+    {
+        QPainter painter(this);
+        paintScale(&painter);
+        paintContent(&painter);
+    }
+    
+public:
+    
+    dbBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbAbstractDisplay(lo,hi)
+    {
+        
+        QFont f = this->font();
+        f.setPointSize(6);
+        this->setFont(f);
+        
+        fBackColor = QBrush(QColor(20,20,20));
+    }
+};
+
+/**
+ * Vertical dB Bargraph
+ */
+class dbVerticalBargraph : public dbBargraph
+{
+protected:
+    /**
+     * Convert a dB value into a vertical position
+     */
+    FAUSTFLOAT dB2y(FAUSTFLOAT dB) const
+    {
+        FAUSTFLOAT s0 = fScaleMin;
+        FAUSTFLOAT s1 = fScaleMax;
+        FAUSTFLOAT sx = dB2Scale(dB);
+        int    h = height();
+        
+        return h - h*(s0-sx)/(s0-s1);
+    }
+    
+    /**
+     * Paint a vertical graduation mark
+     */
+    virtual void paintMark(QPainter* painter, FAUSTFLOAT v) const
+    {
+        int n = 10;
+        int y = dB2y(v);
+        QRect r(0,y-n,width()-1,2*n);
+        if (v > 0.0) {
+            painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v).prepend('+'));
+        } else {
+            painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v));
+        }
+    }
+    
+    /**
+     * Paint a color segment
+     */
+    virtual int paintSegment(QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const
+    {
+        if (pos == -1) pos = height();
+        FAUSTFLOAT y = dB2y(v);
+        painter->fillRect(0, y, width(), pos-y+1, b);
+        return y;
+    }
+    
+    
+public:
+    
+    dbVerticalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbBargraph(lo,hi)
+    {
+        setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+        initLevelsColors(1);
+    }
+    
+    virtual QSize sizeHint () const
+    {
+        return QSize(18, 256);
+    }
+};
+
+/**
+ * Horizontal dB Bargraph
+ */
+class dbHorizontalBargraph : public dbBargraph
+{
+    
+protected:
+    
+    /**
+     * Convert a dB value into an horizontal position
+     */
+    FAUSTFLOAT dB2x(FAUSTFLOAT dB) const
+    {
+        FAUSTFLOAT s0 = fScaleMin;
+        FAUSTFLOAT s1 = fScaleMax;
+        FAUSTFLOAT sx = dB2Scale(dB);
+        int    w = width();
+        
+        return w - w*(s1-sx)/(s1-s0);
+    }
+    
+    /**
+     * Paint an horizontal graduation mark
+     */
+    void paintMark(QPainter* painter, FAUSTFLOAT v) const
+    {
+        int n = 10;
+        int x = dB2x(v);
+        QRect r(x-n,0,2*n, height());
+        painter->drawText(r, Qt::AlignHCenter|Qt::AlignVCenter, QString::number(v));
+    }
+    
+    /**
+     * Paint a horizontal color segment
+     */
+    int paintSegment (QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const
+    {
+        if (pos == -1) pos = 0;
+        FAUSTFLOAT x = dB2x(v);
+        painter->fillRect(pos, 0, x-pos, height(), b);
+        return x;
+    }
+    
+    
+public:
+    
+    dbHorizontalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbBargraph(lo,hi)
+    {
+        setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+        initLevelsColors(0);
+    }
+    
+    virtual QSize sizeHint () const
+    {
+        return QSize(256, 18);
+    }
+    
+};
+
+//
+//===============================END DISPLAYS====================================
+
+//============================= BEGIN GROUP LABEL METADATA===========================
+// Unlike widget's label, metadata inside group's label are not extracted directly by
+// the Faust compiler. Therefore they must be extracted within the architecture file
+//-----------------------------------------------------------------------------------
+//
+
+/**
+ * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string
+ * (but not those in the middle of the string)
+ */
+static std::string rmWhiteSpaces(const std::string& s)
+{
+    size_t i = s.find_first_not_of(" \t");
+    size_t j = s.find_last_not_of(" \t");
+  	if ( (i != std::string::npos) && (j != std::string::npos) ) {
+		return s.substr(i, 1+j-i);
+	} else {
+		return "";
+	}
+}
+
+/**
+ * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata(unit=dB)
+ */
+static void extractMetadata(const std::string& fulllabel, std::string& label, std::map<std::string, std::string>& metadata)
+{
+    enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
+    int state = kLabel; int deep = 0;
+    std::string key, value;
+    
+    for (unsigned int i=0; i < fulllabel.size(); i++) {
+        char c = fulllabel[i];
+        switch (state) {
+            case kLabel :
+                assert (deep == 0);
+                switch (c) {
+                    case '\\' : state = kEscape1; break;
+                    case '[' : state = kKey; deep++; break;
+                    default : label += c;
+                }
+                break;
+                
+            case kEscape1 :
+                label += c;
+                state = kLabel;
+                break;
+                
+            case kEscape2 :
+                key += c;
+                state = kKey;
+                break;
+                
+            case kEscape3 :
+                value += c;
+                state = kValue;
+                break;
+                
+            case kKey :
+                assert (deep > 0);
+                switch (c) {
+                    case '\\' :  state = kEscape2;
+                        break;
+                        
+                    case '[' :  deep++;
+                        key += c;
+                        break;
+                        
+                    case ':' :  if (deep == 1) {
+                        state = kValue;
+                    } else {
+                        key += c;
+                    }
+                        break;
+                    case ']' :  deep--;
+                        if (deep < 1) {
+                            metadata[rmWhiteSpaces(key)] = "";
+                            state = kLabel;
+                            key="";
+                            value="";
+                        } else {
+                            key += c;
+                        }
+                        break;
+                    default :   key += c;
+                }
+                break;
+                
+            case kValue :
+                assert (deep > 0);
+                switch (c) {
+                    case '\\' : state = kEscape3;
+                        break;
+                        
+                    case '[' :  deep++;
+                        value += c;
+                        break;
+                        
+                    case ']' :  deep--;
+                        if (deep < 1) {
+                            metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value);
+                            state = kLabel;
+                            key="";
+                            value="";
+                        } else {
+                            value += c;
+                        }
+                        break;
+                    default :   value += c;
+                }
+                break;
+                
+            default :
+                std::cerr << "ERROR unrecognized state " << state << std::endl;
+        }
+    }
+    label = rmWhiteSpaces(label);
+}
+
+//
+//============================= END GROUP LABEL METADATA===========================
+
+
+/******************************************************************************
+ *******************************************************************************
+ 
+ IMPLEMENTATION OF GUI ITEMS
+ (QT 4.3 for FAUST)
+ 
+ *******************************************************************************
+ *******************************************************************************/
+
+
+/**
+ * A push button that controls/reflects the value (O/1)
+ * of a zone.
+ */
+class uiButton : public QObject, public uiItem
+{
+    Q_OBJECT
+    
+    public :
+	QAbstractButton* 	fButton;
+    
+	uiButton (GUI* ui, FAUSTFLOAT* zone, QAbstractButton* b) : uiItem(ui, zone), fButton(b) {}
+    
+    
+	virtual void reflectZone()
+	{
+		FAUSTFLOAT v = *fZone;
+		fCache = v;
+		fButton->setDown( v > 0.0 );
+	}
+    
+    public slots :
+	void pressed()		{ modifyZone(1.0); }
+	void released()		{ modifyZone(0.0); }
+};
+
+
+/**
+ * A checkbox that controls/reflects the value (O/1)
+ * of a zone.
+ */
+class uiCheckButton : public QObject, public uiItem
+{
+    Q_OBJECT
+    
+    public :
+	QCheckBox* 	fCheckBox;
+    
+	uiCheckButton (GUI* ui, FAUSTFLOAT* zone, QCheckBox* b) : uiItem(ui, zone), fCheckBox(b) {}
+    
+	virtual void reflectZone()
+	{
+		FAUSTFLOAT v = *fZone;
+		fCache = v;
+		fCheckBox->setCheckState( (v < 0.5) ? Qt::Unchecked : Qt::Checked );
+	}
+    
+    public slots :
+	void setState(int v)		{ modifyZone(FAUSTFLOAT(v>0)); }
+};
+
+
+
+/**
+ * A slider that controls/reflects the value (min..max)
+ * of a zone.
+ */
+class uiSlider : public QObject, public uiItem
+{
+    Q_OBJECT
+    
+    public :
+    QAbstractSlider* 	fSlider;
+    FAUSTFLOAT			fCur;
+    FAUSTFLOAT			fMin;
+    FAUSTFLOAT			fMax;
+    FAUSTFLOAT			fStep;
+	ValueConverter*		fConverter;
+    
+	enum Scale {
+		kLin,
+		kLog,
+		kExp
+	};
+    
+    public :
+    
+    uiSlider (GUI* ui, FAUSTFLOAT* zone, QAbstractSlider* slider, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step, Scale scale)
+    : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step)
+    {
+		// select appropriate converter according to scale mode
+		if (scale == kLog) 			{ fConverter = new LogValueConverter(0, 10000, fMin, fMax); }
+		else if (scale == kExp) 	{ fConverter = new ExpValueConverter(0, 10000, fMin, fMax); }
+        else 						{ fConverter = new LinearValueConverter(0, 10000, fMin, fMax); }
+        
+        fSlider->setMinimum(0);
+        fSlider->setMaximum(10000);
+        fSlider->setValue(int(0.5+fConverter->faust2ui(fCur)));
+        *fZone = fCur;
+    }
+    
+	~uiSlider() 
+	{
+		if (fConverter) delete fConverter;
+	}
+    
+    virtual void reflectZone()
+    {
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        fSlider->setValue(fConverter->faust2ui(v));
+    }
+    
+    public slots :
+    void setValue(int v)		{ modifyZone(fConverter->ui2faust(v)); }
+};
+
+
+/**
+ * A zone setter, an object that sets a zone with a predefined value
+ * every time the set(bool) method is called. The boolean parameter
+ * is here for compatibility with some signals and is ignored.
+ */
+class ZoneSetter : public QObject
+{
+    Q_OBJECT
+    FAUSTFLOAT  fValue;
+    FAUSTFLOAT* fZone;
+public:
+    explicit ZoneSetter(FAUSTFLOAT v, FAUSTFLOAT* z, QObject *parent = 0):
+    QObject(parent), fValue(v), fZone(z)
+    {}
+    
+    public slots:
+    void set(bool){
+        *fZone = fValue;
+        //        qDebug() << "setting " << fValue << " --> " << fZone;
+    }
+};
+
+
+/**
+ * A set of mutually exclusive radio buttons vertically
+ * layed out. The names and values used for the radio buttons
+ * are described in the string mdescr with the following syntax
+ * "{'foo':3.14; 'faa':-0.34; ... 'fii':10.5}"
+ */
+class uiRadioButtons : public QGroupBox, public uiItem
+{
+    Q_OBJECT
+    vector<double>          fValues;
+    vector<QRadioButton*>   fButtons;
+    
+    public :
+    
+    uiRadioButtons (GUI* ui, FAUSTFLOAT* z, const char* label,
+                    FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT /*step*/,
+                    bool vertical, const char* mdescr, QWidget* parent)
+    : QGroupBox(label, parent),  uiItem(ui, z)
+    {
+        vector<string>  names;
+        vector<double>  values;
+        
+        if (parseMenuList(mdescr, names, values)) {
+            
+            QBoxLayout*    l;
+            if (vertical) {
+                l = new QVBoxLayout(this);
+            } else {
+                l = new QHBoxLayout(this);
+            }
+            l->setSpacing(5);
+            
+            QRadioButton*   defaultbutton = 0;
+            double          mindelta = FLT_MAX;
+            
+            for (unsigned int i = 0; i < names.size(); i++) {
+                double v = values[i];
+                if ( (v >= lo) && (v <= hi) ) {
+                    
+                    // It is a valid value included in slider's range
+                    QRadioButton*   b = new QRadioButton(QString(names[i].c_str()), this);
+                    ZoneSetter*     s = new ZoneSetter(v,z,b);
+                    fValues.push_back(v);
+                    fButtons.push_back(b);
+                    connect(b,SIGNAL(clicked(bool)), s, SLOT(set(bool)));
+                    l->addWidget(b);
+                    
+                    // Check if this item is a good candidate to represent the current value
+                    double delta = fabs(cur-v);
+                    if (delta < mindelta) {
+                        mindelta = delta;
+                        defaultbutton = b;
+                    }
+                }
+            }
+            // check the best candidate to represent the current value
+            if (defaultbutton) { defaultbutton->setChecked(true); }
+            setLayout(l);
+        }
+        *fZone = cur;
+    }
+    
+    virtual void reflectZone()
+    {
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        
+        // select closest value
+        int             defaultitem = -1;
+        double          mindelta = FLT_MAX;
+        
+        for (unsigned int i=0; i<fValues.size(); i++) {
+            double delta = fabs(fValues[i]-v);
+            if (delta < mindelta) {
+                mindelta = delta;
+                defaultitem = i;
+            }
+        }
+        if (defaultitem > -1) { fButtons[defaultitem]->setChecked(true); }
+    }
+};
+
+
+
+
+/**
+ * A popup menu. The names and values used for the menu items
+ * are described in the string mdescr with the following syntax
+ * "{'foo':3.14; 'faa':-0.34; ... 'fii':10.5}"
+ */
+class uiMenu : public QComboBox, public uiItem
+{
+    Q_OBJECT
+    vector<double>  fValues;
+    
+    public :
+    
+    uiMenu (GUI* ui, FAUSTFLOAT* z, const char* /*label*/,
+            FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT /*step*/,
+            const char* mdescr, QWidget* parent)
+    : QComboBox(parent),  uiItem(ui, z)
+    {
+        vector<string>  names;
+        vector<double>  values;
+        
+        if (parseMenuList(mdescr, names, values)) {
+            
+            int     defaultitem = -1;
+            double  mindelta = FLT_MAX;
+            
+            for (unsigned int i = 0; i < names.size(); i++) {
+                double v = values[i];
+                if ( (v >= lo) && (v <= hi) ) {
+                    
+                    // It is a valid value : add corresponding menu item
+                    addItem(QString(names[i].c_str()), v);
+                    fValues.push_back(v);
+                    
+                    // Check if this item is a good candidate to represent the current value
+                    double delta = fabs(cur-v);
+                    if (delta < mindelta) {
+                        mindelta = delta;
+                        defaultitem = count()-1;
+                    }
+                }
+            }
+            // check the best candidate to represent the current value
+            if (defaultitem > -1) { setCurrentIndex(defaultitem); }
+        }
+        connect(this,SIGNAL(activated(int)), this, SLOT(updateZone(int)));
+        *fZone = cur;
+    }
+    
+    virtual void reflectZone()
+    {
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        
+        // search closest value
+        int             defaultitem = -1;
+        double          mindelta = FLT_MAX;
+        
+        for (unsigned int i=0; i<fValues.size(); i++) {
+            double delta = fabs(fValues[i]-v);
+            if (delta < mindelta) {
+                mindelta = delta;
+                defaultitem = i;
+            }
+        }
+        if (defaultitem > -1) { setCurrentIndex(defaultitem); }
+    }
+    
+    public slots :
+    
+    void updateZone(int)
+    {
+        double x = itemData(currentIndex()).toDouble();
+        *fZone = x;
+    }
+};
+
+
+
+
+/**
+ * A bargraph representing the value of a zone
+ */
+class uiBargraph : public QObject, public uiItem
+{
+    Q_OBJECT
+    
+    public :
+    AbstractDisplay*   fBar;
+    
+    uiBargraph (GUI* ui, FAUSTFLOAT* zone, AbstractDisplay* bar, FAUSTFLOAT lo, FAUSTFLOAT hi)
+    : uiItem(ui, zone), fBar(bar)
+    {
+        fBar->setRange(lo, hi);
+        fBar->setValue(lo);
+        *fZone = lo;
+    }
+    
+    virtual void reflectZone()
+    {
+        FAUSTFLOAT v = *fZone;
+        fCache = v;
+        fBar->setValue(v);
+    }
+};
+
+
+/**
+ * A numerical entry that controls/reflects the value (min..max)
+ * of a zone.
+ */
+class uiNumEntry : public QObject, public uiItem
+{
+    Q_OBJECT
+    
+    public :
+	QDoubleSpinBox* 	fNumEntry;
+	FAUSTFLOAT			fCur;
+	FAUSTFLOAT			fMin;
+	FAUSTFLOAT			fMax;
+	FAUSTFLOAT			fStep;
+	int					fDecimals;
+    
+	uiNumEntry (GUI* ui, FAUSTFLOAT* zone, QDoubleSpinBox* numEntry, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step)
+    : uiItem(ui, zone), fNumEntry(numEntry), fCur(cur), fMin(lo), fMax(hi), fStep(step)
+	{
+		fDecimals = (fStep >= 1.0) ? 0 : int(0.5+log10(1.0/fStep));
+        
+		fNumEntry->setMinimum(fMin);
+		fNumEntry->setMaximum(fMax);
+		fNumEntry->setSingleStep(fStep);
+		fNumEntry->setDecimals(fDecimals);
+		fNumEntry->setValue(fCur);
+		*fZone = fCur;
+	}
+    
+    
+	virtual void reflectZone()
+	{
+		FAUSTFLOAT v = *fZone;
+		fCache = v;
+		fNumEntry->setValue(v);
+	}
+    
+    public slots :
+	void setValue(double v)		{
+		modifyZone(FAUSTFLOAT(v));
+	}
+};
+
+/******************************************************************************
+ *******************************************************************************
+ 
+ IMPLEMENTATION OF THE USER INTERFACE
+ (QT 4.3 for FAUST)
+ 
+ *******************************************************************************
+ *******************************************************************************/
+
+class QTGUI : public QWidget, public GUI
+{
+    Q_OBJECT
+    
+	QTimer*                 fTimer;
+    std::string				gGroupTooltip;
+    std::stack<QWidget* > 	fGroupStack;
+    
+    QMainWindow*            fMainWindow;
+    QVBoxLayout*            fGeneralLayout;
+    
+    QPixmap                 fQrCode;
+    
+    std::map<FAUSTFLOAT*, FAUSTFLOAT>      fGuiSize;            // map widget zone with widget size coef
+    std::map<FAUSTFLOAT*, std::string>     fTooltip;            // map widget zone with tooltip strings
+    std::map<FAUSTFLOAT*, std::string>     fUnit;               // map widget zone to unit string (i.e. "dB")
+    std::map<FAUSTFLOAT*, std::string>     fRadioDescription;   // map zone to {'low':440; ...; 'hi':1000.0}
+    std::map<FAUSTFLOAT*, std::string>     fMenuDescription;    // map zone to {'low':440; ...; 'hi':1000.0}
+    std::set<FAUSTFLOAT*>                  fKnobSet;            // set of widget zone to be knobs
+    std::set<FAUSTFLOAT*>                  fLedSet;             // set of widget zone to be LEDs
+    std::set<FAUSTFLOAT*>                  fNumSet;             // set of widget zone to be numerical bargraphs
+    std::set<FAUSTFLOAT*>                  fLogSet;             // set of widget zone having a log UI scale
+    std::set<FAUSTFLOAT*>                  fExpSet;             // set of widget zone having an exp UI scale
+    
+    void clearMetadata()
+    {
+        fGuiSize.clear();
+        fTooltip.clear();
+        fUnit.clear();
+        fRadioDescription.clear();
+        fMenuDescription.clear();
+        fKnobSet.clear();
+        fLedSet.clear();
+        fNumSet.clear();
+        fLogSet.clear();
+        fExpSet.clear();
+    }
+    
+    /**
+     * Format tooltip string by replacing some white spaces by
+     * return characters so that line width doesn't exceed n.
+     * Limitation : long words exceeding n are not cut
+     */
+	virtual std::string formatTooltip(int n, const std::string& tt)
+	{
+		std::string  ss = tt;	// ss string we are going to format
+		int	lws = 0;	// last white space encountered
+		int 	lri = 0;	// last return inserted
+		for (int i=0; i< (int)tt.size(); i++) {
+			if (tt[i] == ' ') lws = i;
+			if (((i-lri) >= n) && (lws > lri)) {
+				// insert return here
+				ss[lws] = '\n';
+				lri = lws;
+			}
+		}
+		return ss;
+	}
+    
+	bool isTabContext()
+	{
+		//return fGroupStack.empty() || ((!fGroupStack.empty()) && (dynamic_cast<QTabWidget*>(fGroupStack.top()) != 0));
+		return ((!fGroupStack.empty()) && (dynamic_cast<QTabWidget*>(fGroupStack.top()) != 0));
+	}
+    
+    
+    /**
+     * Insert a widget into the parent widget (the top of
+     * the stack group). The label is used if this group is
+     * a tab.
+     */
+    
+    void insert(const char* label, QWidget* widget)
+	{
+        if (!fGroupStack.empty()) {
+			QWidget* mother = fGroupStack.top();
+			QTabWidget*	tab = dynamic_cast<QTabWidget*>(mother);
+			if (tab) {
+				tab->addTab(widget,label);
+			} else {
+				widget->setParent(mother);
+				mother->layout()->addWidget(widget);
+			}
+		}
+	}
+    
+    /**
+     * Analyses a full label and activates the relevant options. returns a simplified
+     * label (without options) and an amount of stack adjustement (in case additional
+     * containers were pushed on the stack).
+     */
+    
+    int checkLabelOptions(QWidget* widget, const std::string& fullLabel, std::string& simplifiedLabel)
+    {
+        std::map<std::string, std::string> metadata;
+        extractMetadata(fullLabel, simplifiedLabel, metadata);
+        
+        if (metadata.count("tooltip")) {
+            widget->setToolTip(metadata["tooltip"].c_str());
+        }
+        if (metadata["option"] == "detachable") {
+            //openHandleBox(simplifiedLabel.c_str());
+            return 1;
+        }
+        
+        // no adjustement of the stack needed
+        return 0;
+    }
+    
+    /**
+     * Check if a tooltip is associated to a zone and add it to the corresponding widget
+     */
+    void checkForTooltip(FAUSTFLOAT* zone, QWidget* widget)
+    {
+        if (fTooltip.count(zone)) {
+            widget->setToolTip(fTooltip[zone].c_str());
+        }
+    }
+    
+    /**
+     * Check if a log scale is required
+     */
+    uiSlider::Scale getScale(FAUSTFLOAT* zone)
+    {
+        if (fLogSet.count(zone) > 0) return uiSlider::kLog;
+		if (fExpSet.count(zone) > 0) return uiSlider::kExp;
+		return uiSlider::kLin;
+    }
+    
+    /**
+     * Check if a knob is required
+     */
+    bool isKnob(FAUSTFLOAT* zone)
+    {
+        return fKnobSet.count(zone) > 0;
+    }
+    
+	void openBox(const char* fulllabel, QLayout* layout)
+	{
+        std::map<std::string, std::string> metadata;
+        std::string label;
+        extractMetadata(fulllabel, label, metadata);
+  		layout->setMargin(5);
+		QWidget* box;
+        
+        label = startWith(label, "0x") ? "" : label;
+        
+        if(fGroupStack.empty())
+        {
+            if (isTabContext()) {
+                box = new QWidget(this);
+                // set background color
+                QPalette pal = box->palette();
+                pal.setColor(box->backgroundRole(), QColor::fromRgb(150, 150, 150));
+                box->setPalette(pal);
+                
+            } else  if (label.size()>0) {
+                QGroupBox* group = new QGroupBox(this);
+                group->setTitle(label.c_str());
+                box = group;
+                
+            } else {
+                // no label here we use simple widget
+                layout->setMargin(0);
+                box = new QWidget(this);
+            }
+            
+            box->setLayout(layout);
+            fGeneralLayout->addWidget(box);
+
+            /*if (metadata.count("tooltip")) {
+             box->setToolTip(metadata["tooltip"].c_str());
+             }*/
+            if (gGroupTooltip != std::string()) {
+                box->setToolTip(gGroupTooltip.c_str());
+                gGroupTooltip = std::string();
+            }
+            
+        }
+        
+        else{
+            if (isTabContext()) {
+                box = new QWidget();
+                // set background color
+                QPalette pal = box->palette();
+                pal.setColor(box->backgroundRole(), QColor::fromRgb(150, 150, 150) );
+                box->setPalette(pal);
+                
+            } else  if (label.size()>0) {
+                QGroupBox* group = new QGroupBox();
+                group->setTitle(label.c_str());
+                box = group;
+                
+            } else {
+                // no label here we use simple widget
+                layout->setMargin(0);
+                box = new QWidget;
+            }
+            
+            box->setLayout(layout);
+            /*        if (metadata.count("tooltip")) {
+             box->setToolTip(metadata["tooltip"].c_str());
+             }*/
+            if (gGroupTooltip != std::string()) {
+                box->setToolTip(gGroupTooltip.c_str());
+                gGroupTooltip = std::string();
+            }
+        }
+        insert(label.c_str(), box);
+        fGroupStack.push(box);
+    }
+    
+	void openTab(const char* label)
+	{
+		QTabWidget* group;
+        
+        if(fGroupStack.empty()){
+            group = new QTabWidget(this);
+            fGeneralLayout->addWidget(group);
+        }
+        else{
+            group = new QTabWidget();
+        }
+        
+		insert(label, group);
+		fGroupStack.push(group);
+	}
+    
+    public slots :
+    
+	void update()		{
+        //std::cout << '.' << std::endl;
+        //		updateAllZones();
+		updateAllGuis();
+	}
+    
+public:
+    
+
+    QTGUI(QWidget* parent) : QWidget(parent){
+        fGeneralLayout = new QVBoxLayout;
+        setLayout(fGeneralLayout);
+        QWidget::show();
+        
+        fMainWindow = NULL;        
+        fTimer = 0;
+    }
+
+    QTGUI():QWidget(){
+        
+        fGeneralLayout = new QVBoxLayout;
+        setLayout(fGeneralLayout);
+        QWidget::show();
+
+        fTimer = 0;
+
+        fMainWindow = new QMainWindow;
+        QScrollArea *sa = new QScrollArea( fMainWindow );
+        
+        sa->setWidgetResizable( true );
+        sa->setWidget(this);
+        
+        fMainWindow->setCentralWidget(sa);
+    }
+
+	virtual ~QTGUI() {
+        
+        delete fGeneralLayout;
+    }
+
+    QString styleSheet(){
+        
+        QString styleSheet("");
+        
+         QFile file(":/Grey.qss");
+        
+        if(file.open(QIODevice::ReadOnly | QIODevice::Text))
+        {
+            styleSheet = QLatin1String(file.readAll());
+            file.close();
+        }
+        
+        return styleSheet;
+    }
+    
+    /**
+     * Analyses the widget zone metadata declarations and takes
+     * appropriate actions
+     */
+    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value)
+    {
+        if (zone == 0) {
+            // special zone 0 means group metadata
+            if (strcmp(key,"tooltip")==0) {
+                // only group tooltip are currently implemented
+                gGroupTooltip = formatTooltip(30, value);
+            }
+        } else {
+            if (strcmp(key,"size")==0) {
+                fGuiSize[zone]=atof(value);
+            }
+            else if (strcmp(key,"tooltip")==0) {
+                fTooltip[zone] = formatTooltip(30, value) ;
+            }
+            else if (strcmp(key,"unit")==0) {
+                fUnit[zone] = value ;
+            }
+            else if (strcmp(key,"scale")==0) {
+                if (strcmp(value,"log") == 0) {
+                    fLogSet.insert(zone);
+                } else if (strcmp(value,"exp") == 0) {
+                    fExpSet.insert(zone);
+                }
+            }
+            else if (strcmp(key,"style")==0) {
+                // else if ((strcmp(key,"style")==0) || (strcmp(key,"type")==0)) {
+                if (strcmp(value,"knob") == 0) {
+                    fKnobSet.insert(zone);
+                } else if (strcmp(value,"led") == 0) {
+                    fLedSet.insert(zone);
+                } else if (strcmp(value,"numerical") == 0) {
+                    fNumSet.insert(zone);
+                } else {
+                    const char* p = value;
+                    if (parseWord(p,"radio")) {
+                        fRadioDescription[zone] = string(p);
+                    } else if (parseWord(p,"menu")) {
+                        fMenuDescription[zone] = string(p);
+                    }
+                }
+            }
+        }
+    }
+    
+#if defined(HTTPCTRL) && defined(QRCODECTRL)
+    
+    //
+    // Returns the IP address of the machine (to be qrcoded)
+    //
+    QString extractIPnum()
+    {
+        QList<QHostAddress> ipAdresses = QNetworkInterface::allAddresses();
+        
+        QList<QHostAddress>::iterator it;
+        
+        QString localhost("localhost"); 
+        
+        for(it = ipAdresses.begin(); it != ipAdresses.end(); it++){
+            if((*it).protocol() == QAbstractSocket::IPv4Protocol && (*it) != QHostAddress::LocalHost)
+                return it->toString();
+            else if((*it).protocol() == QAbstractSocket::IPv4Protocol && (*it) == QHostAddress::LocalHost)
+                localhost = it->toString();
+        }
+        
+        return localhost;
+    }
+    
+    //
+    // Used in HTTPD mode, display the QRCode of the URL of the application
+    //
+    void displayQRCode(int portnum)
+    {
+        QString url("http://");
+        url += extractIPnum();
+        url += ":";
+        url += QString::number(portnum);
+        displayQRCode(url, NULL);
+    }
+    
+    void displayQRCode(const QString& url, QMainWindow* parent = NULL){
+        
+        if(parent == NULL)
+            parent = new QMainWindow;
+        
+        QWidget* centralWidget = new QWidget;
+        parent->setCentralWidget(centralWidget);
+        //    QTextEdit* httpdText = new QTextEdit(centralWidget);
+        QTextBrowser* myBro = new QTextBrowser(centralWidget);
+        
+        //Construction of the flashcode
+        const int padding = 5;
+        QRcode* qrc = QRcode_encodeString(url.toLatin1().data(), 0, QR_ECLEVEL_H, QR_MODE_8, 1);
+        
+        //   qDebug() << "QRcode width = " << qrc->width;
+        
+        QRgb colors[2];
+        colors[0] = qRgb(255, 255, 255); 	// 0 is white
+        colors[1] = qRgb(0, 0, 0); 			// 1 is black
+        
+        // build the QRCode image
+        QImage image(qrc->width+2*padding, qrc->width+2*padding, QImage::Format_RGB32);
+        // clear the image
+        for (int y=0; y<qrc->width+2*padding; y++) {
+            for (int x=0; x<qrc->width+2*padding; x++) {
+                image.setPixel(x, y, colors[0]);
+            }
+        }
+        // copy the qrcode inside
+        for (int y=0; y<qrc->width; y++) {
+            for (int x=0; x<qrc->width; x++) {
+                image.setPixel(x+padding, y+padding, colors[qrc->data[y*qrc->width+x]&1]);
+            }
+        }
+        
+        QImage big = image.scaledToWidth(qrc->width*8);
+        QLabel* myLabel = new QLabel(centralWidget);
+        
+        fQrCode = QPixmap::fromImage(big);
+        
+        myLabel->setPixmap(fQrCode);
+        
+        //----Written Address
+        
+        QString sheet = QString::fromLatin1("a{ text-decoration: underline; color: white; font: Menlo; font-size: 14px }");
+        //    myBro->document()->setDefaultStyleSheet(sheet);
+        //    myBro->setStyleSheet("*{color: white; font: Menlo; font-size: 14px }");
+        
+        QString text("<br>Please connect to ");
+        text += "<br><a href = " + url + ">"+ url+ "</a>";
+        text += "<br>Or scan the QR code below";
+        
+        myBro->setOpenExternalLinks(true);
+        myBro->setHtml(text);
+        myBro->setAlignment(Qt::AlignCenter);
+        myBro->setFixedWidth(qrc->width*8);
+        //    myBro->setFixedHeight(myBro->minimumHeight());
+        
+        QGridLayout *mainLayout = new QGridLayout;
+        mainLayout->addWidget(myBro, 0, 1);
+        mainLayout->addWidget(myLabel, 1, 1);
+        centralWidget->setLayout(mainLayout);
+        centralWidget->show();
+        centralWidget->adjustSize();
+        parent->show();
+    }
+    
+    bool toPNG(const QString& filename, QString& error){
+        
+        QFile file(filename);
+        if(file.open(QIODevice::WriteOnly)){
+            fQrCode.save(&file, "PNG");
+            return true;
+        }
+        else{
+            error = "Impossible to write file.";
+            return false;
+        }
+    }
+#endif
+    
+	virtual void run()
+	{
+		if (fTimer == 0) {
+			fTimer = new QTimer(this);
+     		QObject::connect(fTimer, SIGNAL(timeout()), this, SLOT(update()));
+     		fTimer->start(100);
+		}
+
+        if(fMainWindow)
+            fMainWindow->show();
+	}
+    
+    virtual void stop()
+	{
+		if (fTimer != 0) {
+            fTimer->stop();
+            delete fTimer;
+            fTimer = NULL;
+		}
+        
+        GUI::stop();
+	}
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // OPEN AND CLOSE GROUPS
+    //
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    virtual void openHorizontalBox(const char* label) {
+		openBox(label, new QHBoxLayout());
+	}
+    
+	virtual void openVerticalBox(const char* label) 	{
+        openBox(label, new QVBoxLayout());
+    }
+    
+    virtual void openFrameBox(const char* ) 		{ }
+    
+	virtual void openTabBox(const char* label) 		{ 
+		openTab(label);
+	}
+    
+	virtual void closeBox()
+	{
+		QWidget* group = fGroupStack.top();
+		fGroupStack.pop();
+		if (fGroupStack.empty()) { group->show(); group->adjustSize();}
+	}
+    
+    
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // ADD BUTTONS AND CHECKBOX
+    //
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    virtual void addButton(const char* label, FAUSTFLOAT* zone)
+	{
+		QAbstractButton* 	w = new QPushButton(label);
+		w->setAttribute(Qt::WA_MacNoClickThrough);
+		uiButton* 			c = new uiButton(this, zone, w);
+        
+		insert(label, w);
+		QObject::connect(w, SIGNAL(pressed()), c, SLOT(pressed()));
+		QObject::connect(w, SIGNAL(released()), c, SLOT(released()));
+        checkForTooltip(zone, w);
+        clearMetadata();
+	}
+    
+    virtual void addToggleButton(const char*, FAUSTFLOAT*)
+    {}
+    
+	virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+	{
+		QCheckBox* 	w = new QCheckBox(label);
+		uiCheckButton* 	c = new uiCheckButton(this, zone, w);
+        
+		insert(label, w);
+		QObject::connect(w, SIGNAL(stateChanged(int)), c, SLOT(setState(int)));
+        checkForTooltip(zone, w);
+        clearMetadata();
+	}
+    
+    
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // ADD NUMERICAL ENTRY
+    //
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+    {
+        if (isKnob(zone)) {
+            addVerticalKnob(label, zone, init, min, max, step);
+            return;
+        }
+        //insert(label, new QDoubleSpinBox());
+        if (label && label[0]) openVerticalBox(label);
+        QDoubleSpinBox*     w = new QDoubleSpinBox();
+        uiNumEntry*         c = new uiNumEntry(this, zone, w, init, min, max, step);
+        insert(label, w);
+        w->setSuffix(fUnit[zone].c_str());
+        QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double)));
+        if (label && label[0]) closeBox();
+        checkForTooltip(zone, w);
+        clearMetadata();
+    }
+    
+    // special num entry without buttons
+    virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+    {
+        //insert(label, new QDoubleSpinBox());
+        if (label && label[0]) openVerticalBox(label);
+        QDoubleSpinBox*     w = new QDoubleSpinBox();
+        w->setAlignment(Qt::AlignHCenter);
+#if 1
+        w->setStyleSheet(
+                         "QDoubleSpinBox {"
+                         "border: 2px solid orange;"
+                         "border-radius: 5px;"
+                         "font-size: 8pt;"
+                         "}"
+                         );
+#endif
+        uiNumEntry*         c = new uiNumEntry(this, zone, w, init, min, max, step);
+        insert(label, w);
+        w->setButtonSymbols(QAbstractSpinBox::NoButtons);
+        w->setSuffix(fUnit[zone].c_str());
+        QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double)));
+        if (label && label[0]) closeBox();
+        checkForTooltip(zone, w);
+        clearMetadata();
+    }
+    
+    
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+	//
+    // ADD KNOBS
+	//
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+	virtual void addVerticalKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		openVerticalBox(label);
+		QAbstractSlider* 	w = new QDial(); //qsynthKnob();
+        uiSlider*	c = new uiSlider(this, zone, w, init, min, max, step, getScale(zone));
+		insert(label, w);
+		w->setStyle(new qsynthDialVokiStyle());
+		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
+		addNumDisplay(0, zone, init, min, max, step);
+        
+        // compute the size of the knob+display
+        int width  = int(64*pow(2,fGuiSize[zone]));
+        int height = int(100*pow(2,fGuiSize[zone]));
+        fGroupStack.top()->setMinimumSize(width,height);
+        fGroupStack.top()->setMaximumSize(width,height);
+        
+		closeBox();
+        checkForTooltip(zone, w);
+        clearMetadata();
+	}
+    
+	virtual void addHorizontalKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		openHorizontalBox(label);
+		QAbstractSlider* 	w = new QDial(); //new qsynthKnob();
+        uiSlider*	c = new uiSlider(this, zone, w, init, min, max, step, getScale(zone));
+		insert(label, w);
+		w->setStyle(new qsynthDialVokiStyle());
+		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
+		addNumDisplay(0, zone, init, min, max, step);
+		closeBox();
+        checkForTooltip(zone, w);
+        clearMetadata();
+	}
+    
+    
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+	//
+    // ADD SLIDERS
+	//
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+	virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		if (isKnob(zone)) {
+			addVerticalKnob(label, zone, init, min, max, step);
+			return;
+        } else if (fRadioDescription.count(zone)) {
+            addVerticalRadioButtons(label,zone,init,min,max,step,fRadioDescription[zone].c_str());
+            return;
+        } else if (fMenuDescription.count(zone)) {
+            addMenu(label,zone,init,min,max,step,fMenuDescription[zone].c_str());
+            return;
+        }
+		openVerticalBox(label);
+		QSlider* 	w = new QSlider(Qt::Vertical);
+        w->setMinimumHeight(160);
+        w->setMinimumWidth(34);
+		//w->setTickPosition(QSlider::TicksBothSides);
+ 		uiSlider*	c = new uiSlider(this, zone, w, init, min, max, step, getScale(zone));
+		insert(label, w);
+		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
+		addNumDisplay(0, zone, init, min, max, step);
+		closeBox();
+        checkForTooltip(zone, w);
+        clearMetadata();
+	}
+    
+	virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{
+		if (isKnob(zone)) {
+			addHorizontalKnob(label, zone, init, min, max, step);
+			return;
+        } else if (fRadioDescription.count(zone)) {
+            addHorizontalRadioButtons(label,zone,init,min,max,step,fRadioDescription[zone].c_str());
+            return;
+        } else if (fMenuDescription.count(zone)) {
+            addMenu(label,zone,init,min,max,step,fMenuDescription[zone].c_str());
+            return;
+        }
+		openHorizontalBox(label);
+		QSlider* 	w = new QSlider(Qt::Horizontal);
+        w->setMinimumHeight(34);
+        w->setMinimumWidth(160);
+		//w->setTickPosition(QSlider::TicksBothSides);
+ 		uiSlider*	c = new uiSlider(this, zone, w, init, min, max, step, getScale(zone));
+		insert(label, w);
+		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
+		addNumDisplay(0, zone, init, min, max, step);
+		closeBox();
+        checkForTooltip(zone, w);
+        clearMetadata();
+	}
+    
+    
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // ADD RADIO-BUTTONS AND MENUS
+    //
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    virtual void addVerticalRadioButtons(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min,
+                                         FAUSTFLOAT max, FAUSTFLOAT step, const char* mdescr)
+    {
+        uiRadioButtons* w = new uiRadioButtons(this,zone,label,init,min,max,step,true,mdescr,0);
+        insert(label, w);
+        checkForTooltip(zone, w);
+        clearMetadata();
+    }
+    
+    virtual void addHorizontalRadioButtons(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min,
+                                           FAUSTFLOAT max, FAUSTFLOAT step, const char* mdescr)
+    {
+        uiRadioButtons* w = new uiRadioButtons(this,zone,label,init,min,max,step,false,mdescr,0);
+        insert(label, w);
+        checkForTooltip(zone, w);
+        clearMetadata();
+    }
+    
+    
+    virtual void addMenu(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min,
+                         FAUSTFLOAT max, FAUSTFLOAT step, const char* mdescr)
+    {
+        if (label && label[0]) openVerticalBox(label);
+        uiMenu* w = new uiMenu(this,zone,label,init,min,max,step,mdescr,0);
+        insert(label, w);
+        checkForTooltip(zone, w);
+        if (label && label[0]) closeBox();
+        clearMetadata();
+    }
+    
+    
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // ADD BARGRAPHS
+    //
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    virtual void addHorizontalBargraph(const char* label , FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+    {
+        openVerticalBox(label);
+        bool db = (fUnit[zone] == "dB");
+        
+        
+        if (fNumSet.count(zone)) {
+			addNumDisplay(0, zone, min, min, max, (max-min)/100.0);
+        } else {
+            AbstractDisplay*  bargraph;
+            if (fLedSet.count(zone)) {
+				if (db) {
+					bargraph = new dbLED(min, max);
+				} else {
+					bargraph = new LED(min,max);
+				}
+			} else {
+				if (db) {
+					bargraph = new dbHorizontalBargraph(min, max);
+				} else {
+					bargraph = new linHorizontalBargraph(min, max);
+				}
+			}
+            
+            new uiBargraph(this, zone, bargraph, min, max);
+			insert(label, bargraph);
+            checkForTooltip(zone, bargraph);
+        }
+        closeBox();
+        clearMetadata();
+    }
+    
+    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+    {
+        AbstractDisplay*  bargraph;
+        openVerticalBox(label);
+        bool db = (fUnit[zone] == "dB");
+        
+        if (fNumSet.count(zone)) {
+			addNumDisplay(0, zone, min, min, max, (max-min)/100.0);
+        } else {
+			if (fLedSet.count(zone)) {
+				if (db) {
+					bargraph = new dbLED(min, max);
+				} else {
+                    bargraph = new LED(min, max);
+				}
+			} else {
+				if (db) {
+					bargraph = new dbVerticalBargraph(min, max);
+				} else {
+					bargraph = new linVerticalBargraph(min, max);
+				}
+			}
+            new uiBargraph(this, zone, bargraph, min, max);
+			insert(label, bargraph);
+			addNumDisplay(0, zone, min, min, max, (max-min)/100.0);
+            checkForTooltip(zone, bargraph);
+        }
+        closeBox();
+        clearMetadata();
+    }
+};
+
+#endif
+
diff --git a/architecture/faust/gui/httpdUI.h b/architecture/faust/gui/httpdUI.h
new file mode 100644
index 0000000..4ae0b1e
--- /dev/null
+++ b/architecture/faust/gui/httpdUI.h
@@ -0,0 +1,116 @@
+/*
+   Copyright (C) 2012 Grame - Lyon
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted.
+*/
+
+#ifndef __httpdUI__
+#define __httpdUI__
+
+//#ifdef _WIN32
+//#include "HTTPDControler.h"
+//#include "UI.h"
+//#else
+#include "faust/gui/HTTPDControler.h"
+#include "faust/gui/UI.h"
+//#endif
+/******************************************************************************
+*******************************************************************************
+
+					HTTPD USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+/*
+
+Note about URLs and the Faust UI names:
+----------------------------------------------------
+Characters in a url could be:
+1. Reserved: ; / ? : @ & = + $ ,
+   These characters delimit URL parts.
+2. Unreserved: alphanum - _ . ! ~ * ' ( )
+   These characters have no special meaning and can be used as is.
+3. Excluded: control characters, space, < > # % ", { } | \ ^ [ ] `
+
+To solve potential conflicts between the Faust UI objects naming scheme and
+the URL allowed characters, the reserved and excluded characters are replaced
+with '-' (hyphen).
+Space or tabulation are replaced with '_' (underscore)
+*/
+
+//using namespace std;
+
+class httpdUI : public UI 
+{
+	httpdfaust::HTTPDControler*	fCtrl;	
+	const char* tr(const char* label) const;
+
+ public:
+		
+	httpdUI(const char* applicationname, int inputs, int outputs, int argc, char *argv[], bool init = true) 
+    { 
+		fCtrl = new httpdfaust::HTTPDControler(argc, argv, applicationname, init); 
+        fCtrl->setInputs(inputs);
+        fCtrl->setOutputs(outputs);
+	}
+	
+	virtual ~httpdUI() { delete fCtrl; }
+		
+    // -- widget's layouts
+	virtual void openTabBox(const char* label) 			{ fCtrl->opengroup( "tgroup", tr(label)); }
+	virtual void openHorizontalBox(const char* label) 	{ fCtrl->opengroup( "hgroup", tr(label)); }
+	virtual void openVerticalBox(const char* label) 	{ fCtrl->opengroup( "vgroup", tr(label)); }
+	virtual void closeBox() 							{ fCtrl->closegroup(); }
+	
+	// -- active widgets
+	virtual void addButton(const char* label, FAUSTFLOAT* zone)			{ fCtrl->addnode( "button", tr(label), zone); }
+	virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)	{ fCtrl->addnode( "checkbox", tr(label), zone); }
+	virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+									{ fCtrl->addnode( "vslider", tr(label), zone, init, min, max, step); }
+	virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) 	
+									{ fCtrl->addnode( "hslider", tr(label), zone, init, min, max, step); }
+	virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) 			
+									{ fCtrl->addnode( "nentry", tr(label), zone, init, min, max, step); }
+	
+	// -- passive widgets	
+	virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+									{ fCtrl->addnode( "hbargraph", tr(label), zone, min, max); }
+	virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+									{ fCtrl->addnode( "vbargraph", tr(label), zone, min, max); }
+	
+    virtual void declare (FAUSTFLOAT*, const char* key, const char* val) { fCtrl->declare(key, val); }
+
+	void run()						{ fCtrl->run(); }
+	int getTCPPort()                { return fCtrl->getTCPPort(); }
+    
+    std::string getJSONInterface(){ return fCtrl->getJSONInterface(); }
+
+};
+					
+const char* httpdUI::tr(const char* label) const
+{
+	static char buffer[1024];
+	char * ptr = buffer; int n=1;
+	while (*label && (n++ < 1024)) {
+		switch (*label) {
+			case ' ': case '	':
+				*ptr++ = '_';
+				break;
+			case ';': case '/': case '?': case ':': case '@': 
+			case '&': case '=': case '+': case '$': case ',':
+			case '<': case '>': case '#': case '%': case '"': 
+			case '{': case '}': case '|': case '\\': case '^': 
+			case '[': case ']': case '`':
+				*ptr++ = '_';
+				break;
+			default: 
+				*ptr++ = *label;
+		}
+		label++;
+	}
+	*ptr = 0;
+	return buffer;
+}
+
+#endif
diff --git a/architecture/faust/gui/meta.h b/architecture/faust/gui/meta.h
new file mode 100644
index 0000000..3d21a62
--- /dev/null
+++ b/architecture/faust/gui/meta.h
@@ -0,0 +1,31 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+ ************************************************************************
+ ************************************************************************/
+ 
+#ifndef __meta__
+#define __meta__
+
+struct Meta
+{
+    virtual void declare(const char* key, const char* value) = 0;
+};
+
+#endif
+
diff --git a/architecture/faust/midi/RtMidi.cpp b/architecture/faust/midi/RtMidi.cpp
new file mode 100644
index 0000000..62cc17b
--- /dev/null
+++ b/architecture/faust/midi/RtMidi.cpp
@@ -0,0 +1,2839 @@
+/**********************************************************************/
+/*! \class RtMidi
+    \brief An abstract base class for realtime MIDI input/output.
+
+    This class implements some common functionality for the realtime
+    MIDI input/output subclasses RtMidiIn and RtMidiOut.
+
+    RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
+
+    RtMidi: realtime MIDI i/o C++ classes
+    Copyright (c) 2003-2014 Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********************************************************************/
+
+#include "faust/midi/RtMidi.h"
+#include <sstream>
+
+//*********************************************************************//
+//  RtMidi Definitions
+//*********************************************************************//
+
+RtMidi :: RtMidi()
+  : rtapi_(0)
+{
+}
+
+RtMidi :: ~RtMidi()
+{
+  if ( rtapi_ )
+    delete rtapi_;
+  rtapi_ = 0;
+}
+
+std::string RtMidi :: getVersion( void ) throw()
+{
+  return std::string( RTMIDI_VERSION );
+}
+
+void RtMidi :: getCompiledApi( std::vector<RtMidi::Api> &apis ) throw()
+{
+  apis.clear();
+
+  // The order here will control the order of RtMidi's API search in
+  // the constructor.
+#if defined(__MACOSX_CORE__)
+  apis.push_back( MACOSX_CORE );
+#endif
+#if defined(__LINUX_ALSA__)
+  apis.push_back( LINUX_ALSA );
+#endif
+#if defined(__UNIX_JACK__)
+  apis.push_back( UNIX_JACK );
+#endif
+#if defined(__WINDOWS_MM__)
+  apis.push_back( WINDOWS_MM );
+#endif
+#if defined(__RTMIDI_DUMMY__)
+  apis.push_back( RTMIDI_DUMMY );
+#endif
+}
+
+//*********************************************************************//
+//  RtMidiIn Definitions
+//*********************************************************************//
+
+void RtMidiIn :: openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit )
+{
+  if ( rtapi_ )
+    delete rtapi_;
+  rtapi_ = 0;
+
+#if defined(__UNIX_JACK__)
+  if ( api == UNIX_JACK )
+    rtapi_ = new MidiInJack( clientName, queueSizeLimit );
+#endif
+#if defined(__LINUX_ALSA__)
+  if ( api == LINUX_ALSA )
+    rtapi_ = new MidiInAlsa( clientName, queueSizeLimit );
+#endif
+#if defined(__WINDOWS_MM__)
+  if ( api == WINDOWS_MM )
+    rtapi_ = new MidiInWinMM( clientName, queueSizeLimit );
+#endif
+#if defined(__MACOSX_CORE__)
+  if ( api == MACOSX_CORE )
+    rtapi_ = new MidiInCore( clientName, queueSizeLimit );
+#endif
+#if defined(__RTMIDI_DUMMY__)
+  if ( api == RTMIDI_DUMMY )
+    rtapi_ = new MidiInDummy( clientName, queueSizeLimit );
+#endif
+}
+
+RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit )
+  : RtMidi()
+{
+  if ( api != UNSPECIFIED ) {
+    // Attempt to open the specified API.
+    openMidiApi( api, clientName, queueSizeLimit );
+    if ( rtapi_ ) return;
+
+    // No compiled support for specified API value.  Issue a warning
+    // and continue as if no API was specified.
+    std::cerr << "\nRtMidiIn: no compiled support for specified API argument!\n\n" << std::endl;
+  }
+
+  // Iterate through the compiled APIs and return as soon as we find
+  // one with at least one port or we reach the end of the list.
+  std::vector< RtMidi::Api > apis;
+  getCompiledApi( apis );
+  for ( unsigned int i=0; i<apis.size(); i++ ) {
+    openMidiApi( apis[i], clientName, queueSizeLimit );
+    if ( rtapi_->getPortCount() ) break;
+  }
+
+  if ( rtapi_ ) return;
+
+  // It should not be possible to get here because the preprocessor
+  // definition __RTMIDI_DUMMY__ is automatically defined if no
+  // API-specific definitions are passed to the compiler. But just in
+  // case something weird happens, we'll throw an error.
+  std::string errorText = "RtMidiIn: no compiled API support found ... critical error!!";
+  throw( RtMidiError( errorText, RtMidiError::UNSPECIFIED ) );
+}
+
+RtMidiIn :: ~RtMidiIn() throw()
+{
+}
+
+
+//*********************************************************************//
+//  RtMidiOut Definitions
+//*********************************************************************//
+
+void RtMidiOut :: openMidiApi( RtMidi::Api api, const std::string clientName )
+{
+  if ( rtapi_ )
+    delete rtapi_;
+  rtapi_ = 0;
+
+#if defined(__UNIX_JACK__)
+  if ( api == UNIX_JACK )
+    rtapi_ = new MidiOutJack( clientName );
+#endif
+#if defined(__LINUX_ALSA__)
+  if ( api == LINUX_ALSA )
+    rtapi_ = new MidiOutAlsa( clientName );
+#endif
+#if defined(__WINDOWS_MM__)
+  if ( api == WINDOWS_MM )
+    rtapi_ = new MidiOutWinMM( clientName );
+#endif
+#if defined(__MACOSX_CORE__)
+  if ( api == MACOSX_CORE )
+    rtapi_ = new MidiOutCore( clientName );
+#endif
+#if defined(__RTMIDI_DUMMY__)
+  if ( api == RTMIDI_DUMMY )
+    rtapi_ = new MidiOutDummy( clientName );
+#endif
+}
+
+RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string clientName )
+{
+  if ( api != UNSPECIFIED ) {
+    // Attempt to open the specified API.
+    openMidiApi( api, clientName );
+    if ( rtapi_ ) return;
+
+    // No compiled support for specified API value.  Issue a warning
+    // and continue as if no API was specified.
+    std::cerr << "\nRtMidiOut: no compiled support for specified API argument!\n\n" << std::endl;
+  }
+
+  // Iterate through the compiled APIs and return as soon as we find
+  // one with at least one port or we reach the end of the list.
+  std::vector< RtMidi::Api > apis;
+  getCompiledApi( apis );
+  for ( unsigned int i=0; i<apis.size(); i++ ) {
+    openMidiApi( apis[i], clientName );
+    if ( rtapi_->getPortCount() ) break;
+  }
+
+  if ( rtapi_ ) return;
+
+  // It should not be possible to get here because the preprocessor
+  // definition __RTMIDI_DUMMY__ is automatically defined if no
+  // API-specific definitions are passed to the compiler. But just in
+  // case something weird happens, we'll thrown an error.
+  std::string errorText = "RtMidiOut: no compiled API support found ... critical error!!";
+  throw( RtMidiError( errorText, RtMidiError::UNSPECIFIED ) );
+}
+
+RtMidiOut :: ~RtMidiOut() throw()
+{
+}
+
+//*********************************************************************//
+//  Common MidiApi Definitions
+//*********************************************************************//
+
+MidiApi :: MidiApi( void )
+  : apiData_( 0 ), connected_( false ), errorCallback_(0)
+{
+}
+
+MidiApi :: ~MidiApi( void )
+{
+}
+
+void MidiApi :: setErrorCallback( RtMidiErrorCallback errorCallback )
+{
+    errorCallback_ = errorCallback;
+}
+
+void MidiApi :: error( RtMidiError::Type type, std::string errorString )
+{
+  if ( errorCallback_ ) {
+    static bool firstErrorOccured = false;
+
+    if ( firstErrorOccured )
+      return;
+
+    firstErrorOccured = true;
+    const std::string errorMessage = errorString;
+
+    errorCallback_( type, errorMessage );
+    firstErrorOccured = false;
+    return;
+  }
+
+  if ( type == RtMidiError::WARNING ) {
+    std::cerr << '\n' << errorString << "\n\n";
+  }
+  else if ( type == RtMidiError::DEBUG_WARNING ) {
+#if defined(__RTMIDI_DEBUG__)
+    std::cerr << '\n' << errorString << "\n\n";
+#endif
+  }
+  else {
+    std::cerr << '\n' << errorString << "\n\n";
+    throw RtMidiError( errorString, type );
+  }
+}
+
+//*********************************************************************//
+//  Common MidiInApi Definitions
+//*********************************************************************//
+
+MidiInApi :: MidiInApi( unsigned int queueSizeLimit )
+  : MidiApi()
+{
+  // Allocate the MIDI queue.
+  inputData_.queue.ringSize = queueSizeLimit;
+  if ( inputData_.queue.ringSize > 0 )
+    inputData_.queue.ring = new MidiMessage[ inputData_.queue.ringSize ];
+}
+
+MidiInApi :: ~MidiInApi( void )
+{
+  // Delete the MIDI queue.
+  if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring;
+}
+
+void MidiInApi :: setCallback( RtMidiIn::RtMidiCallback callback, void *userData )
+{
+  if ( inputData_.usingCallback ) {
+    errorString_ = "MidiInApi::setCallback: a callback function is already set!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  if ( !callback ) {
+    errorString_ = "RtMidiIn::setCallback: callback function value is invalid!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  inputData_.userCallback = callback;
+  inputData_.userData = userData;
+  inputData_.usingCallback = true;
+}
+
+void MidiInApi :: cancelCallback()
+{
+  if ( !inputData_.usingCallback ) {
+    errorString_ = "RtMidiIn::cancelCallback: no callback function was set!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  inputData_.userCallback = 0;
+  inputData_.userData = 0;
+  inputData_.usingCallback = false;
+}
+
+void MidiInApi :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense )
+{
+  inputData_.ignoreFlags = 0;
+  if ( midiSysex ) inputData_.ignoreFlags = 0x01;
+  if ( midiTime ) inputData_.ignoreFlags |= 0x02;
+  if ( midiSense ) inputData_.ignoreFlags |= 0x04;
+}
+
+double MidiInApi :: getMessage( std::vector<unsigned char> *message )
+{
+  message->clear();
+
+  if ( inputData_.usingCallback ) {
+    errorString_ = "RtMidiIn::getNextMessage: a user callback is currently set for this port.";
+    error( RtMidiError::WARNING, errorString_ );
+    return 0.0;
+  }
+
+  if ( inputData_.queue.size == 0 ) return 0.0;
+
+  // Copy queued message to the vector pointer argument and then "pop" it.
+  std::vector<unsigned char> *bytes = &(inputData_.queue.ring[inputData_.queue.front].bytes);
+  message->assign( bytes->begin(), bytes->end() );
+  double deltaTime = inputData_.queue.ring[inputData_.queue.front].timeStamp;
+  inputData_.queue.size--;
+  inputData_.queue.front++;
+  if ( inputData_.queue.front == inputData_.queue.ringSize )
+    inputData_.queue.front = 0;
+
+  return deltaTime;
+}
+
+//*********************************************************************//
+//  Common MidiOutApi Definitions
+//*********************************************************************//
+
+MidiOutApi :: MidiOutApi( void )
+  : MidiApi()
+{
+}
+
+MidiOutApi :: ~MidiOutApi( void )
+{
+}
+
+// *************************************************** //
+//
+// OS/API-specific methods.
+//
+// *************************************************** //
+
+#if defined(__MACOSX_CORE__)
+
+// The CoreMIDI API is based on the use of a callback function for
+// MIDI input.  We convert the system specific time stamps to delta
+// time values.
+
+// OS-X CoreMIDI header files.
+#include <CoreMIDI/CoreMIDI.h>
+#include <CoreAudio/HostTime.h>
+#include <CoreServices/CoreServices.h>
+
+// A structure to hold variables related to the CoreMIDI API
+// implementation.
+struct CoreMidiData {
+  MIDIClientRef client;
+  MIDIPortRef port;
+  MIDIEndpointRef endpoint;
+  MIDIEndpointRef destinationId;
+  unsigned long long lastTime;
+  MIDISysexSendRequest sysexreq;
+};
+
+//*********************************************************************//
+//  API: OS-X
+//  Class Definitions: MidiInCore
+//*********************************************************************//
+
+static void midiInputCallback( const MIDIPacketList *list, void *procRef, void */*srcRef*/ )
+{
+  MidiInApi::RtMidiInData *data = static_cast<MidiInApi::RtMidiInData *> (procRef);
+  CoreMidiData *apiData = static_cast<CoreMidiData *> (data->apiData);
+
+  unsigned char status;
+  unsigned short nBytes, iByte, size;
+  unsigned long long time;
+
+  bool& continueSysex = data->continueSysex;
+  MidiInApi::MidiMessage& message = data->message;
+
+  const MIDIPacket *packet = &list->packet[0];
+  for ( unsigned int i=0; i<list->numPackets; ++i ) {
+
+    // My interpretation of the CoreMIDI documentation: all message
+    // types, except sysex, are complete within a packet and there may
+    // be several of them in a single packet.  Sysex messages can be
+    // broken across multiple packets and PacketLists but are bundled
+    // alone within each packet (these packets do not contain other
+    // message types).  If sysex messages are split across multiple
+    // MIDIPacketLists, they must be handled by multiple calls to this
+    // function.
+
+    nBytes = packet->length;
+    if ( nBytes == 0 ) continue;
+
+    // Calculate time stamp.
+
+    if ( data->firstMessage ) {
+      message.timeStamp = 0.0;
+      data->firstMessage = false;
+    }
+    else {
+      time = packet->timeStamp;
+      if ( time == 0 ) { // this happens when receiving asynchronous sysex messages
+        time = AudioGetCurrentHostTime();
+      }
+      time -= apiData->lastTime;
+      time = AudioConvertHostTimeToNanos( time );
+      if ( !continueSysex )
+        message.timeStamp = time * 0.000000001;
+    }
+    apiData->lastTime = packet->timeStamp;
+    if ( apiData->lastTime == 0 ) { // this happens when receiving asynchronous sysex messages
+      apiData->lastTime = AudioGetCurrentHostTime();
+    }
+    //std::cout << "TimeStamp = " << packet->timeStamp << std::endl;
+
+    iByte = 0;
+    if ( continueSysex ) {
+      // We have a continuing, segmented sysex message.
+      if ( !( data->ignoreFlags & 0x01 ) ) {
+        // If we're not ignoring sysex messages, copy the entire packet.
+        for ( unsigned int j=0; j<nBytes; ++j )
+          message.bytes.push_back( packet->data[j] );
+      }
+      continueSysex = packet->data[nBytes-1] != 0xF7;
+
+      if ( !( data->ignoreFlags & 0x01 ) && !continueSysex ) {
+        // If not a continuing sysex message, invoke the user callback function or queue the message.
+        if ( data->usingCallback ) {
+          RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
+          callback( message.timeStamp, &message.bytes, data->userData );
+        }
+        else {
+          // As long as we haven't reached our queue size limit, push the message.
+          if ( data->queue.size < data->queue.ringSize ) {
+            data->queue.ring[data->queue.back++] = message;
+            if ( data->queue.back == data->queue.ringSize )
+              data->queue.back = 0;
+            data->queue.size++;
+          }
+          else
+            std::cerr << "\nMidiInCore: message queue limit reached!!\n\n";
+        }
+        message.bytes.clear();
+      }
+    }
+    else {
+      while ( iByte < nBytes ) {
+        size = 0;
+        // We are expecting that the next byte in the packet is a status byte.
+        status = packet->data[iByte];
+        if ( !(status & 0x80) ) break;
+        // Determine the number of bytes in the MIDI message.
+        if ( status < 0xC0 ) size = 3;
+        else if ( status < 0xE0 ) size = 2;
+        else if ( status < 0xF0 ) size = 3;
+        else if ( status == 0xF0 ) {
+          // A MIDI sysex
+          if ( data->ignoreFlags & 0x01 ) {
+            size = 0;
+            iByte = nBytes;
+          }
+          else size = nBytes - iByte;
+          continueSysex = packet->data[nBytes-1] != 0xF7;
+        }
+        else if ( status == 0xF1 ) {
+            // A MIDI time code message
+           if ( data->ignoreFlags & 0x02 ) {
+            size = 0;
+            iByte += 2;
+           }
+           else size = 2;
+        }
+        else if ( status == 0xF2 ) size = 3;
+        else if ( status == 0xF3 ) size = 2;
+        else if ( status == 0xF8 && ( data->ignoreFlags & 0x02 ) ) {
+          // A MIDI timing tick message and we're ignoring it.
+          size = 0;
+          iByte += 1;
+        }
+        else if ( status == 0xFE && ( data->ignoreFlags & 0x04 ) ) {
+          // A MIDI active sensing message and we're ignoring it.
+          size = 0;
+          iByte += 1;
+        }
+        else size = 1;
+
+        // Copy the MIDI data to our vector.
+        if ( size ) {
+          message.bytes.assign( &packet->data[iByte], &packet->data[iByte+size] );
+          if ( !continueSysex ) {
+            // If not a continuing sysex message, invoke the user callback function or queue the message.
+            if ( data->usingCallback ) {
+              RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
+              callback( message.timeStamp, &message.bytes, data->userData );
+            }
+            else {
+              // As long as we haven't reached our queue size limit, push the message.
+              if ( data->queue.size < data->queue.ringSize ) {
+                data->queue.ring[data->queue.back++] = message;
+                if ( data->queue.back == data->queue.ringSize )
+                  data->queue.back = 0;
+                data->queue.size++;
+              }
+              else
+                std::cerr << "\nMidiInCore: message queue limit reached!!\n\n";
+            }
+            message.bytes.clear();
+          }
+          iByte += size;
+        }
+      }
+    }
+    packet = MIDIPacketNext(packet);
+  }
+}
+
+MidiInCore :: MidiInCore( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
+{
+  initialize( clientName );
+}
+
+MidiInCore :: ~MidiInCore( void )
+{
+  // Close a connection if it exists.
+  closePort();
+
+  // Cleanup.
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+  MIDIClientDispose( data->client );
+  if ( data->endpoint ) MIDIEndpointDispose( data->endpoint );
+  delete data;
+}
+
+void MidiInCore :: initialize( const std::string& clientName )
+{
+  // Set up our client.
+  MIDIClientRef client;
+  OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
+  if ( result != noErr ) {
+    errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Save our api-specific connection information.
+  CoreMidiData *data = (CoreMidiData *) new CoreMidiData;
+  data->client = client;
+  data->endpoint = 0;
+  apiData_ = (void *) data;
+  inputData_.apiData = (void *) data;
+}
+
+void MidiInCore :: openPort( unsigned int portNumber, const std::string portName )
+{
+  if ( connected_ ) {
+    errorString_ = "MidiInCore::openPort: a valid connection already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
+  unsigned int nSrc = MIDIGetNumberOfSources();
+  if (nSrc < 1) {
+    errorString_ = "MidiInCore::openPort: no MIDI input sources found!";
+    error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
+    return;
+  }
+
+  if ( portNumber >= nSrc ) {
+    std::ostringstream ost;
+    ost << "MidiInCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::INVALID_PARAMETER, errorString_ );
+    return;
+  }
+
+  MIDIPortRef port;
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+  OSStatus result = MIDIInputPortCreate( data->client, 
+                                         CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
+                                         midiInputCallback, (void *)&inputData_, &port );
+  if ( result != noErr ) {
+    MIDIClientDispose( data->client );
+    errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Get the desired input source identifier.
+  MIDIEndpointRef endpoint = MIDIGetSource( portNumber );
+  if ( endpoint == 0 ) {
+    MIDIPortDispose( port );
+    MIDIClientDispose( data->client );
+    errorString_ = "MidiInCore::openPort: error getting MIDI input source reference.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Make the connection.
+  result = MIDIPortConnectSource( port, endpoint, NULL );
+  if ( result != noErr ) {
+    MIDIPortDispose( port );
+    MIDIClientDispose( data->client );
+    errorString_ = "MidiInCore::openPort: error connecting OS-X MIDI input port.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Save our api-specific port information.
+  data->port = port;
+
+  connected_ = true;
+}
+
+void MidiInCore :: openVirtualPort( const std::string portName )
+{
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+
+  // Create a virtual MIDI input destination.
+  MIDIEndpointRef endpoint;
+  OSStatus result = MIDIDestinationCreate( data->client,
+                                           CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
+                                           midiInputCallback, (void *)&inputData_, &endpoint );
+  if ( result != noErr ) {
+    errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Save our api-specific connection information.
+  data->endpoint = endpoint;
+}
+
+void MidiInCore :: closePort( void )
+{
+  if ( connected_ ) {
+    CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+    MIDIPortDispose( data->port );
+    connected_ = false;
+  }
+}
+
+unsigned int MidiInCore :: getPortCount()
+{
+  CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
+  return MIDIGetNumberOfSources();
+}
+
+// This function was submitted by Douglas Casey Tucker and apparently
+// derived largely from PortMidi.
+CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal )
+{
+  CFMutableStringRef result = CFStringCreateMutable( NULL, 0 );
+  CFStringRef str;
+
+  // Begin with the endpoint's name.
+  str = NULL;
+  MIDIObjectGetStringProperty( endpoint, kMIDIPropertyName, &str );
+  if ( str != NULL ) {
+    CFStringAppend( result, str );
+    CFRelease( str );
+  }
+
+  MIDIEntityRef entity = 0;
+  MIDIEndpointGetEntity( endpoint, &entity );
+  if ( entity == 0 )
+    // probably virtual
+    return result;
+
+  if ( CFStringGetLength( result ) == 0 ) {
+    // endpoint name has zero length -- try the entity
+    str = NULL;
+    MIDIObjectGetStringProperty( entity, kMIDIPropertyName, &str );
+    if ( str != NULL ) {
+      CFStringAppend( result, str );
+      CFRelease( str );
+    }
+  }
+  // now consider the device's name
+  MIDIDeviceRef device = 0;
+  MIDIEntityGetDevice( entity, &device );
+  if ( device == 0 )
+    return result;
+
+  str = NULL;
+  MIDIObjectGetStringProperty( device, kMIDIPropertyName, &str );
+  if ( CFStringGetLength( result ) == 0 ) {
+      CFRelease( result );
+      return str;
+  }
+  if ( str != NULL ) {
+    // if an external device has only one entity, throw away
+    // the endpoint name and just use the device name
+    if ( isExternal && MIDIDeviceGetNumberOfEntities( device ) < 2 ) {
+      CFRelease( result );
+      return str;
+    } else {
+      if ( CFStringGetLength( str ) == 0 ) {
+        CFRelease( str );
+        return result;
+      }
+      // does the entity name already start with the device name?
+      // (some drivers do this though they shouldn't)
+      // if so, do not prepend
+        if ( CFStringCompareWithOptions( result, /* endpoint name */
+             str /* device name */,
+             CFRangeMake(0, CFStringGetLength( str ) ), 0 ) != kCFCompareEqualTo ) {
+        // prepend the device name to the entity name
+        if ( CFStringGetLength( result ) > 0 )
+          CFStringInsert( result, 0, CFSTR(" ") );
+        CFStringInsert( result, 0, str );
+      }
+      CFRelease( str );
+    }
+  }
+  return result;
+}
+
+// This function was submitted by Douglas Casey Tucker and apparently
+// derived largely from PortMidi.
+static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint )
+{
+  CFMutableStringRef result = CFStringCreateMutable( NULL, 0 );
+  CFStringRef str;
+  OSStatus err;
+  int i;
+
+  // Does the endpoint have connections?
+  CFDataRef connections = NULL;
+  int nConnected = 0;
+  bool anyStrings = false;
+  err = MIDIObjectGetDataProperty( endpoint, kMIDIPropertyConnectionUniqueID, &connections );
+  if ( connections != NULL ) {
+    // It has connections, follow them
+    // Concatenate the names of all connected devices
+    nConnected = CFDataGetLength( connections ) / sizeof(MIDIUniqueID);
+    if ( nConnected ) {
+      const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections));
+      for ( i=0; i<nConnected; ++i, ++pid ) {
+        MIDIUniqueID id = EndianS32_BtoN( *pid );
+        MIDIObjectRef connObject;
+        MIDIObjectType connObjectType;
+        err = MIDIObjectFindByUniqueID( id, &connObject, &connObjectType );
+        if ( err == noErr ) {
+          if ( connObjectType == kMIDIObjectType_ExternalSource  ||
+              connObjectType == kMIDIObjectType_ExternalDestination ) {
+            // Connected to an external device's endpoint (10.3 and later).
+            str = EndpointName( (MIDIEndpointRef)(connObject), true );
+          } else {
+            // Connected to an external device (10.2) (or something else, catch-
+            str = NULL;
+            MIDIObjectGetStringProperty( connObject, kMIDIPropertyName, &str );
+          }
+          if ( str != NULL ) {
+            if ( anyStrings )
+              CFStringAppend( result, CFSTR(", ") );
+            else anyStrings = true;
+            CFStringAppend( result, str );
+            CFRelease( str );
+          }
+        }
+      }
+    }
+    CFRelease( connections );
+  }
+  if ( anyStrings )
+    return result;
+
+  // Here, either the endpoint had no connections, or we failed to obtain names 
+  return EndpointName( endpoint, false );
+}
+
+std::string MidiInCore :: getPortName( unsigned int portNumber )
+{
+  CFStringRef nameRef;
+  MIDIEndpointRef portRef;
+  char name[128];
+
+  std::string stringName;
+  CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
+  if ( portNumber >= MIDIGetNumberOfSources() ) {
+    std::ostringstream ost;
+    ost << "MidiInCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::WARNING, errorString_ );
+    return stringName;
+  }
+
+  portRef = MIDIGetSource( portNumber );
+  nameRef = ConnectedEndpointName(portRef);
+  CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding());
+  CFRelease( nameRef );
+
+  return stringName = name;
+}
+
+//*********************************************************************//
+//  API: OS-X
+//  Class Definitions: MidiOutCore
+//*********************************************************************//
+
+MidiOutCore :: MidiOutCore( const std::string clientName ) : MidiOutApi()
+{
+  initialize( clientName );
+}
+
+MidiOutCore :: ~MidiOutCore( void )
+{
+  // Close a connection if it exists.
+  closePort();
+
+  // Cleanup.
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+  MIDIClientDispose( data->client );
+  if ( data->endpoint ) MIDIEndpointDispose( data->endpoint );
+  delete data;
+}
+
+void MidiOutCore :: initialize( const std::string& clientName )
+{
+  // Set up our client.
+  MIDIClientRef client;
+  OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
+  if ( result != noErr ) {
+    errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Save our api-specific connection information.
+  CoreMidiData *data = (CoreMidiData *) new CoreMidiData;
+  data->client = client;
+  data->endpoint = 0;
+  apiData_ = (void *) data;
+}
+
+unsigned int MidiOutCore :: getPortCount()
+{
+  CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
+  return MIDIGetNumberOfDestinations();
+}
+
+std::string MidiOutCore :: getPortName( unsigned int portNumber )
+{
+  CFStringRef nameRef;
+  MIDIEndpointRef portRef;
+  char name[128];
+
+  std::string stringName;
+  CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
+  if ( portNumber >= MIDIGetNumberOfDestinations() ) {
+    std::ostringstream ost;
+    ost << "MidiOutCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::WARNING, errorString_ );
+    return stringName;
+  }
+
+  portRef = MIDIGetDestination( portNumber );
+  nameRef = ConnectedEndpointName(portRef);
+  CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding());
+  CFRelease( nameRef );
+  
+  return stringName = name;
+}
+
+void MidiOutCore :: openPort( unsigned int portNumber, const std::string portName )
+{
+  if ( connected_ ) {
+    errorString_ = "MidiOutCore::openPort: a valid connection already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false );
+  unsigned int nDest = MIDIGetNumberOfDestinations();
+  if (nDest < 1) {
+    errorString_ = "MidiOutCore::openPort: no MIDI output destinations found!";
+    error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
+    return;
+  }
+
+  if ( portNumber >= nDest ) {
+    std::ostringstream ost;
+    ost << "MidiOutCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::INVALID_PARAMETER, errorString_ );
+    return;
+  }
+
+  MIDIPortRef port;
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+  OSStatus result = MIDIOutputPortCreate( data->client, 
+                                          CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
+                                          &port );
+  if ( result != noErr ) {
+    MIDIClientDispose( data->client );
+    errorString_ = "MidiOutCore::openPort: error creating OS-X MIDI output port.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Get the desired output port identifier.
+  MIDIEndpointRef destination = MIDIGetDestination( portNumber );
+  if ( destination == 0 ) {
+    MIDIPortDispose( port );
+    MIDIClientDispose( data->client );
+    errorString_ = "MidiOutCore::openPort: error getting MIDI output destination reference.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Save our api-specific connection information.
+  data->port = port;
+  data->destinationId = destination;
+  connected_ = true;
+}
+
+void MidiOutCore :: closePort( void )
+{
+  if ( connected_ ) {
+    CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+    MIDIPortDispose( data->port );
+    connected_ = false;
+  }
+}
+
+void MidiOutCore :: openVirtualPort( std::string portName )
+{
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+
+  if ( data->endpoint ) {
+    errorString_ = "MidiOutCore::openVirtualPort: a virtual output port already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  // Create a virtual MIDI output source.
+  MIDIEndpointRef endpoint;
+  OSStatus result = MIDISourceCreate( data->client,
+                                      CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
+                                      &endpoint );
+  if ( result != noErr ) {
+    errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Save our api-specific connection information.
+  data->endpoint = endpoint;
+}
+
+// Not necessary if we don't treat sysex messages any differently than
+// normal messages ... see below.
+//static void sysexCompletionProc( MIDISysexSendRequest *sreq )
+//{
+//  free( sreq );
+//}
+
+void MidiOutCore :: sendMessage( std::vector<unsigned char> *message )
+{
+  // We use the MIDISendSysex() function to asynchronously send sysex
+  // messages.  Otherwise, we use a single CoreMidi MIDIPacket.
+  unsigned int nBytes = message->size();
+  if ( nBytes == 0 ) {
+    errorString_ = "MidiOutCore::sendMessage: no data in message argument!";      
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  //  unsigned int packetBytes, bytesLeft = nBytes;
+  //  unsigned int messageIndex = 0;
+  MIDITimeStamp timeStamp = AudioGetCurrentHostTime();
+  CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
+  OSStatus result;
+
+  /*
+    // I don't think this code is necessary.  We can send sysex
+    // messages through the normal mechanism.  In addition, this avoids
+    // the problem of virtual ports not receiving sysex messages.
+
+  if ( message->at(0) == 0xF0 ) {
+
+    // Apple's fantastic API requires us to free the allocated data in
+    // the completion callback but trashes the pointer and size before
+    // we get a chance to free it!!  This is a somewhat ugly hack
+    // submitted by ptarabbia that puts the sysex buffer data right at
+    // the end of the MIDISysexSendRequest structure.  This solution
+    // does not require that we wait for a previous sysex buffer to be
+    // sent before sending a new one, which was the old way we did it.
+    MIDISysexSendRequest *newRequest = (MIDISysexSendRequest *) malloc(sizeof(struct MIDISysexSendRequest) + nBytes);
+    char * sysexBuffer = ((char *) newRequest) + sizeof(struct MIDISysexSendRequest);
+
+    // Copy data to buffer.
+    for ( unsigned int i=0; i<nBytes; ++i ) sysexBuffer[i] = message->at(i);
+
+    newRequest->destination = data->destinationId;
+    newRequest->data = (Byte *)sysexBuffer;
+    newRequest->bytesToSend = nBytes;
+    newRequest->complete = 0;
+    newRequest->completionProc = sysexCompletionProc;
+    newRequest->completionRefCon = newRequest;
+
+    result = MIDISendSysex(newRequest);
+    if ( result != noErr ) {
+      free( newRequest );
+      errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations.";
+      error( RtMidiError::WARNING, errorString_ );
+      return;
+    }
+    return;
+  }
+  else if ( nBytes > 3 ) {
+    errorString_ = "MidiOutCore::sendMessage: message format problem ... not sysex but > 3 bytes?";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+  */
+
+  MIDIPacketList packetList;
+  MIDIPacket *packet = MIDIPacketListInit( &packetList );
+  packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) );
+  if ( !packet ) {
+    errorString_ = "MidiOutCore::sendMessage: could not allocate packet list";      
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Send to any destinations that may have connected to us.
+  if ( data->endpoint ) {
+    result = MIDIReceived( data->endpoint, &packetList );
+    if ( result != noErr ) {
+      errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations.";
+      error( RtMidiError::WARNING, errorString_ );
+    }
+  }
+
+  // And send to an explicit destination port if we're connected.
+  if ( connected_ ) {
+    result = MIDISend( data->port, data->destinationId, &packetList );
+    if ( result != noErr ) {
+      errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port.";
+      error( RtMidiError::WARNING, errorString_ );
+    }
+  }
+}
+
+#endif  // __MACOSX_CORE__
+
+
+//*********************************************************************//
+//  API: LINUX ALSA SEQUENCER
+//*********************************************************************//
+
+// API information found at:
+//   - http://www.alsa-project.org/documentation.php#Library
+
+#if defined(__LINUX_ALSA__)
+
+// The ALSA Sequencer API is based on the use of a callback function for
+// MIDI input.
+//
+// Thanks to Pedro Lopez-Cabanillas for help with the ALSA sequencer
+// time stamps and other assorted fixes!!!
+
+// If you don't need timestamping for incoming MIDI events, define the
+// preprocessor definition AVOID_TIMESTAMPING to save resources
+// associated with the ALSA sequencer queues.
+
+#include <pthread.h>
+#include <sys/time.h>
+
+// ALSA header file.
+#include <alsa/asoundlib.h>
+
+// A structure to hold variables related to the ALSA API
+// implementation.
+struct AlsaMidiData {
+  snd_seq_t *seq;
+  unsigned int portNum;
+  int vport;
+  snd_seq_port_subscribe_t *subscription;
+  snd_midi_event_t *coder;
+  unsigned int bufferSize;
+  unsigned char *buffer;
+  pthread_t thread;
+  pthread_t dummy_thread_id;
+  unsigned long long lastTime;
+  int queue_id; // an input queue is needed to get timestamped events
+  int trigger_fds[2];
+};
+
+#define PORT_TYPE( pinfo, bits ) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
+
+//*********************************************************************//
+//  API: LINUX ALSA
+//  Class Definitions: MidiInAlsa
+//*********************************************************************//
+
+static void *alsaMidiHandler( void *ptr )
+{
+  MidiInApi::RtMidiInData *data = static_cast<MidiInApi::RtMidiInData *> (ptr);
+  AlsaMidiData *apiData = static_cast<AlsaMidiData *> (data->apiData);
+
+  long nBytes;
+  unsigned long long time, lastTime;
+  bool continueSysex = false;
+  bool doDecode = false;
+  MidiInApi::MidiMessage message;
+  int poll_fd_count;
+  struct pollfd *poll_fds;
+
+  snd_seq_event_t *ev;
+  int result;
+  apiData->bufferSize = 32;
+  result = snd_midi_event_new( 0, &apiData->coder );
+  if ( result < 0 ) {
+    data->doInput = false;
+    std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing MIDI event parser!\n\n";
+    return 0;
+  }
+  unsigned char *buffer = (unsigned char *) malloc( apiData->bufferSize );
+  if ( buffer == NULL ) {
+    data->doInput = false;
+    snd_midi_event_free( apiData->coder );
+    apiData->coder = 0;
+    std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing buffer memory!\n\n";
+    return 0;
+  }
+  snd_midi_event_init( apiData->coder );
+  snd_midi_event_no_status( apiData->coder, 1 ); // suppress running status messages
+
+  poll_fd_count = snd_seq_poll_descriptors_count( apiData->seq, POLLIN ) + 1;
+  poll_fds = (struct pollfd*)alloca( poll_fd_count * sizeof( struct pollfd ));
+  snd_seq_poll_descriptors( apiData->seq, poll_fds + 1, poll_fd_count - 1, POLLIN );
+  poll_fds[0].fd = apiData->trigger_fds[0];
+  poll_fds[0].events = POLLIN;
+
+  while ( data->doInput ) {
+
+    if ( snd_seq_event_input_pending( apiData->seq, 1 ) == 0 ) {
+      // No data pending
+      if ( poll( poll_fds, poll_fd_count, -1) >= 0 ) {
+        if ( poll_fds[0].revents & POLLIN ) {
+          bool dummy;
+          int res = read( poll_fds[0].fd, &dummy, sizeof(dummy) );
+          (void) res;
+        }
+      }
+      continue;
+    }
+
+    // If here, there should be data.
+    result = snd_seq_event_input( apiData->seq, &ev );
+    if ( result == -ENOSPC ) {
+      std::cerr << "\nMidiInAlsa::alsaMidiHandler: MIDI input buffer overrun!\n\n";
+      continue;
+    }
+    else if ( result <= 0 ) {
+      std::cerr << "\nMidiInAlsa::alsaMidiHandler: unknown MIDI input error!\n";
+      perror("System reports");
+      continue;
+    }
+
+    // This is a bit weird, but we now have to decode an ALSA MIDI
+    // event (back) into MIDI bytes.  We'll ignore non-MIDI types.
+    if ( !continueSysex ) message.bytes.clear();
+
+    doDecode = false;
+    switch ( ev->type ) {
+
+    case SND_SEQ_EVENT_PORT_SUBSCRIBED:
+#if defined(__RTMIDI_DEBUG__)
+      std::cout << "MidiInAlsa::alsaMidiHandler: port connection made!\n";
+#endif
+      break;
+
+    case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
+#if defined(__RTMIDI_DEBUG__)
+      std::cerr << "MidiInAlsa::alsaMidiHandler: port connection has closed!\n";
+      std::cout << "sender = " << (int) ev->data.connect.sender.client << ":"
+                << (int) ev->data.connect.sender.port
+                << ", dest = " << (int) ev->data.connect.dest.client << ":"
+                << (int) ev->data.connect.dest.port
+                << std::endl;
+#endif
+      break;
+
+    case SND_SEQ_EVENT_QFRAME: // MIDI time code
+      if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true;
+      break;
+
+    case SND_SEQ_EVENT_TICK: // 0xF9 ... MIDI timing tick
+      if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true;
+      break;
+
+    case SND_SEQ_EVENT_CLOCK: // 0xF8 ... MIDI timing (clock) tick
+      if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true;
+      break;
+
+    case SND_SEQ_EVENT_SENSING: // Active sensing
+      if ( !( data->ignoreFlags & 0x04 ) ) doDecode = true;
+      break;
+
+		case SND_SEQ_EVENT_SYSEX:
+      if ( (data->ignoreFlags & 0x01) ) break;
+      if ( ev->data.ext.len > apiData->bufferSize ) {
+        apiData->bufferSize = ev->data.ext.len;
+        free( buffer );
+        buffer = (unsigned char *) malloc( apiData->bufferSize );
+        if ( buffer == NULL ) {
+          data->doInput = false;
+          std::cerr << "\nMidiInAlsa::alsaMidiHandler: error resizing buffer memory!\n\n";
+          break;
+        }
+      }
+
+    default:
+      doDecode = true;
+    }
+
+    if ( doDecode ) {
+
+      nBytes = snd_midi_event_decode( apiData->coder, buffer, apiData->bufferSize, ev );
+      if ( nBytes > 0 ) {
+        // The ALSA sequencer has a maximum buffer size for MIDI sysex
+        // events of 256 bytes.  If a device sends sysex messages larger
+        // than this, they are segmented into 256 byte chunks.  So,
+        // we'll watch for this and concatenate sysex chunks into a
+        // single sysex message if necessary.
+        if ( !continueSysex )
+          message.bytes.assign( buffer, &buffer[nBytes] );
+        else
+          message.bytes.insert( message.bytes.end(), buffer, &buffer[nBytes] );
+
+        continueSysex = ( ( ev->type == SND_SEQ_EVENT_SYSEX ) && ( message.bytes.back() != 0xF7 ) );
+        if ( !continueSysex ) {
+
+          // Calculate the time stamp:
+          message.timeStamp = 0.0;
+
+          // Method 1: Use the system time.
+          //(void)gettimeofday(&tv, (struct timezone *)NULL);
+          //time = (tv.tv_sec * 1000000) + tv.tv_usec;
+
+          // Method 2: Use the ALSA sequencer event time data.
+          // (thanks to Pedro Lopez-Cabanillas!).
+          time = ( ev->time.time.tv_sec * 1000000 ) + ( ev->time.time.tv_nsec/1000 );
+          lastTime = time;
+          time -= apiData->lastTime;
+          apiData->lastTime = lastTime;
+          if ( data->firstMessage == true )
+            data->firstMessage = false;
+          else
+            message.timeStamp = time * 0.000001;
+        }
+        else {
+#if defined(__RTMIDI_DEBUG__)
+          std::cerr << "\nMidiInAlsa::alsaMidiHandler: event parsing error or not a MIDI event!\n\n";
+#endif
+        }
+      }
+    }
+
+    snd_seq_free_event( ev );
+    if ( message.bytes.size() == 0 || continueSysex ) continue;
+
+    if ( data->usingCallback ) {
+      RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
+      callback( message.timeStamp, &message.bytes, data->userData );
+    }
+    else {
+      // As long as we haven't reached our queue size limit, push the message.
+      if ( data->queue.size < data->queue.ringSize ) {
+        data->queue.ring[data->queue.back++] = message;
+        if ( data->queue.back == data->queue.ringSize )
+          data->queue.back = 0;
+        data->queue.size++;
+      }
+      else
+        std::cerr << "\nMidiInAlsa: message queue limit reached!!\n\n";
+    }
+  }
+
+  if ( buffer ) free( buffer );
+  snd_midi_event_free( apiData->coder );
+  apiData->coder = 0;
+  apiData->thread = apiData->dummy_thread_id;
+  return 0;
+}
+
+MidiInAlsa :: MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
+{
+  initialize( clientName );
+}
+
+MidiInAlsa :: ~MidiInAlsa()
+{
+  // Close a connection if it exists.
+  closePort();
+
+  // Shutdown the input thread.
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( inputData_.doInput ) {
+    inputData_.doInput = false;
+    int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) );
+    (void) res;
+    if ( !pthread_equal(data->thread, data->dummy_thread_id) )
+      pthread_join( data->thread, NULL );
+  }
+
+  // Cleanup.
+  close ( data->trigger_fds[0] );
+  close ( data->trigger_fds[1] );
+  if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport );
+#ifndef AVOID_TIMESTAMPING
+  snd_seq_free_queue( data->seq, data->queue_id );
+#endif
+  snd_seq_close( data->seq );
+  delete data;
+}
+
+void MidiInAlsa :: initialize( const std::string& clientName )
+{
+  // Set up the ALSA sequencer client.
+  snd_seq_t *seq;
+  int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
+  if ( result < 0 ) {
+    errorString_ = "MidiInAlsa::initialize: error creating ALSA sequencer client object.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Set client name.
+  snd_seq_set_client_name( seq, clientName.c_str() );
+
+  // Save our api-specific connection information.
+  AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData;
+  data->seq = seq;
+  data->portNum = -1;
+  data->vport = -1;
+  data->subscription = 0;
+  data->dummy_thread_id = pthread_self();
+  data->thread = data->dummy_thread_id;
+  data->trigger_fds[0] = -1;
+  data->trigger_fds[1] = -1;
+  apiData_ = (void *) data;
+  inputData_.apiData = (void *) data;
+
+   if ( pipe(data->trigger_fds) == -1 ) {
+    errorString_ = "MidiInAlsa::initialize: error creating pipe objects.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Create the input queue
+#ifndef AVOID_TIMESTAMPING
+  data->queue_id = snd_seq_alloc_named_queue(seq, "RtMidi Queue");
+  // Set arbitrary tempo (mm=100) and resolution (240)
+  snd_seq_queue_tempo_t *qtempo;
+  snd_seq_queue_tempo_alloca(&qtempo);
+  snd_seq_queue_tempo_set_tempo(qtempo, 600000);
+  snd_seq_queue_tempo_set_ppq(qtempo, 240);
+  snd_seq_set_queue_tempo(data->seq, data->queue_id, qtempo);
+  snd_seq_drain_output(data->seq);
+#endif
+}
+
+// This function is used to count or get the pinfo structure for a given port number.
+unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int type, int portNumber )
+{
+  snd_seq_client_info_t *cinfo;
+  int client;
+  int count = 0;
+  snd_seq_client_info_alloca( &cinfo );
+
+  snd_seq_client_info_set_client( cinfo, -1 );
+  while ( snd_seq_query_next_client( seq, cinfo ) >= 0 ) {
+    client = snd_seq_client_info_get_client( cinfo );
+    if ( client == 0 ) continue;
+    // Reset query info
+    snd_seq_port_info_set_client( pinfo, client );
+    snd_seq_port_info_set_port( pinfo, -1 );
+    while ( snd_seq_query_next_port( seq, pinfo ) >= 0 ) {
+      unsigned int atyp = snd_seq_port_info_get_type( pinfo );
+      if ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) continue;
+      unsigned int caps = snd_seq_port_info_get_capability( pinfo );
+      if ( ( caps & type ) != type ) continue;
+      if ( count == portNumber ) return 1;
+      ++count;
+    }
+  }
+
+  // If a negative portNumber was used, return the port count.
+  if ( portNumber < 0 ) return count;
+  return 0;
+}
+
+unsigned int MidiInAlsa :: getPortCount()
+{
+  snd_seq_port_info_t *pinfo;
+  snd_seq_port_info_alloca( &pinfo );
+
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, -1 );
+}
+
+std::string MidiInAlsa :: getPortName( unsigned int portNumber )
+{
+  snd_seq_client_info_t *cinfo;
+  snd_seq_port_info_t *pinfo;
+  snd_seq_client_info_alloca( &cinfo );
+  snd_seq_port_info_alloca( &pinfo );
+
+  std::string stringName;
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) ) {
+    int cnum = snd_seq_port_info_get_client( pinfo );
+    snd_seq_get_any_client_info( data->seq, cnum, cinfo );
+    std::ostringstream os;
+    os << snd_seq_client_info_get_name( cinfo );
+    os << " ";                                    // These lines added to make sure devices are listed
+    os << snd_seq_port_info_get_client( pinfo );  // with full portnames added to ensure individual device names
+    os << ":";
+    os << snd_seq_port_info_get_port( pinfo );
+    stringName = os.str();
+    return stringName;
+  }
+
+  // If we get here, we didn't find a match.
+  errorString_ = "MidiInAlsa::getPortName: error looking for port name!";
+  error( RtMidiError::WARNING, errorString_ );
+  return stringName;
+}
+
+void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName )
+{
+  if ( connected_ ) {
+    errorString_ = "MidiInAlsa::openPort: a valid connection already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  unsigned int nSrc = this->getPortCount();
+  if ( nSrc < 1 ) {
+    errorString_ = "MidiInAlsa::openPort: no MIDI input sources found!";
+    error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
+    return;
+  }
+
+  snd_seq_port_info_t *src_pinfo;
+  snd_seq_port_info_alloca( &src_pinfo );
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( portInfo( data->seq, src_pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) {
+    std::ostringstream ost;
+    ost << "MidiInAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::INVALID_PARAMETER, errorString_ );
+    return;
+  }
+
+  snd_seq_addr_t sender, receiver;
+  sender.client = snd_seq_port_info_get_client( src_pinfo );
+  sender.port = snd_seq_port_info_get_port( src_pinfo );
+
+  snd_seq_port_info_t *pinfo;
+  snd_seq_port_info_alloca( &pinfo );
+  if ( data->vport < 0 ) {
+    snd_seq_port_info_set_client( pinfo, 0 );
+    snd_seq_port_info_set_port( pinfo, 0 );
+    snd_seq_port_info_set_capability( pinfo,
+                                      SND_SEQ_PORT_CAP_WRITE |
+                                      SND_SEQ_PORT_CAP_SUBS_WRITE );
+    snd_seq_port_info_set_type( pinfo,
+                                SND_SEQ_PORT_TYPE_MIDI_GENERIC |
+                                SND_SEQ_PORT_TYPE_APPLICATION );
+    snd_seq_port_info_set_midi_channels(pinfo, 16);
+#ifndef AVOID_TIMESTAMPING
+    snd_seq_port_info_set_timestamping(pinfo, 1);
+    snd_seq_port_info_set_timestamp_real(pinfo, 1);    
+    snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id);
+#endif
+    snd_seq_port_info_set_name(pinfo,  portName.c_str() );
+    data->vport = snd_seq_create_port(data->seq, pinfo);
+  
+    if ( data->vport < 0 ) {
+      errorString_ = "MidiInAlsa::openPort: ALSA error creating input port.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+    data->vport = snd_seq_port_info_get_port(pinfo);
+  }
+
+  receiver.client = snd_seq_port_info_get_client( pinfo );
+  receiver.port = data->vport;
+
+  if ( !data->subscription ) {
+    // Make subscription
+    if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) {
+      errorString_ = "MidiInAlsa::openPort: ALSA error allocation port subscription.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+    snd_seq_port_subscribe_set_sender(data->subscription, &sender);
+    snd_seq_port_subscribe_set_dest(data->subscription, &receiver);
+    if ( snd_seq_subscribe_port(data->seq, data->subscription) ) {
+      snd_seq_port_subscribe_free( data->subscription );
+      data->subscription = 0;
+      errorString_ = "MidiInAlsa::openPort: ALSA error making port connection.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+  }
+
+  if ( inputData_.doInput == false ) {
+    // Start the input queue
+#ifndef AVOID_TIMESTAMPING
+    snd_seq_start_queue( data->seq, data->queue_id, NULL );
+    snd_seq_drain_output( data->seq );
+#endif
+    // Start our MIDI input thread.
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
+
+    inputData_.doInput = true;
+    int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_);
+    pthread_attr_destroy(&attr);
+    if ( err ) {
+      snd_seq_unsubscribe_port( data->seq, data->subscription );
+      snd_seq_port_subscribe_free( data->subscription );
+      data->subscription = 0;
+      inputData_.doInput = false;
+      errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!";
+      error( RtMidiError::THREAD_ERROR, errorString_ );
+      return;
+    }
+  }
+
+  connected_ = true;
+}
+
+void MidiInAlsa :: openVirtualPort( std::string portName )
+{
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( data->vport < 0 ) {
+    snd_seq_port_info_t *pinfo;
+    snd_seq_port_info_alloca( &pinfo );
+    snd_seq_port_info_set_capability( pinfo,
+				      SND_SEQ_PORT_CAP_WRITE |
+				      SND_SEQ_PORT_CAP_SUBS_WRITE );
+    snd_seq_port_info_set_type( pinfo,
+				SND_SEQ_PORT_TYPE_MIDI_GENERIC |
+				SND_SEQ_PORT_TYPE_APPLICATION );
+    snd_seq_port_info_set_midi_channels(pinfo, 16);
+#ifndef AVOID_TIMESTAMPING
+    snd_seq_port_info_set_timestamping(pinfo, 1);
+    snd_seq_port_info_set_timestamp_real(pinfo, 1);    
+    snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id);
+#endif
+    snd_seq_port_info_set_name(pinfo, portName.c_str());
+    data->vport = snd_seq_create_port(data->seq, pinfo);
+
+    if ( data->vport < 0 ) {
+      errorString_ = "MidiInAlsa::openVirtualPort: ALSA error creating virtual port.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+    data->vport = snd_seq_port_info_get_port(pinfo);
+  }
+
+  if ( inputData_.doInput == false ) {
+    // Wait for old thread to stop, if still running
+    if ( !pthread_equal(data->thread, data->dummy_thread_id) )
+      pthread_join( data->thread, NULL );
+
+    // Start the input queue
+#ifndef AVOID_TIMESTAMPING
+    snd_seq_start_queue( data->seq, data->queue_id, NULL );
+    snd_seq_drain_output( data->seq );
+#endif
+    // Start our MIDI input thread.
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
+
+    inputData_.doInput = true;
+    int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_);
+    pthread_attr_destroy(&attr);
+    if ( err ) {
+      if ( data->subscription ) {
+        snd_seq_unsubscribe_port( data->seq, data->subscription );
+        snd_seq_port_subscribe_free( data->subscription );
+        data->subscription = 0;
+      }
+      inputData_.doInput = false;
+      errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!";
+      error( RtMidiError::THREAD_ERROR, errorString_ );
+      return;
+    }
+  }
+}
+
+void MidiInAlsa :: closePort( void )
+{
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+
+  if ( connected_ ) {
+    if ( data->subscription ) {
+      snd_seq_unsubscribe_port( data->seq, data->subscription );
+      snd_seq_port_subscribe_free( data->subscription );
+      data->subscription = 0;
+    }
+    // Stop the input queue
+#ifndef AVOID_TIMESTAMPING
+    snd_seq_stop_queue( data->seq, data->queue_id, NULL );
+    snd_seq_drain_output( data->seq );
+#endif
+    connected_ = false;
+  }
+
+  // Stop thread to avoid triggering the callback, while the port is intended to be closed
+  if ( inputData_.doInput ) {
+    inputData_.doInput = false;
+    int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) );
+    (void) res;
+    if ( !pthread_equal(data->thread, data->dummy_thread_id) )
+      pthread_join( data->thread, NULL );
+  }
+}
+
+//*********************************************************************//
+//  API: LINUX ALSA
+//  Class Definitions: MidiOutAlsa
+//*********************************************************************//
+
+MidiOutAlsa :: MidiOutAlsa( const std::string clientName ) : MidiOutApi()
+{
+  initialize( clientName );
+}
+
+MidiOutAlsa :: ~MidiOutAlsa()
+{
+  // Close a connection if it exists.
+  closePort();
+
+  // Cleanup.
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport );
+  if ( data->coder ) snd_midi_event_free( data->coder );
+  if ( data->buffer ) free( data->buffer );
+  snd_seq_close( data->seq );
+  delete data;
+}
+
+void MidiOutAlsa :: initialize( const std::string& clientName )
+{
+  // Set up the ALSA sequencer client.
+  snd_seq_t *seq;
+  int result1 = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK );
+  if ( result1 < 0 ) {
+    errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+	}
+
+  // Set client name.
+  snd_seq_set_client_name( seq, clientName.c_str() );
+
+  // Save our api-specific connection information.
+  AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData;
+  data->seq = seq;
+  data->portNum = -1;
+  data->vport = -1;
+  data->bufferSize = 32;
+  data->coder = 0;
+  data->buffer = 0;
+  int result = snd_midi_event_new( data->bufferSize, &data->coder );
+  if ( result < 0 ) {
+    delete data;
+    errorString_ = "MidiOutAlsa::initialize: error initializing MIDI event parser!\n\n";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+  data->buffer = (unsigned char *) malloc( data->bufferSize );
+  if ( data->buffer == NULL ) {
+    delete data;
+    errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n";
+    error( RtMidiError::MEMORY_ERROR, errorString_ );
+    return;
+  }
+  snd_midi_event_init( data->coder );
+  apiData_ = (void *) data;
+}
+
+unsigned int MidiOutAlsa :: getPortCount()
+{
+	snd_seq_port_info_t *pinfo;
+	snd_seq_port_info_alloca( &pinfo );
+
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, -1 );
+}
+
+std::string MidiOutAlsa :: getPortName( unsigned int portNumber )
+{
+  snd_seq_client_info_t *cinfo;
+  snd_seq_port_info_t *pinfo;
+  snd_seq_client_info_alloca( &cinfo );
+  snd_seq_port_info_alloca( &pinfo );
+
+  std::string stringName;
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) ) {
+    int cnum = snd_seq_port_info_get_client(pinfo);
+    snd_seq_get_any_client_info( data->seq, cnum, cinfo );
+    std::ostringstream os;
+    os << snd_seq_client_info_get_name(cinfo);
+    os << " ";                                    // These lines added to make sure devices are listed
+    os << snd_seq_port_info_get_client( pinfo );  // with full portnames added to ensure individual device names
+    os << ":";
+    os << snd_seq_port_info_get_port(pinfo);
+    stringName = os.str();
+    return stringName;
+  }
+
+  // If we get here, we didn't find a match.
+  errorString_ = "MidiOutAlsa::getPortName: error looking for port name!";
+  error( RtMidiError::WARNING, errorString_ );
+  return stringName;
+}
+
+void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portName )
+{
+  if ( connected_ ) {
+    errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  unsigned int nSrc = this->getPortCount();
+  if (nSrc < 1) {
+    errorString_ = "MidiOutAlsa::openPort: no MIDI output sources found!";
+    error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
+    return;
+  }
+
+	snd_seq_port_info_t *pinfo;
+	snd_seq_port_info_alloca( &pinfo );
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) {
+    std::ostringstream ost;
+    ost << "MidiOutAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::INVALID_PARAMETER, errorString_ );
+    return;
+  }
+
+  snd_seq_addr_t sender, receiver;
+  receiver.client = snd_seq_port_info_get_client( pinfo );
+  receiver.port = snd_seq_port_info_get_port( pinfo );
+  sender.client = snd_seq_client_id( data->seq );
+
+  if ( data->vport < 0 ) {
+    data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(),
+                                              SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
+                                              SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION );
+    if ( data->vport < 0 ) {
+      errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+  }
+
+  sender.port = data->vport;
+
+  // Make subscription
+  if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) {
+    snd_seq_port_subscribe_free( data->subscription );
+    errorString_ = "MidiOutAlsa::openPort: error allocating port subscription.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+  snd_seq_port_subscribe_set_sender(data->subscription, &sender);
+  snd_seq_port_subscribe_set_dest(data->subscription, &receiver);
+  snd_seq_port_subscribe_set_time_update(data->subscription, 1);
+  snd_seq_port_subscribe_set_time_real(data->subscription, 1);
+  if ( snd_seq_subscribe_port(data->seq, data->subscription) ) {
+    snd_seq_port_subscribe_free( data->subscription );
+    errorString_ = "MidiOutAlsa::openPort: ALSA error making port connection.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  connected_ = true;
+}
+
+void MidiOutAlsa :: closePort( void )
+{
+  if ( connected_ ) {
+    AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+    snd_seq_unsubscribe_port( data->seq, data->subscription );
+    snd_seq_port_subscribe_free( data->subscription );
+    connected_ = false;
+  }
+}
+
+void MidiOutAlsa :: openVirtualPort( std::string portName )
+{
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  if ( data->vport < 0 ) {
+    data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(),
+                                              SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
+                                              SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION );
+
+    if ( data->vport < 0 ) {
+      errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+    }
+  }
+}
+
+void MidiOutAlsa :: sendMessage( std::vector<unsigned char> *message )
+{
+  int result;
+  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);
+  unsigned int nBytes = message->size();
+  if ( nBytes > data->bufferSize ) {
+    data->bufferSize = nBytes;
+    result = snd_midi_event_resize_buffer ( data->coder, nBytes);
+    if ( result != 0 ) {
+      errorString_ = "MidiOutAlsa::sendMessage: ALSA error resizing MIDI event buffer.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+    free (data->buffer);
+    data->buffer = (unsigned char *) malloc( data->bufferSize );
+    if ( data->buffer == NULL ) {
+    errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n";
+    error( RtMidiError::MEMORY_ERROR, errorString_ );
+    return;
+    }
+  }
+
+  snd_seq_event_t ev;
+  snd_seq_ev_clear(&ev);
+  snd_seq_ev_set_source(&ev, data->vport);
+  snd_seq_ev_set_subs(&ev);
+  snd_seq_ev_set_direct(&ev);
+  for ( unsigned int i=0; i<nBytes; ++i ) data->buffer[i] = message->at(i);
+  result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev );
+  if ( result < (int)nBytes ) {
+    errorString_ = "MidiOutAlsa::sendMessage: event parsing error!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  // Send the event.
+  result = snd_seq_event_output(data->seq, &ev);
+  if ( result < 0 ) {
+    errorString_ = "MidiOutAlsa::sendMessage: error sending MIDI message to port.";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+  snd_seq_drain_output(data->seq);
+}
+
+#endif // __LINUX_ALSA__
+
+
+//*********************************************************************//
+//  API: Windows Multimedia Library (MM)
+//*********************************************************************//
+
+// API information deciphered from:
+//  - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_midi_reference.asp
+
+// Thanks to Jean-Baptiste Berruchon for the sysex code.
+
+#if defined(__WINDOWS_MM__)
+
+// The Windows MM API is based on the use of a callback function for
+// MIDI input.  We convert the system specific time stamps to delta
+// time values.
+
+// Windows MM MIDI header files.
+#include <windows.h>
+#include <mmsystem.h>
+
+#define  RT_SYSEX_BUFFER_SIZE 1024
+#define  RT_SYSEX_BUFFER_COUNT 4
+
+// A structure to hold variables related to the CoreMIDI API
+// implementation.
+struct WinMidiData {
+  HMIDIIN inHandle;    // Handle to Midi Input Device
+  HMIDIOUT outHandle;  // Handle to Midi Output Device
+  DWORD lastTime;
+  MidiInApi::MidiMessage message;
+  LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT];
+  CRITICAL_SECTION _mutex; // [Patrice] see https://groups.google.com/forum/#!topic/mididev/6OUjHutMpEo
+};
+
+//*********************************************************************//
+//  API: Windows MM
+//  Class Definitions: MidiInWinMM
+//*********************************************************************//
+
+static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/,
+                                        UINT inputStatus, 
+                                        DWORD_PTR instancePtr,
+                                        DWORD_PTR midiMessage,
+                                        DWORD timestamp )
+{
+  if ( inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA && inputStatus != MIM_LONGERROR ) return;
+
+  //MidiInApi::RtMidiInData *data = static_cast<MidiInApi::RtMidiInData *> (instancePtr);
+  MidiInApi::RtMidiInData *data = (MidiInApi::RtMidiInData *)instancePtr;
+  WinMidiData *apiData = static_cast<WinMidiData *> (data->apiData);
+
+  // Calculate time stamp.
+  if ( data->firstMessage == true ) {
+    apiData->message.timeStamp = 0.0;
+    data->firstMessage = false;
+  }
+  else apiData->message.timeStamp = (double) ( timestamp - apiData->lastTime ) * 0.001;
+  apiData->lastTime = timestamp;
+
+  if ( inputStatus == MIM_DATA ) { // Channel or system message
+
+    // Make sure the first byte is a status byte.
+    unsigned char status = (unsigned char) (midiMessage & 0x000000FF);
+    if ( !(status & 0x80) ) return;
+
+    // Determine the number of bytes in the MIDI message.
+    unsigned short nBytes = 1;
+    if ( status < 0xC0 ) nBytes = 3;
+    else if ( status < 0xE0 ) nBytes = 2;
+    else if ( status < 0xF0 ) nBytes = 3;
+    else if ( status == 0xF1 ) {
+      if ( data->ignoreFlags & 0x02 ) return;
+      else nBytes = 2;
+    }
+    else if ( status == 0xF2 ) nBytes = 3;
+    else if ( status == 0xF3 ) nBytes = 2;
+    else if ( status == 0xF8 && (data->ignoreFlags & 0x02) ) {
+      // A MIDI timing tick message and we're ignoring it.
+      return;
+    }
+    else if ( status == 0xFE && (data->ignoreFlags & 0x04) ) {
+      // A MIDI active sensing message and we're ignoring it.
+      return;
+    }
+
+    // Copy bytes to our MIDI message.
+    unsigned char *ptr = (unsigned char *) &midiMessage;
+    for ( int i=0; i<nBytes; ++i ) apiData->message.bytes.push_back( *ptr++ );
+  }
+  else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR )
+    MIDIHDR *sysex = ( MIDIHDR *) midiMessage; 
+    if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) {  
+      // Sysex message and we're not ignoring it
+      for ( int i=0; i<(int)sysex->dwBytesRecorded; ++i )
+        apiData->message.bytes.push_back( sysex->lpData[i] );
+    }
+
+    // The WinMM API requires that the sysex buffer be requeued after
+    // input of each sysex message.  Even if we are ignoring sysex
+    // messages, we still need to requeue the buffer in case the user
+    // decides to not ignore sysex messages in the future.  However,
+    // it seems that WinMM calls this function with an empty sysex
+    // buffer when an application closes and in this case, we should
+    // avoid requeueing it, else the computer suddenly reboots after
+    // one or two minutes.
+    if ( apiData->sysexBuffer[sysex->dwUser]->dwBytesRecorded > 0 ) {
+      //if ( sysex->dwBytesRecorded > 0 ) {
+      EnterCriticalSection( &(apiData->_mutex) );
+      MMRESULT result = midiInAddBuffer( apiData->inHandle, apiData->sysexBuffer[sysex->dwUser], sizeof(MIDIHDR) );
+      LeaveCriticalSection( &(apiData->_mutex) );
+      if ( result != MMSYSERR_NOERROR )
+        std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n";
+
+      if ( data->ignoreFlags & 0x01 ) return;
+    }
+    else return;
+  }
+
+  if ( data->usingCallback ) {
+    RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;
+    callback( apiData->message.timeStamp, &apiData->message.bytes, data->userData );
+  }
+  else {
+    // As long as we haven't reached our queue size limit, push the message.
+    if ( data->queue.size < data->queue.ringSize ) {
+      data->queue.ring[data->queue.back++] = apiData->message;
+      if ( data->queue.back == data->queue.ringSize )
+        data->queue.back = 0;
+      data->queue.size++;
+    }
+    else
+      std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";
+  }
+
+  // Clear the vector for the next input message.
+  apiData->message.bytes.clear();
+}
+
+MidiInWinMM :: MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
+{
+  initialize( clientName );
+}
+
+MidiInWinMM :: ~MidiInWinMM()
+{
+  // Close a connection if it exists.
+  closePort();
+
+  WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+  DeleteCriticalSection( &(data->_mutex) );
+
+  // Cleanup.
+  delete data;
+}
+
+void MidiInWinMM :: initialize( const std::string& /*clientName*/ )
+{
+  // We'll issue a warning here if no devices are available but not
+  // throw an error since the user can plugin something later.
+  unsigned int nDevices = midiInGetNumDevs();
+  if ( nDevices == 0 ) {
+    errorString_ = "MidiInWinMM::initialize: no MIDI input devices currently available.";
+    error( RtMidiError::WARNING, errorString_ );
+  }
+
+  // Save our api-specific connection information.
+  WinMidiData *data = (WinMidiData *) new WinMidiData;
+  apiData_ = (void *) data;
+  inputData_.apiData = (void *) data;
+  data->message.bytes.clear();  // needs to be empty for first input message
+
+  if ( !InitializeCriticalSectionAndSpinCount(&(data->_mutex), 0x00000400) ) {
+    errorString_ = "MidiInWinMM::initialize: InitializeCriticalSectionAndSpinCount failed.";
+    error( RtMidiError::WARNING, errorString_ );
+  }
+}
+
+void MidiInWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ )
+{
+  if ( connected_ ) {
+    errorString_ = "MidiInWinMM::openPort: a valid connection already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  unsigned int nDevices = midiInGetNumDevs();
+  if (nDevices == 0) {
+    errorString_ = "MidiInWinMM::openPort: no MIDI input sources found!";
+    error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
+    return;
+  }
+
+  if ( portNumber >= nDevices ) {
+    std::ostringstream ost;
+    ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::INVALID_PARAMETER, errorString_ );
+    return;
+  }
+
+  WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+  MMRESULT result = midiInOpen( &data->inHandle,
+                                portNumber,
+                                (DWORD_PTR)&midiInputCallback,
+                                (DWORD_PTR)&inputData_,
+                                CALLBACK_FUNCTION );
+  if ( result != MMSYSERR_NOERROR ) {
+    errorString_ = "MidiInWinMM::openPort: error creating Windows MM MIDI input port.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Allocate and init the sysex buffers.
+  for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) {
+    data->sysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ];
+    data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ];
+    data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE;
+    data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator
+    data->sysexBuffer[i]->dwFlags = 0;
+
+    result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) );
+    if ( result != MMSYSERR_NOERROR ) {
+      midiInClose( data->inHandle );
+      errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (PrepareHeader).";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+
+    // Register the buffer.
+    result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) );
+    if ( result != MMSYSERR_NOERROR ) {
+      midiInClose( data->inHandle );
+      errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (AddBuffer).";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+  }
+
+  result = midiInStart( data->inHandle );
+  if ( result != MMSYSERR_NOERROR ) {
+    midiInClose( data->inHandle );
+    errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  connected_ = true;
+}
+
+void MidiInWinMM :: openVirtualPort( std::string /*portName*/ )
+{
+  // This function cannot be implemented for the Windows MM MIDI API.
+  errorString_ = "MidiInWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!";
+  error( RtMidiError::WARNING, errorString_ );
+}
+
+void MidiInWinMM :: closePort( void )
+{
+  if ( connected_ ) {
+    WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+    EnterCriticalSection( &(data->_mutex) );
+    midiInReset( data->inHandle );
+    midiInStop( data->inHandle );
+
+    for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) {
+      int result = midiInUnprepareHeader(data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR));
+      delete [] data->sysexBuffer[i]->lpData;
+      delete [] data->sysexBuffer[i];
+      if ( result != MMSYSERR_NOERROR ) {
+        midiInClose( data->inHandle );
+        errorString_ = "MidiInWinMM::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader).";
+        error( RtMidiError::DRIVER_ERROR, errorString_ );
+        return;
+      }
+    }
+
+    midiInClose( data->inHandle );
+    connected_ = false;
+    LeaveCriticalSection( &(data->_mutex) );
+  }
+}
+
+unsigned int MidiInWinMM :: getPortCount()
+{
+  return midiInGetNumDevs();
+}
+
+std::string MidiInWinMM :: getPortName( unsigned int portNumber )
+{
+  std::string stringName;
+  unsigned int nDevices = midiInGetNumDevs();
+  if ( portNumber >= nDevices ) {
+    std::ostringstream ost;
+    ost << "MidiInWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::WARNING, errorString_ );
+    return stringName;
+  }
+
+  MIDIINCAPS deviceCaps;
+  midiInGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIINCAPS));
+
+#if defined( UNICODE ) || defined( _UNICODE )
+  int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL) - 1;
+  stringName.assign( length, 0 );
+  length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, static_cast<int>(wcslen(deviceCaps.szPname)), &stringName[0], length, NULL, NULL);
+#else
+  stringName = std::string( deviceCaps.szPname );
+#endif
+
+  // Next lines added to add the portNumber to the name so that 
+  // the device's names are sure to be listed with individual names
+  // even when they have the same brand name
+  std::ostringstream os;
+  os << " ";
+  os << portNumber;
+  stringName += os.str();
+
+  return stringName;
+}
+
+//*********************************************************************//
+//  API: Windows MM
+//  Class Definitions: MidiOutWinMM
+//*********************************************************************//
+
+MidiOutWinMM :: MidiOutWinMM( const std::string clientName ) : MidiOutApi()
+{
+  initialize( clientName );
+}
+
+MidiOutWinMM :: ~MidiOutWinMM()
+{
+  // Close a connection if it exists.
+  closePort();
+
+  // Cleanup.
+  WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+  delete data;
+}
+
+void MidiOutWinMM :: initialize( const std::string& /*clientName*/ )
+{
+  // We'll issue a warning here if no devices are available but not
+  // throw an error since the user can plug something in later.
+  unsigned int nDevices = midiOutGetNumDevs();
+  if ( nDevices == 0 ) {
+    errorString_ = "MidiOutWinMM::initialize: no MIDI output devices currently available.";
+    error( RtMidiError::WARNING, errorString_ );
+  }
+
+  // Save our api-specific connection information.
+  WinMidiData *data = (WinMidiData *) new WinMidiData;
+  apiData_ = (void *) data;
+}
+
+unsigned int MidiOutWinMM :: getPortCount()
+{
+  return midiOutGetNumDevs();
+}
+
+std::string MidiOutWinMM :: getPortName( unsigned int portNumber )
+{
+  std::string stringName;
+  unsigned int nDevices = midiOutGetNumDevs();
+  if ( portNumber >= nDevices ) {
+    std::ostringstream ost;
+    ost << "MidiOutWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::WARNING, errorString_ );
+    return stringName;
+  }
+
+  MIDIOUTCAPS deviceCaps;
+  midiOutGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIOUTCAPS));
+
+#if defined( UNICODE ) || defined( _UNICODE )
+  int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL) - 1;
+  stringName.assign( length, 0 );
+  length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, static_cast<int>(wcslen(deviceCaps.szPname)), &stringName[0], length, NULL, NULL);
+#else
+  stringName = std::string( deviceCaps.szPname );
+#endif
+
+  return stringName;
+}
+
+void MidiOutWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ )
+{
+  if ( connected_ ) {
+    errorString_ = "MidiOutWinMM::openPort: a valid connection already exists!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  unsigned int nDevices = midiOutGetNumDevs();
+  if (nDevices < 1) {
+    errorString_ = "MidiOutWinMM::openPort: no MIDI output destinations found!";
+    error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
+    return;
+  }
+
+  if ( portNumber >= nDevices ) {
+    std::ostringstream ost;
+    ost << "MidiOutWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::INVALID_PARAMETER, errorString_ );
+    return;
+  }
+
+  WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+  MMRESULT result = midiOutOpen( &data->outHandle,
+                                 portNumber,
+                                 (DWORD)NULL,
+                                 (DWORD)NULL,
+                                 CALLBACK_NULL );
+  if ( result != MMSYSERR_NOERROR ) {
+    errorString_ = "MidiOutWinMM::openPort: error creating Windows MM MIDI output port.";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  connected_ = true;
+}
+
+void MidiOutWinMM :: closePort( void )
+{
+  if ( connected_ ) {
+    WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+    midiOutReset( data->outHandle );
+    midiOutClose( data->outHandle );
+    connected_ = false;
+  }
+}
+
+void MidiOutWinMM :: openVirtualPort( std::string /*portName*/ )
+{
+  // This function cannot be implemented for the Windows MM MIDI API.
+  errorString_ = "MidiOutWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!";
+  error( RtMidiError::WARNING, errorString_ );
+}
+
+void MidiOutWinMM :: sendMessage( std::vector<unsigned char> *message )
+{
+  if ( !connected_ ) return;
+
+  unsigned int nBytes = static_cast<unsigned int>(message->size());
+  if ( nBytes == 0 ) {
+    errorString_ = "MidiOutWinMM::sendMessage: message argument is empty!";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  MMRESULT result;
+  WinMidiData *data = static_cast<WinMidiData *> (apiData_);
+  if ( message->at(0) == 0xF0 ) { // Sysex message
+
+    // Allocate buffer for sysex data.
+    char *buffer = (char *) malloc( nBytes );
+    if ( buffer == NULL ) {
+      errorString_ = "MidiOutWinMM::sendMessage: error allocating sysex message memory!";
+      error( RtMidiError::MEMORY_ERROR, errorString_ );
+      return;
+    }
+
+    // Copy data to buffer.
+    for ( unsigned int i=0; i<nBytes; ++i ) buffer[i] = message->at(i);
+
+    // Create and prepare MIDIHDR structure.
+    MIDIHDR sysex;
+    sysex.lpData = (LPSTR) buffer;
+    sysex.dwBufferLength = nBytes;
+    sysex.dwFlags = 0;
+    result = midiOutPrepareHeader( data->outHandle,  &sysex, sizeof(MIDIHDR) ); 
+    if ( result != MMSYSERR_NOERROR ) {
+      free( buffer );
+      errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+
+    // Send the message.
+    result = midiOutLongMsg( data->outHandle, &sysex, sizeof(MIDIHDR) );
+    if ( result != MMSYSERR_NOERROR ) {
+      free( buffer );
+      errorString_ = "MidiOutWinMM::sendMessage: error sending sysex message.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+      return;
+    }
+
+    // Unprepare the buffer and MIDIHDR.
+    while ( MIDIERR_STILLPLAYING == midiOutUnprepareHeader( data->outHandle, &sysex, sizeof (MIDIHDR) ) ) Sleep( 1 );
+    free( buffer );
+  }
+  else { // Channel or system message.
+
+    // Make sure the message size isn't too big.
+    if ( nBytes > 3 ) {
+      errorString_ = "MidiOutWinMM::sendMessage: message size is greater than 3 bytes (and not sysex)!";
+      error( RtMidiError::WARNING, errorString_ );
+      return;
+    }
+
+    // Pack MIDI bytes into double word.
+    DWORD packet;
+    unsigned char *ptr = (unsigned char *) &packet;
+    for ( unsigned int i=0; i<nBytes; ++i ) {
+      *ptr = message->at(i);
+      ++ptr;
+    }
+
+    // Send the message immediately.
+    result = midiOutShortMsg( data->outHandle, packet );
+    if ( result != MMSYSERR_NOERROR ) {
+      errorString_ = "MidiOutWinMM::sendMessage: error sending MIDI message.";
+      error( RtMidiError::DRIVER_ERROR, errorString_ );
+    }
+  }
+}
+
+#endif  // __WINDOWS_MM__
+
+
+//*********************************************************************//
+//  API: UNIX JACK
+//
+//  Written primarily by Alexander Svetalkin, with updates for delta
+//  time by Gary Scavone, April 2011.
+//
+//  *********************************************************************//
+
+#if defined(__UNIX_JACK__)
+
+// JACK header files
+#include <jack/jack.h>
+#include <jack/midiport.h>
+#include <jack/ringbuffer.h>
+
+#define JACK_RINGBUFFER_SIZE 16384 // Default size for ringbuffer
+
+struct JackMidiData {
+  jack_client_t *client;
+  jack_port_t *port;
+  jack_ringbuffer_t *buffSize;
+  jack_ringbuffer_t *buffMessage;
+  jack_time_t lastTime;
+  MidiInApi :: RtMidiInData *rtMidiIn;
+  };
+
+//*********************************************************************//
+//  API: JACK
+//  Class Definitions: MidiInJack
+//*********************************************************************//
+
+static int jackProcessIn( jack_nframes_t nframes, void *arg )
+{
+  JackMidiData *jData = (JackMidiData *) arg;
+  MidiInApi :: RtMidiInData *rtData = jData->rtMidiIn;
+  jack_midi_event_t event;
+  jack_time_t time;
+
+  // Is port created?
+  if ( jData->port == NULL ) return 0;
+  void *buff = jack_port_get_buffer( jData->port, nframes );
+
+  // We have midi events in buffer
+  int evCount = jack_midi_get_event_count( buff );
+  for (int j = 0; j < evCount; j++) {
+    MidiInApi::MidiMessage message;
+    message.bytes.clear();
+
+    jack_midi_event_get( &event, buff, j );
+
+    for ( unsigned int i = 0; i < event.size; i++ )
+      message.bytes.push_back( event.buffer[i] );
+
+    // Compute the delta time.
+    time = jack_get_time();
+    if ( rtData->firstMessage == true )
+      rtData->firstMessage = false;
+    else
+      message.timeStamp = ( time - jData->lastTime ) * 0.000001;
+
+    jData->lastTime = time;
+
+    if ( !rtData->continueSysex ) {
+      if ( rtData->usingCallback ) {
+        RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) rtData->userCallback;
+        callback( message.timeStamp, &message.bytes, rtData->userData );
+      }
+      else {
+        // As long as we haven't reached our queue size limit, push the message.
+        if ( rtData->queue.size < rtData->queue.ringSize ) {
+          rtData->queue.ring[rtData->queue.back++] = message;
+          if ( rtData->queue.back == rtData->queue.ringSize )
+            rtData->queue.back = 0;
+          rtData->queue.size++;
+        }
+        else
+          std::cerr << "\nMidiInJack: message queue limit reached!!\n\n";
+      }
+    }
+  }
+
+  return 0;
+}
+
+MidiInJack :: MidiInJack( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit )
+{
+  initialize( clientName );
+}
+
+void MidiInJack :: initialize( const std::string& clientName )
+{
+  JackMidiData *data = new JackMidiData;
+  apiData_ = (void *) data;
+
+  data->rtMidiIn = &inputData_;
+  data->port = NULL;
+  data->client = NULL;
+  this->clientName = clientName;
+
+  connect();
+}
+
+void MidiInJack :: connect()
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  if ( data->client )
+    return;
+
+  // Initialize JACK client
+  if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) {
+    errorString_ = "MidiInJack::initialize: JACK server not running?";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  jack_set_process_callback( data->client, jackProcessIn, data );
+  jack_activate( data->client );
+}
+
+MidiInJack :: ~MidiInJack()
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  closePort();
+
+  if ( data->client )
+    jack_client_close( data->client );
+  delete data;
+}
+
+void MidiInJack :: openPort( unsigned int portNumber, const std::string portName )
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  connect();
+
+  // Creating new port
+  if ( data->port == NULL)
+    data->port = jack_port_register( data->client, portName.c_str(),
+                                     JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 );
+
+  if ( data->port == NULL) {
+    errorString_ = "MidiInJack::openPort: JACK error creating port";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Connecting to the output
+  std::string name = getPortName( portNumber );
+  jack_connect( data->client, name.c_str(), jack_port_name( data->port ) );
+}
+
+void MidiInJack :: openVirtualPort( const std::string portName )
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  connect();
+  if ( data->port == NULL )
+    data->port = jack_port_register( data->client, portName.c_str(),
+                                     JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 );
+
+  if ( data->port == NULL ) {
+    errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+  }
+}
+
+unsigned int MidiInJack :: getPortCount()
+{
+  int count = 0;
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  connect();
+  if ( !data->client )
+    return 0;
+
+  // List of available ports
+  const char **ports = jack_get_ports( data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput );
+
+  if ( ports == NULL ) return 0;
+  while ( ports[count] != NULL )
+    count++;
+
+  free( ports );
+
+  return count;
+}
+
+std::string MidiInJack :: getPortName( unsigned int portNumber )
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  std::string retStr("");
+
+  connect();
+
+  // List of available ports
+  const char **ports = jack_get_ports( data->client, NULL,
+                                       JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput );
+
+  // Check port validity
+  if ( ports == NULL ) {
+    errorString_ = "MidiInJack::getPortName: no ports available!";
+    error( RtMidiError::WARNING, errorString_ );
+    return retStr;
+  }
+
+  if ( ports[portNumber] == NULL ) {
+    std::ostringstream ost;
+    ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::WARNING, errorString_ );
+  }
+  else retStr.assign( ports[portNumber] );
+
+  free( ports );
+  return retStr;
+}
+
+void MidiInJack :: closePort()
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  if ( data->port == NULL ) return;
+  jack_port_unregister( data->client, data->port );
+  data->port = NULL;
+}
+
+//*********************************************************************//
+//  API: JACK
+//  Class Definitions: MidiOutJack
+//*********************************************************************//
+
+// Jack process callback
+static int jackProcessOut( jack_nframes_t nframes, void *arg )
+{
+  JackMidiData *data = (JackMidiData *) arg;
+  jack_midi_data_t *midiData;
+  int space;
+
+  // Is port created?
+  if ( data->port == NULL ) return 0;
+
+  void *buff = jack_port_get_buffer( data->port, nframes );
+  jack_midi_clear_buffer( buff );
+
+  while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) {
+    jack_ringbuffer_read( data->buffSize, (char *) &space, (size_t) sizeof(space) );
+    midiData = jack_midi_event_reserve( buff, 0, space );
+
+    jack_ringbuffer_read( data->buffMessage, (char *) midiData, (size_t) space );
+  }
+
+  return 0;
+}
+
+MidiOutJack :: MidiOutJack( const std::string clientName ) : MidiOutApi()
+{
+  initialize( clientName );
+}
+
+void MidiOutJack :: initialize( const std::string& clientName )
+{
+  JackMidiData *data = new JackMidiData;
+  apiData_ = (void *) data;
+
+  data->port = NULL;
+  data->client = NULL;
+  this->clientName = clientName;
+
+  connect();
+}
+
+void MidiOutJack :: connect()
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  if ( data->client )
+    return;
+
+  // Initialize JACK client
+  if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) {
+    errorString_ = "MidiOutJack::initialize: JACK server not running?";
+    error( RtMidiError::WARNING, errorString_ );
+    return;
+  }
+
+  jack_set_process_callback( data->client, jackProcessOut, data );
+  data->buffSize = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE );
+  data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE );
+  jack_activate( data->client );
+}
+
+MidiOutJack :: ~MidiOutJack()
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  closePort();
+
+  if ( data->client ) {
+    // Cleanup
+    jack_client_close( data->client );
+    jack_ringbuffer_free( data->buffSize );
+    jack_ringbuffer_free( data->buffMessage );
+  }
+
+  delete data;
+}
+
+void MidiOutJack :: openPort( unsigned int portNumber, const std::string portName )
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  connect();
+
+  // Creating new port
+  if ( data->port == NULL )
+    data->port = jack_port_register( data->client, portName.c_str(),
+      JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 );
+
+  if ( data->port == NULL ) {
+    errorString_ = "MidiOutJack::openPort: JACK error creating port";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+    return;
+  }
+
+  // Connecting to the output
+  std::string name = getPortName( portNumber );
+  jack_connect( data->client, jack_port_name( data->port ), name.c_str() );
+}
+
+void MidiOutJack :: openVirtualPort( const std::string portName )
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  connect();
+  if ( data->port == NULL )
+    data->port = jack_port_register( data->client, portName.c_str(),
+      JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 );
+
+  if ( data->port == NULL ) {
+    errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port";
+    error( RtMidiError::DRIVER_ERROR, errorString_ );
+  }
+}
+
+unsigned int MidiOutJack :: getPortCount()
+{
+  int count = 0;
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  connect();
+  if ( !data->client )
+    return 0;
+
+  // List of available ports
+  const char **ports = jack_get_ports( data->client, NULL,
+    JACK_DEFAULT_MIDI_TYPE, JackPortIsInput );
+
+  if ( ports == NULL ) return 0;
+  while ( ports[count] != NULL )
+    count++;
+
+  free( ports );
+
+  return count;
+}
+
+std::string MidiOutJack :: getPortName( unsigned int portNumber )
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+  std::string retStr("");
+
+  connect();
+
+  // List of available ports
+  const char **ports = jack_get_ports( data->client, NULL,
+    JACK_DEFAULT_MIDI_TYPE, JackPortIsInput );
+
+  // Check port validity
+  if ( ports == NULL) {
+    errorString_ = "MidiOutJack::getPortName: no ports available!";
+    error( RtMidiError::WARNING, errorString_ );
+    return retStr;
+  }
+
+  if ( ports[portNumber] == NULL) {
+    std::ostringstream ost;
+    ost << "MidiOutJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";
+    errorString_ = ost.str();
+    error( RtMidiError::WARNING, errorString_ );
+  }
+  else retStr.assign( ports[portNumber] );
+
+  free( ports );
+  return retStr;
+}
+
+void MidiOutJack :: closePort()
+{
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  if ( data->port == NULL ) return;
+  jack_port_unregister( data->client, data->port );
+  data->port = NULL;
+}
+
+void MidiOutJack :: sendMessage( std::vector<unsigned char> *message )
+{
+  int nBytes = message->size();
+  JackMidiData *data = static_cast<JackMidiData *> (apiData_);
+
+  // Write full message to buffer
+  jack_ringbuffer_write( data->buffMessage, ( const char * ) &( *message )[0],
+                         message->size() );
+  jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) );
+}
+
+#endif  // __UNIX_JACK__
diff --git a/architecture/faust/midi/RtMidi.h b/architecture/faust/midi/RtMidi.h
new file mode 100644
index 0000000..b82eab5
--- /dev/null
+++ b/architecture/faust/midi/RtMidi.h
@@ -0,0 +1,773 @@
+/**********************************************************************/
+/*! \class RtMidi
+    \brief An abstract base class for realtime MIDI input/output.
+
+    This class implements some common functionality for the realtime
+    MIDI input/output subclasses RtMidiIn and RtMidiOut.
+
+    RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
+
+    RtMidi: realtime MIDI i/o C++ classes
+    Copyright (c) 2003-2014 Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********************************************************************/
+
+/*!
+  \file RtMidi.h
+ */
+
+#ifndef RTMIDI_H
+#define RTMIDI_H
+
+#define RTMIDI_VERSION "2.1.0"
+
+#include <exception>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#if __APPLE__
+#define __MACOSX_CORE__ 1
+#endif
+
+#if __linux__
+#define __LINUX_ALSA__ 1
+#endif
+
+#if _WIN32
+#define __WINDOWS_MM__ 1
+#endif
+
+/************************************************************************/
+/*! \class RtMidiError
+    \brief Exception handling class for RtMidi.
+
+    The RtMidiError class is quite simple but it does allow errors to be
+    "caught" by RtMidiError::Type. See the RtMidi documentation to know
+    which methods can throw an RtMidiError.
+*/
+/************************************************************************/
+
+class RtMidiError : public std::exception
+{
+ public:
+  //! Defined RtMidiError types.
+  enum Type {
+    WARNING,           /*!< A non-critical error. */
+    DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
+    UNSPECIFIED,       /*!< The default, unspecified error type. */
+    NO_DEVICES_FOUND,  /*!< No devices found on system. */
+    INVALID_DEVICE,    /*!< An invalid device ID was specified. */
+    MEMORY_ERROR,      /*!< An error occured during memory allocation. */
+    INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
+    INVALID_USE,       /*!< The function was called incorrectly. */
+    DRIVER_ERROR,      /*!< A system driver error occured. */
+    SYSTEM_ERROR,      /*!< A system error occured. */
+    THREAD_ERROR       /*!< A thread error occured. */
+  };
+
+  //! The constructor.
+  RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
+ 
+  //! The destructor.
+  virtual ~RtMidiError( void ) throw() {}
+
+  //! Prints thrown error message to stderr.
+  virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
+
+  //! Returns the thrown error message type.
+  virtual const Type& getType(void) const throw() { return type_; }
+
+  //! Returns the thrown error message string.
+  virtual const std::string& getMessage(void) const throw() { return message_; }
+
+  //! Returns the thrown error message as a c-style string.
+  virtual const char* what( void ) const throw() { return message_.c_str(); }
+
+ protected:
+  std::string message_;
+  Type type_;
+};
+
+//! RtMidi error callback function prototype.
+/*!
+    \param type Type of error.
+    \param errorText Error description.
+
+    Note that class behaviour is undefined after a critical error (not
+    a warning) is reported.
+ */
+typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText );
+
+class MidiApi;
+
+class RtMidi
+{
+ public:
+
+  //! MIDI API specifier arguments.
+  enum Api {
+    UNSPECIFIED,    /*!< Search for a working compiled API. */
+    MACOSX_CORE,    /*!< Macintosh OS-X Core Midi API. */
+    LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
+    UNIX_JACK,      /*!< The JACK Low-Latency MIDI Server API. */
+    WINDOWS_MM,     /*!< The Microsoft Multimedia MIDI API. */
+    RTMIDI_DUMMY    /*!< A compilable but non-functional API. */
+  };
+
+  //! A static function to determine the current RtMidi version.
+  static std::string getVersion( void ) throw();
+
+  //! A static function to determine the available compiled MIDI APIs.
+  /*!
+    The values returned in the std::vector can be compared against
+    the enumerated list values.  Note that there can be more than one
+    API compiled for certain operating systems.
+  */
+  static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
+
+  //! Pure virtual openPort() function.
+  virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0;
+
+  //! Pure virtual openVirtualPort() function.
+  virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0;
+
+  //! Pure virtual getPortCount() function.
+  virtual unsigned int getPortCount() = 0;
+
+  //! Pure virtual getPortName() function.
+  virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
+
+  //! Pure virtual closePort() function.
+  virtual void closePort( void ) = 0;
+
+  //! Returns true if a port is open and false if not.
+  virtual bool isPortOpen( void ) const = 0;
+
+  //! Set an error callback function to be invoked when an error has occured.
+  /*!
+    The callback function will be called whenever an error has occured. It is best
+    to set the error callback function before opening a port.
+  */
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0;
+
+ protected:
+
+  RtMidi();
+  virtual ~RtMidi();
+
+  MidiApi *rtapi_;
+};
+
+/**********************************************************************/
+/*! \class RtMidiIn
+    \brief A realtime MIDI input class.
+
+    This class provides a common, platform-independent API for
+    realtime MIDI input.  It allows access to a single MIDI input
+    port.  Incoming MIDI messages are either saved to a queue for
+    retrieval using the getMessage() function or immediately passed to
+    a user-specified callback function.  Create multiple instances of
+    this class to connect to more than one MIDI device at the same
+    time.  With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also
+    possible to open a virtual input port to which other MIDI software
+    clients can connect.
+
+    by Gary P. Scavone, 2003-2014.
+*/
+/**********************************************************************/
+
+// **************************************************************** //
+//
+// RtMidiIn and RtMidiOut class declarations.
+//
+// RtMidiIn / RtMidiOut are "controllers" used to select an available
+// MIDI input or output interface.  They present common APIs for the
+// user to call but all functionality is implemented by the classes
+// MidiInApi, MidiOutApi and their subclasses.  RtMidiIn and RtMidiOut
+// each create an instance of a MidiInApi or MidiOutApi subclass based
+// on the user's API choice.  If no choice is made, they attempt to
+// make a "logical" API selection.
+//
+// **************************************************************** //
+
+class RtMidiIn : public RtMidi
+{
+ public:
+
+  //! User callback function type definition.
+  typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
+
+  //! Default constructor that allows an optional api, client name and queue size.
+  /*!
+    An exception will be thrown if a MIDI system initialization
+    error occurs.  The queue size defines the maximum number of
+    messages that can be held in the MIDI queue (when not using a
+    callback function).  If the queue size limit is reached,
+    incoming messages will be ignored.
+
+    If no API argument is specified and multiple API support has been
+    compiled, the default order of use is ALSA, JACK (Linux) and CORE,
+    JACK (OS-X).
+
+    \param api        An optional API id can be specified.
+    \param clientName An optional client name can be specified. This
+                      will be used to group the ports that are created
+                      by the application.
+    \param queueSizeLimit An optional size of the MIDI input queue can be specified.
+  */
+  RtMidiIn( RtMidi::Api api=UNSPECIFIED,
+            const std::string clientName = std::string( "RtMidi Input Client"),
+            unsigned int queueSizeLimit = 100 );
+
+  //! If a MIDI connection is still open, it will be closed by the destructor.
+  ~RtMidiIn ( void ) throw();
+
+  //! Returns the MIDI API specifier for the current instance of RtMidiIn.
+  RtMidi::Api getCurrentApi( void ) throw();
+
+  //! Open a MIDI input connection given by enumeration number.
+  /*!
+    \param portNumber An optional port number greater than 0 can be specified.
+                      Otherwise, the default or first port found is opened.
+    \param portName An optional name for the application port that is used to connect to portId can be specified.
+  */
+  void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) );
+
+  //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only).
+  /*!
+    This function creates a virtual MIDI input port to which other
+    software applications can connect.  This type of functionality
+    is currently only supported by the Macintosh OS-X, any JACK,
+    and Linux ALSA APIs (the function returns an error for the other APIs).
+
+    \param portName An optional name for the application port that is
+                    used to connect to portId can be specified.
+  */
+  void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) );
+
+  //! Set a callback function to be invoked for incoming MIDI messages.
+  /*!
+    The callback function will be called whenever an incoming MIDI
+    message is received.  While not absolutely necessary, it is best
+    to set the callback function before opening a MIDI port to avoid
+    leaving some messages in the queue.
+
+    \param callback A callback function must be given.
+    \param userData Optionally, a pointer to additional data can be
+                    passed to the callback function whenever it is called.
+  */
+  void setCallback( RtMidiCallback callback, void *userData = 0 );
+
+  //! Cancel use of the current callback function (if one exists).
+  /*!
+    Subsequent incoming MIDI messages will be written to the queue
+    and can be retrieved with the \e getMessage function.
+  */
+  void cancelCallback();
+
+  //! Close an open MIDI connection (if one exists).
+  void closePort( void );
+
+  //! Returns true if a port is open and false if not.
+  virtual bool isPortOpen() const;
+
+  //! Return the number of available MIDI input ports.
+  /*!
+    \return This function returns the number of MIDI ports of the selected API.
+  */
+  unsigned int getPortCount();
+
+  //! Return a string identifier for the specified MIDI input port number.
+  /*!
+    \return The name of the port with the given Id is returned.
+    \retval An empty string is returned if an invalid port specifier is provided.
+  */
+  std::string getPortName( unsigned int portNumber = 0 );
+
+  //! Specify whether certain MIDI message types should be queued or ignored during input.
+  /*!
+    By default, MIDI timing and active sensing messages are ignored
+    during message input because of their relative high data rates.
+    MIDI sysex messages are ignored by default as well.  Variable
+    values of "true" imply that the respective message type will be
+    ignored.
+  */
+  void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
+
+  //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds.
+  /*!
+    This function returns immediately whether a new message is
+    available or not.  A valid message is indicated by a non-zero
+    vector size.  An exception is thrown if an error occurs during
+    message retrieval or an input connection was not previously
+    established.
+  */
+  double getMessage( std::vector<unsigned char> *message );
+
+  //! Set an error callback function to be invoked when an error has occured.
+  /*!
+    The callback function will be called whenever an error has occured. It is best
+    to set the error callback function before opening a port.
+  */
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
+
+ protected:
+  void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
+
+};
+
+/**********************************************************************/
+/*! \class RtMidiOut
+    \brief A realtime MIDI output class.
+
+    This class provides a common, platform-independent API for MIDI
+    output.  It allows one to probe available MIDI output ports, to
+    connect to one such port, and to send MIDI bytes immediately over
+    the connection.  Create multiple instances of this class to
+    connect to more than one MIDI device at the same time.  With the
+    OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a
+    virtual port to which other MIDI software clients can connect.
+
+    by Gary P. Scavone, 2003-2014.
+*/
+/**********************************************************************/
+
+class RtMidiOut : public RtMidi
+{
+ public:
+
+  //! Default constructor that allows an optional client name.
+  /*!
+    An exception will be thrown if a MIDI system initialization error occurs.
+
+    If no API argument is specified and multiple API support has been
+    compiled, the default order of use is ALSA, JACK (Linux) and CORE,
+    JACK (OS-X).
+  */
+  RtMidiOut( RtMidi::Api api=UNSPECIFIED,
+             const std::string clientName = std::string( "RtMidi Output Client") );
+
+  //! The destructor closes any open MIDI connections.
+  ~RtMidiOut( void ) throw();
+
+  //! Returns the MIDI API specifier for the current instance of RtMidiOut.
+  RtMidi::Api getCurrentApi( void ) throw();
+
+  //! Open a MIDI output connection.
+  /*!
+      An optional port number greater than 0 can be specified.
+      Otherwise, the default or first port found is opened.  An
+      exception is thrown if an error occurs while attempting to make
+      the port connection.
+  */
+  void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) );
+
+  //! Close an open MIDI connection (if one exists).
+  void closePort( void );
+
+  //! Returns true if a port is open and false if not.
+  virtual bool isPortOpen() const;
+
+  //! Create a virtual output port, with optional name, to allow software connections (OS X, JACK and ALSA only).
+  /*!
+      This function creates a virtual MIDI output port to which other
+      software applications can connect.  This type of functionality
+      is currently only supported by the Macintosh OS-X, Linux ALSA
+      and JACK APIs (the function does nothing with the other APIs).
+      An exception is thrown if an error occurs while attempting to
+      create the virtual port.
+  */
+  void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) );
+
+  //! Return the number of available MIDI output ports.
+  unsigned int getPortCount( void );
+
+  //! Return a string identifier for the specified MIDI port type and number.
+  /*!
+      An empty string is returned if an invalid port specifier is provided.
+  */
+  std::string getPortName( unsigned int portNumber = 0 );
+
+  //! Immediately send a single message out an open MIDI output port.
+  /*!
+      An exception is thrown if an error occurs during output or an
+      output connection was not previously established.
+  */
+  void sendMessage( std::vector<unsigned char> *message );
+
+  //! Set an error callback function to be invoked when an error has occured.
+  /*!
+    The callback function will be called whenever an error has occured. It is best
+    to set the error callback function before opening a port.
+  */
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
+
+ protected:
+  void openMidiApi( RtMidi::Api api, const std::string clientName );
+};
+
+
+// **************************************************************** //
+//
+// MidiInApi / MidiOutApi class declarations.
+//
+// Subclasses of MidiInApi and MidiOutApi contain all API- and
+// OS-specific code necessary to fully implement the RtMidi API.
+//
+// Note that MidiInApi and MidiOutApi are abstract base classes and
+// cannot be explicitly instantiated.  RtMidiIn and RtMidiOut will
+// create instances of a MidiInApi or MidiOutApi subclass.
+//
+// **************************************************************** //
+
+class MidiApi
+{
+ public:
+
+  MidiApi();
+  virtual ~MidiApi();
+  virtual RtMidi::Api getCurrentApi( void ) = 0;
+  virtual void openPort( unsigned int portNumber, const std::string portName ) = 0;
+  virtual void openVirtualPort( const std::string portName ) = 0;
+  virtual void closePort( void ) = 0;
+
+  virtual unsigned int getPortCount( void ) = 0;
+  virtual std::string getPortName( unsigned int portNumber ) = 0;
+
+  inline bool isPortOpen() const { return connected_; }
+  void setErrorCallback( RtMidiErrorCallback errorCallback );
+
+  //! A basic error reporting function for RtMidi classes.
+  void error( RtMidiError::Type type, std::string errorString );
+
+protected:
+  virtual void initialize( const std::string& clientName ) = 0;
+
+  void *apiData_;
+  bool connected_;
+  std::string errorString_;
+  RtMidiErrorCallback errorCallback_;
+};
+
+class MidiInApi : public MidiApi
+{
+ public:
+
+  MidiInApi( unsigned int queueSizeLimit );
+  virtual ~MidiInApi( void );
+  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
+  void cancelCallback( void );
+  virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
+  double getMessage( std::vector<unsigned char> *message );
+
+  // A MIDI structure used internally by the class to store incoming
+  // messages.  Each message represents one and only one MIDI message.
+  struct MidiMessage { 
+    std::vector<unsigned char> bytes; 
+    double timeStamp;
+
+    // Default constructor.
+  MidiMessage()
+  :bytes(0), timeStamp(0.0) {}
+  };
+
+  struct MidiQueue {
+    unsigned int front;
+    unsigned int back;
+    unsigned int size;
+    unsigned int ringSize;
+    MidiMessage *ring;
+
+    // Default constructor.
+  MidiQueue()
+  :front(0), back(0), size(0), ringSize(0) {}
+  };
+
+  // The RtMidiInData structure is used to pass private class data to
+  // the MIDI input handling function or thread.
+  struct RtMidiInData {
+    MidiQueue queue;
+    MidiMessage message;
+    unsigned char ignoreFlags;
+    bool doInput;
+    bool firstMessage;
+    void *apiData;
+    bool usingCallback;
+    RtMidiIn::RtMidiCallback userCallback;
+    void *userData;
+    bool continueSysex;
+
+    // Default constructor.
+  RtMidiInData()
+  : ignoreFlags(7), doInput(false), firstMessage(true),
+      apiData(0), usingCallback(false), userCallback(0), userData(0),
+      continueSysex(false) {}
+  };
+
+ protected:
+  RtMidiInData inputData_;
+};
+
+class MidiOutApi : public MidiApi
+{
+ public:
+
+  MidiOutApi( void );
+  virtual ~MidiOutApi( void );
+  virtual void sendMessage( std::vector<unsigned char> *message ) = 0;
+};
+
+// **************************************************************** //
+//
+// Inline RtMidiIn and RtMidiOut definitions.
+//
+// **************************************************************** //
+
+inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
+inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
+inline void RtMidiIn :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
+inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
+inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
+inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); }
+inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); }
+inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
+inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
+inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
+inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
+inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
+
+inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
+inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
+inline void RtMidiOut :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
+inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
+inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
+inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
+inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
+inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
+inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
+
+// **************************************************************** //
+//
+// MidiInApi and MidiOutApi subclass prototypes.
+//
+// **************************************************************** //
+
+#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__)
+  #define __RTMIDI_DUMMY__
+#endif
+
+#if defined(__MACOSX_CORE__)
+
+class MidiInCore: public MidiInApi
+{
+ public:
+  MidiInCore( const std::string clientName, unsigned int queueSizeLimit );
+  ~MidiInCore( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+
+ protected:
+  void initialize( const std::string& clientName );
+};
+
+class MidiOutCore: public MidiOutApi
+{
+ public:
+  MidiOutCore( const std::string clientName );
+  ~MidiOutCore( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+  void sendMessage( std::vector<unsigned char> *message );
+
+ protected:
+  void initialize( const std::string& clientName );
+};
+
+#endif
+
+#if defined(__UNIX_JACK__)
+
+class MidiInJack: public MidiInApi
+{
+ public:
+  MidiInJack( const std::string clientName, unsigned int queueSizeLimit );
+  ~MidiInJack( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+
+ protected:
+  std::string clientName;
+
+  void connect( void );
+  void initialize( const std::string& clientName );
+};
+
+class MidiOutJack: public MidiOutApi
+{
+ public:
+  MidiOutJack( const std::string clientName );
+  ~MidiOutJack( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+  void sendMessage( std::vector<unsigned char> *message );
+
+ protected:
+  std::string clientName;
+
+  void connect( void );
+  void initialize( const std::string& clientName );
+};
+
+#endif
+
+#if defined(__LINUX_ALSA__)
+
+class MidiInAlsa: public MidiInApi
+{
+ public:
+  MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit );
+  ~MidiInAlsa( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+
+ protected:
+  void initialize( const std::string& clientName );
+};
+
+class MidiOutAlsa: public MidiOutApi
+{
+ public:
+  MidiOutAlsa( const std::string clientName );
+  ~MidiOutAlsa( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+  void sendMessage( std::vector<unsigned char> *message );
+
+ protected:
+  void initialize( const std::string& clientName );
+};
+
+#endif
+
+#if defined(__WINDOWS_MM__)
+
+class MidiInWinMM: public MidiInApi
+{
+ public:
+  MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit );
+  ~MidiInWinMM( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+
+ protected:
+  void initialize( const std::string& clientName );
+};
+
+class MidiOutWinMM: public MidiOutApi
+{
+ public:
+  MidiOutWinMM( const std::string clientName );
+  ~MidiOutWinMM( void );
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
+  void openPort( unsigned int portNumber, const std::string portName );
+  void openVirtualPort( const std::string portName );
+  void closePort( void );
+  unsigned int getPortCount( void );
+  std::string getPortName( unsigned int portNumber );
+  void sendMessage( std::vector<unsigned char> *message );
+
+ protected:
+  void initialize( const std::string& clientName );
+};
+
+#endif
+
+#if defined(__RTMIDI_DUMMY__)
+
+class MidiInDummy: public MidiInApi
+{
+ public:
+ MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
+  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
+  void openVirtualPort( const std::string /*portName*/ ) {}
+  void closePort( void ) {}
+  unsigned int getPortCount( void ) { return 0; }
+  std::string getPortName( unsigned int portNumber ) { return ""; }
+
+ protected:
+  void initialize( const std::string& /*clientName*/ ) {}
+};
+
+class MidiOutDummy: public MidiOutApi
+{
+ public:
+  MidiOutDummy( const std::string /*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
+  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
+  void openVirtualPort( const std::string /*portName*/ ) {}
+  void closePort( void ) {}
+  unsigned int getPortCount( void ) { return 0; }
+  std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
+  void sendMessage( std::vector<unsigned char> * /*message*/ ) {}
+
+ protected:
+  void initialize( const std::string& /*clientName*/ ) {}
+};
+
+#endif
+
+#endif
diff --git a/architecture/faust/midi/midi.h b/architecture/faust/midi/midi.h
new file mode 100644
index 0000000..098bbc6
--- /dev/null
+++ b/architecture/faust/midi/midi.h
@@ -0,0 +1,49 @@
+/************************************************************************
+    FAUST Architecture File
+    Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+    EXCEPTION : As a special exception, you may create a larger work
+    that contains this FAUST architecture section and distribute
+    that work under terms of your choice, so long as this FAUST
+    architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __midi__
+#define __midi__
+
+//----------------------------------------------------------------
+//  MIDI processor definition
+//----------------------------------------------------------------
+
+class midi {
+ 
+    public:
+
+        midi() {}
+        virtual ~midi() {}
+
+        virtual void keyOn(int channel, int note, int velocity)         = 0;
+        virtual void keyOff(int channel, int note, int velocity)        = 0;
+        virtual void pitchWheel(int channel, int wheel)                 = 0;
+        virtual void ctrlChange(int channel, int ctrl, int value)       = 0;
+        virtual void progChange(int channel, int pgm)                   = 0;
+       
+};
+
+#endif
diff --git a/architecture/faust/midi/rt-midi.h b/architecture/faust/midi/rt-midi.h
new file mode 100644
index 0000000..43de414
--- /dev/null
+++ b/architecture/faust/midi/rt-midi.h
@@ -0,0 +1,233 @@
+/************************************************************************
+    FAUST Architecture File
+    Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+    EXCEPTION : As a special exception, you may create a larger work
+    that contains this FAUST architecture section and distribute
+    that work under terms of your choice, so long as this FAUST
+    architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+ 
+#include <iostream>
+#include <cstdlib>
+#include "faust/midi/RtMidi.cpp"
+#include "faust/midi/midi.h"
+
+class rtmidi : public midi {
+
+    private:
+    
+        enum MidiStatus {
+	
+            // channel voice messages
+            MIDI_NOTE_OFF           = 0x80,
+            MIDI_NOTE_ON            = 0x90,
+            MIDI_CONTROL_CHANGE     = 0xB0,
+            MIDI_PROGRAM_CHANGE     = 0xC0,
+            MIDI_PITCH_BEND         = 0xE0,
+            MIDI_AFTERTOUCH         = 0xD0,	// aka channel pressure
+            MIDI_POLY_AFTERTOUCH    = 0xA0	// aka key pressure
+
+        };
+  
+        RtMidiIn* fInput;
+        RtMidiOut* fOutput;
+        std::vector<midi*> fMidiInputs;
+        std::string fName;
+        
+        static void midiCallback(double deltatime, std::vector<unsigned char>* message, void* arg)
+        {
+            rtmidi* midi = static_cast<rtmidi*>(arg);
+            unsigned int nBytes = message->size();
+            
+            int cmd = (int)message->at(0) >> 4;
+            int channel = (int)message->at(0) & 0xf;
+            
+            if (nBytes == 2) {
+             
+                int data1 = (int)message->at(1);
+                if (cmd == 12) {
+                    for (int i = 0; i < midi->fMidiInputs.size(); i++) {
+                        midi->fMidiInputs[i]->progChange(channel, data1);
+                    }
+                }
+            
+            } else if (nBytes == 3) {
+            
+                int data1 = (int)message->at(1);
+                int data2 = (int)message->at(2);
+                if (channel == 9) {
+                    return;
+                } else if (cmd == 8 || ((cmd == 9) && (data2 == 0))) { 
+                    for (int i = 0; i < midi->fMidiInputs.size(); i++) {
+                        midi->fMidiInputs[i]->keyOff(channel, data1, data2);
+                    }
+                } else if (cmd == 9) {
+                    for (int i = 0; i < midi->fMidiInputs.size(); i++) {
+                        midi->fMidiInputs[i]->keyOn(channel, data1, data2);
+                    }
+                } else if (cmd == 11) {
+                    for (int i = 0; i < midi->fMidiInputs.size(); i++) {
+                        midi->fMidiInputs[i]->ctrlChange(channel, data1, data2);
+                    }
+                } else if (cmd == 14) {
+                    for (int i = 0; i < midi->fMidiInputs.size(); i++) {
+                        midi->fMidiInputs[i]->pitchWheel(channel, ((data2 * 128.0 + data1) - 8192) / 8192.0);
+                    }
+                }
+                
+            } else {
+                 std::cout << "long message : " << nBytes << endl;
+            }
+        }
+        
+        bool chooseMidiInputPort(const std::string& name)
+        {
+            // opens a virtual port when available on API
+            fInput->openVirtualPort(name);
+            
+            /*
+            unsigned int i = 0, nPorts = fInput->getPortCount();
+            if (nPorts == 0) {
+                std::cout << "No input ports available!" << std::endl;
+                return false;
+            }
+            
+            for (i = 0; i < nPorts; i++) {
+                std::string portName = fInput->getPortName(i);
+                std::cout << "Input port #" << i << ": " << portName << '\n';
+                fInput->openPort(i);
+            }
+            */
+
+            return true;
+        }
+        
+        bool chooseMidiOutPort(const std::string& name)
+        {
+            // opens a virtual port when available on API
+            fOutput->openVirtualPort(name);
+        
+            /*
+            unsigned int i = 0, nPorts = fOutput->getPortCount();
+            if (nPorts == 0) {
+                std::cout << "No output ports available!" << std::endl;
+                return false;
+            }
+            
+            for (i = 0; i < nPorts; i++) {
+                std::string portName = fOutput->getPortName(i);
+                std::cout << "Output port #" << i << ": " << portName << '\n';
+                fOutput->openPort(i);
+            }
+            */
+
+            return true;
+        }
+    
+    public:
+    
+        rtmidi(const std::string& name = "RtMidi"):fInput(0), fOutput(0), fName(name)
+        {}
+        
+        virtual ~rtmidi()
+        {
+            stop();
+        }
+        
+        void addMidiIn(midi* dsp) { fMidiInputs.push_back(dsp); }
+        
+        bool start()
+        {
+            try {
+            
+                fInput = new RtMidiIn();
+                if (!chooseMidiInputPort(fName)) goto cleanup;
+                fInput->setCallback(&midiCallback, this);
+                
+                fOutput = new RtMidiOut();
+                if (!chooseMidiOutPort(fName)) goto cleanup; 
+                
+                return true;
+                
+            } catch (RtMidiError &error) {
+                error.printMessage();
+                return false;
+            }
+            
+        cleanup:
+
+            delete fInput;
+            delete fOutput;
+            return false;
+        }
+        
+        void stop()
+        {
+            delete fInput;
+            delete fOutput;
+            fInput = 0;
+            fOutput = 0;
+        }
+        
+        void ctrlChange(int channel, int ctrl, int val) 
+        {
+            std::vector<unsigned char> message;
+            message.push_back(MIDI_CONTROL_CHANGE+(channel-1));
+            message.push_back(ctrl);
+            message.push_back(val);
+            fOutput->sendMessage(&message);
+        }
+        
+        void progChange(int channel, int pgm) 
+        {
+            std::vector<unsigned char> message;
+            message.push_back(MIDI_PROGRAM_CHANGE+(channel-1));
+            message.push_back(pgm);
+            fOutput->sendMessage(&message);
+        }
+        
+        void keyOn(int channel, int note, int velocity) 
+        {
+            std::vector<unsigned char> message;
+            message.push_back(MIDI_NOTE_ON+(channel-1));
+            message.push_back(note);
+            message.push_back(velocity);
+            fOutput->sendMessage(&message);
+        }
+        
+        void keyOff(int channel, int note, int velocity) 
+        {
+            std::vector<unsigned char> message;
+            message.push_back(MIDI_NOTE_OFF+(channel-1));
+            message.push_back(note);
+            message.push_back(velocity);
+            fOutput->sendMessage(&message);
+        }
+        
+        void pitchWheel(int channel, int wheel) 
+        {
+            std::vector<unsigned char> message;
+            message.push_back(MIDI_PITCH_BEND+(channel-1));
+            message.push_back(wheel & 0x7F);		// lsb 7bit
+            message.push_back((wheel >> 7) & 0x7F);	// msb 7bit
+            fOutput->sendMessage(&message);
+        }
+   
+};
diff --git a/architecture/faust/misc.h b/architecture/faust/misc.h
new file mode 100644
index 0000000..ca0b94d
--- /dev/null
+++ b/architecture/faust/misc.h
@@ -0,0 +1,69 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+ ************************************************************************
+ ************************************************************************/
+ 
+#ifndef __misc__
+#define __misc__
+
+#include <algorithm>
+#include <map>
+#include <string.h>
+#include <stdlib.h>
+
+#include "faust/gui/meta.h"
+
+using std::max;
+using std::min;
+
+struct XXXX_Meta : std::map<const char*, const char*>
+{
+    void declare(const char* key, const char* value) { (*this)[key]=value; }
+};
+
+struct MY_Meta : Meta, std::map<const char*, const char*>
+{
+    void declare(const char* key, const char* value) { (*this)[key]=value; }
+};
+
+inline int	lsr(int x, int n)	{ return int(((unsigned int)x) >> n); }
+inline int 	int2pow2(int x)		{ int r=0; while ((1<<r)<x) r++; return r; }
+
+long lopt(char *argv[], const char *name, long def)
+{
+	int	i;
+	for (i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
+	return def;
+}
+
+bool isopt(char *argv[], const char *name)
+{
+	int	i;
+	for (i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return true;
+	return false;
+}
+
+const char* lopts(char *argv[], const char *name, const char* def)
+{
+	int	i;
+	for (i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return argv[i+1];
+	return def;
+}
+#endif
+
diff --git a/architecture/faust/sound-file.h b/architecture/faust/sound-file.h
new file mode 100644
index 0000000..e847d6e
--- /dev/null
+++ b/architecture/faust/sound-file.h
@@ -0,0 +1,128 @@
+/*
+
+Copyright (C) Grame 2015
+
+This library is free software; you can redistribute it and modify it under
+the terms of the GNU Library General Public License as published by the
+Free Software Foundation version 2 of the License, or any later version.
+
+This library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License
+for more details.
+
+You should have received a copy of the GNU Library 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.
+
+Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France
+research at grame.fr
+
+*/
+
+#ifndef __SoundFileReader__
+#define __SoundFileReader__
+
+#include <sndfile.h>
+#include <stdlib.h>
+
+#define BUFFER_SIZE 1024
+
+#ifndef FAUSTFLOAT
+#define READ_SAMPLE sf_readf_float
+#define FAUSTFLOAT float
+#else
+#define READ_SAMPLE sf_readf_double
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SoundFileReader {
+    FAUSTFLOAT** fBuffer;
+    SNDFILE* fSoundFile;
+    int fChannels;
+    int fFramesNum;
+} SoundFileReader;
+    
+inline static SoundFileReader* createSFR(const char* name)
+{
+    SoundFileReader* reader = (SoundFileReader*)calloc(1, sizeof(SoundFileReader));
+    if (!reader) return NULL;
+
+    {
+        SF_INFO	snd_info;
+        snd_info.format = 0;
+        reader->fSoundFile = sf_open(name, SFM_READ, &snd_info);
+        
+        if (!reader->fSoundFile) {
+            printf("soundfile '%s' cannot be opened\n", name);
+            goto error;
+        }
+        
+        reader->fChannels = snd_info.channels;
+        reader->fFramesNum = snd_info.frames;
+
+        reader->fBuffer = (FAUSTFLOAT**)malloc(reader->fChannels * sizeof(FAUSTFLOAT*));
+        if (!reader) goto error;
+        
+        for (int i = 0; i < reader->fChannels; i++) {
+            reader->fBuffer[i] = (FAUSTFLOAT*)malloc(reader->fFramesNum * sizeof(FAUSTFLOAT));
+            if (!reader->fBuffer[i]) goto error;
+        }
+        
+        // Read file in memory
+        int nbf, cur_index = 0;
+        FAUSTFLOAT buffer[BUFFER_SIZE * reader->fChannels];
+        do {
+            nbf = READ_SAMPLE(reader->fSoundFile, buffer, BUFFER_SIZE);
+            for (int sample = 0; sample < nbf; sample++) {
+                for (int chan = 0; chan < reader->fChannels; chan++) {
+                    reader->fBuffer[chan][cur_index + sample] = buffer[sample * reader->fChannels + chan];
+                }
+            }
+            cur_index += nbf;
+        } while (nbf == BUFFER_SIZE);
+        
+        return reader;
+    }
+    
+error:
+    if (reader->fBuffer) free(reader->fBuffer);
+    if (reader) free(reader);
+    return NULL;
+}
+
+inline static void destroySFR(SoundFileReader* reader)
+{
+    if (reader) {
+        sf_close(reader->fSoundFile);
+        for (int i = 0; i < reader->fChannels; i++) {
+            free(reader->fBuffer[i]);
+        }
+        free(reader->fBuffer);
+        free(reader);
+    }
+}
+
+inline static int sizeSFR(SoundFileReader* reader)
+{
+    return (reader) ? reader->fFramesNum : 1; 
+}
+
+inline static int channelsSFR(SoundFileReader* reader)
+{
+    return (reader) ? reader->fChannels : 1; 
+}
+
+inline static FAUSTFLOAT sampleSFR(SoundFileReader* reader, int channel, int index)
+{   
+    return (reader) ? reader->fBuffer[channel][index] : 0.f;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/architecture/faust/vst/faust.h b/architecture/faust/vst/faust.h
new file mode 100644
index 0000000..4b54d1b
--- /dev/null
+++ b/architecture/faust/vst/faust.h
@@ -0,0 +1,116 @@
+#ifndef __VST_FAUST_H__
+#define __VST_FAUST_H__
+
+#include <list>
+#include <map>
+#include <vector>
+
+#include "audioeffectx.h"
+//#include "../audio/dsp.h"
+
+const int MAX_POLYPHONY = 10;
+
+const int INITIAL_TEMP_OUTPUT_SIZE = 1024;
+
+//////////////////////////////////////////////////////////////////
+// Faust class definition
+// This class implements the abstract methods of AudioEffectX
+// that define the VST instrument behavior.
+//////////////////////////////////////////////////////////////////
+class Faust : public AudioEffectX {
+public:
+	// Constructor
+  Faust(audioMasterCallback audioMaster, dsp* dspi, vstUI* dspUIi);
+
+	// Destructor
+  virtual ~Faust();
+
+  virtual void processReplacing (FAUSTFLOAT** inputs, FAUSTFLOAT** outputs, VstInt32 sampleFrames);
+  virtual VstInt32 processEvents (VstEvents* events);
+
+  virtual void setProgram (VstInt32 program);
+  virtual void setProgramName (const char *name);
+  virtual void getProgramName (char *name);
+  virtual bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char *text);
+
+  virtual void setParameter (VstInt32 index, float value);
+  virtual float getParameter (VstInt32 index);
+  virtual void getParameterLabel (VstInt32 index, char *label);
+  virtual void getParameterDisplay (VstInt32 index, char *text);
+  virtual void getParameterName (VstInt32 index, char *text);
+	virtual bool getParameterProperties(VstInt32 index, VstParameterProperties* properties);
+
+  virtual void setSampleRate (float sampleRate);
+
+  virtual bool getInputProperties (VstInt32 index, VstPinProperties *properties);
+  virtual bool getOutputProperties (VstInt32 index, VstPinProperties *properties);
+
+  virtual bool getEffectName (char *name);
+  virtual bool getVendorString (char *text);
+  virtual bool getProductString (char *text);
+  virtual VstInt32 getVendorVersion ();
+  virtual VstInt32 canDo (const char *text);
+
+  virtual VstInt32 getNumMidiInputChannels ();
+  virtual VstInt32 getNumMidiOutputChannels ();
+
+  virtual VstInt32 getMidiProgramName (VstInt32 channel, MidiProgramName *midiProgramName);
+  virtual VstInt32 getCurrentMidiProgram (VstInt32 channel, MidiProgramName *currentProgram);
+  virtual VstInt32 getMidiProgramCategory (VstInt32 channel, MidiProgramCategory *category);
+
+private:
+  // Get metadata supplied by Faust compiler
+  const char* getMetadata(const char* key, const char* defaultString);
+
+  void initProcess ();
+  void noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta);
+  void noteOff (VstInt32 note, VstInt32 delta);
+	void allNotesOff( void );
+  void fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn);
+
+	void synthProcessReplacing(float **inputs, float **outputs, 
+														 VstInt32 sampleFrames);
+
+	void compute(float** inputs, float** outputs, VstInt32 sampleFrames);
+	void bendPitch(float bend);
+
+  dsp* m_dsp;
+  vstUI*	m_dspUI;
+
+  // For synths:
+  bool noteIsOn;
+  VstInt32 currentNote;
+  VstInt32 currentVelocity;
+  VstInt32 currentDelta;
+
+  std::list<VstInt32> m_currentNotes;
+  std::list<VstInt32> m_currentVelocities;
+  std::list<VstInt32> m_currentDeltas;
+
+  char programName[kVstMaxProgNameLen + 1];
+
+  // Polyphony
+	std::vector<Voice*> m_voices;
+
+	// Occupied voices - map note to voice index
+	struct voice_node {
+		VstInt32 note;
+		int voice;
+	};
+
+	std::list<voice_node*> m_playingVoices;
+
+	// key off but still sounding
+	std :: vector< int > m_releasedVoices;
+
+	// Free voices - currently rot playing
+	std :: list< int > m_freeVoices;
+
+	// Previously played voice
+	int m_prevVoice;
+
+	FAUSTFLOAT** m_tempOutputs;
+	size_t m_tempOutputSize; // in float frames
+}; // end of Faust class
+
+#endif
diff --git a/architecture/faust/vst/voice.h b/architecture/faust/vst/voice.h
new file mode 100644
index 0000000..7020afc
--- /dev/null
+++ b/architecture/faust/vst/voice.h
@@ -0,0 +1,22 @@
+//////////////////////////////////////////////////////
+// Faust VST Voice
+//////////////////////////////////////////////////////
+
+#ifndef __VST_VOICE_H__
+#define __VST_VOICE_H__
+
+//#include "../audio/dsp.h"
+
+class Voice : public vstUI {
+public:
+	Voice(int samplingRate) 
+		: vstUI(), m_dsp() 
+	{
+		m_dsp.init(samplingRate);
+		m_dsp.buildUserInterface(this);
+	}
+
+	mydsp m_dsp;
+}; //end of Voice vlass
+
+#endif
diff --git a/architecture/faust/vst/vstui.h b/architecture/faust/vst/vstui.h
new file mode 100644
index 0000000..dc66216
--- /dev/null
+++ b/architecture/faust/vst/vstui.h
@@ -0,0 +1,455 @@
+#ifndef __VST_UI_H__
+#define __VST_UI_H__
+
+#include <audioeffectx.h>
+#include <faust/gui/UI.h>
+
+#ifdef DEBUG
+#define TRACE(x) x
+#else
+#define TRACE(x)
+#endif
+
+//////////////////////////// VST UI ////////////////////////
+
+class vstUIObject { /* superclass of all VST UI widgets */
+    
+protected:
+    
+    string fLabel;
+    float* fZone;
+	Meta metadata;
+    
+    float clip(float min, float max, float val) 
+    {
+        return (val < min) ? min : (val > max) ? max : val;
+    }
+    
+    float normalize(float min, float max, float val) 
+    { // VST parameters are normalized to the range [0;1] on the host
+        val = min + val * (max - min);
+        return (val < min) ? min : (val > max) ? max : val;
+    }
+    
+public:		
+	
+    vstUIObject(const char* label, float* zone)
+    : fLabel(label), fZone(zone), metadata()
+	{}
+    
+    virtual ~vstUIObject()
+	{}
+    
+    virtual void  GetName(char *text) {
+		std::strcpy(text,fLabel.c_str());
+	}
+    
+    virtual void  SetValue(double f) {
+		*fZone = normalize(0.0f,1.0f,(float)f);
+	}
+    
+    virtual void  SetValueNoNormalization(double f) {
+		*fZone = clip(0.0f,1.0f,(float)f);
+	}
+    
+    virtual float GetValue() {
+		return *fZone;
+	}
+    
+	virtual float GetValueNoNormalization() {
+		return *fZone;
+	}
+    
+    virtual void  GetDisplay(char *text){
+		std::sprintf(text,"%f",*fZone);
+	}
+	
+    virtual long  GetID() {	
+		/* returns the sum of all the ASCII characters  contained in the 
+         parameter's label */
+        unsigned int i;
+        long acc;
+        for(i=0,acc = 0; i < fLabel.length(); i++) {
+			acc += (fLabel.c_str())[i];
+		}
+        return acc;
+    }
+    
+	const float* getZone() const {
+		return fZone;
+	}
+}; // end of vstUIObject class
+
+/*-------------------------------------------------------------------------*/
+class vstToggleButton : public vstUIObject {
+	
+public:	
+	
+    vstToggleButton(const char* label, float* zone)
+    : vstUIObject(label,zone) 
+    {}
+    
+    virtual ~vstToggleButton() {}
+    virtual float GetValue() {
+		return *fZone;
+	}
+    
+    virtual void SetValue(double f) {
+		*fZone = (f>0.5f) ? 1.0f : 0.0f;
+	}
+    
+	virtual void  GetDisplay(char *text) {
+		(*fZone > 0.5f) ? std::strcpy(text,"ON") : std::strcpy(text,"OFF");
+	}
+};
+
+/*--------------------------------------------------------------------------*/
+class vstCheckButton : public vstUIObject {
+	
+public:
+	
+    vstCheckButton(const char* label, float* zone):vstUIObject(label,zone) {}	
+    
+    virtual ~vstCheckButton() {}
+    
+    virtual float GetValue() {
+		return *fZone;
+	}
+    
+    virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}
+    
+    virtual void GetDisplay(char *text) {
+		(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");
+	}
+};
+
+/*--------------------------------------------------------------------------*/
+class vstButton : public vstUIObject {
+	
+public:
+	
+    vstButton(const char* label, float* zone)
+    : vstUIObject(label,zone) 
+    {}
+    
+    virtual ~vstButton() {}		
+    virtual float GetValue() {return *fZone;}
+    virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}		
+    virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
+};
+
+#define MAX_PARAM_DISPLAY_PRECISION 6
+/*--------------------------------------------------------------------------*/
+class vstSlider : public vstUIObject{
+    
+private:
+	
+    float fInit;
+    float fMin;
+    float fMax;
+    float fStep;
+    int fPrecision;
+	
+public:	
+	
+    vstSlider(const char* label, float* zone, float init, float min, float max, float step)
+    :vstUIObject(label,zone), fInit(init), fMin(min), fMax(max), fStep(step), fPrecision(0) {
+        for (fPrecision = 0; fPrecision < MAX_PARAM_DISPLAY_PRECISION && step != floor(step); ++fPrecision, step *= 10.0) {;}
+    }
+    virtual ~vstSlider() {}	
+    
+    // The VST host calls GetValue() and expects a result in [0,1].
+    // The VST host calls SetValue(f) with f in [0,1]. We convert to real units.
+    // When we process MIDI controls, we call SetValueNoNormalization(f) with f in real units.
+    virtual float GetValue() {
+		return (*fZone-fMin)/(fMax-fMin); // normalize
+	}
+    
+    virtual void SetValue(double f) {
+		*fZone = normalize(fMin,fMax,(float)f); // denormalize
+	}
+    
+    virtual void SetValueNoNormalization(double f) {
+		*fZone = clip(fMin,fMax,(float)f); // raw
+	}
+    
+	int getMinValue() const {
+		return fMin;
+	}
+    
+	int getMaxValue() const {
+		return fMax;
+	}
+    
+	int getStep() const {
+		return fStep;
+	}
+    
+    void GetDisplay(char *text) {
+		if(fPrecision == 0) {
+			std::sprintf(text, "%d", int(*fZone));
+		} else {
+			std::sprintf(text,"%.*f", fPrecision, *fZone);
+        }
+	}
+    
+};
+
+/*--------------------------------------------------------------------------*/
+class vstUI : public UI
+{
+    
+private:
+    
+    bool fStopped;
+    
+    vector<vstUIObject*> fUITable;
+	map<const float*, Meta*> m_controlMetadataMap;
+	
+public:
+    
+    int freqIndex; // note frequency
+    int gainIndex; // note velocity
+    int gateIndex; // note on/off
+    
+	// can be used for effects such as portamento where
+	// we have to know the previous note
+	int prevFreqIndex;
+    
+	// pitchbend wheel
+	int pitchbendIndex;
+    
+    // Constructor
+    vstUI()
+    : fStopped(false), freqIndex(-1), gainIndex(-1), gateIndex(-1)
+	{ }
+    
+    // Destructor
+    virtual ~vstUI() 
+    {
+		for (vector<vstUIObject*>::iterator iter = fUITable.begin(); 
+             iter != fUITable.end(); iter++) {
+			delete *iter;
+		}
+        
+		for (map<const float*, Meta*>::iterator iter = m_controlMetadataMap.begin();
+             iter != m_controlMetadataMap.end(); ++iter)
+		{
+			delete iter->second;
+		}
+    } // end of destructor
+    
+    void stop()      { fStopped = true; }
+    bool stopped() { return fStopped; }
+    
+    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value) {
+		map<const float*, Meta*>::iterator iter = m_controlMetadataMap.find(zone);
+		if (iter == m_controlMetadataMap.end()) {
+			// if Meta for zone doesn't exist, create it now
+			pair<const float*, Meta*> entry(zone, new Meta());
+			pair< map<const float*, Meta*>::iterator, bool> result = m_controlMetadataMap.insert(entry);
+			if (!result.second) {
+				TRACE(fprintf(stderr, "Failed adding metadata %s:%s\n", key, value));
+				return;
+			}
+            
+			iter = result.first;
+		}
+		
+		iter->second->declare(key, value);	
+    } // end of declare
+    
+	/*
+     Return metadata for control (such as style, unit, etc...).
+     */
+	const char* getControlMetadata(int index, const char* key, const char* defaultString)
+	{
+		if (index < 0 || index > (int)fUITable.size()) {
+			TRACE(fprintf(stderr, "Illegal index (%d) accessed by getControlMetadata\n",
+                          index));
+			return defaultString;
+		}
+        
+		const	float* zone = fUITable[index]->getZone();
+		map<const float*, Meta*>::iterator iter = m_controlMetadataMap.find(zone);
+		if (iter == m_controlMetadataMap.end()) {
+			TRACE(fprintf(stderr, "Metadata for control %d not found\n", index));
+			return defaultString;
+		}
+        
+		return iter->second->get(key, defaultString);
+	} // end of getControlMetadata
+    
+	void setAny(int anyIndex, float val, const char *str) {
+		if (anyIndex < 0) {
+			// On the Receptor, and perhaps other hosts, output to stderr is 
+			// logged in a file.
+			TRACE(fprintf(stderr,"*** Faust vsti: %sIndex = %d never set!\n",
+                          str,anyIndex) );
+			return;
+		}
+        
+		if (anyIndex >= (int)fUITable.size()) {
+			TRACE(fprintf(stderr,"*** Faust vsti: %sIndex = %d too large!\n",
+                          str,anyIndex));
+			return;
+		}
+		TRACE(fprintf(stderr,"*** Faust vsti: Setting %sIndex = %d to %f\n",
+                      str,anyIndex,val));
+		fUITable[anyIndex]->SetValueNoNormalization(val);
+	} // end of setAny
+    
+    
+	float getAny(int anyIndex, const char* str) {
+		if (anyIndex < 0) {
+			TRACE(fprintf(stderr, "=== Faust VSTi: %sIndex = %d never set!\n",
+                           str, anyIndex));
+			return -1;
+		}
+        
+		return fUITable[anyIndex]->GetValueNoNormalization();
+	} // end of getAny
+    
+	void setFreq(float val) {
+		setAny(freqIndex, val, "freq");
+    }
+    
+	float getFreq( void ) {
+		return getAny(freqIndex, "freq");	
+	}
+    
+    void setGate(float val) {
+        setAny(gateIndex, val, "gate");
+    }
+	
+    void setGain(float val) {
+        setAny(gainIndex, val, "gain");
+    }
+    
+	void setPrevFreq(float val) {
+		setAny(prevFreqIndex, val, "prevfreq");
+	}
+    
+	void setPitchBend(float val) {
+		setAny(pitchbendIndex, val, "pitchbend");
+	}
+    
+    bool ckAnyMatch(const char* label, const char* indexName, int *index) {
+        if (0 == strcmp(label,indexName)) { 
+            TRACE( fprintf(stderr,"=== Faust vsti: label '%s' matches '%s'\n",label,indexName) );
+            *index = fUITable.size() - 1; 
+            return true;
+        }
+        return false;
+    }
+    
+    void ckAllMatches(const char* label) {
+        ckAnyMatch(label,"gain",&gainIndex);
+        ckAnyMatch(label,"gate",&gateIndex);
+        ckAnyMatch(label,"freq",&freqIndex);
+		ckAnyMatch(label,"prevfreq", &prevFreqIndex);
+		ckAnyMatch(label,"pitchbend", &pitchbendIndex);
+    }
+    
+    void addButton(const char* label, float* zone) {
+        vstButton* theButton = new vstButton(label, zone);
+        fUITable.push_back(theButton);
+        TRACE( fprintf(stderr,"=== Faust vsti: Adding Button with label '%s'\n",label) );
+        ckAnyMatch(label,"gate",&gateIndex);
+    }
+    
+	void addToggleButton(const char* label, float* zone) {
+		fUITable.push_back(new vstToggleButton(label, zone));
+	}
+    
+    void addCheckButton(const char* label, float* zone) {
+		fUITable.push_back(new vstCheckButton(label, zone));
+    }
+    
+    void addVerticalSlider(const char* label, float* zone, float init, 
+                           float min, float max, float step) 
+    { 	
+		vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step);
+		fUITable.push_back(theSlider);
+		TRACE( fprintf(stderr,"=== Faust vsti: Adding VSlider (HSlider) "
+                       "with label '%s'\n",label) );
+		ckAllMatches(label);
+    }
+	
+    void addHorizontalSlider(const char* label, float* zone, float init, 
+                             float min, float max, float step) 
+    {
+		vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step);
+		fUITable.push_back(theSlider);
+		TRACE( fprintf(stderr,"=== Faust vsti: Adding HSlider with label '%s'\n",label) );
+		ckAllMatches(label);
+    }
+    
+    void addNumEntry(const char* label, float* zone, float init, float min, 
+                     float max, float step)
+    { 
+		/* Number entries converted to horizontal sliders */
+		vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step);
+        fUITable.push_back(theSlider);
+        TRACE( fprintf(stderr,"=== Faust vsti: Adding NumEntry (HSlider) with "
+                       "label '%s'\n",label) );
+		ckAllMatches(label);
+    }
+    
+	void openFrameBox(const char* label) {}
+	void openTabBox(const char* label) {}
+    void openHorizontalBox(const char* label) {}
+    void openVerticalBox(const char* label) {}
+    void closeBox() {}
+    
+    void  SetValue(VstInt32 index, double f) {
+		assert(index < (VstInt32)fUITable.size()); 
+		fUITable[index]->SetValue(f);
+	}
+    
+    float GetValue(VstInt32 index) {
+		assert(index < (VstInt32)fUITable.size()); 
+		return fUITable[index]->GetValue();
+	}
+    
+    void  GetDisplay(VstInt32 index, char *text) {
+		assert(index < (VstInt32)fUITable.size()); 
+		fUITable[index]->GetDisplay(text);
+    }
+    
+    void  GetName(VstInt32 index, char *text) {
+        assert(index < (VstInt32)fUITable.size()); 
+		fUITable[index]->GetName(text);
+    }
+    
+    long GetNumParams() {
+        return fUITable.size();
+    }
+    
+    /* Creates a (unique?)id by summing all the parameter's labels, 
+     * then wrapping it in the range [0;maxNumberOfId] and adding 
+     * this number to the offset made by the Four Character ID: 'FAUS'
+     */
+    long makeID() {   
+        const long maxNumberOfId = 128;
+        long baseid = 'FAUS';
+        long id=0;
+        
+        for(int i=0;i<(int)fUITable.size();i++) {
+			id += fUITable[i]->GetID();
+		}
+        
+		return baseid + id % maxNumberOfId;
+    }
+    
+    // To be implemented
+    void addNumDisplay(const char* label, float* zone, int precision) {}
+    void addTextDisplay(const char* label, float* zone, char* names[], 
+                        float min, float max){}
+    void addHorizontalBargraph(const char* label, float* zone, float min, 
+                               float max){}
+    void addVerticalBargraph(const char* label, float* zone, float min, 
+                             float max){}
+}; // end of vstUI class
+
+#endif
diff --git a/architecture/filter.lib b/architecture/filter.lib
index 7e2b7c7..6a69bae 100644
--- a/architecture/filter.lib
+++ b/architecture/filter.lib
@@ -29,11 +29,15 @@ pole(p) = + ~ *(p);
 
 integrator = + ~ _ ;
 
-//----------------------- tau2pole ---------------------------
+//------------------ tau2pole, pole2tau ----------------------
 // tau2pole(tau) returns a real pole giving exponential decay with
 // tau = time-constant in seconds
-//
+// Note that t60 (time to decay 60 dB) is ~6.91 time constants.
+// pole2tau(pole) returns the time-constant, in seconds, 
+// corresponding to the given real, positive pole in (0,1).
+
 tau2pole(tau) = exp(-1.0/(tau*SR));
+pole2tau(pole) = -1.0/(log(pole)*SR);
 
 //---------------------- smooth(s) --------------------------
 // Exponential smoothing by a unity-dc-gain one-pole lowpass
@@ -98,6 +102,14 @@ with {
   b2 = b0;
 };
 
+//---------------------------- latch(c) --------------------------------
+// Latch input on positive-going transition of "clock" ("sample-and-hold")
+//
+// USAGE:
+//   _ : latch(clocksig) : _
+
+latch(c,x) = x * s : + ~ *(1-s) with { s = ((c'<=0)&(c>0)); };
+
 //========================= Comb Filters ===============================
 
 //----------------------- ff_comb, ff_fcomb ----------------------------
@@ -143,8 +155,8 @@ ffcombfilter(maxdel,del,g) = ff_comb(maxdel,del,1,g);
 // Reference: 
 //   https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html
 
-fb_comb (maxdel,N,b0,aN) = (+ <:  delay(maxdel,N),_) ~ *(-aN) : !,*(b0);
-fb_fcomb(maxdel,N,b0,aN) = (+ <: fdelay(maxdel,N),_) ~ *(-aN) : !,*(b0);
+fb_comb (maxdel,N,b0,aN) = (+ <:  delay(maxdel,N-1),_) ~ *(-aN) : !,*(b0):mem;
+fb_fcomb(maxdel,N,b0,aN) = (+ <: fdelay(maxdel,float(N)-1.0),_) ~ *(-aN) : !,*(b0):mem;
 
 // The "rev1 section" dates back to the 1960s in computer-music reverberation.
 // See the jcrev and brassrev in effect.lib for usage examples.
@@ -182,6 +194,12 @@ allpass_comb(maxdel,N,aN) = (+ <:
    delay(maxdel,N-1),*(aN)) ~ *(-aN)
    : mem,_ : + ;
 
+allpass_fcomb(maxdel,N,aN) = (+ <: fdelay(maxdel,N-1),*(aN)) ~ *(-aN) : mem,_ : + ;
+allpass_fcomb5(maxdel,N,aN) = (+ <: fdelay5(maxdel,N-1),*(aN)) ~ *(-aN) : mem,_ : + ;
+allpass_fcomb1a(maxdel,N,aN) = (+ <: fdelay1a(maxdel,N-1),*(aN)) ~ *(-aN) : mem,_ : + ;
+// Interpolation helps - look at an fft of faust2octave on
+// 1-1' <: allpass_fcomb(1024,10.5,0.95), allpass_fcomb5(1024,10.5,0.95);
+
 // The "rev2 section" dates back to the 1960s in computer-music reverberation:
 rev2(maxlen,len,g) = allpass_comb(maxlen,len,-g);
 
@@ -195,7 +213,7 @@ rev2(maxlen,len,g) = allpass_comb(maxlen,len,-g);
 // Such filter structures are termed "direct form".
 //
 // USAGE:
-//   _ : iir(order,bcoeffs,acoeffs) : _
+//   _ : iir(bcoeffs,acoeffs) : _
 // where
 //   order = filter order (int) = max(#poles,#zeros)
 //   bcoeffs = (b0,b1,...,b_order) = TF numerator coefficients
@@ -223,7 +241,11 @@ sub(x,y) = y-x; // move to math.lib?
 // EQUIVALENT (note double parens):
 //   process = noise : fir((.2,.2,.2,.2,.2));
 
-fir(bv) = conv(bv);
+//fir(bv) = conv(bv);
+fir((b0,bv)) = _ <: *(b0), R(1,bv) :> _ with {
+	R(n,(bn,bv)) = (@(n):*(bn)), R(n+1,bv);
+	R(n, bn)     = (@(n):*(bn));              };
+fir(b0) = *(b0);
 
 //--------------------------- conv, convN -------------------------------
 // Convolution of input signal with given coefficients
@@ -232,15 +254,35 @@ fir(bv) = conv(bv);
 //  _ : conv((k1,k2,k3,...,kN)) : _; // Argument = one signal bank
 //  _ : convN(N,(k1,k2,k3,...)) : _; // Useful when N < count((k1,...))
 
-convN(N,kv,x) = sum(i,N,take(i+1,kv) * x at i); // take() defined in math.lib
+//convN(N,kv,x) = sum(i,N,take(i+1,kv) * x at i); // take() defined in math.lib
+convN(N,kv)     = sum(i,N, @(i)*take(i+1,kv)); // take() defined in math.lib
+
+//conv(kv,x) = sum(i,count(kv),take(i+1,kv) * x at i); // count() from math.lib
+conv(kv) = fir(kv);
 
-conv(kv,x) = sum(i,count(kv),take(i+1,kv) * x at i); // count() from math.lib
 
 // Named special cases:
 //----------------------------- tf1, tf2 ---------------------------------
 // tfN = N'th-order direct-form digital filter
 tf1(b0,b1,a1) = _ <: *(b0), (mem : *(b1)) :> + ~ *(0-a1);
 tf2(b0,b1,b2,a1,a2) = iir((b0,b1,b2),(a1,a2)); // cf. TF2 in music.lib)
+// tf2 is a variant of tf22 below with duplicated mems
+
+//=============== Direct-Form second-order biquad sections ================
+// REFERENCE: https://ccrma.stanford.edu/~jos/filters/Four_Direct_Forms.html
+
+//---------------------- tf21, tf21t, tf22, tf22t ------------------------
+tf21(b0,b1,b2,a1,a2) = // tf2, direct-form 1:
+    _ <:(mem<:((mem:*(b2)),*(b1))),*(b0) :>_
+    : ((_,_,_:>_) ~(_<:*(-a1),(mem:*(-a2))));
+tf22(b0,b1,b2,a1,a2) = // tf2, direct-form 2:
+    _ : (((_,_,_:>_)~*(-a1)<:mem,*(b0))~*(-a2))
+      : (_<:mem,*(b1)),_ : *(b2),_,_ :> _;
+tf22t(b0,b1,b2,a1,a2) = // tf2, direct-form 2 transposed:
+    _ : (_,_,(_ <: *(b2)',*(b1)',*(b0))
+      : _,+',_,_ :> _)~*(-a1)~*(-a2) : _;
+tf21t(b0,b1,b2,a1,a2) = // tf2, direct-form 1 transposed:
+    tf22t(1,0,0,a1,a2) : tf22t(b0,b1,b2,0,0); // or write it out if you want
 
 //===================== Ladder/Lattice Digital Filters ======================
 // Ladder and lattice digital filters generally have superior numerical
@@ -253,7 +295,7 @@ tf2(b0,b1,b2,a1,a2) = iir((b0,b1,b2),(a1,a2)); // cf. TF2 in music.lib)
 //  J. D. Markel and A. H. Gray: Linear Prediction of Speech, New York: Springer Verlag, 1976.
 //  https://ccrma.stanford.edu/~jos/pasp/Conventional_Ladder_Filters.html
 
-//------------------------------ block, crossn,crossn1 ----------------------------------
+//------------------------- block, crossn,crossn1 -----------------------------
 // signal block/crossing utilities
 // (move to math.lib?)
 
@@ -403,7 +445,7 @@ with {
   tgr(i) = take(M+1-i,tg);
   tghr(n) = tgr(n)/pi(n);
   pi(0) = 1;
-  s(n) = take(M-n+1,sv);
+  s(n) = take(M-n+1,sv); // reflection coefficient = sin(theta) 
   c(n) = sqrt(max(0,1-s(n)*s(n))); // compiler crashes on sqrt(-)
   pi(n) = pi(n-1)*c(n);
 };
@@ -636,7 +678,7 @@ with {
 //
 tf1s(b1,b0,a0,w1) = tf1(b0d,b1d,a1d)
 with {
-  c   = 1/tan((w1)*0.5/SR); // bilinear-transform scale-factor
+  c   = 1/tan(w1*0.5/SR); // bilinear-transform scale-factor
   d   = a0 + c;
   b1d = (b0 - b1*c) / d;
   b0d = (b0 + b1*c) / d;
@@ -718,7 +760,7 @@ with {
 //   _ : lowpass(N,fc) : _
 //   _ : highpass(N,fc) : _
 // where
-//   N = filter order (number of poles) [nonnegative integer]
+//   N = filter order (number of poles) [nonnegative constant integer]
 //   fc = desired cut-off frequency (-3dB frequency) in Hz
 // REFERENCE: 
 //  https://ccrma.stanford.edu/~jos/filters/Butterworth_Lowpass_Design.html
@@ -1003,40 +1045,77 @@ with { // octave script output:
 //================= Parametric Equalizers (Shelf, Peaking)  ==================
 // REFERENCES
 // - http://en.wikipedia.org/wiki/Equalization
-// - Digital Audio Signal Processing, Udo Zolzer, Wiley, 1999, p. 124
-// - http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
-//   http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+// - filterbank (below, here in filter.lib)
+// - http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+//   Digital Audio Signal Processing, Udo Zolzer, Wiley, 1999, p. 124
 // - https://ccrma.stanford.edu/~jos/filters/Low_High_Shelving_Filters.html
 // - https://ccrma.stanford.edu/~jos/filters/Peaking_Equalizers.html
 // - maxmsp.lib in the Faust distribution
 // - bandfilter.dsp in the faust2pd distribution 
 
-//----------------------------- low_shelf ------------------------------------
+//------------------------------ low_shelf -------------------------------------
 // First-order "low shelf" filter (gain boost|cut between dc and some frequency)
-// USAGE: lowshelf(L0,fx), where
-//  L0 = desired boost (dB) between dc and fx
-//  fx = desired transition frequency (Hz) from boost to unity gain
-// The gain at SR/2 is constrained to be 1.
 //
-low_shelf = low_shelf3; // default
-low_shelf1(L0,fx,x) = x + (db2linear(L0)-1)*lowpass(1,fx,x);
-low_shelf1_l(G0,fx,x) = x + (G0-1)*lowpass(1,fx,x);
-low_shelf3(L0,fx,x) = x + (db2linear(L0)-1)*lowpass(3,fx,x);
-low_shelf5(L0,fx,x) = x + (db2linear(L0)-1)*lowpass(5,fx,x);
-
-//----------------------------- high_shelf -----------------------------------
+// USAGE: 
+//   _ : lowshelf(N,L0,fx) : _
+// where
+//   N = filter order 1, 3, 5, ... (odd only).
+//  L0 = desired level (dB) between dc and fx (boost L0>0 or cut L0<0)
+//  fx = -3dB frequency of lowpass band (L0>0) or upper band (L0<0)
+//       (see "SHELF SHAPE" below).
+//
+// The gain at SR/2 is constrained to be 1.
+// The generalization to arbitrary odd orders is based on the well known
+// fact that odd-order Butterworth band-splits are allpass-complementary
+// (see filterbank documentation below for references).
+//
+// SHELF SHAPE 
+//  The magnitude frequency response is approximately piecewise-linear
+//  on a log-log plot ("BODE PLOT").  The Bode "stick diagram" approximation
+//  L(lf) is easy to state in dB versus dB-frequency lf = dB(f):
+// L0 > 0:
+//  L(lf) = L0, f between 0 and fx = 1st corner frequency;
+//  L(lf) = L0 - N * (lf - lfx), f between fx and f2 = 2nd corner frequency;
+//  L(lf) = 0, lf > lf2.
+//    lf2 = lfx + L0/N = dB-frequency at which level gets back to 0 dB.
+//    See lowshelf_other_freq() below.
+// L0 < 0:
+//  L(lf) = L0, f between 0 and f1 = 1st corner frequency;
+//  L(lf) = - N * (lfx - lf), f between f1 and lfx = 2nd corner frequency;
+//  L(lf) = 0, lf > lfx.
+//    lf1 = lfx + L0/N = dB-frequency at which level goes up from L0.
+//    See lowshelf_other_freq() below.
+
+lowshelf(N,L0,fx) = filterbank(N,(fx)) : _, *(db2linear(L0)) :> _;
+// Special cases and optimization:
+low_shelf  = lowshelf(3); // default = 3rd order Butterworth
+low_shelf1(L0,fx,x) = x + (db2linear(L0)-1)*lowpass(1,fx,x); // optimized
+low_shelf1_l(G0,fx,x) = x + (G0-1)*lowpass(1,fx,x); // optimized
+
+lowshelf_other_freq(N, L0, fx) = db2linear(linear2db(fx) + L0/N); // convenience
+
+//------------------------------ high_shelf ------------------------------------
 // First-order "high shelf" filter (gain boost|cut above some frequency)
 //
-// USAGE: high_shelf(Lpi,fx), where
-//  Lpi = desired boost or cut (dB) between fx and SR/2
-//  fx = desired transition frequency in Hz
-// The gain at dc is constrained to be 1
+// USAGE: 
+//   _ : highshelf(N,Lpi,fx) : _
+// where
+//    N = filter order 1, 3, 5, ... (odd only).
+//  Lpi = desired level (dB) between fx and SR/2 (boost Lpi>0 or cut Lpi<0)
+//   fx = -3dB frequency of highpass band (L0>0) or lower band (L0<0)
+//        (Use highshelf_other_freq() below to find the other one.)
 //
-high_shelf=high_shelf3; //default
-high_shelf1(Lpi,fx,x) = x + (db2linear(Lpi)-1)*highpass(1,fx,x);
-high_shelf1_l(Gpi,fx,x) = x + (Gpi-1)*highpass(1,fx,x);
-high_shelf3(Lpi,fx,x) = x + (db2linear(Lpi)-1)*highpass(3,fx,x);
-high_shelf5(Lpi,fx,x) = x + (db2linear(Lpi)-1)*highpass(5,fx,x);
+// The gain at dc is constrained to be 1.
+// See lowshelf documentation above regarding SHELF SHAPE.
+
+highshelf(N,Lpi,fx) = filterbank(N,(fx)) : *(db2linear(Lpi)), _ :> _;
+// Special cases and optimization:
+high_shelf = highshelf(3); // default = 3rd order Butterworth
+high_shelf1(Lpi,fx,x) = x + (db2linear(Lpi)-1)*highpass(1,fx,x); // optimized
+high_shelf1_l(Gpi,fx,x) = x + (Gpi-1)*highpass(1,fx,x); //optimized
+
+// shelf transitions between frequency fx and this one:
+highshelf_other_freq(N, Lpi, fx) = db2linear(linear2db(fx) - Lpi/N);
 
 //-------------------------------- peak_eq -----------------------------------
 // Second order "peaking equalizer" section 
@@ -1044,7 +1123,7 @@ high_shelf5(Lpi,fx,x) = x + (db2linear(Lpi)-1)*highpass(5,fx,x);
 //   Also called a "parametric equalizer" section
 // USAGE: _ : peak_eq(Lfx,fx,B) : _;
 // where
-//    Lfx = level (dB) at fx
+//    Lfx = level (dB) at fx (boost Lfx>0 or cut Lfx<0)
 //     fx = peak frequency (Hz)
 //      B = bandwidth (B) of peak in Hz
 //
@@ -1106,7 +1185,7 @@ with {
   LL = ls_group(hslider("[0] Low Boost|Cut [unit:dB] [style:knob]
                 [tooltip: Amount of low-frequency boost or cut in decibels]",
                 0,-40,40,0.1));
-  FL = ls_group(hslider("[1] Transition Frequency [unit:Hz] [style:knob]
+  FL = ls_group(hslider("[1] Transition Frequency [unit:Hz] [style:knob] [scale:log]
                 [tooltip: Transition-frequency from boost (cut) to unity gain]",
                 200,1,5000,1));
 
@@ -1116,13 +1195,13 @@ with {
                 [tooltip: Amount of local boost or cut in decibels]",
                 0,-40,40,0.1));
   FP = pq_group(hslider("[1] Peak Frequency [unit:PK] [style:knob]
-       [tooltip: Peak Frequency in Piano Key (PK) units (A-440= 49 PK)]",
+       [tooltip: Peak Frequency in Piano Key (PK) units (A440 = 49PK)]",
                 49,1,100,1)) : smooth(0.999) : pianokey2hz 
 		with { pianokey2hz(x) = 440.0*pow(2.0, (x-49.0)/12); };
 
-  Q = pq_group(hslider("[2] Peak Q [style:knob]
+  Q = pq_group(hslider("[2] Peak Q [style:knob] [scale:log]
               [tooltip: Quality factor (Q) of the peak = center-frequency/bandwidth]",
-              40,1,50,0.1));
+              40,1,1000,0.1));
 
   BP = FP/Q;
 
@@ -1132,100 +1211,66 @@ with {
   LH = hs_group(hslider("[0] High Boost|Cut [unit:dB] [style:knob]
                 [tooltip: Amount of high-frequency boost or cut in decibels]",
                 0,-40,40,.1));
-  FH = hs_group(hslider("[1] Transition Frequency [unit:Hz] [style:knob]
+  FH = hs_group(hslider("[1] Transition Frequency [unit:Hz] [style:knob] [scale:log]
                 [tooltip: Transition-frequency from boost (cut) to unity gain]",
                 8000,20,10000,1));
 };
 
 //========================= Lagrange Interpolation ========================
-// Reference:
+
+//-------------------------- fdelaylti, fdelayltv -------------------------
+// Fractional delay line using Lagrange interpolation
+// USAGE: _ : fdelaylt[i|v](order, maxdelay, delay, inputsignal) : _
+// where order=1,2,3,... is the order of the Lagrange interpolation polynomial.
+// fdelaylti is most efficient, but designed for constant/slowly-varying delay.
+// fdelayltv is more expensive and more robust when the delay varies rapidly.
+//
+// NOTE: The requested delay should not be less than (N-1)/2.
+//
+// The first-order case (linear interpolation) is equivalent to 
+// fdelay in music.lib (delay d in [0,1])
+//
+// REFERENCES:
+//
 // https://ccrma.stanford.edu/~jos/pasp/Lagrange_Interpolation.html
-// 
-//------------------ fdelay1, fdelay2, fdelay3, fdelay4 ---------------
-// Delay lines interpolated using Lagrange interpolation
-// USAGE: _ : fdelayN(maxdelay, delay, inputsignal) : _
-//        (exactly like fdelay in music.lib)
-// where N=1,2,3, or 4 is the order of the Lagrange interpolation polynomial.
 //
-// NOTE: requested delay should not be less than (N-1)/2.
+// Timo I. Laakso et al., "Splitting the Unit Delay - Tools for Fractional
+//         Delay Filter Design", IEEE Signal Processing Magazine,
+//         vol. 13, no. 1, pp. 30-60, Jan 1996.
 //
-// NOTE: While the implementations below appear to use multiple delay lines,
-//  they in fact use only one thanks to optimization by the Faust compiler.
-
-// first-order case (linear interpolation) - equivalent to fdelay in music.lib
-// delay d in [0,1] 
-fdelay1(n,d,x)  = delay(n,id,x)*(1 - fd) + delay(n,id+1,x)*fd
-with {
-  id = int(d);
-  fd = frac(d);
-};
+// Philippe Depalle and Stephan Tassart, "Fractional Delay Lines using
+//         Lagrange Interpolators", ICMC Proceedings, pp. 341-343, 1996.
 
-// second-order (quadratic) case, delay in [0.5,1.5]
-// delay d should be at least 0.5
-fdelay2(n,d,x) = delay(n,id,x)*(1-fd)*(2-fd)/2 
-               + delay(n,id+1,x)*(2-fd)*fd
-               + delay(n,id+2,x)*(fd-1)*fd/2
+fdelaylti(N,n,d,x)  = delay(n,id,x) <: seq(i,N,section(i)) : !,_
 with {
-  o = 0.49999; // offset to make life easy for interpolator
-  dmo = d - o; // assumed nonnegative
+  o = (N-1.00001)/2; // offset to ~center FIR interpolator
+  dmo = d - o; // assumed nonnegative [d > (N-1)/2]
   id = int(dmo);
   fd = o + frac(dmo);
+  section(i,x,y) = (x-x') * c(i) <: _,+(y);
+  c(i) = (i - fd)/(i+1);
 };
 
-// third-order (cubic) case, delay in [1,2]
-// delay d should be at least 1
-fdelay3(n,d,x) = delay(n,id,x) * (0-fdm1*fdm2*fdm3)/6
-               + delay(n,id+1,x) * fd*fdm2*fdm3/2
-               + delay(n,id+2,x) * (0-fd*fdm1*fdm3)/2
-               + delay(n,id+3,x) * fd*fdm1*fdm2/6
-with {
-  id = int(d-1); 
-  fd = 1+frac(d);
-  fdm1 = fd-1;
-  fdm2 = fd-2;
-  fdm3 = fd-3;
-};
-
-// fourth-order (quartic) case, delay in [1.5,2.5]
-// delay d should be at least 1.5
-fdelay4(n,d,x) = delay(n,id,x)   * fdm1*fdm2*fdm3*fdm4/24 
-               + delay(n,id+1,x) * (0-fd*fdm2*fdm3*fdm4)/6
-               + delay(n,id+2,x) * fd*fdm1*fdm3*fdm4/4
-               + delay(n,id+3,x) * (0-fd*fdm1*fdm2*fdm4)/6
-               + delay(n,id+4,x) * fd*fdm1*fdm2*fdm3/24
+fdelayltv(N,n,d,x) = sum(i, N+1, delay(n,id+i,x) * h(N,fd,i))
 with {
-//v1:  o = 1;
-  o = 1.49999;
-  dmo = d - o; // assumed nonnegative
+  o = (N-1.00001)/2;  // ~center FIR interpolator
+  dmo = d - o; // assumed >=0 [d > (N-1)/2]
   id = int(dmo);
   fd = o + frac(dmo);
-  fdm1 = fd-1;
-  fdm2 = fd-2;
-  fdm3 = fd-3;
-  fdm4 = fd-4;
+  h(N,d,n) = facs1(N,d,n) * facs2(N,d,n);
+  facs1(N,d,n) = select2(n,1,prod(k,max(1,n),select2(k<n,1,fac(d,n,k))));
+  facs2(N,d,n) = select2(n<N,1,prod(l,max(1,N-n),fac(d,n,l+n+1)));
+  fac(d,n,k) = (d-k)/((n-k)+(n==k));
+  // Explicit formula for Lagrange interpolation coefficients:
+  // h_d(n) = \prod_{\stackrel{k=0}{k\neq n}}^N \frac{d-k}{n-k}, n=0:N
 };
 
-// fifth-order case, delay in [2,3]
-// delay d should be at least 2
-fdelay5(n,d,x) = 
-   delay(n,id,x)   *    -fdm1*fdm2*fdm3*fdm4*fdm5/120
- + delay(n,id+1,x) *  fd*     fdm2*fdm3*fdm4*fdm5/24
- + delay(n,id+2,x) * -fd*fdm1*     fdm3*fdm4*fdm5/12
- + delay(n,id+3,x) *  fd*fdm1*fdm2*     fdm4*fdm5/12
- + delay(n,id+4,x) * -fd*fdm1*fdm2*fdm3*     fdm5/24
- + delay(n,id+5,x) *  fd*fdm1*fdm2*fdm3*fdm4     /120
-with {
-//v1:  o = 1;
-  o = 1.99999;
-  dmo = d - o; // assumed nonnegative
-  id = int(dmo);
-  fd = o + frac(dmo);
-  fdm1 = fd-1;
-  fdm2 = fd-2;
-  fdm3 = fd-3;
-  fdm4 = fd-4;
-  fdm5 = fd-5;
-};
+// Backward compatibility:
+fdelay1 = fdelayltv(1);
+fdelay2 = fdelayltv(2);
+fdelay3 = fdelayltv(3);
+fdelay4 = fdelayltv(4);
+fdelay5 = fdelayltv(5);
 
 //====================== Thiran Allpass Interpolation =====================
 // Reference:
@@ -1253,8 +1298,7 @@ with {
 //       as Lagrange interpolation under time-varying conditions.
 //       (You may hear clicks when changing the delay rapidly.)
 //
-// first-order allpass interpolation, allpass delay in [0.5,1.5]
-// delay d should be at least 0.5
+// first-order allpass interpolation, delay d in [0.5,1.5]
 fdelay1a(n,d,x)  = delay(n,id,x) : tf1(eta,1,eta)
 with {
   o = 0.49999; // offset to make life easy for allpass
@@ -1265,7 +1309,6 @@ with {
 };
 
 // second-order allpass delay in [1.5,2.5]
-// delay d should be at least 1.5
 fdelay2a(n,d,x) = delay(n,id,x) : tf2(a2,a1,1,a1,a2)
 with {
   o = 1.49999;
@@ -1294,7 +1337,7 @@ with {
 
 // fourth-order allpass delay in [3.5,4.5]
 // delay d should be at least 3.5
-fdelay4a(n,d,x) = delay(n,id,x) : tf4(a4,a3,a2,a1,1,a1,a2,a3,a4)
+fdelay4a(n,d,x) = delay(n,id,x) : iir((a4,a3,a2,a1,1),(a1,a2,a3,a4))
 with {
   o = 3.49999;
   dmo = d - o;
@@ -1340,8 +1383,9 @@ with {
 // "power complementary", i.e., the power spectra of the individual bands
 // sum to the original power spectrum (to within some negligible tolerance).
 //
-// The filter-banks below are implemented as Butterworth spectrum-analyzers 
-// followed by delay equalizers that make them allpass-complementary.
+// The filter-banks below are implemented as Butterworth or Elliptic
+// spectrum-analyzers followed by delay equalizers that make them 
+// allpass-complementary.
 //
 // INCREASING CHANNEL ISOLATION
 //   Go to higher filter orders - see Regalia et al. or Vaidyanathan (cited 
@@ -1445,13 +1489,13 @@ mth_octave_spectral_level6e(M,ftop,N,tau,dB_offset) = _<:
      meter(N-i-1);
     meter(i) = speclevel_group(vbargraph("[%2i] [unit:dB] 
      [tooltip: Spectral Band Level in dB]", -50, 10));
-  // Can M be included in the label string somehow?
-  speclevel_group(x)  = hgroup("[0] CONSTANT-Q SPECTRUM ANALYZER (6E)
+  O = int(((N-2)/M)+0.4999);
+  speclevel_group(x)  = hgroup("[0] CONSTANT-Q SPECTRUM ANALYZER (6E), %N bands spanning LP, %O octaves below %ftop Hz, HP
      [tooltip: See Faust's filter.lib for documentation and references]", x);
 };
 
 mth_octave_spectral_level_default = mth_octave_spectral_level6e;
-spectral_level = mth_octave_spectral_level(2,10000,20);  // simplest case
+spectral_level = mth_octave_spectral_level(2,10000,20);  // simple default
 
 //---------------------- mth_octave_spectral_level_demo ----------------------
 // Demonstrate mth_octave_spectral_level in a standalone GUI.
@@ -1461,14 +1505,14 @@ spectral_level = mth_octave_spectral_level(2,10000,20);  // simplest case
 mth_octave_spectral_level_demo(M) = 
   mth_octave_spectral_level_default(M,ftop,N,tau,dB_offset) 
 with {
-  // Span nearly 10 octaves so that lowest band-edge is at 
-  // ftop*2^(-Noct+2) = 40 Hz when ftop=10 kHz:
-  N = int(10*M); // without 'int()', segmentation fault observed for M=1.67
-  ftop = 10000;
+  ftop = 16000;
+  Noct = 10; // number of octaves down from ftop
+  // Lowest band-edge is at ftop*2^(-Noct+2) = 62.5 Hz when ftop=16 kHz:
+  N = int(Noct*M); // without 'int()', segmentation fault observed for M=1.67
   ctl_group(x)  = hgroup("[1] SPECTRUM ANALYZER CONTROLS", x);
-  tau = ctl_group(hslider("[0] Level Averaging Time [unit:sec]
-        [tooltip: band-level averaging time in seconds]",
-        0.1,0,1,0.01)); 
+  tau = ctl_group(hslider("[0] Level Averaging Time [unit:ms] [scale:log]
+        [tooltip: band-level averaging time in milliseconds]",
+        100,1,10000,1)) * 0.001; 
   dB_offset = ctl_group(hslider("[1] Level dB Offset [unit:dB]
         [tooltip: Level offset in decibels]",
         50,0,100,1)); 
@@ -1558,12 +1602,13 @@ analyzer(O,lfreqs) = _ <: bsplit(nb) with
 };
 
 //----------------------------- filterbank -------------------------------------
-filterbank(O,lfreqs) = analyzer(O,lfreqs) : delayeq with
+filterbank(O,lfreqs) = analyzer(O,lfreqs) : delayeq(nb) with
 {
    nb = count(lfreqs);
    fc(n) = take(n, lfreqs);
    ap(n) = highpass_plus_lowpass(O,fc(n));
-   delayeq = par(i,nb-1,apchain(nb-1-i)),_,_;
+   delayeq(1) = _,_; // par(i,0,...) does not fly
+   delayeq(nb) = par(i,nb-1,apchain(nb-1-i)),_,_;
    apchain(0) = _;
    apchain(i) =  ap(i) : apchain(i-1);
 };
diff --git a/architecture/gen-json.cpp b/architecture/gen-json.cpp
new file mode 100644
index 0000000..0c1bcb4
--- /dev/null
+++ b/architecture/gen-json.cpp
@@ -0,0 +1,72 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+
+	This is sample code. This file is provided as an example of minimal
+	FAUST architecture file. Redistribution and use in source and binary
+	forms, with or without modification, in part or in full are permitted.
+	In particular you can create a derived work of this FAUST architecture
+	and distribute that work under terms of your choice.
+
+	This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#include <cmath>
+#include <string.h>
+
+#include "faust/gui/GUI.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/meta.h"
+#include "faust/gui/jsonfaustui.h"
+#include "faust/gui/JSONUI.h"
+
+using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/******************************************************************************
+*******************************************************************************
+
+			ABSTRACT USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+
+<<includeclass>>
+
+mydsp DSP;
+
+int main(int argc, char *argv[])
+{
+    /*
+    httpdfaust::jsonfaustui json("", "", 0);
+    DSP.buildUserInterface(&json);
+    mydsp::metadata(&json);
+    json.numInput(DSP.getNumInputs());
+    json.numOutput(DSP.getNumOutputs());
+    cout << json.json();
+    */
+    
+    JSONUI json(DSP.getNumInputs(), DSP.getNumOutputs());
+    // Add metadata before UI is mandatory for proper JSONUI functionning
+    mydsp::metadata(&json);
+    DSP.buildUserInterface(&json);
+    cout << json.JSON();
+}
diff --git a/architecture/gui/FUI.h b/architecture/gui/FUI.h
deleted file mode 100644
index 07593b2..0000000
--- a/architecture/gui/FUI.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#ifndef FAUST_FUI_H
-#define FAUST_FUI_H
-
-#include "UI.h"
-
-#include <string>
-#include <map>
-#include <set>
-#include <vector>
-#include <stack>
-
-#include <iostream>
-#include <fstream>
-
-using namespace std;
-
-#if 1
-
-/*******************************************************************************
- * FUI : used to save and recall the state of the user interface
- * This class provides essentially two new methods saveState() and recallState()
- * used to save on file and recall from file the state of the user interface.
- * The file is human readble and editable
- ******************************************************************************/
-
-class FUI  : public UI
-{
-	stack<string>		fGroupStack;
-	vector<string>		fNameList;
-	map<string, float*>	fName2Zone;
-
- protected:
-
- 	// labels are normalized by replacing white spaces by underscores and by
- 	// removing parenthesis
-	string normalizeLabel(const char* label)
-	{
-		string 	s;
-		char 	c;
-
-		while ((c=*label++)) {
-			if (isspace(c)) 				{ s += '_'; }
-			//else if ((c == '(') | (c == ')') ) 	{ }
-			else 							{ s += c; }
-		}
-		return s;
-	}
-
-	// add an element by relating its full name and memory zone
-	virtual void addElement (const char* label, float* zone)
-	{
-		string fullname (fGroupStack.top() + '/' + normalizeLabel(label));
-		fNameList.push_back(fullname);
-		fName2Zone[fullname] = zone;
-	}
-
-	// keep track of full group names in a stack
-	virtual void pushGroupLabel(const char* label)
-	{
-		if (fGroupStack.empty()) {
-			fGroupStack.push(normalizeLabel(label));
-		} else {
-			fGroupStack.push(fGroupStack.top() + '/' + normalizeLabel(label));
-		}
-	}
-
-	virtual void popGroupLabel()
-	{
-		fGroupStack.pop();
-	};
-
- public:
-
-	FUI() 			{}
-	virtual ~FUI() 	{}
-
-	// -- Save and recall methods
-
-	// save the zones values and full names
-	virtual void saveState(const char* filename)
-	{
-		ofstream f(filename);
-
-		for (unsigned int i=0; i<fNameList.size(); i++) {
-			string	n = fNameList[i];
-			float*	z = fName2Zone[n];
-			f << *z << ' ' << n << endl;
-		}
-
-		f << endl;
-		f.close();
-	}
-
-	// recall the zones values and full names
-	virtual void recallState(const char* filename)
-	{
-		ifstream f(filename);
-		float	v;
-		string	n;
-
-		while (f.good()) {
-			f >> v >> n;
-			if (fName2Zone.count(n)>0) {
-				*(fName2Zone[n]) = v;
-			} else {
-				cerr << "recallState : parameter not found : " << n << " with value : " << v << endl;
-			}
-		}
-		f.close();
-	}
-
-
-    // -- widget's layouts (just keep track of group labels)
-
-    virtual void openFrameBox(const char* label) 		{ pushGroupLabel(label); }
-    virtual void openTabBox(const char* label) 			{ pushGroupLabel(label); }
-    virtual void openHorizontalBox(const char* label) 	{ pushGroupLabel(label); }
-    virtual void openVerticalBox(const char* label)  	{ pushGroupLabel(label); }
-    virtual void closeBox() 							{ popGroupLabel(); };
-
-    // -- active widgets (just add an element)
-
-    virtual void addButton(const char* label, float* zone) 			{ addElement(label, zone); }
-    virtual void addToggleButton(const char* label, float* zone) 	{ addElement(label, zone); }
-    virtual void addCheckButton(const char* label, float* zone) 	{ addElement(label, zone); }
-    virtual void addVerticalSlider(const char* label, float* zone, float , float , float , float )
-    																{ addElement(label, zone); }
-    virtual void addHorizontalSlider(const char* label, float* zone, float , float , float , float )
-    																{ addElement(label, zone); }
-    virtual void addNumEntry(const char* label, float* zone, float , float , float , float )
-    																{ addElement(label, zone); }
-
-    // -- passive widgets (are ignored)
-
-    virtual void addNumDisplay(const char* , float* , int ) {};
-    virtual void addTextDisplay(const char* , float* , const char*[], float , float ) {};
-    virtual void addHorizontalBargraph(const char* , float* , float , float ) {};
-    virtual void addVerticalBargraph(const char* , float* , float , float ) {};
-
-	// -- metadata are not used
-
-    virtual void declare(float* , const char* , const char* ) {}
-};
-#endif
-
-#endif
-
diff --git a/architecture/gui/GUI.h b/architecture/gui/GUI.h
deleted file mode 100644
index 3e9add9..0000000
--- a/architecture/gui/GUI.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef FAUST_GUI_H
-#define FAUST_GUI_H
-
-#include "UI.h"
-#include <list>
-#include <map>
-
-using namespace std;
-
-
-/*******************************************************************************
- * GUI : Abstract Graphic User Interface
- * Provides additional macchanismes to synchronize widgets and zones. Widgets
- * should both reflect the value of a zone and allow to change this value.
- ******************************************************************************/
-
-struct uiItem;
-typedef void (*uiCallback)(float val, void* data);
-
-class GUI : public UI
-{
-	typedef list<uiItem*> clist;
-	typedef map<float*, clist*> zmap;
-	
- private:
- 	static list<GUI*>	fGuiList;
-	zmap				fZoneMap;
-	bool				fStopped;
-	
- public:
-		
-	GUI() : fStopped(false) {	
-		fGuiList.push_back(this);
-	}
-	
-	virtual ~GUI() {
-		// suppression de this dans fGuiList
-	}
-
-	// -- registerZone(z,c) : zone management
-	
-	void registerZone(float* z, uiItem* c)
-	{
-		if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist();
-		fZoneMap[z]->push_back(c);
-	} 	
-
-	void updateAllZones();
-	
-	void updateZone(float* z);
-	
-	static void updateAllGuis()
-	{
-		list<GUI*>::iterator g;
-		for (g = fGuiList.begin(); g != fGuiList.end(); g++) {
-			(*g)->updateAllZones();
-		}
-	}
-    void addCallback(float* zone, uiCallback foo, void* data);
-    virtual void show() {};	
-    virtual void run() {};
-	
-	void stop()		{ fStopped = true; }
-	bool stopped() 	{ return fStopped; }
-
-    virtual void declare(float* , const char* , const char* ) {}
-};
-
-
-
-/**
- * User Interface Item: abstract definition
- */
-
-class uiItem
-{
-  protected :
-		  
-	GUI*		fGUI;
-	float*		fZone;
-	float		fCache;
-	
-	uiItem (GUI* ui, float* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321) 
-	{ 
-		ui->registerZone(zone, this); 
-	}
-	
-	
-  public :
-	virtual ~uiItem() {}
-	
-	void modifyZone(float v) 	
-	{ 
-		fCache = v;
-		if (*fZone != v) {
-			*fZone = v;
-			fGUI->updateZone(fZone);
-		}
-	}
-		  	
-	float			cache()			{ return fCache; }
-	virtual void 	reflectZone() 	= 0;	
-};
-
-
-/**
- * Callback Item
- */
-
-struct uiCallbackItem : public uiItem
-{
-	uiCallback	fCallback;
-	void*		fData;
-	
-	uiCallbackItem(GUI* ui, float* zone, uiCallback foo, void* data) 
-			: uiItem(ui, zone), fCallback(foo), fData(data) {}
-	
-	virtual void 	reflectZone() {		
-		float 	v = *fZone;
-		fCache = v; 
-		fCallback(v, fData);	
-	}
-};
-
-// en cours d'installation de call back. a finir!!!!!
-
-/**
- * Update all user items reflecting zone z
- */
-
-inline void GUI::updateZone(float* z)
-{
-	float 	v = *z;
-	clist* 	l = fZoneMap[z];
-	for (clist::iterator c = l->begin(); c != l->end(); c++) {
-		if ((*c)->cache() != v) (*c)->reflectZone();
-	}
-}
-
-
-/**
- * Update all user items not up to date
- */
-
-inline void GUI::updateAllZones()
-{
-	for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) {
-		float* 	z = m->first;
-		clist*	l = m->second;
-		float	v = *z;
-		for (clist::iterator c = l->begin(); c != l->end(); c++) {
-			if ((*c)->cache() != v) (*c)->reflectZone();
-		}
-	}
-}
-
-inline void GUI::addCallback(float* zone, uiCallback foo, void* data) 
-{ 
-	new uiCallbackItem(this, zone, foo, data); 
-};
-
-#endif
diff --git a/architecture/gui/OSCUI.h b/architecture/gui/OSCUI.h
deleted file mode 100644
index 38173b8..0000000
--- a/architecture/gui/OSCUI.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-   Copyright (C) 2011 Grame - Lyon
-   All rights reserved.
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted.
-*/
-
-#include "OSCControler.h"
-#include "GUI.h"
-#include <vector>
-
-/******************************************************************************
-*******************************************************************************
-
-					OSC (Open Sound Control) USER INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-/*
-
-Note about the OSC addresses and the Faust UI names:
-----------------------------------------------------
-There are potential conflicts between the Faust UI objects naming scheme and 
-the OSC address space. An OSC symbolic names is an ASCII string consisting of
-printable characters other than the following:
-	space 
-#	number sign
-*	asterisk
-,	comma
-/	forward
-?	question mark
-[	open bracket
-]	close bracket
-{	open curly brace
-}	close curly brace
-
-a simple solution to address the problem consists in replacing 
-space or tabulation with '_' (underscore)
-all the other osc excluded characters with '-' (hyphen)
-
-This solution is implemented in the proposed OSC UI;
-*/
-
-using namespace std;
-
-//class oscfaust::OSCIO;
-class OSCUI : public GUI 
-{
-	oscfaust::OSCControler*	fCtrl;
-	vector<const char*>		fAlias;
-	
-	const char* tr(const char* label) const;
-	
-	// add all accumulated alias
-	void addalias(float* zone, float init, float min, float max) 
-	{
-		for (unsigned int i=0; i<fAlias.size(); i++) {
-			fCtrl->addfullpathnode(fAlias[i], zone, 0, 1, init, min, max);
-		}
-		fAlias.clear();
-	}
-	
- public:
-		
-	OSCUI(char* /*applicationname*/, int argc, char *argv[], oscfaust::OSCIO* io=0) : GUI() 
-    { 
-		fCtrl = new oscfaust::OSCControler(argc, argv, io); 
-//		fCtrl->opengroup(applicationname);
-	}
-	
-	virtual ~OSCUI() { delete fCtrl; }
-	
-	// -- active widgets
-	virtual void addButton(const char* label, float* zone) 															{ addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, 0, 0, 1); }
-	virtual void addToggleButton(const char* label, float* zone) 													{ addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, 0, 0, 1); }
-	virtual void addCheckButton(const char* label, float* zone) 													{ addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, 0, 0, 1); }
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float /*step*/) 	{ addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); }
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float /*step*/) 	{ addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); }
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float /*step*/) 			{ addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); }
-	
-	// -- passive widgets
-	
-	virtual void addNumDisplay(const char* /*label*/, float* /*zone*/, int /*precision*/) {}
-	virtual void addTextDisplay(const char* /*label*/, float* /*zone*/, const char* /*names*/[], float /*min*/, float /*max*/) {}
-	virtual void addHorizontalBargraph(const char* /*label*/, float* /*zone*/, float /*min*/, float /*max*/) {}
-	virtual void addVerticalBargraph(const char* /*label*/, float* /*zone*/, float /*min*/, float /*max*/) {}
-		
-	virtual void openFrameBox(const char* label)		{ fCtrl->opengroup( tr(label)); }
-	virtual void openTabBox(const char* label) 			{ fCtrl->opengroup( tr(label)); }
-	virtual void openHorizontalBox(const char* label) 	{ fCtrl->opengroup( tr(label)); }
-	virtual void openVerticalBox(const char* label) 	{ fCtrl->opengroup( tr(label)); }
-	virtual void closeBox() 							{ fCtrl->closegroup(); }
-	
-	virtual void declare(float* , const char* key , const char* alias) 
-	{ 
-		if (strcasecmp(key,"OSC")==0) fAlias.push_back(alias);
-	}
-
-
-	virtual void show() {}
-
-	void run()											{ fCtrl->run(); }
-	const char* getRootName()							{ return fCtrl->getRootName(); }
-};
-
-					
-const char* OSCUI::tr(const char* label) const
-{
-	static char buffer[1024];
-	char * ptr = buffer; int n=1;
-	while (*label && (n++ < 1024)) {
-		switch (*label) {
-			case ' ': case '	':
-				*ptr++ = '_';
-				break;
-			case '#': case '*': case ',': case '/': case '?':
-			case '[': case ']': case '{': case '}':
-				*ptr++ = '_';
-				break;
-			default: 
-				*ptr++ = *label;
-		}
-		label++;
-	}
-	*ptr = 0;
-	return buffer;
-}
diff --git a/architecture/gui/UI.h b/architecture/gui/UI.h
deleted file mode 100644
index cd5b11c..0000000
--- a/architecture/gui/UI.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef FAUST_UI_H
-#define FAUST_UI_H
-
-
-/*******************************************************************************
- * UI : Faust User Interface
- * This abstract class contains only the method that the faust compiler can
- * generate to describe a DSP interface.
- ******************************************************************************/
-
-class UI
-{
-
- public:
-
-	UI() {	}
-
-	virtual ~UI() {	}
-
-    // -- widget's layouts
-
-    virtual void openFrameBox(const char* label) = 0;
-    virtual void openTabBox(const char* label) = 0;
-    virtual void openHorizontalBox(const char* label) = 0;
-    virtual void openVerticalBox(const char* label) = 0;
-    virtual void closeBox() = 0;
-
-    // -- active widgets
-
-    virtual void addButton(const char* label, float* zone) = 0;
-    virtual void addToggleButton(const char* label, float* zone) = 0;
-    virtual void addCheckButton(const char* label, float* zone) = 0;
-    virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-    virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-
-    // -- passive widgets
-
-    virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-    virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) = 0;
-    virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-    virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-
-	// -- metadata declarations
-
-    virtual void declare(float* , const char* , const char* ) {}
-};
-
-#endif
diff --git a/architecture/gui/console.h b/architecture/gui/console.h
deleted file mode 100644
index bb7c010..0000000
--- a/architecture/gui/console.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections :
-	the ARCHITECTURE section (in two parts) and the USER section. Each section
-	is governed by its own copyright and license. Please check individually
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work
-	that contains this FAUST architecture section and distribute
-	that work under terms of your choice, so long as this FAUST
-	architecture section is not modified.
-
-
- ************************************************************************
- ************************************************************************/
-#ifndef __faustconsole__
-#define __faustconsole__
-
-#include "GUI.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stack>
-#include <string>
-#include <map>
-#include <iostream>
-
-using namespace std;
-
-/******************************************************************************
-*******************************************************************************
-
-								USER INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-struct param {
-	float* fZone; float fMin; float fMax;
-	param(float* z, float a, float b) : fZone(z), fMin(a), fMax(b) {}
-};
-
-class CMDUI : public GUI
-{
-	int					fArgc;
-	char**				fArgv;
-	stack<string>		fPrefix;
-	map<string, param>	fKeyParam;
-
-	void addOption(const char* label, float* zone, float min, float max)
-	{
-		string fullname = fPrefix.top() + label;
-		fKeyParam.insert(make_pair(fullname, param(zone, min, max)));
-	}
-
-	void openAnyBox(const char* label)
-	{
-		string prefix;
-
-		if (label && label[0]) {
-			prefix = fPrefix.top() + "-" + label;
-		} else {
-			prefix = fPrefix.top();
-		}
-		fPrefix.push(prefix);
-	}
-
-public:
-
-	CMDUI(int argc, char *argv[]) : GUI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); }
-	virtual ~CMDUI() {}
-
-	virtual void openFrameBox(const char* label)		{ openAnyBox(label); }
-	virtual void openTabBox(const char* label)          { openAnyBox(label); }
-	virtual void openHorizontalBox(const char* label)	{ openAnyBox(label); }
-	virtual void openVerticalBox(const char* label)     { openAnyBox(label); }
-	virtual void closeBox()                             { fPrefix.pop(); }
-
-	virtual void addButton(const char* label, float* zone) 		{};
-	virtual void addToggleButton(const char* label, float* zone) 	{};
-	virtual void addCheckButton(const char* label, float* zone) 	{};
-
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,min,max);
-	}
-
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,min,max);
-	}
-
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,min,max);
-	}
-
-	// -- passive widgets
-
-	virtual void addNumDisplay(const char* label, float* zone, int precision) 						{}
-	virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) 	{}
-	virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) 			{}
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) 			{}
-
-	virtual void show() {}
-	virtual void run()
-	{
-		char c;
-		printf("Type 'q' to quit\n");
-		while ((c = getchar()) != 'q') {
-			sleep(1);
-		}
-	}
-
-	void print()
-	{
-		map<string, param>::iterator i;
-		cout << fArgc << "\n";
-		cout << fArgv[0] << " option list : ";
-		for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
-			cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
-		}
-	}
-
-	void process_command()
-	{
-		map<string, param>::iterator p;
-		for (int i = 1; i < fArgc; i++) {
-			if (fArgv[i][0] == '-') {
-				p = fKeyParam.find(fArgv[i]);
-				if (p == fKeyParam.end()) {
-					cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
-					print();
-					exit(1);
-				}
-				char*	end;
-				*(p->second.fZone) = float(strtod(fArgv[i+1], &end));
-				i++;
-			}
-		}
-	}
-
-	void process_init()
-	{
-		map<string, param>::iterator p;
-		for (int i = 1; i < fArgc; i++) {
-			if (fArgv[i][0] == '-') {
-				p = fKeyParam.find(fArgv[i]);
-				if (p == fKeyParam.end()) {
-					cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
-					exit(1);
-				}
-				char*	end;
-				*(p->second.fZone) = float(strtod(fArgv[i+1], &end));
-				i++;
-			}
-		}
-	}
-};
-
-#endif
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
diff --git a/architecture/gui/faustgtk.h b/architecture/gui/faustgtk.h
deleted file mode 100644
index 68e6055..0000000
--- a/architecture/gui/faustgtk.h
+++ /dev/null
@@ -1,1550 +0,0 @@
-#ifndef FAUST_GTKUI_H
-#define FAUST_GTKUI_H
-
-#include "GUI.h"
-
-/******************************************************************************
-*******************************************************************************
-
-                                GRAPHIC USER INTERFACE
-                                  gtk interface
-
-*******************************************************************************
-*******************************************************************************/
-#include <string>
-#include <set>
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <assert.h>
-
-using namespace std;
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-#define stackSize 256
-
-// Insertion modes
-
-#define kSingleMode 0
-#define kBoxMode 1
-#define kTabMode 2
-
-//------------ calculate needed precision
-static int precision(double n)
-{
-	if (n < 0.009999) return 3;
-	else if (n < 0.099999) return 2;
-	else if (n < 0.999999) return 1;
-	else return 0;
-}
-
-namespace gtk_knob
-{
-
-class GtkKnob
-{
-private:
-	double start_x, start_y, max_value;
-public:
-	GtkRange parent;
-	int last_quadrant;
-	GtkKnob();
-	~GtkKnob();
-	GtkWidget *gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment);
-	
-};
-
-#define GTK_TYPE_KNOB          (gtk_knob_get_type())
-#define GTK_KNOB(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_KNOB, GtkKnob))
-#define GTK_IS_KNOB(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_KNOB))
-#define GTK_KNOB_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),  GTK_TYPE_KNOB, GtkKnobClass))
-#define GTK_IS_KNOB_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GTK_TYPE_KNOB))
-
-GtkKnob::GtkKnob()
-// GtkKnob constructor
-{
-
-}
-
-GtkKnob::~GtkKnob()
-{
-	// Nothing specific to do...
-}
-
-struct GtkKnobClass {
-	GtkRangeClass parent_class;
-	int knob_x;
-	int knob_y;
-	int knob_step;
-	int button_is;
-
-};
-
-//------forward declaration
-GType gtk_knob_get_type ();
-
-/****************************************************************
- ** calculate the knop pointer with dead zone
- */
-
-const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs
-
-static void knob_expose(GtkWidget *widget, int knob_x, int knob_y, GdkEventExpose *event, int arc_offset)
-{
-	/** check resize **/
-	int grow;
-	if(widget->allocation.width > widget->allocation.height) {
-		grow = widget->allocation.height;
-	} else {
-		grow =  widget->allocation.width;
-	}
-	knob_x = grow-4;
-	knob_y = grow-4;
-	/** get values for the knob **/
-	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
-	int knobx = (widget->allocation.x+2 + (widget->allocation.width-4 - knob_x) * 0.5);
-	int knoby = (widget->allocation.y+2 + (widget->allocation.height-4 - knob_y) * 0.5);
-	int knobx1 = (widget->allocation.x+2 + (widget->allocation.width-4)* 0.5);
-	int knoby1 = (widget->allocation.y+2 + (widget->allocation.height-4) * 0.5);
-	double knobstate = (adj->value - adj->lower) / (adj->upper - adj->lower);
-	double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero);
-	double knobstate1 = (0. - adj->lower) / (adj->upper - adj->lower);
-	double pointer_off = knob_x/6;
-	double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2;
-	double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle);
-	double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle);
-	double radius1 = min(knob_x, knob_y) / 2 ;
-
-	/** get widget forground color convert to cairo **/
-	GtkStyle *style = gtk_widget_get_style (widget);
-	double r = min(0.6,style->fg[gtk_widget_get_state(widget)].red/65535.0),
-		   g = min(0.6,style->fg[gtk_widget_get_state(widget)].green/65535.0),
-		   b = min(0.6,style->fg[gtk_widget_get_state(widget)].blue/65535.0);
-
-	/** paint focus **/
-	if (GTK_WIDGET_HAS_FOCUS(widget)== TRUE) {
-		gtk_paint_focus(widget->style, widget->window, GTK_STATE_NORMAL, NULL, widget, NULL,
-		                knobx-2, knoby-2, knob_x+4, knob_y+4);
-	}
-	/** create clowing knobs with cairo **/
-	cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
-	GdkRegion *region;
-	region = gdk_region_rectangle (&widget->allocation);
-	gdk_region_intersect (region, event->region);
-	gdk_cairo_region (cr, region);
-	cairo_clip (cr);
-	
-	cairo_arc(cr,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI );
-	cairo_pattern_t*pat =
-		cairo_pattern_create_radial (knobx1+arc_offset-knob_x/6,knoby1+arc_offset-knob_x/6, 1,knobx1+arc_offset,knoby1+arc_offset,knob_x/2.1 );
-	if(adj->lower<0 && adj->value>0.) {
-		cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 + knobstate-knobstate1, b+0.4);
-		cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + (knobstate-knobstate1)*0.5, b+0.15);
-		cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
-	} else if(adj->lower<0 && adj->value<=0.) {
-		cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4 +knobstate1- knobstate, g+0.4, b+0.4);
-		cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15 +(knobstate1- knobstate)*0.5, g+0.15, b+0.15);
-		cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
-	} else {
-		cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 +knobstate, b+0.4);
-		cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + knobstate*0.5, b+0.15);
-		cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
-	}
-	cairo_set_source (cr, pat);
-	cairo_fill_preserve (cr);
-	gdk_cairo_set_source_color(cr, gtk_widget_get_style (widget)->fg);
-	cairo_set_line_width(cr, 2.0);
-	cairo_stroke(cr);
-
-	/** create a rotating pointer on the kob**/
-	cairo_set_source_rgb(cr,  0.1, 0.1, 0.1);
-	cairo_set_line_width(cr,max(3, min(7, knob_x/15)));
-	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); 
-	cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
-	cairo_move_to(cr, knobx+radius1, knoby+radius1);
-	cairo_line_to(cr,lengh_x,lengh_y);
-	cairo_stroke(cr);
-	cairo_set_source_rgb(cr,  0.9, 0.9, 0.9);
-	cairo_set_line_width(cr,min(5, max(1,knob_x/30)));
-	cairo_move_to(cr, knobx+radius1, knoby+radius1);
-	cairo_line_to(cr,lengh_x,lengh_y);
-	cairo_stroke(cr);
-	cairo_pattern_destroy (pat);
-	gdk_region_destroy (region);
-	cairo_destroy(cr);
-}
-
-/****************************************************************
- ** general expose events for all "knob" controllers
- */
-
-//----------- draw the Knob when moved
-static gboolean gtk_knob_expose (GtkWidget *widget, GdkEventExpose *event)
-{
-	g_assert(GTK_IS_KNOB(widget));
-	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-	knob_expose(widget, klass->knob_x, klass->knob_y, event, 0);
-	return TRUE;
-}
-
-/****************************************************************
- ** set initial size for GdkDrawable per type
- */
-
-static void gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition)
-{
-	g_assert(GTK_IS_KNOB(widget));
-	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-	requisition->width = klass->knob_x;
-	requisition->height = klass->knob_y;
-}
-
-/****************************************************************
- ** set value from key bindings
- */
-
-static void gtk_knob_set_value (GtkWidget *widget, int dir_down)
-{
-	g_assert(GTK_IS_KNOB(widget));
-
-	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
-
-	int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment);
-	int step;
-	int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment);
-	if (dir_down)
-		step = oldstep - 1;
-	else
-		step = oldstep + 1;
-	float value = adj->lower + step * double(adj->upper - adj->lower) / nsteps;
-	gtk_widget_grab_focus(widget);
-	gtk_range_set_value(GTK_RANGE(widget), value);
-}
-
-/****************************************************************
- ** keyboard bindings
- */
-
-static gboolean gtk_knob_key_press (GtkWidget *widget, GdkEventKey *event)
-{
-	g_assert(GTK_IS_KNOB(widget));
-
-	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
-	switch (event->keyval) {
-	case GDK_Home:
-		gtk_range_set_value(GTK_RANGE(widget), adj->lower);
-		return TRUE;
-	case GDK_End:
-		gtk_range_set_value(GTK_RANGE(widget), adj->upper);
-		return TRUE;
-	case GDK_Up:
-		gtk_knob_set_value(widget, 0);
-		return TRUE;
-	case GDK_Right:
-		gtk_knob_set_value(widget, 0);
-		return TRUE;
-	case GDK_Down:
-		gtk_knob_set_value(widget, 1);
-		return TRUE;
-	case GDK_Left:
-		gtk_knob_set_value(widget, 1);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-/****************************************************************
- ** alternative (radial) knob motion mode (ctrl + mouse pressed)
- */
-
-static void knob_pointer_event(GtkWidget *widget, gdouble x, gdouble y, int knob_x, int knob_y,
-                               bool drag, int state)
-{
-	static double last_y = 2e20;
-	GtkKnob *knob = GTK_KNOB(widget);
-	GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
-	double radius =  min(knob_x, knob_y) / 2;
-	int  knobx = (widget->allocation.width - knob_x) / 2;
-	int  knoby = (widget->allocation.height - knob_y) / 2;
-	double posx = (knobx + radius) - x; // x axis right -> left
-	double posy = (knoby + radius) - y; // y axis top -> bottom
-	double value;
-	if (!drag) {
-		if (state & GDK_CONTROL_MASK) {
-			last_y = 2e20;
-			return;
-		} else {
-			last_y = posy;
-		}
-	}
-	if (last_y < 1e20) { // in drag started with Control Key
-		const double scaling = 0.005;
-		double scal = (state & GDK_SHIFT_MASK ? scaling*0.1 : scaling);
-		value = (last_y - posy) * scal;
-		last_y = posy;
-		gtk_range_set_value(GTK_RANGE(widget), adj->value - value * (adj->upper - adj->lower));
-		return;
-	}
-
-	double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI
-	if (drag) {
-		// block "forbidden zone" and direct moves between quadrant 1 and 4
-		int quadrant = 1 + int(angle/M_PI_2);
-		if (knob->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) {
-			angle = scale_zero;
-		} else if (knob->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) {
-			angle = 2*M_PI - scale_zero;
-		} else {
-			if (angle < scale_zero) {
-				angle = scale_zero;
-			} else if (angle > 2*M_PI - scale_zero) {
-				angle = 2*M_PI - scale_zero;
-			}
-			knob->last_quadrant = quadrant;
-		}
-	} else {
-		if (angle < scale_zero) {
-			angle = scale_zero;
-		} else if (angle > 2*M_PI - scale_zero) {
-			angle = 2*M_PI - scale_zero;
-		}
-		knob->last_quadrant = 0;
-	}
-	angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1
-	gtk_range_set_value(GTK_RANGE(widget), adj->lower + angle * (adj->upper - adj->lower));
-}
-
-/****************************************************************
- ** mouse button pressed set value
- */
-
-static gboolean gtk_knob_button_press (GtkWidget *widget, GdkEventButton *event)
-{
-	g_assert(GTK_IS_KNOB(widget));
-	
-	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-	
-
-	switch (event->button) {
-	case 1:  // left button
-		gtk_widget_grab_focus(widget);
-		gtk_widget_grab_default (widget);
-		gtk_grab_add(widget);
-		klass->button_is = 1;
-		knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y,
-						   false, event->state);
-		break;
-	case 2: //wheel
-		klass->button_is = 2;
-		break;
-	case 3:  // right button 
-		klass->button_is = 3;
-		break;
-	default: // do nothing
-		break;
-	}
-	return TRUE;
-}
-
-/****************************************************************
- ** mouse button release
- */
-
-static gboolean gtk_knob_button_release (GtkWidget *widget, GdkEventButton *event)
-{
-	g_assert(GTK_IS_KNOB(widget));
-	GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget))->button_is = 0;
-	if (GTK_WIDGET_HAS_GRAB(widget))
-		gtk_grab_remove(widget);
-	return FALSE;
-}
-
-/****************************************************************
- ** set the value from mouse movement
- */
-
-static gboolean gtk_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
-{
-	g_assert(GTK_IS_KNOB(widget));
-	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-	
-	gdk_event_request_motions (event);
-	
-	if (GTK_WIDGET_HAS_GRAB(widget)) {
-		knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y,
-						   true, event->state);
-	}
-	return FALSE;
-}
-
-/****************************************************************
- ** set value from mouseweel
- */
-
-static gboolean gtk_knob_scroll (GtkWidget *widget, GdkEventScroll *event)
-{
-	usleep(5000);
-	gtk_knob_set_value(widget, event->direction);
-	return FALSE;
-}
-
-/****************************************************************
- ** init the GtkKnobClass
- */
-
-static void gtk_knob_class_init (GtkKnobClass *klass)
-{
-	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
-
-	/** set here the sizes and steps for the used knob **/
-//--------- small knob size and steps
-	
-	klass->knob_x = 30;
-	klass->knob_y = 30;
-	klass->knob_step = 86;
-
-//--------- event button
-	klass->button_is = 0;
-
-//--------- connect the events with funktions
-	widget_class->expose_event = gtk_knob_expose;
-	widget_class->size_request = gtk_knob_size_request;
-	widget_class->button_press_event = gtk_knob_button_press;
-	widget_class->button_release_event = gtk_knob_button_release;
-	widget_class->motion_notify_event = gtk_knob_pointer_motion;
-	widget_class->key_press_event = gtk_knob_key_press;
-	widget_class->scroll_event = gtk_knob_scroll;
-}
-
-/****************************************************************
- ** init the Knob type/size
- */
-
-static void gtk_knob_init (GtkKnob *knob)
-{
-	GtkWidget *widget = GTK_WIDGET(knob);
-	GtkKnobClass *klass =  GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-
-	GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_FOCUS);
-	GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_DEFAULT);
-
-	widget->requisition.width = klass->knob_x;
-	widget->requisition.height = klass->knob_y;
-
-}
-
-/****************************************************************
- ** redraw when value changed
- */
-
-static gboolean gtk_knob_value_changed(gpointer obj)
-{
-	GtkWidget *widget = (GtkWidget *)obj;
-	gtk_widget_queue_draw(widget);
-	return FALSE;
-}
-
-/****************************************************************
- ** create small knob
- */
-
-GtkWidget *GtkKnob::gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment)
-{
-	GtkWidget *widget = GTK_WIDGET( g_object_new (GTK_TYPE_KNOB, NULL ));
-	GtkKnob *knob = GTK_KNOB(widget);
-	knob->last_quadrant = 0;
-	if (widget) {
-		gtk_range_set_adjustment(GTK_RANGE(widget), _adjustment);
-		g_signal_connect(GTK_OBJECT(widget), "value-changed",
-		                 G_CALLBACK(gtk_knob_value_changed), widget);
-	}
-	return widget;
-}
-
-/****************************************************************
- ** get the Knob type
- */
-
-GType gtk_knob_get_type (void)
-{
-	static GType kn_type = 0;
-	if (!kn_type) {
-		static const GTypeInfo kn_info = {
-			sizeof(GtkKnobClass), NULL,  NULL, (GClassInitFunc)gtk_knob_class_init, NULL, NULL, sizeof (GtkKnob), 0, (GInstanceInitFunc)gtk_knob_init
-		};
-		kn_type = g_type_register_static(GTK_TYPE_RANGE,  "GtkKnob", &kn_info, (GTypeFlags)0);
-	}
-	return kn_type;
-}
-}/* end of gtk_knob namespace */
-
-gtk_knob::GtkKnob myGtkKnob;
-
-/**
- * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string
- * (but not those in the middle of the string)
- */
-static string rmWhiteSpaces(const string& s)
-{
-    size_t i = s.find_first_not_of(" \t");
-    size_t j = s.find_last_not_of(" \t");
-
-    if (i != string::npos & j != string::npos) {
-        return s.substr(i, 1+j-i);
-    } else {
-        return "";
-    }
-}
-
-
-/**
- * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata
- */
-static void extractMetadata(const string& fulllabel, string& label, map<string, string>& metadata)
-{
-    enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
-    int state = kLabel; int deep = 0;
-    string key, value;
-
-    for (unsigned int i=0; i < fulllabel.size(); i++) {
-        char c = fulllabel[i];
-        switch (state) {
-            case kLabel :
-                assert (deep == 0);
-                switch (c) {
-                    case '\\' : state = kEscape1; break;
-                    case '[' : state = kKey; deep++; break;
-                    default : label += c;
-                }
-                break;
-
-            case kEscape1 :
-                label += c;
-                state = kLabel;
-                break;
-
-            case kEscape2 :
-                key += c;
-                state = kKey;
-                break;
-
-            case kEscape3 :
-                value += c;
-                state = kValue;
-                break;
-
-            case kKey :
-                assert (deep > 0);
-                switch (c) {
-                    case '\\' :  state = kEscape2;
-                                break;
-
-                    case '[' :  deep++;
-                                key += c;
-                                break;
-
-                    case ':' :  if (deep == 1) {
-                                    state = kValue;
-                                } else {
-                                    key += c;
-                                }
-                                break;
-                    case ']' :  deep--;
-                                if (deep < 1) {
-                                    metadata[rmWhiteSpaces(key)] = "";
-                                    state = kLabel;
-                                    key="";
-                                    value="";
-                                } else {
-                                    key += c;
-                                }
-                                break;
-                    default :   key += c;
-                }
-                break;
-
-            case kValue :
-                assert (deep > 0);
-                switch (c) {
-                    case '\\' : state = kEscape3;
-                                break;
-
-                    case '[' :  deep++;
-                                value += c;
-                                break;
-
-                    case ']' :  deep--;
-                                if (deep < 1) {
-                                    metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value);
-                                    state = kLabel;
-                                    key="";
-                                    value="";
-                                } else {
-                                    value += c;
-                                }
-                                break;
-                    default :   value += c;
-                }
-                break;
-
-            default :
-                cerr << "ERROR unrecognized state " << state << endl;
-        }
-    }
-    label = rmWhiteSpaces(label);
-}
-
-
-class GTKUI : public GUI
-{
- private :
-    static bool                         fInitialized;
-    static map<float*, float>           fGuiSize;       // map widget zone with widget size coef
-    static map<float*, string>          fTooltip;       // map widget zone with tooltip strings
-    static set<float*>                  fKnobSet;       // set of widget zone to be knobs
-	string								gGroupTooltip;
-    
-    bool isKnob(float* zone){return fKnobSet.count(zone) > 0;}
-    
- protected :
-    GtkWidget*  fWindow;
-    int         fTop;
-    GtkWidget*  fBox[stackSize];
-    int         fMode[stackSize];
-    bool        fStopped;
-
-    GtkWidget* addWidget(const char* label, GtkWidget* w);
-    virtual void pushBox(int mode, GtkWidget* w);
-
-        
- public :
-    static const gboolean expand = TRUE;
-    static const gboolean fill = TRUE;
-    static const gboolean homogene = FALSE;
-         
-    GTKUI(char * name, int* pargc, char*** pargv);
-
-    // -- Labels and metadata
-
-    virtual void declare (float* zone, const char* key, const char* value);
-    virtual int  checkLabelOptions (GtkWidget* widget, const string& fullLabel, string& simplifiedLabel);
-    virtual void checkForTooltip (float* zone, GtkWidget* widget);
-    
-    // -- layout groups
-    
-    virtual void openFrameBox(const char* label);   
-    virtual void openTabBox(const char* label = "");
-    virtual void openHorizontalBox(const char* label = "");
-    virtual void openVerticalBox(const char* label = "");
-
-    // -- extra widget's layouts
-
-    virtual void openDialogBox(const char* label, float* zone);
-    virtual void openEventBox(const char* label = "");
-    virtual void openHandleBox(const char* label = "");
-    virtual void openExpanderBox(const char* label, float* zone);
-    
-    virtual void closeBox();
-    virtual void adjustStack(int n);
-
-    // -- active widgets
-    
-    virtual void addButton(const char* label, float* zone);
-    virtual void addToggleButton(const char* label, float* zone);
-    virtual void addCheckButton(const char* label, float* zone);
-    virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);   
-    virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step); 
-    virtual void addKnob(const char* label, float* zone, float init, float min, float max, float step);
-    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
-    
-    // -- passive display widgets
-    
-    virtual void addNumDisplay(const char* label, float* zone, int precision);
-    virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max);
-    virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
-    virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
-    
-    virtual void show();
-    virtual void run();
-    
-};
-
-
-
-/******************************************************************************
-*******************************************************************************
-
-                                GRAPHIC USER INTERFACE (v2)
-                                  gtk implementation
-
-*******************************************************************************
-*******************************************************************************/
-
-// global static fields
-
-bool                        GTKUI::fInitialized = false;
-map<float*, float>          GTKUI::fGuiSize;
-map<float*, string>         GTKUI::fTooltip;
-set<float*>                 GTKUI::fKnobSet;       // set of widget zone to be knobs
-
-/**
-* Format tooltip string by replacing some white spaces by 
-* return characters so that line width doesn't exceed n.
-* Limitation : long words exceeding n are not cut 
-*/
-static string formatTooltip(int n, const string& tt)
-{
-	string  ss = tt;	// ss string we are going to format
-	int		lws = 0;	// last white space encountered
-	int 	lri = 0;	// last return inserted
-	for (int i=0; i<tt.size(); i++) {
-		if (tt[i] == ' ') lws = i;
-		if (((i-lri) >= n) && (lws > lri)) {
-			// insert return here
-			ss[lws] = '\n';
-			lri = lws;
-		}
-	}
-	cout << ss;
-	return ss;
-}
-
-
-
-static gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
-{
-    return FALSE; 
-}
-
-static void destroy_event( GtkWidget *widget, gpointer data )
-{
-    gtk_main_quit ();
-}
-
-         
-GTKUI::GTKUI(char * name, int* pargc, char*** pargv) 
-{
-    if (!fInitialized) {
-        gtk_init(pargc, pargv);
-        fInitialized = true;
-    }
-    
-    fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    //gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10);
-    gtk_window_set_title (GTK_WINDOW (fWindow), name);
-    gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);
-    gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL);
-
-    fTop = 0;
-    fBox[fTop] = gtk_vbox_new (homogene, 4);
-    fMode[fTop] = kBoxMode;
-    gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]);
-    fStopped = false;
-}
-
-// empilement des boites
-
-void GTKUI::pushBox(int mode, GtkWidget* w)
-{
-    ++fTop;
-    assert(fTop < stackSize);
-    fMode[fTop]     = mode;
-    fBox[fTop]      = w;
-}
-
-
-/**
- * Remove n levels from the stack S before the top level
- * adjustStack(n): S -> S' with S' = S(0),S(n+1),S(n+2),...
- */
-void GTKUI::adjustStack(int n)
-{
-    if (n > 0) {
-        assert(fTop >= n);
-
-        fTop -= n; 
-        fMode[fTop] = fMode[fTop+n];
-        fBox[fTop]  = fBox[fTop+n];
-    }
-}
-
-void GTKUI::closeBox()
-{
-    --fTop;
-    assert(fTop >= 0);
-}
-
-
-/**
- * Analyses the widget zone metadata declarations and takes
- * appropriate actions 
- */
-void GTKUI::declare(float* zone, const char* key, const char* value)
-{
-	if (zone == 0) {
-		// special zone 0 means group metadata
-		if (strcmp(key,"tooltip")==0) {
-			// only group tooltip are currently implemented
-			gGroupTooltip = formatTooltip(30, value);
-		}
-	} else {
-		if (strcmp(key,"size")==0) {
-			fGuiSize[zone]=atof(value);
-		}
-		else if (strcmp(key,"tooltip")==0) {
-			fTooltip[zone] = formatTooltip(30,value) ;
-		}
-		else if (strcmp(key,"style")==0) {
-			if (strcmp(value,"knob") == 0) {
-				fKnobSet.insert(zone);
-			}
-		}
-	}
-}
-        
-        
-
-/**
- * Analyses a full label and activates the relevant options. returns a simplified
- * label (without options) and an amount of stack adjustement (in case additional
- * containers were pushed on the stack). 
- */
-
-int GTKUI::checkLabelOptions(GtkWidget* widget, const string& fullLabel, string& simplifiedLabel)
-{   
-    map<string, string> metadata;
-    extractMetadata(fullLabel, simplifiedLabel, metadata);
-
-    if (metadata.count("tooltip")) {
-        gtk_tooltips_set_tip (gtk_tooltips_new (), widget, metadata["tooltip"].c_str(), NULL);
-    }
-    if (metadata["option"] == "detachable") {
-        openHandleBox(simplifiedLabel.c_str());
-        return 1;
-    }
-
-	//---------------------
-	if (gGroupTooltip != string()) {
-		gtk_tooltips_set_tip (gtk_tooltips_new (), widget, gGroupTooltip.c_str(), NULL);
-		gGroupTooltip = string();
-	}
-	
-	//----------------------
-	
-    // no adjustement of the stack needed
-    return 0;
-}
-
-/**
- * Check if a tooltip is associated to a zone and add it to the corresponding widget
- */
-void GTKUI::checkForTooltip(float* zone, GtkWidget* widget)
-{
-    if (fTooltip.count(zone)) {
-        gtk_tooltips_set_tip (gtk_tooltips_new (), widget, fTooltip[zone].c_str(), NULL);
-    }
-}
-
-
-// les differentes boites
-
-void GTKUI::openFrameBox(const char* label)
-{
-    GtkWidget * box = gtk_frame_new (label);
-    //gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-            
-    pushBox(kSingleMode, addWidget(label, box));
-}
-
-
-void GTKUI::openTabBox(const char* fullLabel)
-{
-    string  label;
-    GtkWidget* widget = gtk_notebook_new();
-
-    int     adjust = checkLabelOptions(widget, fullLabel, label);
-
-    pushBox(kTabMode, addWidget(label.c_str(), widget));
-
-    // adjust stack because otherwise Handlebox will remain open
-    adjustStack(adjust);
-}
-
-
-void GTKUI::openHorizontalBox(const char* fullLabel)
-{   
-    string   label;
-    GtkWidget* box = gtk_hbox_new (homogene, 4);
-    int     adjust = checkLabelOptions(box, fullLabel, label);
-
-    gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-            
-    if (fMode[fTop] != kTabMode && label[0] != 0) {
-        GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str()));
-        gtk_container_add (GTK_CONTAINER(frame), box);
-        gtk_widget_show(box);
-        pushBox(kBoxMode, box);
-    } else {
-        pushBox(kBoxMode, addWidget(label.c_str(), box));
-    }
-
-    // adjust stack because otherwise Handlebox will remain open
-    adjustStack(adjust);
-}
-
-
-void GTKUI::openVerticalBox(const char* fullLabel)
-{
-    string  label;
-    GtkWidget * box = gtk_vbox_new (homogene, 4);
-    int      adjust = checkLabelOptions(box, fullLabel, label);
-
-    gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-            
-    if (fMode[fTop] != kTabMode && label[0] != 0) {
-        GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str()));
-        gtk_container_add (GTK_CONTAINER(frame), box);
-        gtk_widget_show(box);
-        pushBox(kBoxMode, box);
-    } else {
-        pushBox(kBoxMode, addWidget(label.c_str(), box));
-    }
-
-    // adjust stack because otherwise Handlebox will remain open
-    adjustStack(adjust);
-}
-
-
-void GTKUI::openHandleBox(const char* label)
-{
-    GtkWidget * box = gtk_hbox_new (homogene, 4);
-    gtk_container_set_border_width (GTK_CONTAINER (box), 2);
-    if (fMode[fTop] != kTabMode && label[0] != 0)
-    {
-        GtkWidget * frame = addWidget(label, gtk_handle_box_new ());
-        gtk_container_add (GTK_CONTAINER(frame), box);
-        gtk_widget_show(box);
-        pushBox(kBoxMode, box);
-    }
-    else
-    {
-        pushBox(kBoxMode, addWidget(label, box));
-    }
-}
-
-
-void GTKUI::openEventBox(const char* label)
-{
-    GtkWidget * box = gtk_hbox_new (homogene, 4);
-    gtk_container_set_border_width (GTK_CONTAINER (box), 2);
-    if (fMode[fTop] != kTabMode && label[0] != 0)
-    {
-        GtkWidget * frame = addWidget(label, gtk_event_box_new ());
-        gtk_container_add (GTK_CONTAINER(frame), box);
-        gtk_widget_show(box);
-        pushBox(kBoxMode, box);
-    }
-    else
-    {
-        pushBox(kBoxMode, addWidget(label, box));
-    }
-}
-
-
-struct uiExpanderBox : public uiItem
-{
-    GtkExpander* fButton;
-    uiExpanderBox(GUI* ui, float* zone, GtkExpander* b) : uiItem(ui, zone), fButton(b) {}
-    static void expanded (GtkWidget *widget, gpointer data)
-    {
-        float   v = gtk_expander_get_expanded  (GTK_EXPANDER(widget));
-        if (v == 1.000000)
-        {
-            v = 0;
-        }
-        else v = 1;
-        ((uiItem*)data)->modifyZone(v);
-    }
-
-    virtual void reflectZone()
-    {
-        float   v = *fZone;
-        fCache = v;
-        gtk_expander_set_expanded(GTK_EXPANDER(fButton), v);
-    }
-};
-
-void GTKUI::openExpanderBox(const char* label, float* zone)
-{
-    *zone = 0.0;
-    GtkWidget * box = gtk_hbox_new (homogene, 4);
-    gtk_container_set_border_width (GTK_CONTAINER (box), 2);
-    if (fMode[fTop] != kTabMode && label[0] != 0)
-    {
-        GtkWidget * frame = addWidget(label, gtk_expander_new (label));
-        gtk_container_add (GTK_CONTAINER(frame), box);
-        uiExpanderBox* c = new uiExpanderBox(this, zone, GTK_EXPANDER(frame));
-        gtk_signal_connect (GTK_OBJECT (frame), "activate", GTK_SIGNAL_FUNC (uiExpanderBox::expanded), (gpointer)c);
-        gtk_widget_show(box);
-        pushBox(kBoxMode, box);
-    }
-    else
-    {
-        pushBox(kBoxMode, addWidget(label, box));
-    }
-}
-
-
-
-GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w)
-{ 
-    switch (fMode[fTop]) {
-        case kSingleMode    : gtk_container_add (GTK_CONTAINER(fBox[fTop]), w);                             break;
-        case kBoxMode       : gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0);                 break;
-        case kTabMode       : gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break;
-    }
-    gtk_widget_show (w);
-    return w;
-}
-
-// --------------------------- Press button ---------------------------
-
-struct uiButton : public uiItem
-{
-    GtkButton*  fButton;
-    
-    uiButton (GUI* ui, float* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {}
-    
-    static void pressed( GtkWidget *widget, gpointer   data )
-    {
-        uiItem* c = (uiItem*) data;
-        c->modifyZone(1.0);
-    }
-
-    static void released( GtkWidget *widget, gpointer   data )
-    {
-        uiItem* c = (uiItem*) data;
-        c->modifyZone(0.0);
-    }
-
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v; 
-        if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton);
-    }
-};
-
-void GTKUI::addButton(const char* label, float* zone)
-{
-    *zone = 0.0;
-    GtkWidget*  button = gtk_button_new_with_label (label);
-    addWidget(label, button);
-    
-    uiButton* c = new uiButton(this, zone, GTK_BUTTON(button));
-    
-    gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c);
-    gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c);
-
-    checkForTooltip(zone, button);
-}
-
-// ---------------------------  Toggle Buttons ---------------------------
-
-struct uiToggleButton : public uiItem
-{
-    GtkToggleButton* fButton;
-    
-    uiToggleButton(GUI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
-    
-    static void toggled (GtkWidget *widget, gpointer data)
-    {
-        float   v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; 
-        ((uiItem*)data)->modifyZone(v);
-    }
-
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v; 
-        gtk_toggle_button_set_active(fButton, v > 0.0); 
-    }
-};
-
-void GTKUI::addToggleButton(const char* label, float* zone)
-{
-    *zone = 0.0;
-    GtkWidget*  button = gtk_toggle_button_new_with_label (label);
-    addWidget(label, button);
-    
-    uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button));
-    gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c);
-
-    checkForTooltip(zone, button);
-}
-
-
-
-void show_dialog(GtkWidget *widget, gpointer data)
-{
-    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == TRUE)
-    {
-        gtk_widget_show(GTK_WIDGET(data));
-        gint root_x, root_y;
-        gtk_window_get_position (GTK_WINDOW(data), &root_x, &root_y);
-        root_y -= 120;
-        gtk_window_move(GTK_WINDOW(data), root_x, root_y);
-    }
-    else gtk_widget_hide(GTK_WIDGET(data));
-}
-
-static gboolean deleteevent( GtkWidget *widget, gpointer   data )
-{
-return TRUE;
-} 
-
-void GTKUI::openDialogBox(const char* label, float* zone)
-{
-    // create toplevel window and set properties
-    GtkWidget * dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_decorated(GTK_WINDOW(dialog), TRUE);
-    gtk_window_set_deletable(GTK_WINDOW(dialog), FALSE);
-    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-    gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_SOUTH);
-    gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(fWindow));
-    gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
-    gtk_window_set_keep_below (GTK_WINDOW(dialog), FALSE);
-    gtk_window_set_title (GTK_WINDOW (dialog), label);
-    g_signal_connect (G_OBJECT (dialog), "delete_event", G_CALLBACK (deleteevent), NULL); 
-    gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
-
-    GtkWidget * box = gtk_hbox_new (homogene, 4);
- 
-    *zone = 0.0;
-    GtkWidget*  button = gtk_toggle_button_new ();
-    gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (show_dialog), (gpointer) dialog);
- 
-    gtk_container_add (GTK_CONTAINER(fBox[fTop]), button);
-    gtk_container_add (GTK_CONTAINER(dialog), box);
-    gtk_widget_show (button);
-    gtk_widget_show(box);
-    pushBox(kBoxMode, box);
-}
-
-
-
-
-// ---------------------------  Check Button ---------------------------
-
-struct uiCheckButton : public uiItem
-{
-    GtkToggleButton* fButton;
-    
-    uiCheckButton(GUI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
-    
-    static void toggled (GtkWidget *widget, gpointer data)
-    {
-        float   v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; 
-        ((uiItem*)data)->modifyZone(v);
-    }
-
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v; 
-        gtk_toggle_button_set_active(fButton, v > 0.0); 
-    }
-};
-
-void GTKUI::addCheckButton(const char* label, float* zone)
-{
-    *zone = 0.0;
-    GtkWidget*  button = gtk_check_button_new_with_label (label);
-    addWidget(label, button);
-    
-    uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button));
-    gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c);
-
-    checkForTooltip(zone, button);
-}
-
-
-// ---------------------------  Adjustmenty based widgets ---------------------------
-
-struct uiAdjustment : public uiItem
-{
-    GtkAdjustment* fAdj;
-    
-    uiAdjustment(GUI* ui, float* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {}
-    
-    static void changed (GtkWidget *widget, gpointer data)
-    {
-        float   v = GTK_ADJUSTMENT (widget)->value; 
-        ((uiItem*)data)->modifyZone(v);
-    }
-
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v; 
-        gtk_adjustment_set_value(fAdj, v);  
-    }
-};
-
-// --------------------------- format knob value display ---------------------------
-
-struct uiValueDisplay : public uiItem
-{
-	GtkLabel* fLabel;
-	int	fPrecision ;
-
-	uiValueDisplay(GUI* ui, float* zone, GtkLabel* label, int precision)
-		: uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
-
-	virtual void reflectZone()
-		{
-			float v = *fZone;
-			fCache = v;
-			char s[64];
-			if (fPrecision <= 0)
-				snprintf(s, 63, "%d", int(v));
-
-			else if (fPrecision > 3)
-				snprintf(s, 63, "%f", v);
-
-			else if (fPrecision == 1)
-			{
-				const char* format[] = {"%.1f", "%.2f", "%.3f"};
-				snprintf(s, 63, format[1-1], v);
-			}
-			else if (fPrecision == 2)
-			{
-				const char* format[] = {"%.1f", "%.2f", "%.3f"};
-				snprintf(s, 63, format[2-1], v);
-			}
-			else
-			{
-				const char* format[] = {"%.1f", "%.2f", "%.3f"};
-				snprintf(s, 63, format[3-1], v);
-			}
-			gtk_label_set_text(fLabel, s);
-		}
-};
-
-// ------------------------------- Knob -----------------------------------------
-
-void GTKUI::addKnob(const char* label, float* zone, float init, float min, float max, float step)
-{
-	*zone = init;
-    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-    
-    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-    
-	GtkWidget* slider = gtk_vbox_new (FALSE, 0);
-	GtkWidget* fil = gtk_vbox_new (FALSE, 0);
-	GtkWidget* rei = gtk_vbox_new (FALSE, 0);
-	GtkWidget* re =myGtkKnob.gtk_knob_new_with_adjustment(GTK_ADJUSTMENT(adj));
-	GtkWidget* lw = gtk_label_new("");
-	new uiValueDisplay(this, zone, GTK_LABEL(lw),precision(step));
-	gtk_container_add (GTK_CONTAINER(rei), re);
-	if(fGuiSize[zone]) {
-		float size = 30 * fGuiSize[zone];
-		gtk_widget_set_size_request(rei, size, size );
-		gtk_box_pack_start (GTK_BOX(slider), fil, TRUE, TRUE, 0);
-		gtk_box_pack_start (GTK_BOX(slider), rei, FALSE, FALSE, 0);
-	} else {
-		gtk_container_add (GTK_CONTAINER(slider), fil);
-		gtk_container_add (GTK_CONTAINER(slider), rei);
-	}
-	gtk_container_add (GTK_CONTAINER(slider), lw);
-	gtk_widget_show_all(slider);
-	
-	if (label && label[0]!=0) {
-        openFrameBox(label);
-        addWidget(label, slider);
-        closeBox();
-    } else {
-        addWidget(label, slider);
-    }
-
-    checkForTooltip(zone, slider);
-}
-
-// -------------------------- Vertical Slider -----------------------------------
-
-void GTKUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
-	if (isKnob(zone)) { 
-		addKnob(label, zone, init, min, max, step);
-		return;
-	} 
-    *zone = init;
-    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-    
-    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-    
-	GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj));
-	gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
-	float size = 160;
-	if(fGuiSize[zone]) {
-		size = 160 * fGuiSize[zone];
-	}
-	gtk_widget_set_size_request(slider, -1, size);
-	
-    gtk_range_set_inverted (GTK_RANGE(slider), TRUE);
-    
-    if (label && label[0]!=0) {
-        openFrameBox(label);
-        addWidget(label, slider);
-        closeBox();
-    } else {
-        addWidget(label, slider);
-    }
-
-    checkForTooltip(zone, slider);
-}
-
-// -------------------------- Horizontal Slider -----------------------------------
-
-void GTKUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
-	if (isKnob(zone)) { 
-		addKnob(label, zone, init, min, max, step);
-		return;
-	} 
-    *zone = init;
-    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-    
-    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-    
-    GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj));
-	gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
-	float size = 160;
-	if(fGuiSize[zone]) {
-		size = 160 * fGuiSize[zone];
-	}
-	gtk_widget_set_size_request(slider, size, -1);
-    
-    if (label && label[0]!=0) {
-        openFrameBox(label);
-        addWidget(label, slider);
-        closeBox();
-    } else {
-        addWidget(label, slider);
-    }             
-
-    checkForTooltip(zone, slider);
-}
-
-
-// ------------------------------ Num Entry -----------------------------------
-
-void GTKUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-{
-	if (isKnob(zone)) { 
-		addKnob(label, zone, init, min, max, step);
-		return;
-	} 
-    *zone = init;
-    GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step);
-    
-    uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-    gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-    
-    GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step));
-
-    openFrameBox(label);
-    addWidget(label, spinner);
-    closeBox();
-
-    checkForTooltip(zone, spinner);
-}
-
-
-// ==========================   passive widgets ===============================
-
-
-// ------------------------------ Progress Bar -----------------------------------
-
-struct uiBargraph : public uiItem
-{
-    GtkProgressBar*     fProgressBar;
-    float               fMin;
-    float               fMax;
-    
-    uiBargraph(GUI* ui, float* zone, GtkProgressBar* pbar, float lo, float hi) 
-            : uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {}
-
-    float scale(float v)        { return (v-fMin)/(fMax-fMin); }
-    
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v; 
-        gtk_progress_bar_set_fraction(fProgressBar, scale(v));  
-    }
-};
-
-    
-
-void GTKUI::addVerticalBargraph(const char* label, float* zone, float lo, float hi)
-{
-    GtkWidget* pb = gtk_progress_bar_new();
-    gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP);
-    gtk_widget_set_size_request(pb, 8, -1);
-    new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
-    openFrameBox(label);
-    addWidget(label, pb);
-    closeBox();
-
-    checkForTooltip(zone, pb);
-}
-    
-
-void GTKUI::addHorizontalBargraph(const char* label, float* zone, float lo, float hi)
-{
-    GtkWidget* pb = gtk_progress_bar_new();
-    gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT);
-    gtk_widget_set_size_request(pb, -1, 8);
-    new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
-    openFrameBox(label);
-    addWidget(label, pb);
-    closeBox();
-
-    checkForTooltip(zone, pb);
-}
-
-
-// ------------------------------ Num Display -----------------------------------
-
-struct uiNumDisplay : public uiItem
-{
-    GtkLabel* fLabel;
-    int fPrecision;
-    
-    uiNumDisplay(GUI* ui, float* zone, GtkLabel* label, int precision) 
-            : uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
-
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v;
-        char s[64]; 
-        if (fPrecision <= 0) { 
-            snprintf(s, 63, "%d", int(v)); 
-        } else if (fPrecision>3) {
-            snprintf(s, 63, "%f", v);
-        } else {
-            const char* format[] = {"%.1f", "%.2f", "%.3f"};
-            snprintf(s, 63, format[fPrecision-1], v);
-        }
-        gtk_label_set_text(fLabel, s);
-    }
-};
-    
-
-void GTKUI::addNumDisplay(const char* label, float* zone, int precision )
-{
-    GtkWidget* lw = gtk_label_new("");
-    new uiNumDisplay(this, zone, GTK_LABEL(lw), precision);
-    openFrameBox(label);
-    addWidget(label, lw);
-    closeBox();
-
-    checkForTooltip(zone, lw);
-}
-
-
-// ------------------------------ Text Display -----------------------------------
-
-struct uiTextDisplay : public uiItem
-{
-        GtkLabel*           fLabel;
-        const char**    fNames;
-        float               fMin;
-        float               fMax;
-        int                         fNum;
-        
-        
-        uiTextDisplay (GUI* ui, float* zone, GtkLabel* label, const char* names[], float lo, float hi)
-                        : uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi)
-        {
-                fNum = 0;
-                while (fNames[fNum] != 0) fNum++;
-    }
-
-    virtual void reflectZone()  
-    { 
-        float   v = *fZone;
-        fCache = v;
-        
-        int idx = int(fNum*(v-fMin)/(fMax-fMin));
-        
-        if      (idx < 0)       idx = 0; 
-        else if (idx >= fNum)   idx = fNum-1;
-                
-        gtk_label_set_text(fLabel, fNames[idx]); 
-    }
-};
-    
-
-void GTKUI::addTextDisplay(const char* label, float* zone, const char* names[], float lo, float hi )
-{
-    GtkWidget* lw = gtk_label_new("");
-    new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi);
-    openFrameBox(label);
-    addWidget(label, lw);
-    closeBox();
-
-    checkForTooltip(zone, lw);
-}
-
-
-
-void GTKUI::show() 
-{
-    assert(fTop == 0);
-    gtk_widget_show  (fBox[0]);
-    gtk_widget_show  (fWindow);
-}
-
-
-/**
- * Update all user items reflecting zone z
- */
-    
-static gboolean callUpdateAllGuis(gpointer)
-{ 
-    GUI::updateAllGuis(); 
-    return TRUE;
-}
-
-
-void GTKUI::run() 
-{
-    assert(fTop == 0);
-    gtk_widget_show  (fBox[0]);
-    gtk_widget_show  (fWindow);
-    gtk_timeout_add(40, callUpdateAllGuis, 0);
-    gtk_main ();
-    stop();
-}
-
-
-
-#endif
-
diff --git a/architecture/gui/faustqt.h b/architecture/gui/faustqt.h
deleted file mode 100644
index 46aab5b..0000000
--- a/architecture/gui/faustqt.h
+++ /dev/null
@@ -1,1753 +0,0 @@
-/************************************************************************
- ************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
-
- ************************************************************************
- ************************************************************************/
-#ifndef __faustqt__
-#define __faustqt__
-
-#include <cassert>
-#include <cmath>
-#include <fstream>
-#include <iostream>
-#include <list>
-#include <map>
-#include <set>
-#include <vector>
-#include <stack>
-
-#include <QApplication>
-#include <QCheckBox>
-#include <QColormap>
-#include <QDial>
-#include <QDoubleSpinBox>
-#include <QGroupBox>
-#include <QHBoxLayout>
-#include <QLayout>
-#include <QMouseEvent>
-#include <QObject>
-#include <QPainter>
-#include <QProgressBar>
-#include <QPushButton>
-#include <QRadialGradient>
-#include <QSlider>
-#include <QStyle>
-#include <QTabWidget>
-#include <QTimer>
-#include <QToolTip>
-#include <QVBoxLayout>
-#include <QWheelEvent>
-#include <QWidget>
-#include <QtGui>
-
-#include "GUI.h"
-
-//----------------------------------
-
-// for compatibility
-#define minValue minimum
-#define maxValue maximum
-
-
-using namespace std;
-
-
-//==============================BEGIN QSYNTHKNOB=====================================
-//
-//   qsynthknob and qsynthDialVokiStyle borrowed from qsynth-0.3.3 by Rui Nuno Capela
-//   This widget is based on a design by Thorsten Wilms,
-//   implemented by Chris Cannam in Rosegarden,
-//   adapted for QSynth by Pedro Lopez-Cabanillas,
-//   improved for Qt4 by David Garcia Garzon.
-//
-
-#define DIAL_MIN      (0.25 * M_PI)
-#define DIAL_MAX      (1.75 * M_PI)
-#define DIAL_RANGE    (DIAL_MAX - DIAL_MIN)
-
-class qsynthDialVokiStyle : public QCommonStyle
-{
-public:
-	qsynthDialVokiStyle() {};
-	virtual ~qsynthDialVokiStyle() {};
-
-    virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget = 0) const
-	{
-		if (cc != QStyle::CC_Dial)
-		{
-			QCommonStyle::drawComplexControl(cc, opt, p, widget);
-			return;
-		}
-
-		const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt);
-		if (dial == NULL)
-			return;
-
-		double angle = DIAL_MIN // offset
-			+ (DIAL_RANGE *
-				(double(dial->sliderValue - dial->minimum) /
-				(double(dial->maximum - dial->minimum))));
-		int degrees = int(angle * 180.0 / M_PI);
-		int side = dial->rect.width() < dial->rect.height() ? dial->rect.width() : dial->rect.height();
-		int xcenter = dial->rect.width() / 2;
-		int ycenter = dial->rect.height() / 2;
-		int notchWidth   = 1 + side / 400;
-		int pointerWidth = 2 + side / 30;
-		int scaleShadowWidth = 1 + side / 100;
-		int knobBorderWidth = 0;
-		int ns = dial->tickInterval;
-		int numTicks = 1 + (dial->maximum + ns - dial->minimum) / ns;
-		int indent = int(0.15 * side) + 2;
-		int knobWidth = side - 2 * indent;
-		int shineFocus = knobWidth / 4;
-		int shineCenter = knobWidth / 5;
-		int shineExtension = shineCenter * 4;
-		int shadowShift = shineCenter * 2;
-		int meterWidth = side - 2 * scaleShadowWidth;
-
-		QPalette pal = opt->palette;
-		QColor knobColor = pal.mid().color();
-		QColor borderColor = knobColor.light();
-		QColor meterColor = (dial->state & State_Enabled) ?
-                            QColor("orange") : pal.mid().color();
-                         // pal.highlight().color() : pal.mid().color();
-		QColor background = pal.window().color();
-
-		p->save();
-		p->setRenderHint(QPainter::Antialiasing, true);
-
-		// The bright metering bit...
-
-		QConicalGradient meterShadow(xcenter, ycenter, -90);
-		meterShadow.setColorAt(0, meterColor.dark());
-		meterShadow.setColorAt(0.5, meterColor);
-		meterShadow.setColorAt(1.0, meterColor.light().light());
-		p->setBrush(meterShadow);
-		p->setPen(Qt::transparent);
-		p->drawPie(xcenter - meterWidth / 2, ycenter - meterWidth / 2,
-			meterWidth, meterWidth, (180 + 45) * 16, -(degrees - 45) * 16);
-
-		// Knob projected shadow
-		QRadialGradient projectionGradient(
-			xcenter + shineCenter, ycenter + shineCenter,
-			shineExtension,	xcenter + shadowShift, ycenter + shadowShift);
-		projectionGradient.setColorAt(0, QColor(  0, 0, 0, 100));
-		projectionGradient.setColorAt(1, QColor(200, 0, 0,  10));
-		QBrush shadowBrush(projectionGradient);
-		p->setBrush(shadowBrush);
-		p->drawEllipse(xcenter - shadowShift, ycenter - shadowShift,
-			knobWidth, knobWidth);
-
-		// Knob body and face...
-
-		QPen pen;
-		pen.setColor(knobColor);
-		pen.setWidth(knobBorderWidth);
-		p->setPen(pen);
-
-		QRadialGradient gradient(
-			xcenter - shineCenter, ycenter - shineCenter,
-			shineExtension,	xcenter - shineFocus, ycenter - shineFocus);
-		gradient.setColorAt(0.2, knobColor.light().light());
-		gradient.setColorAt(0.5, knobColor);
-		gradient.setColorAt(1.0, knobColor.dark(150));
-		QBrush knobBrush(gradient);
-		p->setBrush(knobBrush);
-		p->drawEllipse(xcenter - knobWidth / 2, ycenter - knobWidth / 2,
-			knobWidth, knobWidth);
-
-		// Tick notches...
-
-		p->setBrush(Qt::NoBrush);
-
-		if (dial->subControls & QStyle::SC_DialTickmarks)
-		{
-			pen.setColor(pal.dark().color());
-			pen.setWidth(notchWidth);
-			p->setPen(pen);
-			double hyp = double(side - scaleShadowWidth) / 2.0;
-			double len = hyp / 4;
-			for (int i = 0; i < numTicks; ++i) {
-				int div = numTicks;
-				if (div > 1) --div;
-				bool internal = (i != 0 && i != numTicks - 1);
-				double angle = DIAL_MIN
-					+ (DIAL_MAX - DIAL_MIN) * i / div;
-				double dir = (internal ? -1 : len);
-				double sinAngle = sin(angle);
-				double cosAngle = cos(angle);
-				double x0 = xcenter - (hyp - len) * sinAngle;
-				double y0 = ycenter + (hyp - len) * cosAngle;
-				double x1 = xcenter - (hyp + dir) * sinAngle;
-				double y1 = ycenter + (hyp + dir) * cosAngle;
-				p->drawLine(QLineF(x0, y0, x1, y1));
-			}
-		}
-
-		// Shadowing...
-
-		// Knob shadow...
-		if (knobBorderWidth > 0) {
-			QLinearGradient inShadow(xcenter - side / 4, ycenter - side / 4,
-				xcenter + side / 4, ycenter + side / 4);
-			inShadow.setColorAt(0.0, borderColor.light());
-			inShadow.setColorAt(1.0, borderColor.dark());
-			p->setPen(QPen(QBrush(inShadow), knobBorderWidth * 7 / 8));
-			p->drawEllipse(xcenter - side / 2 + indent,
-				ycenter - side / 2 + indent,
-				side - 2 * indent, side - 2 * indent);
-		}
-
-		// Scale shadow...
-		QLinearGradient outShadow(xcenter - side / 3, ycenter - side / 3,
-			xcenter + side / 3, ycenter + side / 3);
-		outShadow.setColorAt(0.0, background.dark().dark());
-		outShadow.setColorAt(1.0, background.light().light());
-		p->setPen(QPen(QBrush(outShadow), scaleShadowWidth));
-		p->drawArc(xcenter - side / 2 + scaleShadowWidth / 2,
-			ycenter - side / 2 + scaleShadowWidth / 2,
-			side - scaleShadowWidth, side - scaleShadowWidth, -45 * 16, 270 * 16);
-
-		// Pointer notch...
-
-		double hyp = double(side) / 2.0;
-		double len = hyp - indent - 1;
-
-		double x = xcenter - len * sin(angle);
-		double y = ycenter + len * cos(angle);
-
-		QColor pointerColor = pal.dark().color();
-		pen.setColor((dial->state & State_Enabled) ? pointerColor.dark(140) : pointerColor);
-		pen.setWidth(pointerWidth + 2);
-		p->setPen(pen);
-		p->drawLine(QLineF(xcenter, ycenter, x, y));
-		pen.setColor((dial->state & State_Enabled) ? pointerColor.light() : pointerColor.light(140));
-		pen.setWidth(pointerWidth);
-		p->setPen(pen);
-		p->drawLine(QLineF(xcenter - 1, ycenter - 1, x - 1, y - 1));
-
-		// done
-		p->restore();
-	}
-
-};
-//
-//===============================END QSYNTHKNOB======================================
-
-
-//==============================BEGIN DISPLAYS===================================
-//
-// This section constains displays, passive QT widgets that displays values in
-// different ways, in particular bargraphs
-//
-
-/**
- * An abstract widget that display a value in a range
- */
-class AbstractDisplay : public QWidget
-{
-    protected :
-        float           fMin;
-        float           fMax;
-        float           fValue;
-
-    public:
-
-        AbstractDisplay (float lo, float hi) : fMin(lo), fMax(hi), fValue(lo)
-        {
-        }
-
-        /**
-         * set the range of displayed values
-         */
-        virtual void setRange(float lo, float hi)
-        {
-            fMin = lo;
-            fMax = hi;
-        }
-
-        /**
-         * set the value to be displayed
-         */
-        virtual void setValue(float v)
-        {
-            if (v < fMin)       v = fMin;
-            else if (v > fMax)  v = fMax;
-
-            if (v != fValue) {
-                fValue = v;
-                update();
-            }
-        }
-};
-
-
-/**
- * Displays dB values using a scale of colors
- */
-class dbAbstractDisplay : public AbstractDisplay
-{
-    protected :
-
-        float           fScaleMin;
-        float           fScaleMax;
-        vector<int>     fLevel;
-        vector<QBrush>  fBrush;
-
-
-        /**
-        * Convert a dB value into a scale between 0 and 1 (following IEC standard ?)
-        */
-        float dB2Scale ( float dB ) const
-        {
-            float fScale = 1.0f;
-
-            /*if (dB < -70.0f)
-                fScale = 0.0f;
-            else*/ if (dB < -60.0f)
-                fScale = (dB + 70.0f) * 0.0025f;
-            else if (dB < -50.0f)
-                fScale = (dB + 60.0f) * 0.005f + 0.025f;
-            else if (dB < -40.0)
-                fScale = (dB + 50.0f) * 0.0075f + 0.075f;
-            else if (dB < -30.0f)
-                fScale = (dB + 40.0f) * 0.015f + 0.15f;
-            else if (dB < -20.0f)
-                fScale = (dB + 30.0f) * 0.02f + 0.3f;
-            else if (dB < -0.001f || dB > 0.001f)  /* if (dB < 0.0f) */
-                fScale = (dB + 20.0f) * 0.025f + 0.5f;
-
-            return fScale;
-        }
-
-
-        /**
-         * Create the scale of colors used to paint the bargraph in relation to the levels
-         * The parameter x indicates the direction of the gradient. x=1 means an horizontal
-         * gradient typically used by a vertical bargraph, and x=0 a vertical gradient.
-         */
-        void initLevelsColors(int x)
-        {
-            int alpha = 200;
-            { // level until -10 dB
-                QColor c(40, 160, 40, alpha);
-                QLinearGradient g(0,0,x,1-x);
-                g.setCoordinateMode(QGradient::ObjectBoundingMode);
-                g.setColorAt(0.0,   c.lighter());
-                g.setColorAt(0.2,   c);
-                g.setColorAt(0.8,   c);
-                g.setColorAt(0.9,   c.darker(120));
-
-                fLevel.push_back(-10);
-                fBrush.push_back(QBrush(g));
-            }
-
-            { // level until -6 dB
-                QColor c(160, 220, 20, alpha);
-                QLinearGradient g(0,0,x,1-x);
-                g.setCoordinateMode(QGradient::ObjectBoundingMode);
-                g.setColorAt(0.0,   c.lighter());
-                g.setColorAt(0.2,   c);
-                g.setColorAt(0.8,   c);
-                g.setColorAt(0.9,   c.darker(120));
-
-                fLevel.push_back(-6);
-                fBrush.push_back(QBrush(g));
-            }
-
-            { // level until -3 dB
-                QColor c(220, 220, 20, alpha);
-                QLinearGradient g(0,0,x,1-x);
-                g.setCoordinateMode(QGradient::ObjectBoundingMode);
-                g.setColorAt(0.0,   c.lighter());
-                g.setColorAt(0.2,   c);
-                g.setColorAt(0.8,   c);
-                g.setColorAt(0.9,   c.darker(120));
-
-                fLevel.push_back(-3);
-                fBrush.push_back(QBrush(g));
-            }
-
-            { // level until -0 dB
-                QColor c(240, 160, 20, alpha);
-                QLinearGradient g(0,0,x,1-x);
-                g.setCoordinateMode(QGradient::ObjectBoundingMode);
-                g.setColorAt(0.0,   c.lighter());
-                g.setColorAt(0.2,   c);
-                g.setColorAt(0.8,   c);
-                g.setColorAt(0.9,   c.darker(120));
-
-                fLevel.push_back(0);
-                fBrush.push_back(QBrush(g));
-            }
-
-            { // until 10 dB (and over because last one)
-                QColor c(240,  0, 20, alpha);   // ColorOver
-                QLinearGradient g(0,0,x,1-x);
-                g.setCoordinateMode(QGradient::ObjectBoundingMode);
-                g.setColorAt(0.0,   c.lighter());
-                g.setColorAt(0.2,   c);
-                g.setColorAt(0.8,   c);
-                g.setColorAt(0.9,   c.darker(120));
-
-                fLevel.push_back(+10);
-                fBrush.push_back(QBrush(g));
-            }
-
-        }
-
-    public:
-
-        dbAbstractDisplay(float lo, float hi) : AbstractDisplay(lo,hi)
-        {
-        }
-
-        /**
-         * set the range of displayed values
-         */
-        virtual void setRange(float lo, float hi)
-        {
-            AbstractDisplay::setRange(lo, hi);
-            fScaleMin = dB2Scale(fMin);
-            fScaleMax = dB2Scale(fMax);
-        }
-};
-
-
-/**
- * Small rectangular LED display which color changes with the level in dB
- */
-class dbLED : public dbAbstractDisplay
-{
-    protected:
-
-        /**
-         * Draw the LED using a color depending of its value in dB
-         */
-        virtual void paintEvent ( QPaintEvent *)
-        {
-            QPainter painter(this);
-            painter.drawRect(rect());
-
-            if (fValue <= fLevel[0]) {
-
-                // interpolate the first color on the alpha channel
-                QColor c(40, 160, 40) ;
-                float a = (fValue-fMin)/(fLevel[0]-fMin);
-                c.setAlphaF(a);
-                painter.fillRect(rect(), c);
-
-            } else {
-
-                // find the minimal level > value
-                int l = fLevel.size()-1; while (fValue < fLevel[l] && l > 0) l--;
-                painter.fillRect(rect(), fBrush[l]);
-            }
-        }
-
-    public:
-
-        dbLED(float lo, float hi) : dbAbstractDisplay(lo,hi)
-        {
-            setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-            initLevelsColors(1);
-       }
-
-        virtual QSize sizeHint () const
-        {
-            return QSize(16, 8);
-        }
-};
-/**
- * Small rectangular LED display which intensity (alpha channel) changes according to the value
- */
-class LED : public AbstractDisplay
-{
-    QColor  fColor;
-
-    protected:
-
-        /**
-         * Draw the LED using a transparency depending of its value
-         */
-        virtual void paintEvent ( QPaintEvent *)
-        {
-            QPainter painter(this);
-            painter.drawRect(rect());
-            // interpolate the first color on the alpha channel
-            QColor c = fColor ;
-            float a = (fValue-fMin)/(fMax-fMin);
-            c.setAlphaF(a);
-            painter.fillRect(rect(), c);
-        }
-
-    public:
-
-        LED(float lo, float hi) : AbstractDisplay(lo,hi), fColor("yellow")
-        {
-            setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-       }
-
-        virtual QSize sizeHint () const
-        {
-            return QSize(16, 8);
-        }
-};
-
-
-
-/**
- * A simple bargraph that detect automatically its direction
- */
-class linBargraph : public AbstractDisplay
-{
-    protected :
-        QBrush  fBrush;
-
-        /**
-         * No scale implemented yet
-         */
-        void paintScale(QPainter* painter) const
-        {
-            painter->drawRect(0,0,width(),height());
-        }
-
-        /**
-         * The length of the rectangle is proportional to the value
-         */
-        void paintContent (QPainter* painter) const
-        {
-            int     w = width();
-            int     h = height();
-            float   v = (fValue-fMin)/(fMax-fMin);
-
-            if (h>w) {
-                // draw vertical rectangle
-                painter->fillRect(0,(1-v)*h,w, v*h, fBrush);
-            } else {
-                // draw horizontal rectangle
-                painter->fillRect(0, 0, h, v*w, fBrush);
-            }
-
-        }
-
-        virtual void paintEvent ( QPaintEvent *)
-        {
-            QPainter painter(this);
-            paintContent(&painter);
-            paintScale(&painter);
-        }
-
-    public:
-
-        linBargraph(float lo, float hi) : AbstractDisplay(lo,hi)
-        {
-            // compute the brush that will be used to
-            // paint the value
-            QColor c(0xffa500);                 // orange
-            int x = int(height() < width());    // gradient direction
-            QLinearGradient g(0,0,x,1-x);
-            g.setCoordinateMode(QGradient::ObjectBoundingMode);
-            g.setColorAt(0.0,   c.lighter());
-            g.setColorAt(0.2,   c);
-            g.setColorAt(0.8,   c);
-            g.setColorAt(0.9,   c.darker(120));
-            fBrush = QBrush(g);
-        }
-};
-
-
-/**
- * A simple vertical bargraph
- */
-class linVerticalBargraph : public linBargraph
-{
-    public:
-
-        linVerticalBargraph(float lo, float hi) : linBargraph(lo,hi)
-        {
-            setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
-        }
-
-        virtual QSize sizeHint () const
-        {
-            return QSize(16, 128);
-        }
-};
-
-
-
-/**
- * A simple horizontal bargraph
- */
-class linHorizontalBargraph : public linBargraph
-{
-    public:
-
-        linHorizontalBargraph(float lo, float hi) : linBargraph(lo,hi)
-        {
-            setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
-        }
-
-        virtual QSize sizeHint () const
-        {
-            return QSize(128, 16);
-        }
-};
-
-
-
-
-/**
- * A dB Bargraph with a scale of colors
- */
-class dbBargraph : public dbAbstractDisplay
-{
-    QBrush  fBackColor;
-
-    protected :
-
-        // These two abstract methods are implemented
-        // according to the vertical or horizontal direction
-        // in dbVerticalBargraph and dbHorizontalBargraph
-        virtual void paintMark(QPainter* painter, float v) const = 0;
-        virtual int paintSegment (QPainter* painter, int pos, float v, const QBrush& b) const = 0;
-
-        /**
-         * Draw the logarithmic scale
-         */
-        void paintScale(QPainter* painter) const
-        {
-            painter->fillRect(0,0,width(),height(), fBackColor);
-            painter->save();
-            painter->setPen(QColor(0x6699aa)); //0xffa500));
-            for (float v = -10; v > fMin; v -= 10) paintMark(painter, v);
-            for (float v = -6; v < fMax; v += 3) paintMark(painter, v);
-            painter->restore();
-        }
-
-
-        /**
-         * Draw the content using colored segments
-         */
-        void paintContent (QPainter* painter) const
-        {
-            int   l = fLevel.size();
-
-            float   p = -1;   // fake value indicates to start from border
-            int     n = 0;
-            // paint all the full segments < fValue
-            for (n=0; (n < l) && (fValue > fLevel[n]); n++) {
-                p = paintSegment(painter, p, fLevel[n], fBrush[n]);
-            }
-            // paint the last segment
-            if (n == l) n = n-1;
-            p=paintSegment(painter, p, fValue, fBrush[n]);
-
-            painter->drawRect(0,0,width(),height());
-       }
-
-
-        virtual void paintEvent ( QPaintEvent *)
-        {
-            QPainter painter(this);
-            paintScale(&painter);
-            paintContent(&painter);
-        }
-
-    public:
-
-        dbBargraph(float lo, float hi) : dbAbstractDisplay(lo,hi)
-        {
-
-            QFont f = this->font();
-            f.setPointSize(6);
-            this->setFont(f);
-
-            fBackColor = QBrush(QColor(20,20,20));
-        }
-};
-
-
-/**
- * Vertical dB Bargraph
- */
-class dbVerticalBargraph : public dbBargraph
-{
-    protected:
-        /**
-         * Convert a dB value into a vertical position
-         */
-        float dB2y (float dB) const
-        {
-            float s0 = fScaleMin;
-            float s1 = fScaleMax;
-            float sx = dB2Scale(dB);
-            int    h = height();
-
-            return h - h*(s0-sx)/(s0-s1);
-        }
-
-        /**
-         * Paint a vertical graduation mark
-         */
-        virtual void paintMark(QPainter* painter, float v) const
-        {
-            int n = 10;
-            int y = dB2y(v);
-            QRect r(0,y-n,width()-1,2*n);
-            if (v > 0.0) {
-                painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v).prepend('+'));
-            } else {
-                painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v));
-            }
-        }
-
-        /**
-         * Paint a color segment
-         */
-        virtual int paintSegment (QPainter* painter, int pos, float v, const QBrush& b) const
-        {
-            if (pos == -1) pos = height();
-            float y = dB2y(v);
-            painter->fillRect(0, y, width(), pos-y+1, b);
-            return y;
-        }
-
-
-    public:
-
-        dbVerticalBargraph(float lo, float hi) : dbBargraph(lo,hi)
-        {
-            setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
-            initLevelsColors(1);
-        }
-
-        virtual QSize sizeHint () const
-        {
-            return QSize(18, 256);
-        }
-};
-
-/**
- * Horizontal dB Bargraph
- */
-class dbHorizontalBargraph : public dbBargraph
-{
-
-    protected:
-
-        /**
-         * Convert a dB value into an horizontal position
-         */
-        float dB2x (float dB) const
-        {
-            float s0 = fScaleMin;
-            float s1 = fScaleMax;
-            float sx = dB2Scale(dB);
-            int    w = width();
-
-            return w - w*(s1-sx)/(s1-s0);
-        }
-
-        /**
-         * Paint an horizontal graduation mark
-         */
-        void paintMark(QPainter* painter, float v) const
-        {
-            int n = 10;
-            int x = dB2x(v);
-            QRect r(x-n,0,2*n, height());
-            painter->drawText(r, Qt::AlignHCenter|Qt::AlignVCenter, QString::number(v));
-        }
-
-        /**
-         * Paint a horizontal color segment
-         */
-        int paintSegment (QPainter* painter, int pos, float v, const QBrush& b) const
-        {
-            if (pos == -1) pos = 0;
-            float x = dB2x(v);
-            painter->fillRect(pos, 0, x-pos, height(), b);
-            return x;
-        }
-
-
-    public:
-
-        dbHorizontalBargraph(float lo, float hi) : dbBargraph(lo,hi)
-        {
-            setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
-            initLevelsColors(0);
-        }
-
-        virtual QSize sizeHint () const
-        {
-            return QSize(256, 18);
-        }
-
-};
-
-//
-//===============================END DISPLAYS====================================
-
-//============================= BEGIN GROUP LABEL METADATA===========================
-// Unlike widget's label, metadata inside group's label are not extracted directly by
-// the Faust compiler. Therefore they must be extracted within the architecture file
-//-----------------------------------------------------------------------------------
-//
-
-/**
- * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string
- * (but not those in the middle of the string)
- */
-static string rmWhiteSpaces(const string& s)
-{
-    size_t i = s.find_first_not_of(" \t");
-    size_t j = s.find_last_not_of(" \t");
-  	if ( (i != string::npos) && (j != string::npos) ) {
-		return s.substr(i, 1+j-i);
-	} else {
-		return "";
-	}
-}
-
-/**
- * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata(unit=dB)
- */
-static void extractMetadata(const string& fulllabel, string& label, map<string, string>& metadata)
-{
-    enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
-    int state = kLabel; int deep = 0;
-    string key, value;
-
-    for (unsigned int i=0; i < fulllabel.size(); i++) {
-        char c = fulllabel[i];
-        switch (state) {
-            case kLabel :
-                assert (deep == 0);
-                switch (c) {
-                    case '\\' : state = kEscape1; break;
-                    case '[' : state = kKey; deep++; break;
-                    default : label += c;
-                }
-                break;
-
-            case kEscape1 :
-                label += c;
-                state = kLabel;
-                break;
-
-            case kEscape2 :
-                key += c;
-                state = kKey;
-                break;
-
-            case kEscape3 :
-                value += c;
-                state = kValue;
-                break;
-
-            case kKey :
-                assert (deep > 0);
-                switch (c) {
-                    case '\\' :  state = kEscape2;
-                                break;
-
-                    case '[' :  deep++;
-                                key += c;
-                                break;
-
-                    case ':' :  if (deep == 1) {
-                                    state = kValue;
-                                } else {
-                                    key += c;
-                                }
-                                break;
-                    case ']' :  deep--;
-                                if (deep < 1) {
-                                    metadata[rmWhiteSpaces(key)] = "";
-                                    state = kLabel;
-                                    key="";
-                                    value="";
-                                } else {
-                                    key += c;
-                                }
-                                break;
-                    default :   key += c;
-                }
-                break;
-
-            case kValue :
-                assert (deep > 0);
-                switch (c) {
-                    case '\\' : state = kEscape3;
-                                break;
-
-                    case '[' :  deep++;
-                                value += c;
-                                break;
-
-                    case ']' :  deep--;
-                                if (deep < 1) {
-                                    metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value);
-                                    state = kLabel;
-                                    key="";
-                                    value="";
-                                } else {
-                                    value += c;
-                                }
-                                break;
-                    default :   value += c;
-                }
-                break;
-
-            default :
-                cerr << "ERROR unrecognized state " << state << endl;
-        }
-    }
-    label = rmWhiteSpaces(label);
-}
-//
-//============================= END GROUP LABEL METADATA===========================
-
-
-/******************************************************************************
-*******************************************************************************
-
-							IMPLEMENTATION OF GUI ITEMS
-							   (QT 4.3 for FAUST)
-
-*******************************************************************************
-*******************************************************************************/
-
-
-class uiButton : public QObject, public uiItem
-{
-    Q_OBJECT
-
- public :
-	QAbstractButton* 	fButton;
-
-	uiButton (GUI* ui, float* zone, QAbstractButton* b) : uiItem(ui, zone), fButton(b) {}
-
-
-	virtual void reflectZone()
-	{
-		float v = *fZone;
-		fCache = v;
-		fButton->setDown( v > 0.0 );
-	}
-
- public slots :
-	void pressed()		{ modifyZone(1.0); }
-	void released()		{ modifyZone(0.0); }
-};
-
-
-class uiCheckButton : public QObject, public uiItem
-{
-    Q_OBJECT
-
- public :
-	QCheckBox* 	fCheckBox;
-
-	uiCheckButton (GUI* ui, float* zone, QCheckBox* b) : uiItem(ui, zone), fCheckBox(b) {}
-
-	virtual void reflectZone()
-	{
-		float v = *fZone;
-		fCache = v;
-		fCheckBox->setCheckState( (v < 0.5) ? Qt::Unchecked : Qt::Checked );
-	}
-
- public slots :
-	void setState(int v)		{ modifyZone(float(v>0)); }
-};
-
-
-class uiSlider : public QObject, public uiItem
-{
-    Q_OBJECT
-
-	int		faust2qt(float x) 	{ return int(0.5 + (x-fMin)/fStep); }
-	float	qt2faust (int v)	{ return fMin + v*fStep; }
-	int		optimalTick()		{
-				float x=fStep;
-				while((fMax-fMin)/x > 50) x*=10;
-				while((fMax-fMin)/x < 10) x/=2;
-				return faust2qt(fMin+x);
-			}
-
- public :
-	QSlider* 	fSlider;
-	float		fCur;
-	float		fMin;
-	float		fMax;
-	float		fStep;
-
-	uiSlider (GUI* ui, float* zone, QSlider* slider, float cur, float lo, float hi, float step)
-		: uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step)
-	{
-		fSlider->setMinimum(0);
-		fSlider->setMaximum(faust2qt(fMax));
-		fSlider->setValue(faust2qt(fCur));
-		fSlider->setTickInterval(optimalTick());
-		*fZone = fCur;
-	}
-
-	virtual void reflectZone()
-	{
-		float 	v = *fZone;
-		fCache = v;
-		fSlider->setValue(faust2qt(v));
-	}
-
- public slots :
-	void setValue(int v)		{ modifyZone(qt2faust(v)); }
-};
-
-
-class uiKnob : public QObject, public uiItem
-{
-    Q_OBJECT
-
-	int		faust2qt(float x) 	{ return int(0.5 + (x-fMin)/fStep); }
-	float	qt2faust (int v)	{ return fMin + v*fStep; }
-	int		optimalTick()		{
-				float x=fStep;
-				while((fMax-fMin)/x > 50) x*=10;
-				while((fMax-fMin)/x < 10) x/=2;
-				return faust2qt(fMin+x);
-			}
-
- public :
-	QAbstractSlider* 	fSlider;
-	float				fCur;
-	float				fMin;
-	float				fMax;
-	float				fStep;
-
-	uiKnob (GUI* ui, float* zone, QAbstractSlider* slider, float cur, float lo, float hi, float step)
-		: uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step)
-	{
-		fSlider->setMinimum(0);
-		fSlider->setMaximum(faust2qt(fMax));
-		fSlider->setValue(faust2qt(fCur));
-		//fSlider->setTickInterval(optimalTick());
-		*fZone = fCur;
-	}
-
-	virtual void reflectZone()
-	{
-		float 	v = *fZone;
-		fCache = v;
-		fSlider->setValue(faust2qt(v));
-	}
-
- public slots :
-	void setValue(int v)		{ modifyZone(qt2faust(v)); }
-};
-
-
-class uiBargraph : public QObject, public uiItem
-{
-    Q_OBJECT
-
-    int     faust2qt(float x)   { return int(0.5 + (x-fMin)/(fMax-fMin)*fStep); }
-
- public :
-    QProgressBar*   fBar;
-    float           fMin;
-    float           fMax;
-    int             fStep;
-
-    uiBargraph (GUI* ui, float* zone, QProgressBar* bar, float lo, float hi)
-        : uiItem(ui, zone), fBar(bar), fMin(lo), fMax(hi), fStep(1024)
-    {
-        fBar->setRange(0, fStep);
-        fBar->setValue(0);
-        *fZone = 0;
-    }
-
-    virtual void reflectZone()
-    {
-        float   v = *fZone;
-        fCache = v;
-        int x = faust2qt(v);
-        //std::cout << "update *" << fBar << " = " << x << std::endl;
-        fBar->setValue(x);
-    }
-};
-
-
-class uiBargraph2 : public QObject, public uiItem
-{
-    Q_OBJECT
-
- public :
-    AbstractDisplay*   fBar;
-
-    uiBargraph2 (GUI* ui, float* zone, AbstractDisplay* bar, float lo, float hi)
-        : uiItem(ui, zone), fBar(bar)
-    {
-        fBar->setRange(lo, hi);
-        fBar->setValue(lo);
-        *fZone = lo;
-    }
-
-    virtual void reflectZone()
-    {
-        float   v = *fZone;
-        fCache = v;
-        fBar->setValue(v);
-    }
-};
-
-
-
-class uiNumEntry : public QObject, public uiItem
-{
-    Q_OBJECT
-
- public :
-	QDoubleSpinBox* 	fNumEntry;
-	float				fCur;
-	float				fMin;
-	float				fMax;
-	float				fStep;
-	int					fDecimals;
-
-	uiNumEntry (GUI* ui, float* zone, QDoubleSpinBox* numEntry, float cur, float lo, float hi, float step)
-		: uiItem(ui, zone), fNumEntry(numEntry), fCur(cur), fMin(lo), fMax(hi), fStep(step)
-	{
-		fDecimals = (fStep >= 1.0) ? 0 : int(0.5+log10(1.0/fStep));
-
-		fNumEntry->setMinimum(fMin);
-		fNumEntry->setMaximum(fMax);
-		fNumEntry->setSingleStep(fStep);
-		fNumEntry->setDecimals(fDecimals);
-		fNumEntry->setValue(fCur);
-		*fZone = fCur;
-	}
-
-
-	virtual void reflectZone()
-	{
-		float 	v = *fZone;
-		fCache = v;
-		fNumEntry->setValue(v);
-	}
-
- public slots :
-	void setValue(double v)		{
-		modifyZone(float(v));
-	}
-};
-
-
-
-
-/******************************************************************************
-*******************************************************************************
-
-						IMPLEMENTATION OF THE USER INTERFACE
-							   (QT 4.3 for FAUST)
-
-*******************************************************************************
-*******************************************************************************/
-
-
-class QTGUI : public QObject, public GUI
-{
-    Q_OBJECT
-	QApplication		fAppl;
-	QTimer*				fTimer;
-	QStyle*			 	fStyle;
-	string				gGroupTooltip;
-	stack<QWidget* > 	fGroupStack;
-
-    map<float*, float>           fGuiSize;       // map widget zone with widget size coef
-    map<float*, string>          fTooltip;       // map widget zone with tooltip strings
-    map<float*, string>          fUnit;          // map widget zone to unit string (i.e. "dB")
-    set<float*>                  fKnobSet;       // set of widget zone to be knobs
-    set<float*>                  fLedSet;        // set of widget zone to be LEDs
-
-
-    /**
-    * Format tooltip string by replacing some white spaces by
-	* return characters so that line width doesn't exceed n.
-	* Limitation : long words exceeding n are not cut
-    */
-	virtual string formatTooltip(int n, const string& tt)
-	{
-		string  ss = tt;	// ss string we are going to format
-		int	lws = 0;	// last white space encountered
-		int 	lri = 0;	// last return inserted
-		for (int i=0; i< (int)tt.size(); i++) {
-			if (tt[i] == ' ') lws = i;
-			if (((i-lri) >= n) && (lws > lri)) {
-				// insert return here
-				ss[lws] = '\n';
-				lri = lws;
-			}
-		}
-		return ss;
-	}
-
-
-    /**
-    * Analyses the widget zone metadata declarations and takes
-    * appropriate actions
-    */
-    virtual void declare(float* zone, const char* key, const char* value)
-    {
-		if (zone == 0) {
-			// special zone 0 means group metadata
-			if (strcmp(key,"tooltip")==0) {
-				// only group tooltip are currently implemented
-				gGroupTooltip = formatTooltip(30, value);
-			}
-		} else {
-			if (strcmp(key,"size")==0) {
-				fGuiSize[zone]=atof(value);
-			}
-			else if (strcmp(key,"tooltip")==0) {
-				fTooltip[zone] = formatTooltip(30, value) ;
-			}
-			else if (strcmp(key,"unit")==0) {
-				fUnit[zone] = value ;
-			}
-			else if (strcmp(key,"style")==0) {
-			// else if ((strcmp(key,"style")==0) || (strcmp(key,"type")==0)) {
-				if (strcmp(value,"knob") == 0) {
-					fKnobSet.insert(zone);
-				} else if (strcmp(value,"led") == 0) {
-					fLedSet.insert(zone);
-				}
-			}
-		}
-	}
-
-	bool isTabContext()
-	{
-		return fGroupStack.empty() || ((!fGroupStack.empty()) && (dynamic_cast<QTabWidget*>(fGroupStack.top()) != 0));
-	}
-
-	void insert(const char* label, QWidget* widget)
-	{
-		if (fStyle) widget->setStyle(fStyle);
-		if (!fGroupStack.empty()) {
-			QWidget* mother = fGroupStack.top();
-			QTabWidget*	tab = dynamic_cast<QTabWidget*>(mother);
-			if (tab) {
-				tab->addTab(widget,label);
-			} else {
-				widget->setParent(mother);
-				mother->layout()->addWidget(widget);
-			}
-		}
-	}
-
-    /**
-    * Analyses a full label and activates the relevant options. returns a simplified
-    * label (without options) and an amount of stack adjustement (in case additional
-    * containers were pushed on the stack).
-    */
-
-    int checkLabelOptions(QWidget* widget, const string& fullLabel, string& simplifiedLabel)
-    {
-        map<string, string> metadata;
-        extractMetadata(fullLabel, simplifiedLabel, metadata);
-
-        if (metadata.count("tooltip")) {
-            widget->setToolTip(metadata["tooltip"].c_str());
-        }
-        if (metadata["option"] == "detachable") {
-            //openHandleBox(simplifiedLabel.c_str());
-            return 1;
-        }
-
-        // no adjustement of the stack needed
-        return 0;
-    }
-
-    /**
-    * Check if a tooltip is associated to a zone and add it to the corresponding widget
-    */
-    void checkForTooltip(float* zone, QWidget* widget)
-    {
-        if (fTooltip.count(zone)) {
-            widget->setToolTip(fTooltip[zone].c_str());
-        }
-    }
-
-    /**
-    * Check if a knob is required
-    */
-    bool isKnob(float* zone)
-    {
-        return fKnobSet.count(zone) > 0;
-    }
-
-	void openBox(const char* fulllabel, QLayout* layout)
-	{
-		map<string, string> metadata;
-        string label;
-        extractMetadata(fulllabel, label, metadata);
-  		layout->setMargin(5);
-		QWidget* box;
-
-        if (isTabContext()) {
-			box = new QWidget();
-            // set background color
-            QPalette pal = box->palette();
-            pal.setColor(box->backgroundRole(), QColor::fromRgb(150, 150, 150) );
-            box->setPalette(pal);
-
-		} else  if (label.size()>0) {
-			QGroupBox* group = new QGroupBox();
-			group->setTitle(label.c_str());
-			box = group;
-		} else {
-			// no label here we use simple widget
-			layout->setMargin(0);
-			box = new QWidget();
-		}
-
-        box->setLayout(layout);
-/*        if (metadata.count("tooltip")) {
-            box->setToolTip(metadata["tooltip"].c_str());
-        }*/
-        if (gGroupTooltip != string()) {
-			box->setToolTip(gGroupTooltip.c_str());
-			gGroupTooltip = string();
-		}
-        insert(label.c_str(), box);
-        fGroupStack.push(box);
-    }
-
-	void openTab(const char* label)
-	{
-		QTabWidget* group = new QTabWidget();
-		if (fStyle) group->setStyle(fStyle);
-		insert(label, group);
-		fGroupStack.push(group);
-	}
-
-
-  public slots :
-	void update()		{
-        //std::cout << '.' << std::endl;
-		updateAllZones();
-	}
-
-  public:
-
-	QTGUI(int argc, char* argv[], QStyle* style = 0) : fAppl(argc, argv), fTimer(0), fStyle(style){
-        //fGroupStack.push(new QMainWindow());
-    }
-
-	virtual ~QTGUI() {}
-
-	virtual void run()
-	{
-		if (fTimer == 0) {
-			fTimer = new QTimer(this);
-     		QObject::connect(fTimer, SIGNAL(timeout()), this, SLOT(update()));
-     		fTimer->start(100);
-		}
-#if 1
-        fAppl.setStyleSheet(
-
-// BUTTONS
-                        "QPushButton {"
-                                    "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,"
-                                                                    "stop: 0 #B0B0B0, stop: 1 #404040);"
-                                    "border: 2px solid grey;"
-                                    "border-radius: 6px;"
-                                    "margin-top: 1ex;"
-                                 "}"
-
-                 "QPushButton:hover {"
-                                    "border: 2px solid orange;"
-                                 "}"
-
-                 "QPushButton:pressed {"
-                                    //"border: 1px solid orange;"
-                                    "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
-                                                                        "stop: 0 #404040, stop: 1 #B0B0B0);"
-                                 "}"
-// GROUPS
-                       "QGroupBox {"
-                                    "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,"
-                                                                    "stop: 0 #A0A0A0, stop: 1 #202020);"
-                                    "border: 2px solid gray;"
-                                    "border-radius: 5px;"
-                                    "margin-top: 1ex;"
-                                    "font-size:7pt;"
-                                    "font-weight:bold;"
-                                  //"color: dark grey;"
-                                    "color: white;"
-                                 "}"
-
-                "QGroupBox::title {"
-                                    "subcontrol-origin: margin;"
-                                    "subcontrol-position: top center;" /* position at the top center */
-                                    "padding: 0 5px;"
-                                 "}"
-// SLIDERS
-                    // horizontal sliders
-                    "QSlider::groove:vertical {"
-                        "background: red;"
-                        "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */
-                        "left: 13px; right: 13px;"
-                    "}"
-
-                    "QSlider::handle:vertical {"
-                        "height: 40px;"
-                        "width: 30px;"
-                        "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
-                                                          "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);"
-                        "margin: 0 -5px; /* expand outside the groove */"
-                        "border-radius: 5px;"
-                    "}"
-
-                    "QSlider::add-page:vertical {"
-                        "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
-                                                          "stop: 0 yellow, stop : 0.5 orange);"
-                    "}"
-
-                    "QSlider::sub-page:vertical {"
-                        "background: grey;"
-                    "}"
-
-                    // horizontal sliders
-
-                    "QSlider::groove:horizontal {"
-                        "background: red;"
-                        "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */
-                        "top: 14px; bottom: 14px;"
-                    "}"
-
-                    "QSlider::handle:horizontal {"
-                        "width: 40px;"
-                        "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
-                                                          "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);"
-                        "margin: -5px 0; /* expand outside the groove */"
-                        "border-radius: 5px;"
-                    "}"
-
-                    "QSlider::sub-page:horizontal {"
-                        "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
-                                                          "stop: 0 yellow, stop : 0.5 orange);"
-                    "}"
-
-                    "QSlider::add-page:horizontal {"
-                        "background: grey;"
-                    "}"
-
-// TABS
-                    //TabWidget and TabBar
-                    "QTabWidget::pane {" /* The tab widget frame */
-                        //"border-top: 2px solid #C2C7CB;"
-                        "border-top: 2px solid orange;"
-                        "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
-                                                        "stop: 0 #A0A0A0, stop: 1 #202020);"
-                    "}"
-
-                    "QTabWidget::tab-bar {"
-                        "left: 5px;" /* move to the right by 5px */
-                    "}"
-
-                    /* Style the tab using the tab sub-control. Note that
-                        it reads QTabBar _not_ QTabWidget */
-                    "QTabBar::tab {"
-                        "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
-                                                    "stop: 0 #909090, stop: 0.4 #888888,"
-                                                    "stop: 0.5 #808080, stop: 1.0 #909090);"
-                        "border: 2px solid #808080;"
-                        //"border-bottom-color: #C2C7CB;" /* same as the pane color */
-                        "border-bottom-color: orange;" /* same as the pane color */
-                        "border-top-left-radius: 4px;"
-                        "border-top-right-radius: 4px;"
-                        "min-width: 8ex;"
-                        "padding: 2px;"
-                    "}"
-
-                    "QTabBar::tab:selected, QTabBar::tab:hover {"
-                        "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
-                                                    "stop: 0 #D0D0D0, stop: 0.4 #A0A0A0,"
-                                                    "stop: 0.5 #808080, stop: 1.0 #A0A0A0);"
-                                                    //"stop: 0.5 #A0A0A0, stop: 1.0 #C0C0C0);"
-                                                    //"stop: 0 #fafafa, stop: 0.4 #f4f4f4,"
-                                                    //"stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);"
-                        //"border-bottom-color: orange;" /* same as the pane color */
-                    "}"
-
-                    "QTabBar::tab:selected {"
-                        "border-color: orange;"
-                        "border-bottom-color: #A0A0A0;" /* same as pane color */
-                    "}"
-
-                    "QTabBar::tab:!selected {"
-                    "    margin-top: 2px;" /* make non-selected tabs look smaller */
-                    "}"
-                            );
-#endif
-		fAppl.exec();
-		stop();
-
-	}
-
-
-	// ------------------------- Groups -----------------------------------
-
-	virtual void openHorizontalBox(const char* label) { 
-		openBox(label, new QHBoxLayout());
-	}
-
-	virtual void openVerticalBox(const char* label) 	{
-        openBox(label, new QVBoxLayout());
-    }
-
-    virtual void openFrameBox(const char* ) 		{ }
-	virtual void openTabBox(const char* label) 		{ 
-		openTab(label);
-	}
-
-	virtual void closeBox()
-	{
-		QWidget* group = fGroupStack.top();
-		fGroupStack.pop();
-		if (fGroupStack.empty()) { group->show(); }
-	}
-
-	// ------------------------- active widgets -----------------------------------
-
-	virtual void addButton(const char* label , float* zone)
-	{
-		QAbstractButton* 	w = new QPushButton(label);
-		uiButton* 			c = new uiButton(this, zone, w);
-
-		insert(label, w);
-		QObject::connect(w, SIGNAL(pressed()), c, SLOT(pressed()));
-		QObject::connect(w, SIGNAL(released()), c, SLOT(released()));
-        checkForTooltip(zone, w);
-	}
-
-    virtual void addToggleButton(const char* , float* )
-    {}
-
-	virtual void addCheckButton(const char* label , float* zone)
-	{
-		QCheckBox* 	w = new QCheckBox(label);
-		uiCheckButton* 	c = new uiCheckButton(this, zone, w);
-
-		insert(label, w);
-		QObject::connect(w, SIGNAL(stateChanged(int)), c, SLOT(setState(int)));
-        checkForTooltip(zone, w);
-	}
-
-    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-    {
-        if (isKnob(zone)) {
-            addVerticalKnob(label, zone, init, min, max, step);
-            return;
-        }
-        //insert(label, new QDoubleSpinBox());
-        if (label && label[0]) openVerticalBox(label);
-        QDoubleSpinBox*     w = new QDoubleSpinBox();
-        uiNumEntry*         c = new uiNumEntry(this, zone, w, init, min, max, step);
-        insert(label, w);
-        w->setSuffix(fUnit[zone].c_str());
-        QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double)));
-        if (label && label[0]) closeBox();
-        checkForTooltip(zone, w);
-    }
-
-    // special num entry without buttons
-    virtual void addNumDisplay(const char* label, float* zone, float init, float min, float max, float step)
-    {
-        //insert(label, new QDoubleSpinBox());
-        if (label && label[0]) openVerticalBox(label);
-        QDoubleSpinBox*     w = new QDoubleSpinBox();
-        w->setAlignment(Qt::AlignHCenter);
-#if 1
-        w->setStyleSheet(
-                  "QDoubleSpinBox {"
-                                    "border: 2px solid orange;"
-                                    "border-radius: 5px;"
-                                 "}"
-        );
-#endif
-        uiNumEntry*         c = new uiNumEntry(this, zone, w, init, min, max, step);
-        insert(label, w);
-        w->setButtonSymbols(QAbstractSpinBox::NoButtons);
-        w->setSuffix(fUnit[zone].c_str());
-        QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double)));
-        if (label && label[0]) closeBox();
-        checkForTooltip(zone, w);
-    }
-
-
-	//////////////////////////////////////////////////////////////////////////////////////////////////////////
-	//
-	// KNOBS
-	//
-	//////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-	virtual void addVerticalKnob(const char* label , float* zone, float init, float min, float max, float step)
-	{
-		openVerticalBox(label);
-		QAbstractSlider* 	w = new QDial(); //qsynthKnob();
-		uiKnob*	c = new uiKnob(this, zone, w, init, min, max, step);
-		insert(label, w);
-		w->setStyle(new qsynthDialVokiStyle());
-		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
-		addNumDisplay(0, zone, init, min, max, step);
-
-        // compute the size of the knob+display
-        int width  = int(64*pow(2,fGuiSize[zone]));
-        int height = int(100*pow(2,fGuiSize[zone]));
-        fGroupStack.top()->setMinimumSize(width,height);
-        fGroupStack.top()->setMaximumSize(width,height);
-
-		closeBox();
-        checkForTooltip(zone, w);
-	}
-
-	virtual void addHorizontalKnob(const char* label , float* zone, float init, float min, float max, float step)
-	{
-		openHorizontalBox(label);
-		QAbstractSlider* 	w = new QDial(); //new qsynthKnob();
-		uiKnob*	c = new uiKnob(this, zone, w, init, min, max, step);
-		insert(label, w);
-		w->setStyle(new qsynthDialVokiStyle());
-		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
-		addNumDisplay(0, zone, init, min, max, step);
-		closeBox();
-        checkForTooltip(zone, w);
-	}
-
-	//////////////////////////////////////////////////////////////////////////////////////////////////////////
-	//
-	// SLIDERS
-	//
-	//////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-	virtual void addVerticalSlider(const char* label , float* zone, float init, float min, float max, float step)
-	{
-		if (isKnob(zone)) {
-			addVerticalKnob(label, zone, init, min, max, step);
-			return;
-		}
-		openVerticalBox(label);
-		QSlider* 	w = new QSlider(Qt::Vertical);
-        w->setMinimumHeight(160);
-        w->setMinimumWidth(34);
-		//w->setTickPosition(QSlider::TicksBothSides);
-		uiSlider*	c = new uiSlider(this, zone, w, init, min, max, step);
-		insert(label, w);
-		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
-		addNumDisplay(0, zone, init, min, max, step);
-		closeBox();
-        checkForTooltip(zone, w);
-	}
-
-	virtual void addHorizontalSlider(const char* label , float* zone, float init, float min, float max, float step)
-	{
-		if (isKnob(zone)) {
-			addHorizontalKnob(label, zone, init, min, max, step);
-			return;
-		}
-		openHorizontalBox(label);
-		QSlider* 	w = new QSlider(Qt::Horizontal);
-        w->setMinimumHeight(34);
-        w->setMinimumWidth(160);
-		//w->setTickPosition(QSlider::TicksBothSides);
-		uiSlider*	c = new uiSlider(this, zone, w, init, min, max, step);
-		insert(label, w);
-		QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int)));
-		addNumDisplay(0, zone, init, min, max, step);
-		closeBox();
-        checkForTooltip(zone, w);
-	}
-
-	// ------------------------- passive widgets -----------------------------------
-
-    virtual void addNumDisplay(const char*, float*, int)
-    {}
-
-	virtual void addTextDisplay(const char*, float*, const char* [], float, float)
-    {}
-
-    virtual void addHorizontalBargraph(const char* label , float* zone, float min, float max)
-    {
-        AbstractDisplay*  bargraph;
-        openVerticalBox(label);
-        bool db = (fUnit[zone] == "dB");
-
-        if (fLedSet.count(zone)) {
-            if (db) {
-                bargraph = new dbLED(min, max);
-            } else {
-                bargraph = new LED(min,max);
-            }
-        } else {
-            if (db) {
-                bargraph = new dbHorizontalBargraph(min, max);
-            } else {
-                bargraph = new linHorizontalBargraph(min, max);
-            }
-        }
-
-        new uiBargraph2(this, zone, bargraph, min, max);
-        insert(label, bargraph);
-        closeBox();
-        checkForTooltip(zone, bargraph);
-    }
-
-    virtual void addVerticalBargraph(const char* label , float* zone, float min, float max)
-    {
-        AbstractDisplay*  bargraph;
-        openVerticalBox(label);
-        bool db = (fUnit[zone] == "dB");
-
-        if (fLedSet.count(zone)) {
-            if (db) {
-                bargraph = new dbLED(min, max);
-            } else {
-                bargraph = new LED(min,max);
-            }
-        } else {
-            if (db) {
-                bargraph = new dbVerticalBargraph(min, max);
-            } else {
-                bargraph = new linVerticalBargraph(min, max);
-            }
-        }
-        new uiBargraph2(this, zone, bargraph, min, max);
-        insert(label, bargraph);
-        closeBox();
-        checkForTooltip(zone, bargraph);
-    }
-
-};
-
-#endif
diff --git a/architecture/gui/mocfaustqt.cpp b/architecture/gui/mocfaustqt.cpp
deleted file mode 100644
index c5ee644..0000000
--- a/architecture/gui/mocfaustqt.cpp
+++ /dev/null
@@ -1,490 +0,0 @@
-/****************************************************************************
-** Meta object code from reading C++ file 'faustqt.h'
-**
-** Created: Fri Feb 25 08:07:38 2011
-**      by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
-**
-** WARNING! All changes made in this file will be lost!
-*****************************************************************************/
-
-#include "faustqt.h"
-#if !defined(Q_MOC_OUTPUT_REVISION)
-#error "The header file 'faustqt.h' doesn't include <QObject>."
-#elif Q_MOC_OUTPUT_REVISION != 62
-#error "This file was generated using the moc from 4.7.0. It"
-#error "cannot be used with the include files from this version of Qt."
-#error "(The moc has changed too much.)"
-#endif
-
-QT_BEGIN_MOC_NAMESPACE
-static const uint qt_meta_data_uiButton[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       2,   14, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
- // slots: signature, parameters, type, tag, flags
-      10,    9,    9,    9, 0x0a,
-      20,    9,    9,    9, 0x0a,
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiButton[] = {
-    "uiButton\0\0pressed()\0released()\0"
-};
-
-const QMetaObject uiButton::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiButton,
-      qt_meta_data_uiButton, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiButton::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiButton::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiButton::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiButton))
-        return static_cast<void*>(const_cast< uiButton*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiButton*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    if (_c == QMetaObject::InvokeMetaMethod) {
-        switch (_id) {
-        case 0: pressed(); break;
-        case 1: released(); break;
-        default: ;
-        }
-        _id -= 2;
-    }
-    return _id;
-}
-static const uint qt_meta_data_uiCheckButton[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       1,   14, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
- // slots: signature, parameters, type, tag, flags
-      17,   15,   14,   14, 0x0a,
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiCheckButton[] = {
-    "uiCheckButton\0\0v\0setState(int)\0"
-};
-
-const QMetaObject uiCheckButton::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiCheckButton,
-      qt_meta_data_uiCheckButton, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiCheckButton::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiCheckButton::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiCheckButton::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiCheckButton))
-        return static_cast<void*>(const_cast< uiCheckButton*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiCheckButton*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    if (_c == QMetaObject::InvokeMetaMethod) {
-        switch (_id) {
-        case 0: setState((*reinterpret_cast< int(*)>(_a[1]))); break;
-        default: ;
-        }
-        _id -= 1;
-    }
-    return _id;
-}
-static const uint qt_meta_data_uiSlider[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       1,   14, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
- // slots: signature, parameters, type, tag, flags
-      12,   10,    9,    9, 0x0a,
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiSlider[] = {
-    "uiSlider\0\0v\0setValue(int)\0"
-};
-
-const QMetaObject uiSlider::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiSlider,
-      qt_meta_data_uiSlider, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiSlider::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiSlider::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiSlider::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiSlider))
-        return static_cast<void*>(const_cast< uiSlider*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiSlider*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    if (_c == QMetaObject::InvokeMetaMethod) {
-        switch (_id) {
-        case 0: setValue((*reinterpret_cast< int(*)>(_a[1]))); break;
-        default: ;
-        }
-        _id -= 1;
-    }
-    return _id;
-}
-static const uint qt_meta_data_uiKnob[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       1,   14, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
- // slots: signature, parameters, type, tag, flags
-      10,    8,    7,    7, 0x0a,
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiKnob[] = {
-    "uiKnob\0\0v\0setValue(int)\0"
-};
-
-const QMetaObject uiKnob::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiKnob,
-      qt_meta_data_uiKnob, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiKnob::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiKnob::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiKnob::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiKnob))
-        return static_cast<void*>(const_cast< uiKnob*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiKnob*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiKnob::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    if (_c == QMetaObject::InvokeMetaMethod) {
-        switch (_id) {
-        case 0: setValue((*reinterpret_cast< int(*)>(_a[1]))); break;
-        default: ;
-        }
-        _id -= 1;
-    }
-    return _id;
-}
-static const uint qt_meta_data_uiBargraph[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       0,    0, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiBargraph[] = {
-    "uiBargraph\0"
-};
-
-const QMetaObject uiBargraph::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiBargraph,
-      qt_meta_data_uiBargraph, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiBargraph::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiBargraph::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiBargraph::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiBargraph))
-        return static_cast<void*>(const_cast< uiBargraph*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiBargraph*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiBargraph::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    return _id;
-}
-static const uint qt_meta_data_uiBargraph2[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       0,    0, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiBargraph2[] = {
-    "uiBargraph2\0"
-};
-
-const QMetaObject uiBargraph2::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiBargraph2,
-      qt_meta_data_uiBargraph2, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiBargraph2::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiBargraph2::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiBargraph2::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiBargraph2))
-        return static_cast<void*>(const_cast< uiBargraph2*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiBargraph2*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiBargraph2::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    return _id;
-}
-static const uint qt_meta_data_uiNumEntry[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       1,   14, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
- // slots: signature, parameters, type, tag, flags
-      14,   12,   11,   11, 0x0a,
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_uiNumEntry[] = {
-    "uiNumEntry\0\0v\0setValue(double)\0"
-};
-
-const QMetaObject uiNumEntry::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_uiNumEntry,
-      qt_meta_data_uiNumEntry, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &uiNumEntry::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *uiNumEntry::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *uiNumEntry::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_uiNumEntry))
-        return static_cast<void*>(const_cast< uiNumEntry*>(this));
-    if (!strcmp(_clname, "uiItem"))
-        return static_cast< uiItem*>(const_cast< uiNumEntry*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int uiNumEntry::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    if (_c == QMetaObject::InvokeMetaMethod) {
-        switch (_id) {
-        case 0: setValue((*reinterpret_cast< double(*)>(_a[1]))); break;
-        default: ;
-        }
-        _id -= 1;
-    }
-    return _id;
-}
-static const uint qt_meta_data_QTGUI[] = {
-
- // content:
-       5,       // revision
-       0,       // classname
-       0,    0, // classinfo
-       1,   14, // methods
-       0,    0, // properties
-       0,    0, // enums/sets
-       0,    0, // constructors
-       0,       // flags
-       0,       // signalCount
-
- // slots: signature, parameters, type, tag, flags
-       7,    6,    6,    6, 0x0a,
-
-       0        // eod
-};
-
-static const char qt_meta_stringdata_QTGUI[] = {
-    "QTGUI\0\0update()\0"
-};
-
-const QMetaObject QTGUI::staticMetaObject = {
-    { &QObject::staticMetaObject, qt_meta_stringdata_QTGUI,
-      qt_meta_data_QTGUI, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &QTGUI::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *QTGUI::metaObject() const
-{
-    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *QTGUI::qt_metacast(const char *_clname)
-{
-    if (!_clname) return 0;
-    if (!strcmp(_clname, qt_meta_stringdata_QTGUI))
-        return static_cast<void*>(const_cast< QTGUI*>(this));
-    if (!strcmp(_clname, "UI"))
-        return static_cast< UI*>(const_cast< QTGUI*>(this));
-    return QObject::qt_metacast(_clname);
-}
-
-int QTGUI::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
-    _id = QObject::qt_metacall(_c, _id, _a);
-    if (_id < 0)
-        return _id;
-    if (_c == QMetaObject::InvokeMetaMethod) {
-        switch (_id) {
-        case 0: update(); break;
-        default: ;
-        }
-        _id -= 1;
-    }
-    return _id;
-}
-QT_END_MOC_NAMESPACE
diff --git a/architecture/hoa.lib b/architecture/hoa.lib
new file mode 100644
index 0000000..fe144ee
--- /dev/null
+++ b/architecture/hoa.lib
@@ -0,0 +1,207 @@
+declare name "HOA";
+declare title "High Order Ambisonics library";
+
+declare author "Pierre Guillot";
+declare author "Eliott Paris";
+declare author "Julien Colafrancesco";
+
+declare copyright "2012-2013 Guillot, Paris, Colafrancesco, CICM labex art H2H, U. Paris 8";
+
+
+import("math.lib");
+
+//----------------------------------------------------------------------------//
+//------------------------------ HOA functions -------------------------------//
+//----------------------------------------------------------------------------//
+
+// encoder : encodes a signal in the circular harmonics domain depending on an order of decomposition and an angle.
+
+// decoder : decodes an ambisonics sound field for a circular array of loudspeakers. 
+
+// decoderStereo : decodes an ambisonic sound field for stereophonic configuration. 
+
+// optimBasic, optimMaxRe, optimInPhase : weights the circular harmonics signals depending to the ambisonics optimization. It can be "basic" for no optimization, "maxRe" or "inPhase".
+
+// wider : can be used to wide the diffusion of a localized sound. The order depending signals are weighted and appear in a logarithmic way to have linear changes.
+
+// map : encodes a source with distance compensation.
+
+// rotate : applies a rotation of the sound field.
+
+
+//----------------------------------------------------------------------------//
+//------------------------ Ambisonic encoder ---------------------------------//
+//----------------------------------------------------------------------------//
+
+encoder(0, x, a) = x;
+encoder(n, x, a) = encoder(n-1, x, a), x*sin(n*a), x*cos(n*a);
+
+// Usage : n is the order, x is the signal and a the angle in radiant
+// Exemple : encoder(3, signal, angle)
+
+
+
+//----------------------------------------------------------------------------//
+//------------------------ Ambisonic decoder ---------------------------------//
+//----------------------------------------------------------------------------//
+
+decoder(n, p)	= par(i, 2*n+1, _) <: par(i, p, speaker(n, 2*PI*i/p))
+with 
+{
+   speaker(n,a)	= /(2), par(i, 2*n, _), encoder(n,2/(2*n+1),a) : dot(2*n+1);
+};
+
+// Usage : n is the order and p the number of loudspeakers
+// Exemple : decoder(3,8)
+// Informations :  Number of loudspeakers must be greater or equal to 2n+1. It's souhaitable to use 2n+2 loudspeakers.
+
+
+//----------------------------------------------------------------------------//
+//------------------------ Ambisonic decoder stereo --------------------------//
+//----------------------------------------------------------------------------//
+
+decoderStereo(n) = decoder(n, p) <: (par(i, 2*n+2, gainLeft(360 * i / p)) :> _), (par(i, 2*n+2, gainRight(360 * i / p)) :> _)
+with 
+{
+	p = 2*n+2;
+	
+   	gainLeft(a) =  _ * sin(ratio_minus + ratio_cortex)
+	with 
+	{
+		ratio_minus = PI*.5 * abs( (30 + a) / 60 * ((a <= 30)) + (a - 330) / 60 * (a >= 330) );
+		ratio_cortex= PI*.5 * abs( (120 + a) / 150 * (a > 30) * (a <= 180));
+	};
+
+	gainRight(a) =  _ * sin(ratio_minus + ratio_cortex)
+	with 
+	{
+		ratio_minus = PI*.5 * abs( (390 - a) / 60 * (a >= 330) + (30 - a) / 60 * (a <= 30) );
+		ratio_cortex= PI*.5 * abs( (180 - a) / 150 * (a < 330) * (a >= 180));
+	};
+};
+
+// Usage : n is the order
+// Exemple : decoderStereo(3,8)
+// Informations : An "home made" ambisonic decoder for stereophonic restitution (30° - 330°) : Sound field lose energy around 180°. You should use inPhase optimization with ponctual sources.
+
+
+//----------------------------------------------------------------------------//
+//------------------------ Ambisonic decoder quadri --------------------------//
+//----------------------------------------------------------------------------//
+
+
+
+//----------------------------------------------------------------------------//
+//-------------------------- Ambisonic Optim ---------------------------------//
+//----------------------------------------------------------------------------//
+
+//--------------------------------Basic---------------------------------------//
+
+optimBasic(n)	= par(i, 2*n+1, _);
+
+// Usage : n is the order
+// Exemple : optimBasic(3)
+// Informations : The basic optimization has no effect and should be used for a perfect circle of loudspeakers with one listener at the perfect center loudspeakers array.
+
+//--------------------------------maxRe---------------------------------------//
+
+optimMaxRe(n)	= par(i, 2*n+1, optim(i, n, _))
+ with {
+   	optim(i, n, _)= _ * cos(indexabs  / (2*n+1) * PI)
+	with {
+		numberOfharmonics = 2 *n + 1;
+		indexabs = (int)((i - 1) / 2 + 1);
+	};
+ };
+
+// Usage : n is the order
+// Exemple : optimMaxRe(3)
+// Informations : The maxRe optimization optimize energy vector. It should be used for an auditory confined in the center of the loudspeakers array.
+
+//-------------------------------inPhase--------------------------------------//
+
+optimInPhase(n)	= par(i, 2*n+1, optim(i, n, _))
+with 
+{
+   	optim(i, n, _)= _ * (fact(n)^2.) / (fact(n+indexabs) * fact(n-indexabs))
+	with 
+	{
+		indexabs = (int)((i - 1) / 2 + 1);
+		fact(0) = 1;
+		fact(n) = n * fact(n-1);
+	};
+ };
+
+// Usage : n is the order
+// Exemple : optimInPhase(3)
+// Informations : The inPhase Optimization optimize energy vector and put all loudspeakers signals in phase. It should be used for an auditory
+
+
+
+//----------------------------------------------------------------------------//
+//-------------------------- Ambisonic wider ---------------------------------//
+//----------------------------------------------------------------------------//
+
+wider(n, w)	= par(i, 2*n+1, perform(n, w, i, _))
+with 
+{	
+	perform(n, w, i, _) = _ * (log(n+1) * (1 - w) + 1) * clipweight
+	with
+	{
+		clipweight = weighter(n, w, i) * (weighter(n, w, i) > 0) * (weighter(n, w, i) <= 1) + (weighter(n, w, i) > 1)
+		with
+		{
+			weighter(n, w, 0) = 1.;
+			weighter(n, w, i) = (((w * log(n+1)) - log(indexabs)) / (log(indexabs+1) - log(indexabs)))
+			with 
+				{
+					indexabs = (int)((i - 1) / 2 + 1);
+				};
+		};
+	};
+};
+
+// Usage : n is the order and w the widen value between 0 - 1
+// Exemple : wider(3, w)
+// Informations : It can be used to wide the diffusion of a localized sound. The order depending signals are weighted to simulate fractional order. When w = 0, there's only the harmonic 0 and the sound is omnidirectional when w = 1, the processing have no effect and the sound field have the highest spatial resolution. From 0 to 1, harmonics appear in a logarithmic way to have linear changes. Wider is used to simulate sources inside the loudspeakers array.
+
+
+
+//----------------------------------------------------------------------------//
+//---------------------------- Ambisonic map ---------------------------------//
+//----------------------------------------------------------------------------//
+
+map(n, x, r, a)	= encoder(n, x * volume(r), a) : wider(n, ouverture(r))
+with
+{
+	volume(r) = 1. / (r * r * (r > 1) + (r < 1));
+	ouverture(r) = r * (r < 1) + (r > 1);
+};
+
+// Usage : n is the order, x the signal, r the radius and a the angle in radiant
+// Exemple : map(3, signal, radius, angle)
+// Informations : It simulate the distance of the source by applying a gain on the signal and a wider processing on the soundfield.
+
+
+
+//----------------------------------------------------------------------------//
+//-------------------------- Ambisonic rotate --------------------------------//
+//----------------------------------------------------------------------------//
+
+rotate(n, a) = par(i, 2*n+1, _) <: par(i, 2*n+1, rotation(i, a))
+with
+{
+	rotation(i, a) = (par(j, 2*n+1, gain1(i, j, a)), par(j, 2*n+1, gain2(i, j, a)), par(j, 2*n+1, gain3(i, j, a)) :> _)
+	with
+	{	
+		indexabs = (int)((i - 1) / 2 + 1);
+		gain1(i, j, a) = _ * cos(a * indexabs) * (j == i);
+		gain2(i, j, a) = _ * sin(a * indexabs) * (j-1 == i) * (j != 0) * (i%2 == 1);
+		gain3(i, j, a) = (_ * sin(a * indexabs)) * (j+1 == i) * (j != 0) * (i%2 == 0);
+	};
+};
+
+
+// Usage : n is the order, a the angle in radiant
+// Exemple : rotate(3, angle)
+// Informations : It rotates the sound field.
\ No newline at end of file
diff --git a/architecture/httpdlib/changelog.txt b/architecture/httpdlib/changelog.txt
new file mode 100644
index 0000000..0eaa2b0
--- /dev/null
+++ b/architecture/httpdlib/changelog.txt
@@ -0,0 +1,24 @@
+====================================================
+FAUST HTTPD Library
+----------------------------------------------------
+GRAME - Centre national de creation musicale
+http://www.grame.fr
+research at grame.fr
+====================================================
+Copyright GRAME (c) 2011-2012
+
+----------------------------------------------------
+Version 0.71
+- JSON description available from /JSON instead of '/?JSON=' 
+
+----------------------------------------------------
+Version 0.70
+- new JSON format  
+
+----------------------------------------------------
+Version 0.61
+- FAUSTFLOAT support  
+
+----------------------------------------------------
+Version 0.50                              [Feb 2012]
+- first release 
diff --git a/architecture/httpdlib/cmake/CMakeLists.txt b/architecture/httpdlib/cmake/CMakeLists.txt
new file mode 100644
index 0000000..514a1ea
--- /dev/null
+++ b/architecture/httpdlib/cmake/CMakeLists.txt
@@ -0,0 +1,95 @@
+cmake_minimum_required(VERSION 2.6)
+project(HTTPDFaust)
+
+#######################################
+# cmake build types configuration
+set (CMAKE_CONFIGURATION_TYPES Debug Release)
+
+set (TARGET	HTTPDFaust)
+#######################################
+# versions management
+set (version 0.71)
+
+#######################################
+if(WIN32)
+	add_definitions(-DWINVER=0x0400 -DWIN32)
+  if(MSVC)
+	add_definitions(-DMSVC)
+  endif(MSVC)
+else(WIN32)
+	add_definitions(-Wall)
+endif(WIN32)
+
+if(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
+	if (${CMAKE_SYSTEM_VERSION} VERSION_LESS 9.0.0)
+		set (CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.4u.sdk)
+	elseif (${CMAKE_SYSTEM_VERSION} VERSION_LESS 10.8.0)
+		set (CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
+	else ()
+		set (CMAKE_OSX_SYSROOT "macosx10.7")
+	endif (${CMAKE_SYSTEM_VERSION} VERSION_LESS 9.0.0)
+
+	set (CMAKE_OSX_ARCHITECTURES "x86_64")
+	set (CMAKE_C++_FLAGS -mmacosx-version-min=10.4)
+endif(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
+
+#######################################
+# set directories, src and headers.
+set (ROOT 			${CMAKE_CURRENT_SOURCE_DIR}/../src)
+set (LIBDIR 		${CMAKE_CURRENT_SOURCE_DIR}/../..)
+set (SRCFOLDERS 	lib include msg httpd nodes json html)
+
+set(SRC ${SRC} "${ROOT}/*.cpp")						# add source files
+foreach(folder ${SRCFOLDERS})
+	set(SRC ${SRC} "${ROOT}/${folder}/*.cpp")		# add source files
+endforeach(folder)
+if (WIN32)
+	set(SRC ${SRC} "${ROOT}/threads/win*.cpp")		# add threads src per platform
+else (WIN32)
+	set(SRC ${SRC} "${ROOT}/threads/pthread*.cpp")	# add threads src per platform
+endif (WIN32)
+
+file (GLOB SRCFILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${SRC})
+
+foreach(folder ${SRCFOLDERS})
+	set(HEADERS ${HEADERS} "${ROOT}/${folder}/*.h")		# add header files
+endforeach(folder)
+set(HEADERS ${HEADERS} "${ROOT}/threads/*.h")		# add header files
+file (GLOB HEADERFILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${HEADERS})
+
+foreach(folder ${SRCFOLDERS})
+	set(INCL ${INCL} "${ROOT}/${folder}")			# add include folders
+endforeach(folder)
+set(INCL ${INCL} "${LIBDIR}" "${ROOT}/threads" "/usr/local/include")	# add other include folders
+
+#######################################
+# set targets
+include_directories (${INCL} )
+
+#######################################
+# target lib settings
+if (STATIC STREQUAL "yes")
+	message (STATUS "Generates a static library - Use -DSTATIC=no to change.")
+	set (lib "STATIC")
+else ()
+	message (STATUS "Generates a dynamic library - Use -DSTATIC=yes to change.")
+	set (lib "SHARED")
+endif ()
+
+add_library ( ${TARGET} ${lib} ${SRCFILES} ${HEADERFILES} )
+set_source_files_properties (${HEADERFILES} PROPERTIES HEADER_FILE_ONLY TRUE)
+set_target_properties (${TARGET} PROPERTIES 
+	VERSION ${version} 
+	ARCHIVE_OUTPUT_DIRECTORY "${ROOT}/.."
+	ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${ROOT}/.."
+)
+
+if(WIN32)
+  target_link_libraries ( ${TARGET} ws2_32.lib microhttpd.lib)
+ set (OUTLIB "${TARGET}.lib")
+else()
+  set_target_properties ( ${TARGET} PROPERTIES LINK_FLAGS -L/usr/local/lib )
+  target_link_libraries ( ${TARGET} microhttpd )
+ set (OUTLIB "lib${TARGET}.a")
+endif()
+
diff --git a/architecture/osclib/faust/Doxyfile b/architecture/httpdlib/doc/Doxyfile
similarity index 100%
copy from architecture/osclib/faust/Doxyfile
copy to architecture/httpdlib/doc/Doxyfile
diff --git a/architecture/httpdlib/doc/jsonfaust.txt b/architecture/httpdlib/doc/jsonfaust.txt
new file mode 100644
index 0000000..4abf476
--- /dev/null
+++ b/architecture/httpdlib/doc/jsonfaust.txt
@@ -0,0 +1,64 @@
+FAUST JSON specs.
+
+<json> = { 	
+			"name"		: "karplus"
+			"address"	: "localhost"
+			"port" 		: 5510,
+//			"inputs" 	: 2,							still pending
+//			"outputs" 	: 2,							still pending
+//			"meta" 		: [{"clef":"valeur"}, ...],		still pending
+			"ui" 		: <ui>
+}
+
+<ui> = <group> | <slider> | <nentry> | <button> | <bargraph>
+
+<group> = { "type" : "(vht)group",
+			"label": "excitation",
+			"items": [<ui>...]
+		  }
+		  
+<slider>= {
+			"type": "(vh)slider",
+			"label": "excitation",
+			"address": "/karplus/excitator/excitation",
+			"meta": [{"clef" : "valeur"}, ...],
+			"init": "128",
+			"min": "2",
+			"max": "512",
+			"step": "1"
+		  }
+		  
+<nentry>= {
+			"type": "nentry",
+			"label": "excitation",
+			"address": "/karplus/excitator/excitation",
+			"meta": [{"clef" : "valeur"}, ...],
+			"init": "128",
+			"min": "2",
+			"max": "512",
+			"step": "1"
+		  }
+		  
+<button>= {
+			"type": "button",
+			"label": "excitation",
+			"address": "/karplus/excitator/excitation"
+			"meta": [{"clef" : "valeur"}, ...],
+		  }
+		  
+<checkbox>= {
+			"type": "checkbox",
+			"label": "excitation",
+			"address": "/karplus/excitator/excitation"
+			"meta": [{"clef" : "valeur"}, ...],
+		  }
+		  
+<bargraph>= {
+			"type" : "(vh)bargraph",
+			"label": "excitation",
+			"address": "/karplus/excitator/excitation",
+			"meta": [{"clef" : "valeur"}, ...],
+			"min" : "2",
+			"max" : "512",
+		  }
+
diff --git a/architecture/httpdlib/html/css/style1.css b/architecture/httpdlib/html/css/style1.css
new file mode 100644
index 0000000..9f35dbf
--- /dev/null
+++ b/architecture/httpdlib/html/css/style1.css
@@ -0,0 +1,37 @@
+
+body { 
+	background-color:lightgray;
+	font-family :  Helvetica; 
+	font-size : 10pt; 
+	margin: 1cm 1cm 1cm 1cm;
+}
+.name { 
+	font-family :  Helvetica; 
+	font-size : 12pt; 
+	font-weight: bold;
+}
+.host { 
+	font-family :  Helvetica; 
+	font-size : 10pt; 
+}
+.label { 
+	font-family :  Helvetica; 
+	font-size : 10pt; 
+	font-weight: bold;
+}
+.url {  
+	font-family :  Courier; 
+	text-align :  center; 
+	font-size : 9pt; 
+	color: rgb(80,80,80);
+}
+.port  {
+	font-family :  Courier; 
+	font-size : 9pt; 
+	color: rgb(80,80,80);
+}
+.group  {
+	font-family :  Helvetica; 
+	font-size : 10pt; 
+	color: rgb(80,80,80);
+}
diff --git a/architecture/httpdlib/html/css/style2.css b/architecture/httpdlib/html/css/style2.css
new file mode 100644
index 0000000..551a20c
--- /dev/null
+++ b/architecture/httpdlib/html/css/style2.css
@@ -0,0 +1,70 @@
+
+body { 
+	background-color: rgb(0,0,0);
+	font-family :  Helvetica; 
+	font-size : 10pt; 
+	color: lightgrey;
+	margin: 1cm 1cm 1cm 1cm;
+}
+hr {
+	background-color: rgb(40,40,100);
+	color: rgb(40,40,100);
+	height: 2px;
+	border: 0;
+}
+.sep hr {
+	background-color: rgb(100,100,100);
+	color: rgb(200,100,100);
+	height: 2px;
+	border: 0;
+}
+td {
+	border-width: 5px;
+}
+.ui {
+	background-color: rgb(40,40,40);
+	padding: 0.8cm 0.8cm 0.8cm 0.8cm;
+	border-spacing: 5px;
+}
+.host { 
+	font-family :  Arial; 
+	font-size : 11pt; 
+	color: rgb(200,200,200);
+}
+.name { 
+	font-family :  Arial; 
+	font-size : 14pt; 
+	font-weight: bold;
+	color: Blue;
+}
+.url {  
+	font-family :  Courier; 
+	text-align :  center; 
+	font-size : 9pt; 
+	text-align :  right; 
+	color: Aquamarine ;
+}
+.port  {
+	font-family :  Courier; 
+	font-size : 9pt; 
+	color: Aquamarine ;
+}
+.label { 
+	font-family :  Arial; 
+	font-size : 11pt; 
+	text-align: right;
+	color: Orange;
+}
+.control { 
+	background-color: rgb(50,50,50);
+	text-align: center;
+	padding-left: 10px;
+	padding-right: 10px;
+}
+.value { 
+}
+.group  {
+	font-family :  Arial; 
+	font-size : 11pt; 
+	color: AliceBlue;
+}
diff --git a/architecture/httpdlib/html/faust.html b/architecture/httpdlib/html/faust.html
new file mode 100644
index 0000000..e4e885c
--- /dev/null
+++ b/architecture/httpdlib/html/faust.html
@@ -0,0 +1,65 @@
+<html>
+<head>
+	<link id="css" rel="stylesheet" type="text/css" href="css/style1.css" />
+	<script src="js/jdesc.js" language="javascript"></script>
+	<script src="js/faustui.js" language="javascript"></script>
+	<script src="js/faustuihtml.js" language="javascript"></script>
+	<script src="js/jquery-1.7.1.min.js" language="javascript"></script>
+	<title id=titre>Faust Program UI</title>
+</head>
+
+<body onload=checkmode()>
+
+<br/>
+
+<script>
+	var builder = buildui;		// function to build the user interface
+								// can be based on textual html (default)
+								// or on javascript objects (?mode=js)
+								// depending on an optional 'mode' argument of the url
+	function setStyle(num) {
+		$("#css").attr("href","css/style"+num+".css");
+	}
+	function getjson() {
+		var url = "http://" + $("#host").val() + ":" + $("#port").val();
+		var nav = navigator.appVersion.search("Chrome");
+		if (nav < 0) {  // not using chrome
+			$.get( url+"/?JSON=", function(data) { $("#ui").html (builder( data )); } );
+		}
+		else
+			$("#ui").html (builder (getDesc()));
+	}
+	function checkmode() {
+		var mode = document.URL.search("mode=js");
+		if (mode < 0)	// use html based page generation
+			builder = buildhtmlui;
+		else
+			builder = buildui;
+	}
+</script>
+
+<center>
+<div id="trace"></div>
+<div id="style">
+Style: 
+<input type="radio" id="style1" name="style" value=1 checked onclick= setStyle(this.value) >
+<input type="radio" id="style2" name="style" value=2 onclick= setStyle(this.value) >
+</div>
+
+<br/>
+<form>
+<table>
+<tr><td class="host">Host:</td><td> <input type="text" id="host" size=40 value="localhost" /></td></tr>
+<tr><td class="host">Port:</td><td> <input type="text" id="port" size=5 value="5510" /></td></tr>
+<tr><td></td><td><button type="button" onclick="getjson()">Get UI</button></td></tr>
+</table>
+</form>
+</center>
+
+<br/>
+<center>
+<div id="ui"></div>
+</center>
+
+</body>
+</html>
diff --git a/architecture/httpdlib/html/js/faust.js b/architecture/httpdlib/html/js/faust.js
new file mode 100644
index 0000000..6951ce3
--- /dev/null
+++ b/architecture/httpdlib/html/js/faust.js
@@ -0,0 +1,39 @@
+
+//-----------------------------------------------------------------------------
+// handlers to send a faust 'set' message
+// actually using a 'GET' method
+//-----------------------------------------------------------------------------
+function fausthandler(dest, value) {
+	if (0) {
+		var msg = "$.get( " + dest +"?value=" + value + ");";
+		$("#trace").html(msg);
+	}
+	else $.get(dest +"?value=" + value);
+}
+
+function sliderhandler(dest, value, id) {
+	fausthandler (dest, value);
+	$(id).val(Math.round(value*10000)/10000);
+}
+
+//-----------------------------------------------------------------------------
+// poll current values from the server
+//-----------------------------------------------------------------------------
+function dispatch (data) {
+	var lines = data.toString().split('\n');
+	var limit = lines.length;
+	for (i=0; i < limit; i++) {
+		var values = lines[i].toString().split(' ');
+		if (values.length > 1) {
+			var address = values[0];
+			var value = Math.round(values[1]*10000)/10000;
+			$('[name="'+address+'"]').val(value);
+		}
+	}
+}
+
+function update (root) {
+	$.get( root, function(data) { dispatch( data ); } );
+	setTimeout ( function () { update(root); }, 200);
+}
+$(document).ready(function() { update ($('#root').val()); });
diff --git a/architecture/httpdlib/html/js/faust_webaudio_tools.js b/architecture/httpdlib/html/js/faust_webaudio_tools.js
new file mode 100644
index 0000000..0dfcbfd
--- /dev/null
+++ b/architecture/httpdlib/html/js/faust_webaudio_tools.js
@@ -0,0 +1,124 @@
+
+var context;
+var source;
+var faustdsp;
+var code = "";
+var ui;
+
+function loadSample(url) 
+{
+    // Load asynchronously
+    var request = new XMLHttpRequest();
+    request.open("GET", url, true);
+    request.responseType = "arraybuffer";
+
+    request.onload = function() { 
+        source.buffer = context.createBuffer(request.response, false);
+        source.loop = true;
+        source.noteOn(0);
+    }
+
+    request.send();
+}
+
+function loadDSP(url) 
+{
+    var request = new XMLHttpRequest();
+    request.onreadystatechange = function() {
+        if (request.readyState == 4) { 
+            code = request.responseText; 
+            buildFaustNodeSVG(code);
+        }
+    }
+    request.open("GET", url, true);
+    request.send(null);
+}
+
+function buildFaustNode(code)
+{
+    // Remove old connections
+    if (faustdsp) {
+        if (source) {
+            source.disconnect(faustdsp);
+        }
+        faustdsp.disconnect(context.destination);
+    }
+    
+    // Clear UI
+    ui.clear();
+    
+    faustdsp = context.createFaustNode(code);
+    var controls = faustdsp.numberOfAudioParams();
+   
+    console.log("numberOfAudioParams = %d", controls);    
+    console.log("numberOfInputs = %d", faustdsp.numberOfInputs);
+    console.log("numberOfOutputs = %d", faustdsp.numberOfOutputs);
+    console.log("JSON "+ faustdsp.json);
+    
+    // Build simple UI
+    for (var i = 0; i < controls; i++) {
+        var ctrl = faustdsp.getAudioParam(i);
+        console.log("getAudioParam : name = %s, min = %d, max = %d, default = %d", ctrl.name, ctrl.minValue, ctrl.maxValue, ctrl.defaultValue);
+        ui.addHorizontalSlider(ctrl.name, function handler(obj) { function setval(val) { obj.value = val; } return setval; }(ctrl), ctrl.defaultValue, ctrl.minValue, ctrl.maxValue, Math.abs(ctrl.maxValue - ctrl.minValue)/100);
+    }
+  
+    // Connection to output
+    faustdsp.connect(context.destination);
+}
+
+function buildFaustNodeSVG(code)
+{
+    // Remove old connections
+    if (faustdsp) {
+        if (source) {
+            source.disconnect(faustdsp);
+        }
+        faustdsp.disconnect(context.destination);
+    }
+    
+    // Clear UI
+    //ui.clear();
+    
+    faustdsp = context.createFaustNode(code);
+    var controls = faustdsp.numberOfAudioParams();
+   
+    console.log("numberOfAudioParams = %d", controls);    
+    console.log("numberOfInputs = %d", faustdsp.numberOfInputs);
+    console.log("numberOfOutputs = %d", faustdsp.numberOfOutputs);
+    console.log("JSON "+ faustdsp.json);
+  
+    // Connection to output
+    faustdsp.connect(context.destination);
+}
+
+function initAudio(url) 
+{
+    context = new webkitAudioContext();
+    ui = new JUI(document.getElementById("FaustUI"));
+    loadDSP(url);
+}
+
+function initDefaultAudio() 
+{
+    context = new webkitAudioContext();
+    ui = new JUI(document.getElementById("FaustUI"));
+}
+
+function playsound()
+{
+    var url = $("#sound").val();
+    if (source) {
+        source.noteOff(0);
+        source.disconnect(0);
+        source = null;
+    }
+    source = context.createBufferSource();
+    loadSample(url);
+    source.connect(faustdsp);
+}
+
+function stopsound()
+{
+    source.noteOff(0);
+    source.disconnect(0);
+}
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/faustui.js b/architecture/httpdlib/html/js/faustui.js
new file mode 100644
index 0000000..5cc7aa3
--- /dev/null
+++ b/architecture/httpdlib/html/js/faustui.js
@@ -0,0 +1,152 @@
+
+//-----------------------------------------------------------------------------
+// a function to build a slider
+// a faust slider is a composite object that embeds a label, a 'range' input
+// and a 'text' input displaying the slider value
+// slider and text value are linked together to reflect the same value.
+//-----------------------------------------------------------------------------
+function makeslider(id, orientation, min, max, value, step, sethandler, dest) {
+	var slider = document.createElement('input');
+	slider.id		= id;
+	slider.type		= "range";
+	slider.min		= min;
+	slider.max		= max;
+	slider.value 	= value;
+	slider.step 	= step;
+
+	var valId="v"+id;
+	var textval = document.createElement('input');
+	textval.id		= valId;
+	textval.type	= "text";
+	textval.value 	= value;
+	textval.size	= 6;
+
+	textval.onchange = function(){ $( "#"+id ).val( this.value ); sethandler(dest, this.value); };
+	slider.onchange  = function(){ $( "#"+valId ).val( this.value ); sethandler(dest, this.value); };
+	slider.fTextValue = textval;
+	return slider;
+}
+
+//-----------------------------------------------------------------------------
+// a push button
+//-----------------------------------------------------------------------------
+function makebutton(label, id, sethandler, dest) {
+	var button = document.createElement('button');
+	button.id		= id;
+	button.type		= "button";
+	button.innerHTML= label;
+	button.value	= 1;
+	button.onmousedown = function(){ sethandler(dest, 1); };
+	button.onmouseup = function(){ sethandler(dest, 0); };
+	return button;
+}
+
+//-----------------------------------------------------------------------------
+// a check box
+//-----------------------------------------------------------------------------
+function makecheckbox(id, sethandler, dest) {
+	var cbox = document.createElement('input');
+	cbox.id		= id;
+	cbox.type	= "checkbox";
+	cbox.value	= 0;
+	cbox.onchange = function(){ this.value = (this.value==1) ? 0 : 1; sethandler(dest, this.value); };
+	return cbox;
+}
+
+//-----------------------------------------------------------------------------
+// a handler to send a faust 'set' message
+// actually using a 'GET' method
+//-----------------------------------------------------------------------------
+function makesethandler() {
+	return function( dest, val) {
+		var msg = dest+"?value="+val;
+		if (0) $("#trace").html(msg);
+		else $.get( dest+"?value="+val );
+	};
+}
+
+function makeCol (elt, classname) {
+	var col = document.createElement('td');
+	if (typeof elt == 'object') {
+		col.appendChild (elt);
+		elt.className = classname;
+	}
+	else col.innerHTML = elt;
+	if (typeof classname != 'undefined') 
+		col.className = classname;
+	return col;
+}
+
+function makehr (span) {
+	var row = document.createElement('tr');
+	var col = document.createElement('td');
+	col.appendChild (document.createElement('hr'));
+	row.appendChild (col);
+	col.colSpan = span;
+	return row;
+}
+
+//-----------------------------------------------------------------------------
+// build a single UI element 
+// the element is returned in a row
+//-----------------------------------------------------------------------------
+function makeControl (elt, i, address, dest) {
+	var row 	= document.createElement('tr');
+	if (elt.type == 'button') {
+		row.appendChild ( document.createElement('td'));
+		row.appendChild ( makebutton(elt.label, "button"+i, makesethandler(), address + elt.address));
+		row.appendChild ( document.createElement('td'));
+		dest.appendChild (row);
+	}
+	else if ((elt.type == 'togglebutton') ||  (elt.type == 'checkbutton')) {
+		var box = makecheckbox("checkbox"+i, makesethandler(), address + elt.address);
+		row.appendChild ( makeCol (elt.label, "label"));
+		row.appendChild ( makeCol (box));
+		row.appendChild ( document.createElement('td'));
+		dest.appendChild (row);
+	}
+	else if ((elt.type == 'verticalslider') ||  (elt.type == 'horizontalslider') || (elt.type == 'numentry')) {
+		var slider	= makeslider("slider"+i, 'vertical', elt.min, elt.max, elt.init, elt.step, 
+						  makesethandler(), address + elt.address);
+		row.appendChild (makeCol (elt.label, "label") );
+		row.appendChild (makeCol (slider), "control" );
+		row.appendChild (makeCol (slider.fTextValue), "value" );
+		dest.appendChild (row);
+ 	}
+ 	else {
+ 	alert (elt.type + " " + elt.label + " " + elt.elements);
+ 	if (elt.elements.length > 0) {
+ 		row.appendChild ( makeCol (elt.label, "group"));
+		dest.appendChild (row);
+		for (var j=0; j<elt.elements.length; j++) {
+			i = makeControl (elt.elements, i, address, dest);
+		}
+		dest.appendChild (makehr(3));
+ 	}
+ 	}
+	return i+1;
+}
+
+//-----------------------------------------------------------------------------
+// build a faust program UI from a JSON description
+//-----------------------------------------------------------------------------
+function buildui (data) {
+	var desc = $.parseJSON (data);
+	var serial = 0;
+	$("#titre").html(desc.name);
+	var ui = desc.ui;
+	var address = "http://"+desc.address+":"+desc.port;
+	var table = document.createElement('table');
+	var row 	= document.createElement('tr');
+	table.className = "ui";
+	row.appendChild (makeCol (desc.name, "name") );
+	row.appendChild (makeCol (desc.address, "url") );
+	row.appendChild (makeCol (desc.port, "port") );
+	table.appendChild (row);
+	table.appendChild (makehr(3));
+	for (var i=0; i<ui.length; i++) {
+		serial = makeControl (ui[i], serial, address, table);
+	}
+	table.appendChild (makehr(3));
+	return table;
+}
diff --git a/architecture/httpdlib/html/js/faustuihtml.js b/architecture/httpdlib/html/js/faustuihtml.js
new file mode 100644
index 0000000..905244a
--- /dev/null
+++ b/architecture/httpdlib/html/js/faustuihtml.js
@@ -0,0 +1,158 @@
+
+//-----------------------------------------------------------------------------
+// a function to build a slider
+// a faust slider is a composite object that embeds a label, a 'range' input
+// and a 'text' input displaying the slider value
+// slider and text value are linked together to reflect the same value.
+//-----------------------------------------------------------------------------
+function htmlslider(id, orientation, min, max, value, step, dest) {
+	var valId="v"+id;
+	var html = "<input type='range' id='" + id
+		 	 + "' min=" + min + " max=" + max + " step=" + step + " value=" + value
+			 + " onchange='sliderhandler(\"" + dest + "\", this.value, \"#" + valId + "\")'>";
+	var text = "<input type='text' id='" + valId
+			 + "' value=" + value + " size=6"
+			 + " onchange='sliderhandler(\"" + dest + "\", this.value, \"#" + id + "\")'>";
+	var out = new Array (html, text);
+	return out;
+}
+
+//-----------------------------------------------------------------------------
+// a push button
+//-----------------------------------------------------------------------------
+function htmlbutton(label, id, dest) {
+	var html = "<button id='" + id
+			 + "' onmousedown='fausthandler(\"" + dest + "\", 1)' onmouseup='fausthandler(\"" + dest + "\", 0)'>"
+			 + label
+			 +"</button>";
+	return html;
+}
+
+//-----------------------------------------------------------------------------
+// a check box
+//-----------------------------------------------------------------------------
+function htmlcheckbox(id, dest) {
+	var html = "<input type='checkbox' id='" + id
+			 + "' value=0 onchange='fausthandler(\"" + dest + "\", this.value)'>";
+	return html;
+}
+
+//-----------------------------------------------------------------------------
+// builds a column with an optional class name
+//-----------------------------------------------------------------------------
+function htmlCol (html, classname) {
+	var classt = "";
+	if (typeof classname != 'undefined') 
+		classt = " class='" + classname + "'";
+	var html = "<td" + classt + ">" + html + "</td>\n";
+	return html;
+}
+
+//-----------------------------------------------------------------------------
+// a simple <hr> over 'span' columns
+//-----------------------------------------------------------------------------
+function htmlhr (span) {
+	var html = "<tr><td colspan=" + span + " class='sep'><hr/></td></tr>\n";
+	return html;
+}
+
+//-----------------------------------------------------------------------------
+// build a single UI element 
+// the element is returned in a row
+//-----------------------------------------------------------------------------
+function htmlControl (elt, i, address) {
+	var row 	= "<tr>";
+	if (elt.type == 'button') {
+		row += htmlCol ("", "label");
+		row += htmlCol (htmlbutton(elt.label, "button"+i, address + elt.address), "control");
+		row += htmlCol ("", "value");
+	}
+	else if ((elt.type == 'togglebutton') ||  (elt.type == 'checkbutton')) {
+		row += htmlCol (elt.label, "label");
+		row += htmlCol (htmlcheckbox("checkbox"+i, address + elt.address), "control");
+		row += htmlCol ("", "value");
+	}
+	else if ((elt.type == 'verticalslider') ||  (elt.type == 'horizontalslider') || (elt.type == 'numentry')) {
+		var slider	= htmlslider("slider"+i, 'vertical', elt.min, elt.max, elt.init, elt.step, address + elt.address);
+		row += htmlCol (elt.label, "label");
+		row += htmlCol (slider[0], "control");
+		row += htmlCol (slider[1], "value");
+ 	}
+ 	else {
+ 	alert (elt.type + " " + elt.label + " " + elt.elements);
+ 	if (elt.elements.length > 0) {
+//  		row.appendChild ( makeCol (elt.label, "group"));
+// 		dest.appendChild (row);
+// 		for (var j=0; j<elt.elements.length; j++) {
+// 			i = htmlControl (elt.elements, i, address, dest);
+// 		}
+ 	}
+ 	}
+ 	row += "</tr>\n";
+ 	var out = new Array(row, i+1);
+	return out;
+}
+
+//-----------------------------------------------------------------------------
+// build a faust program UI from a JSON description
+//-----------------------------------------------------------------------------
+function buildhtmlui (data) {
+	var desc = $.parseJSON (data);
+	var serial = 0;
+	$("#titre").html(desc.name);
+	var ui = desc.ui;
+	var address = "http://"+desc.address+":"+desc.port;
+	var table = "<table class='ui'>\n<tr>";
+	table += htmlCol ( desc.name, "name");
+	table += htmlCol ( desc.address, "url");
+	table += htmlCol ( desc.port, "port");
+	table += "</tr>\n" + htmlhr(3);
+
+	for (var i=0; i<ui.length; i++) {
+		var control = htmlControl (ui[i], serial, address);
+		table += control[0];
+		serial = control[1];
+	}
+	table += htmlhr(3) + "</table>\n";
+//	alert(table);
+	return table;
+}
+
+//-----------------------------------------------------------------------------
+// handlers to send a faust 'set' message
+// actually using a 'GET' method
+//-----------------------------------------------------------------------------
+function fausthandler(dest, value) {
+	if (0) {
+		var msg = "$.get( " + dest +"?value=" + value + ");";
+		$("#trace").html(msg);
+	}
+	else $.get(dest +"?value=" + value);
+}
+
+function sliderhandler(dest, value, id) {
+	fausthandler (dest, value);
+	$(id).val(Math.round(value*10000)/10000);
+}
+
+//-----------------------------------------------------------------------------
+// poll current values from the server
+//-----------------------------------------------------------------------------
+function dispatch (data) {
+	var lines = data.toString().split('\n');
+	var limit = lines.length;
+	for (i=0; i < limit; i++) {
+		var values = lines[i].toString().split(' ');
+		if (values.length > 1) {
+			var address = values[0];
+			var value = Math.round(values[1]*10000)/10000;
+			$('[name="'+address+'"]').val(value);
+		}
+	}
+}
+
+function update (root) {
+	$.get( root, function(data) { dispatch( data ); } );
+	setTimeout ( function () { update(root); }, 250);
+}
+$(document).ready(function() { update ($('#root').val()); });
diff --git a/architecture/httpdlib/html/js/jdesc.js b/architecture/httpdlib/html/js/jdesc.js
new file mode 100644
index 0000000..b6b5d86
--- /dev/null
+++ b/architecture/httpdlib/html/js/jdesc.js
@@ -0,0 +1,51 @@
+
+function getDesc() {
+	return '{\
+	"name": "karplus",\
+	"address": "localhost",\
+	"port": "5510",\
+	"ui": [\
+		{\
+			"type": "horizontalslider",\
+			"label": "excitation",\
+			"address": "/karplus/excitator/excitation",\
+			"init": "128",\
+			"min": "2",\
+			"max": "512",\
+			"step": "1"\
+		},\
+		{\
+			"type": "button",\
+			"label": "play",\
+			"address": "/karplus/excitator/play"\
+		},\
+		{\
+			"type": "horizontalslider",\
+			"label": "level",\
+			"address": "/karplus/level",\
+			"init": "0.5",\
+			"min": "0",\
+			"max": "1",\
+			"step": "0.1"\
+		},\
+		{\
+			"type": "horizontalslider",\
+			"label": "attenuation",\
+			"address": "/karplus/resonator/attenuation",\
+			"init": "0.1",\
+			"min": "0",\
+			"max": "1",\
+			"step": "0.01"\
+		},\
+		{\
+			"type": "horizontalslider",\
+			"label": "duration",\
+			"address": "/karplus/resonator/duration",\
+			"init": "128",\
+			"min": "2",\
+			"max": "512",\
+			"step": "1"\
+		}\
+	]\
+}';
+}
diff --git a/architecture/httpdlib/html/js/jquery-1.7.1.min.js b/architecture/httpdlib/html/js/jquery-1.7.1.min.js
new file mode 100644
index 0000000..198b3ff
--- /dev/null
+++ b/architecture/httpdlib/html/js/jquery-1.7.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
+f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
+{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/Makefile b/architecture/httpdlib/html/js/svg/api/Makefile
new file mode 100644
index 0000000..61e095d
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FaustWebUIAPI.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FaustWebUIAPI.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/FaustWebUIAPI"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FaustWebUIAPI"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/architecture/httpdlib/html/js/svg/api/build/doctrees/constants.doctree b/architecture/httpdlib/html/js/svg/api/build/doctrees/constants.doctree
new file mode 100644
index 0000000..6626db2
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/doctrees/constants.doctree differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/doctrees/customizing.doctree b/architecture/httpdlib/html/js/svg/api/build/doctrees/customizing.doctree
new file mode 100644
index 0000000..fc27cad
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/doctrees/customizing.doctree differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/doctrees/environment.pickle b/architecture/httpdlib/html/js/svg/api/build/doctrees/environment.pickle
new file mode 100644
index 0000000..6dcd96b
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/doctrees/environment.pickle differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/doctrees/index.doctree b/architecture/httpdlib/html/js/svg/api/build/doctrees/index.doctree
new file mode 100644
index 0000000..4be8a22
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/doctrees/index.doctree differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/doctrees/overview.doctree b/architecture/httpdlib/html/js/svg/api/build/doctrees/overview.doctree
new file mode 100644
index 0000000..63e24ee
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/doctrees/overview.doctree differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/.buildinfo b/architecture/httpdlib/html/js/svg/api/build/html/.buildinfo
new file mode 100644
index 0000000..32cbe34
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/.buildinfo
@@ -0,0 +1,4 @@
+# Sphinx build info version 1
+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: 4c9bf47ded7abaf52f81d77010c93463
+tags: fbb0d17656682115ca4d033fb2f83ba1
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_sources/constants.txt b/architecture/httpdlib/html/js/svg/api/build/html/_sources/constants.txt
new file mode 100644
index 0000000..3f8e890
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_sources/constants.txt
@@ -0,0 +1,34 @@
+Constants
+=========
+
+Certain constants are defined in the Web UI API to facilitate customization.
+As explained in the next chapter, these constants can be used directly in
+external JS files or in the URL itself to control the look and feel of the
+faust application.  Examples of this are given in the next chapter as well.
+
+============================  ================================================  ================================
+Property name                 Description                                       Value of internal representation
+============================  ================================================  ================================
+_f4u$t.TEXT_HEIGHT            Estimation of the height of text                  20
+_f4u$t.TEXT_PADDING           Padding between an object and its label           10
+_f4u$t.VALUE_BOX_W            Width of the value box of an object               60
+_f4u$t.VALUE_BOX_H            Height of the value box of an object              60
+_f4u$t.TEXT_BOX_PADDING       Padding between an object and its value box       3
+_f4u$t.X_AXIS                 Enum-like constant for the X axis                 0
+_f4u$t.Y_AXIS                 Enum-like constant for the Y axis                 1
+_f4u$t.NO_AXES                Enum-like constant for the end of axis iterators  2
+_f4u$t.LEFT                   Enum-like constant for left                       -1
+_f4u$t.RIGHT                  Enum-like constant for rifght                     1
+_f4u$t.UP                     Enum-like constant for up                         -1
+_f4u$t.DOWN                   Enum-like constant for down                       1
+_f4u$t.CENTER                 Enum-like constant for center                     0
+_f4u$t.NONE                   Representation of JS null                         null
+_f4u$t.BLACK                  The color black                                   [0,0,0]
+_f4u$t.WHITE                  The color white                                   [255,255,255]
+_f4u$t.CYAN                   The color cyan                                    [0,255,255]
+_f4u$t.GREY                   The color grey                                    [100,100,100]
+_f4u$t.PINK                   The color pink                                    [233,150,122]
+_f4u$t.GREEN                  The color green                                   [173,255,47]
+_f4u$t.KERMIT                 The color kermit                                  [47,243,160]
+_f4u$t.PALEGREEN              The color pale green                              [152,251,152]
+============================  ================================================  ================================
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_sources/customizing.txt b/architecture/httpdlib/html/js/svg/api/build/html/_sources/customizing.txt
new file mode 100644
index 0000000..f0ed94c
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_sources/customizing.txt
@@ -0,0 +1,373 @@
+Customizing the Web UI
+======================
+
+The Web UI has a built-in customization system that allows users to specify
+the look of certain objects in the interface.  This spefication can take one
+of three forms:
+
+- The inclusion of external CSS files
+- The inclusion of external JavaScript files
+- The specification of parameters in the URL
+
+External CSS files
+------------------
+
+External CSS files can be used to style the Faust Web UI by setting the css
+argument in the url.  For example, to include the CSS file
+``http://www.ensemble101.fr/foo.css`` on the previously mentioned application,
+one would use the link::
+
+  http://www.ensemble101.fr:8000/#css=http://www.ensemble101.fr/foo.css
+
+The css argument can be specified multiple times for multiple CSS files.
+
+Below is a list of all customizable CSS parameters for all objects. Information
+on all of these parameters, as well as information on SVG CSS, can be found on
+http://www.w3.org/TR/SVG/styling.html.
+
+* Clipping, Masking and Compositing properties
+
+  * opacity
+
+* Color and Painting properties
+
+  * color-profile
+  * color-rendering
+  * fill
+  * fill-opacity
+  * fill-rule
+  * stroke
+  * stroke-dasharray
+  * stroke-dashoffset
+  * stroke-linecap
+  * stroke-linejoin
+  * stroke-miterlimit
+  * stroke-opacity
+  * stroke-width
+
+* Font properties
+
+  * font
+  * font-family
+  * font-size
+  * font-size-adjust
+  * font-stretch
+  * font-style
+  * font-variant
+  * font-weight
+
+* Text properties
+
+  * text-rendering
+  * alignment-baseline
+  * baseline-shift
+  * dominant-baseline
+  * glyph-orientation-horizontal
+  * glyph-orientation-vertical
+  * kerning
+  * text-anchor
+  * writing-mode
+  * direction
+  * letter-spacing
+  * text-decoration
+  * unicode-bidi
+  * word-spacing
+
+None of these parameters are set by default, as all of them are set dynamically
+in the DOM via JavaScript as described below. However, customized CSS will
+take precedence over JavaScript when set.
+
+Below is a list of all faust objects with sublists indicating the CSS
+classes that compose the objects as well as the meaning of the class.
+
+Rotating Button
+^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-rbutton-joint                  The "joint" in which a rotating button rotates.
+faust-rbutton-knob                   The "knob" that does the actual rotating.
+==================================   ===================================================
+
+Slider (both horizontal and vertical)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-slider-joint                   The "joint" in which a slider slides.
+faust-slider-knob                    The "knob" that does the actual sliding.
+==================================   ===================================================
+
+Bar Graph (both horizontal and vertical)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==================================   ========================================================
+Class name                           Description                        
+==================================   ========================================================
+faust-bargraph-joint                 The "joint" in which a bar graph moves.
+faust-bargraph-knob                  The "meter" that does the actual showing of information.
+==================================   ========================================================
+
+Checkbox
+^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-checkbox-box                   The box of a checkbox.
+faust-checkbox-check                 The check of a checkbox.
+==================================   ===================================================
+
+Button
+^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-button-box                     The box of a button.
+faust-button-text                    Text of a button.
+==================================   ===================================================
+
+Numerical Entry
+^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-nentry-operation               The operation sign (plus/minus) of a numerical entry.
+faust-nentry-button                  The button on which the operation signs appear.
+==================================   ===================================================
+
+Value Box
+^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-button-box                     The box of a value box.
+faust-button-text                    Number of a value box.
+==================================   ===================================================
+
+Layout Manager (both horizontal and vertical)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-group-background               The background of a layout manager.
+faust-group-label                    The label of a layout manager.
+==================================   ===================================================
+
+Tab Group
+^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-tgroup-tab                     A tab of a tab group.
+faust-tgroup-label                   A label of a tab in a tab group.
+==================================   ===================================================
+
+Below is a model CSS file setting several of the classes above ::
+
+  .faust-slider-joint {opacity:0.2;}
+  .faust-rbutton-knob {stroke-linecap:percentage;}
+  .faust-tgroup-label {font-weight:bold;}
+
+External JS files
+-----------------
+
+As the CSS specification only allows the customization of parameters in the
+specification and disallows customized parameters, faust-specific parameters
+must be specified via JavaScript.  There are numerous parameters one can
+control: the width of sliders, the girth of a rotating button's knob, and
+the height of a button, for example, can all be controlled via JavaScript.
+This is also true of more "traditional" parameters such as fill color.
+Where there is overlap in things that can be specified in both JS and CSS
+(fill and stroke, for example), the CSS will, if specified, take priority.
+
+Often times, a customizable parameter can be set that will interfere with the
+normal display of faust information. For example, one can specify the text
+of all checkbox labels, but this would interfere with the labels specified
+by the server.  Therefore, in the tables below, there is a "Touch?" parameter
+that, when specified as "No", means that it should not be tinkered with.
+
+External JS files can be used to style the Faust Web UI by setting the js
+argument in the url.  For example, to include the JS file
+``http://www.ensemble101.fr/foo.js`` on the previously mentioned application,
+one would use the link::
+
+  http://www.ensemble101.fr:8000/#js=http://www.ensemble101.fr/foo.js
+
+The js argument can be specified multiple times for multiple JS files.
+
+Below is a list of all faust objects with sublists indicating the JS
+variables that may be set as well as the meaning of these variables.
+
+Rotating Button
+^^^^^^^^^^^^^^^
+==================================   ==============================================   ======   ==============================
+Property name                        Description                                      Touch?   Default
+==================================   ==============================================   ======   ==============================
+_f4u$t.rbutton_inits.mom             Parent widget of the object                      No       null
+_f4u$t.rbutton_inits.label           Label of the object                              No       null
+_f4u$t.rbutton_inits.ir              The ideal radius of the button                   Yes      50
+_f4u$t.rbutton_inits.a0              The angle from which the button starts           Yes      180
+_f4u$t.rbutton_inits.sweep           The degrees that the button sweeps               Yes      180
+_f4u$t.rbutton_inits.sp              The fraction of the sweep taken up by the knob   Yes      0.1
+_f4u$t.rbutton_inits.unit            Units of the button                              No       null
+_f4u$t.rbutton_inits.min             Min value of the button                          No       0
+_f4u$t.rbutton_inits.max             Max value of the button                          No       100
+_f4u$t.rbutton_inits.init            Initial value of the button                      No       50
+_f4u$t.rbutton_inits.step            Step over the range                              No       1
+_f4u$t.rbutton_inits.integer         True of the initial value is an integer          No       false
+_f4u$t.rbutton_inits.ndec            Number of decimal places to show                 No       0
+_f4u$t.rbutton_inits.lpadding_y      Padding between text box and label               Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.rbutton_inits.box_padding     Padding between object and text box              Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.rbutton_inits.gravity         X,Y placement in the parent widget               Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.rbutton_inits.joint_fill      Fill of the joint                                Yes      _f4u$t.PALEGREEN
+_f4u$t.rbutton_inits.knob_fill       Fill of the knob                                 Yes      _f4u$t.GREY
+_f4u$t.rbutton_inits.joint_stroke    Stroke of the joint                              Yes      _f4u$t.BLACK
+_f4u$t.rbutton_inits.knob_stroke     Stroke of the knob                               Yes      _f4u$t.BLACK
+_f4u$t.rbutton_inits.value_box_w     Width of the value box                           Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.rbutton_inits.value_box_h     Height of the value box                          Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.rbutton_inits.address         Address on the server                            No       null
+==================================   ==============================================   ======   ==============================
+
+Slider
+^^^^^^
+==================================   ===============================================   ======   ==============================
+Property name                        Description                                       Touch?   Default
+==================================   ===============================================   ======   ==============================
+_f4u$t.slider_inits.mom              Parent widget of the object                       No       null
+_f4u$t.slider_inits.label            Label of the object                               No       null
+_f4u$t.slider_inits.axis             Orientation of the object                         No       _f4u$t.X_AXIS
+_f4u$t.slider_inits.girth            Width of the object                               Yes      40
+_f4u$t.slider_inits.length           Length of the object                              Yes      200
+_f4u$t.slider_inits.sp               The fraction of the slider taken up by the knob   Yes      0.1
+_f4u$t.slider_inits.unit             Units of the slider                               No       null
+_f4u$t.slider_inits.min              Min value of the button                           No       0
+_f4u$t.slider_inits.max              Max value of the button                           No       100
+_f4u$t.slider_inits.init             Initial value of the button                       No       50
+_f4u$t.slider_inits.step             Step over the range                               No       1
+_f4u$t.slider_inits.integer          True of the initial value is an integer           No       false
+_f4u$t.slider_inits.ndec             Number of decimal places to show                  No       0
+_f4u$t.slider_inits.lpadding_y       Padding between text box and label                Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.slider_inits.box_padding      Padding between object and text box               Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.slider_inits.gravity          X,Y placement in the parent widget                Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.slider_inits.joint_fill       Fill of the joint                                 Yes      _f4u$t.PALEGREEN
+_f4u$t.slider_inits.knob_fill        Fill of the knob                                  Yes      _f4u$t.GREY
+_f4u$t.slider_inits.joint_stroke     Stroke of the joint                               Yes      _f4u$t.BLACK
+_f4u$t.slider_inits.knob_stroke      Stroke of the knob                                Yes      _f4u$t.BLACK
+_f4u$t.slider_inits.value_box_w      Width of the value box                            Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.slider_inits.value_box_h      Height of the value box                           Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.slider_inits.address          Address on the server                             No       null
+==================================   ===============================================   ======   ==============================
+
+In order to customize horizontal and vertical sliders individually, the
+properties above may be set by adding v or h before slider (i.e. _f4u$t.vslider_inits.joint_stroke).
+
+Bar Graph
+^^^^^^^^^
+==================================     ===============================================   ======   ==============================
+Property name                          Description                                       Touch?   Default
+==================================     ===============================================   ======   ==============================
+_f4u$t.bargraph_inits.mom              Parent widget of the object                       No       null
+_f4u$t.bargraph_inits.label            Label of the object                               No       null
+_f4u$t.bargraph_inits.axis             Orientation of the object                         No       _f4u$t.X_AXIS
+_f4u$t.bargraph_inits.girth            Width of the object                               Yes      40
+_f4u$t.bargraph_inits.length           Length of the object                              Yes      200
+_f4u$t.bargraph_inits.unit             Units of the slider                               No       null
+_f4u$t.bargraph_inits.min              Min value of the button                           No       0
+_f4u$t.bargraph_inits.max              Max value of the button                           No       100
+_f4u$t.bargraph_inits.init             Initial value of the button                       No       50
+_f4u$t.bargraph_inits.step             Step over the range                               No       1
+_f4u$t.bargraph_inits.integer          True of the initial value is an integer           No       false
+_f4u$t.bargraph_inits.ndec             Number of decimal places to show                  No       0
+_f4u$t.bargraph_inits.lpadding_y       Padding between text box and label                Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.bargraph_inits.box_padding      Padding between object and text box               Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.bargraph_inits.gravity          X,Y placement in the parent widget                Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.bargraph_inits.joint_fill       Fill of the joint                                 Yes      _f4u$t.PALEGREEN
+_f4u$t.bargraph_inits.meter_fill       Fill of the meter                                 Yes      _f4u$t.GREY
+_f4u$t.bargraph_inits.joint_stroke     Stroke of the joint                               Yes      _f4u$t.BLACK
+_f4u$t.bargraph_inits.meter_stroke     Stroke of the meter                               Yes      _f4u$t.BLACK
+_f4u$t.bargraph_inits.value_box_w      Width of the value box                            Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.bargraph_inits.value_box_h      Height of the value box                           Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.bargraph_inits.address          Address on the server                             No       null
+==================================     ===============================================   ======   ==============================
+
+In order to customize horizontal and vertical bar graphs individually, the
+properties above may be set by adding v or h before bar graph (i.e. _f4u$t.vbargraph_inits.joint_stroke).
+
+Numerical Entry
+^^^^^^^^^^^^^^^
+====================================     ===============================================   ======   ==============================
+Property name                            Description                                       Touch?   Default
+====================================     ===============================================   ======   ==============================
+_f4u$t.nentry_inits.mom                  Parent widget of the object                       No       null
+_f4u$t.nentry_inits.label                Label of the object                               No       null
+_f4u$t.nentry_inits.length               Length of the object                              Yes      200
+_f4u$t.nentry_inits.unit                 Units of the slider                               No       null
+_f4u$t.nentry_inits.min                  Min value of the button                           No       0
+_f4u$t.nentry_inits.max                  Max value of the button                           No       100
+_f4u$t.nentry_inits.init                 Initial value of the button                       No       50
+_f4u$t.nentry_inits.step                 Step over the range                               No       1
+_f4u$t.nentry_inits.integer              True of the initial value is an integer           No       false
+_f4u$t.nentry_inits.ndec                 Number of decimal places to show                  No       0
+_f4u$t.nentry_inits.lpadding_y           Padding between text box and label                Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.nentry_inits.box_padding          Padding between object and text box               Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.nentry_inits.padding              Padding around an operation in a button           Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.nentry_inits.gravity              X,Y placement in the parent widget                Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.nentry_inits.operation_fill       Fill of the operation symbol                      Yes      _f4u$t.PALEGREEN
+_f4u$t.nentry_inits.button_fill          Fill of the operation button                      Yes      _f4u$t.GREY
+_f4u$t.nentry_inits.operation_stroke     Stroke of the operation symbol                    Yes      _f4u$t.BLACK
+_f4u$t.nentry_inits.button_stroke        Stroke of the operation button                    Yes      _f4u$t.BLACK
+_f4u$t.nentry_inits.value_box_w          Width of the value box                            Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.nentry_inits.value_box_h          Height of the value box                           Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.nentry_inits.address              Address on the server                             No       null
+====================================     ===============================================   ======   ==============================
+
+Checkbox
+^^^^^^^^
+==================================   ===================================  ======  ==============================
+Property name                        Description                          Touch?  Default
+==================================   ===================================  ======  ==============================
+_f4u$t.checkbox_inits.mom            Parent widget of the object          No      null
+_f4u$t.checkbox_inits.label          Label of the object                  No      null
+_f4u$t.checkbox_inits.d              Dimension                            Yes     19
+_f4u$t.checkbox_inits.gravity        X,Y placement in the parent widget   Yes     [_f4u$t.CENTER, _f4u$t.CENTER]
+_f4u$t.checkbox_inits.check_fill     Fill of the check                    Yes     _f4u$t.BLACK
+_f4u$t.checkbox_inits.check_stroke   Stroke of the check                  Yes     _f4u$t.BLACK
+_f4u$t.checkbox_inits.box_fill       Fill of the box                      Yes     _f4u$t.WHITE
+_f4u$t.checkbox_inits.box_stroke     Stroke of the box                    Yes     _f4u$t.BLACK
+_f4u$t.checkbox_inits.init           Initial value of the checkbox        No      false
+_f4u$t.checkbox_inits.lpadding_y     Padding between object and label     Yes     _f4u$t.TEXT_HEIGHT
+_f4u$t.checkbox_inits.address        Address on the server                No      null
+==================================   ===================================  ======  ==============================
+
+Button
+^^^^^^
+===================================  ======================================  ======  ==============================
+Property name                        Description                             Touch?  Default
+===================================  ======================================  ======  ==============================
+_f4u$t.button_inits.mom              Parent widget of the object             No      null
+_f4u$t.button_inits.label            Label of the object                     No      null
+_f4u$t.button_inits.ideal_width      Ideal width [#f1]_                      Yes     80
+_f4u$t.button_inits.ideal_height     Ideal height [#f1]_                     Yes     40
+_f4u$t.button_inits.gravity          X,Y placement in the parent widget      Yes     [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.button_inits.fill_on          Fill when the button is on              Yes     _f4u$t.PINK
+_f4u$t.button_inits.fill_off         Fill when the button is off             Yes     _f4u$t.GREEN
+_f4u$t.button_inits.stroke           Stroke of the button box                Yes     _f4u$t.BLACK
+_f4u$t.button_inits.baseline_skip    Gap between bottom of button and label  Yes     5
+_f4u$t.button_inits.address          Address on the server                   No      null
+===================================  ======================================  ======  ==============================
+
+Below is a model JS file setting several of the variables above ::
+
+  _f4u$t.button_inits.stroke = _f4u$t.BLACK;
+  _f4u$t.checkbox_inits.d = 40;
+  _f4u$t.hslider_inits.sp = 0.3;
+
+URL Parameter Specification
+---------------------------
+
+JS parameters can also be specified in the URL.  For example, the model
+JS file above can be embeded in the URL as follows ::
+
+  http://www.ensemble101.fr:8000/#button_inits.stroke=_f4u$t.BLACK&checkbox_inits.d=40&hslider_inits.sp=0.3
+
+.. rubric:: Footnotes
+.. [#f1] Ideal because it will adapt to the size of the bounded text if necessary.
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_sources/index.txt b/architecture/httpdlib/html/js/svg/api/build/html/_sources/index.txt
new file mode 100644
index 0000000..90023f0
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_sources/index.txt
@@ -0,0 +1,26 @@
+.. Faust Web UI API documentation master file, created by
+   sphinx-quickstart on Tue Jan  1 15:41:15 2013.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to Faust Web UI API's documentation!
+============================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   overview
+   constants
+   customizing
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_sources/overview.txt b/architecture/httpdlib/html/js/svg/api/build/html/_sources/overview.txt
new file mode 100644
index 0000000..acb2207
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_sources/overview.txt
@@ -0,0 +1,23 @@
+Overview
+========
+
+This page provides an overview of the Faust Web UI.  The Faust Web UI can be
+used to control Faust applications running on a server via GET requests.
+An experimental version of WebKit also provides a serverless version of the
+Web UI.
+
+Using the Web UI
+----------------
+
+In order to use the Faust Web UI, one may access a server running a Faust
+application over the appropriate port via a browser that visualizes SVG
+according to the W3C specification (http://www.w3.org/2000/svg).  Once the
+URL is composed, the graphical UI for the application will be displayed in
+the browser.  So, for example, if the website www.ensemble101.fr is running
+a faust application on port 8000, the URL http://www.ensemble101.fr:8000 would
+be used to access the application.
+
+The goal of Faust Web UI is to provide a robust graphical UI similar to that
+of other Faust interfaces (Qt, gtk+, etc.). Should a Faust Web UI fail to
+parallel one of these interfaces in the objects drawn or their responsiveness,
+an e-mail can be sent to faustwebui at grame.fr.
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/ajax-loader.gif b/architecture/httpdlib/html/js/svg/api/build/html/_static/ajax-loader.gif
new file mode 100644
index 0000000..61faf8c
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/ajax-loader.gif differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/basic.css b/architecture/httpdlib/html/js/svg/api/build/html/_static/basic.css
new file mode 100644
index 0000000..43e8baf
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/basic.css
@@ -0,0 +1,540 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+    width: 170px;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+    width: 30px;
+}
+
+img {
+    border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+    width: 100%;
+}
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+div.modindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+    clear: left;
+    float: left;
+    margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+    clear: right;
+    float: right;
+    margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-center {
+    text-align: center;
+}
+
+.align-right {
+    text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px 7px 0 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+table.citation {
+    border-left: solid 1px gray;
+    margin-left: 1px;
+}
+
+table.citation td {
+    border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+    list-style: decimal;
+}
+
+ol.loweralpha {
+    list-style: lower-alpha;
+}
+
+ol.upperalpha {
+    list-style: upper-alpha;
+}
+
+ol.lowerroman {
+    list-style: lower-roman;
+}
+
+ol.upperroman {
+    list-style: upper-roman;
+}
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dt:target, .highlighted {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.refcount {
+    color: #060;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa;
+}
+
+.line-block {
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.line-block .line-block {
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+    font-family: sans-serif;
+}
+
+.accelerator {
+    text-decoration: underline;
+}
+
+.classifier {
+    font-style: oblique;
+}
+
+abbr, acronym {
+    border-bottom: dotted 1px;
+    cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.viewcode-link {
+    float: right;
+}
+
+.viewcode-back {
+    float: right;
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    margin: -1px -10px;
+    padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+ at media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0 !important;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/comment-bright.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/comment-bright.png
new file mode 100644
index 0000000..551517b
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/comment-bright.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/comment-close.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/comment-close.png
new file mode 100644
index 0000000..09b54be
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/comment-close.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/comment.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/comment.png
new file mode 100644
index 0000000..92feb52
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/comment.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/contents.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/contents.png
new file mode 100644
index 0000000..7fb8215
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/contents.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/default.css b/architecture/httpdlib/html/js/svg/api/build/html/_static/default.css
new file mode 100644
index 0000000..21f3f50
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/default.css
@@ -0,0 +1,256 @@
+/*
+ * default.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- default theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+ at import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #11303d;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: #1c4e63;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: #ffffff;
+    color: #000000;
+    padding: 0 20px 30px 20px;
+}
+
+div.footer {
+    color: #ffffff;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #ffffff;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #133f52;
+    line-height: 30px;
+    color: #ffffff;
+}
+
+div.related a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    color: #ffffff;
+}
+
+div.sphinxsidebar a {
+    color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:visited {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    background-color: #f2f2f2;
+    font-weight: normal;
+    color: #20435c;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition p {
+    margin-bottom: 5px;
+}
+
+div.admonition pre {
+    margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+    margin-bottom: 5px;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: #eeffcc;
+    color: #333333;
+    line-height: 120%;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+th {
+    background-color: #ede;
+}
+
+.warning tt {
+    background: #efc2c2;
+}
+
+.note tt {
+    background: #d6d6d6;
+}
+
+.viewcode-back {
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/doctools.js b/architecture/httpdlib/html/js/svg/api/build/html/_static/doctools.js
new file mode 100644
index 0000000..d4619fd
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/doctools.js
@@ -0,0 +1,247 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+    "profile", "profileEnd"];
+  window.console = {};
+  for (var i = 0; i < names.length; ++i)
+    window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+  return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+  if (typeof s == 'undefined')
+    s = document.location.search;
+  var parts = s.substr(s.indexOf('?') + 1).split('&');
+  var result = {};
+  for (var i = 0; i < parts.length; i++) {
+    var tmp = parts[i].split('=', 2);
+    var key = jQuery.urldecode(tmp[0]);
+    var value = jQuery.urldecode(tmp[1]);
+    if (key in result)
+      result[key].push(value);
+    else
+      result[key] = [value];
+  }
+  return result;
+};
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+  for (var i = 0; i < arr.length; i++) {
+    if (arr[i] == item)
+      return true;
+  }
+  return false;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+  function highlight(node) {
+    if (node.nodeType == 3) {
+      var val = node.nodeValue;
+      var pos = val.toLowerCase().indexOf(text);
+      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
+        var span = document.createElement("span");
+        span.className = className;
+        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+          document.createTextNode(val.substr(pos + text.length)),
+          node.nextSibling));
+        node.nodeValue = val.substr(0, pos);
+      }
+    }
+    else if (!jQuery(node).is("button, select, textarea")) {
+      jQuery.each(node.childNodes, function() {
+        highlight(this);
+      });
+    }
+  }
+  return this.each(function() {
+    highlight(this);
+  });
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+  init : function() {
+    this.fixFirefoxAnchorBug();
+    this.highlightSearchWords();
+    this.initIndexTable();
+  },
+
+  /**
+   * i18n support
+   */
+  TRANSLATIONS : {},
+  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+  LOCALE : 'unknown',
+
+  // gettext and ngettext don't access this so that the functions
+  // can safely bound to a different name (_ = Documentation.gettext)
+  gettext : function(string) {
+    var translated = Documentation.TRANSLATIONS[string];
+    if (typeof translated == 'undefined')
+      return string;
+    return (typeof translated == 'string') ? translated : translated[0];
+  },
+
+  ngettext : function(singular, plural, n) {
+    var translated = Documentation.TRANSLATIONS[singular];
+    if (typeof translated == 'undefined')
+      return (n == 1) ? singular : plural;
+    return translated[Documentation.PLURALEXPR(n)];
+  },
+
+  addTranslations : function(catalog) {
+    for (var key in catalog.messages)
+      this.TRANSLATIONS[key] = catalog.messages[key];
+    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+    this.LOCALE = catalog.locale;
+  },
+
+  /**
+   * add context elements like header anchor links
+   */
+  addContextElements : function() {
+    $('div[id] > :header:first').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this headline')).
+      appendTo(this);
+    });
+    $('dt[id]').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this definition')).
+      appendTo(this);
+    });
+  },
+
+  /**
+   * workaround a firefox stupidity
+   */
+  fixFirefoxAnchorBug : function() {
+    if (document.location.hash && $.browser.mozilla)
+      window.setTimeout(function() {
+        document.location.href += '';
+      }, 10);
+  },
+
+  /**
+   * highlight the search words provided in the url in the text
+   */
+  highlightSearchWords : function() {
+    var params = $.getQueryParameters();
+    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+    if (terms.length) {
+      var body = $('div.body');
+      window.setTimeout(function() {
+        $.each(terms, function() {
+          body.highlightText(this.toLowerCase(), 'highlighted');
+        });
+      }, 10);
+      $('<p class="highlight-link"><a href="javascript:Documentation.' +
+        'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+          .appendTo($('#searchbox'));
+    }
+  },
+
+  /**
+   * init the domain index toggle buttons
+   */
+  initIndexTable : function() {
+    var togglers = $('img.toggler').click(function() {
+      var src = $(this).attr('src');
+      var idnum = $(this).attr('id').substr(7);
+      $('tr.cg-' + idnum).toggle();
+      if (src.substr(-9) == 'minus.png')
+        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+      else
+        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+    }).css('display', '');
+    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+        togglers.click();
+    }
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords : function() {
+    $('#searchbox .highlight-link').fadeOut(300);
+    $('span.highlighted').removeClass('highlighted');
+  },
+
+  /**
+   * make the url absolute
+   */
+  makeURL : function(relativeURL) {
+    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+  },
+
+  /**
+   * get the current relative url
+   */
+  getCurrentURL : function() {
+    var path = document.location.pathname;
+    var parts = path.split(/\//);
+    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+      if (this == '..')
+        parts.pop();
+    });
+    var url = parts.join('/');
+    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+  }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+  Documentation.init();
+});
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/down-pressed.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/down-pressed.png
new file mode 100644
index 0000000..6f7ad78
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/down-pressed.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/down.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/down.png
new file mode 100644
index 0000000..3003a88
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/down.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/file.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/file.png
new file mode 100644
index 0000000..d18082e
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/file.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/jquery.js b/architecture/httpdlib/html/js/svg/api/build/html/_static/jquery.js
new file mode 100644
index 0000000..7c24308
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/jquery.js
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/minus.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/minus.png
new file mode 100644
index 0000000..da1c562
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/minus.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/navigation.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/navigation.png
new file mode 100644
index 0000000..1081dc1
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/navigation.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/plus.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/plus.png
new file mode 100644
index 0000000..b3cb374
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/plus.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/pygments.css b/architecture/httpdlib/html/js/svg/api/build/html/_static/pygments.css
new file mode 100644
index 0000000..1a14f2a
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/pygments.css
@@ -0,0 +1,62 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight  { background: #eeffcc; }
+.highlight .c { color: #408090; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #303030 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #208050 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #208050 } /* Literal.Number.Float */
+.highlight .mh { color: #208050 } /* Literal.Number.Hex */
+.highlight .mi { color: #208050 } /* Literal.Number.Integer */
+.highlight .mo { color: #208050 } /* Literal.Number.Oct */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/searchtools.js b/architecture/httpdlib/html/js/svg/api/build/html/_static/searchtools.js
new file mode 100644
index 0000000..663be4c
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/searchtools.js
@@ -0,0 +1,560 @@
+/*
+ * searchtools.js_t
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+  var textLower = text.toLowerCase();
+  var start = 0;
+  $.each(keywords, function() {
+    var i = textLower.indexOf(this.toLowerCase());
+    if (i > -1)
+      start = i;
+  });
+  start = Math.max(start - 120, 0);
+  var excerpt = ((start > 0) ? '...' : '') +
+  $.trim(text.substr(start, 240)) +
+  ((start + 240 - text.length) ? '...' : '');
+  var rv = $('<div class="context"></div>').text(excerpt);
+  $.each(hlwords, function() {
+    rv = rv.highlightText(this, 'highlighted');
+  });
+  return rv;
+}
+
+
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+  var step2list = {
+    ational: 'ate',
+    tional: 'tion',
+    enci: 'ence',
+    anci: 'ance',
+    izer: 'ize',
+    bli: 'ble',
+    alli: 'al',
+    entli: 'ent',
+    eli: 'e',
+    ousli: 'ous',
+    ization: 'ize',
+    ation: 'ate',
+    ator: 'ate',
+    alism: 'al',
+    iveness: 'ive',
+    fulness: 'ful',
+    ousness: 'ous',
+    aliti: 'al',
+    iviti: 'ive',
+    biliti: 'ble',
+    logi: 'log'
+  };
+
+  var step3list = {
+    icate: 'ic',
+    ative: '',
+    alize: 'al',
+    iciti: 'ic',
+    ical: 'ic',
+    ful: '',
+    ness: ''
+  };
+
+  var c = "[^aeiou]";          // consonant
+  var v = "[aeiouy]";          // vowel
+  var C = c + "[^aeiouy]*";    // consonant sequence
+  var V = v + "[aeiou]*";      // vowel sequence
+
+  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
+  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
+  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
+  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
+
+  this.stemWord = function (w) {
+    var stem;
+    var suffix;
+    var firstch;
+    var origword = w;
+
+    if (w.length < 3)
+      return w;
+
+    var re;
+    var re2;
+    var re3;
+    var re4;
+
+    firstch = w.substr(0,1);
+    if (firstch == "y")
+      w = firstch.toUpperCase() + w.substr(1);
+
+    // Step 1a
+    re = /^(.+?)(ss|i)es$/;
+    re2 = /^(.+?)([^s])s$/;
+
+    if (re.test(w))
+      w = w.replace(re,"$1$2");
+    else if (re2.test(w))
+      w = w.replace(re2,"$1$2");
+
+    // Step 1b
+    re = /^(.+?)eed$/;
+    re2 = /^(.+?)(ed|ing)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      re = new RegExp(mgr0);
+      if (re.test(fp[1])) {
+        re = /.$/;
+        w = w.replace(re,"");
+      }
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1];
+      re2 = new RegExp(s_v);
+      if (re2.test(stem)) {
+        w = stem;
+        re2 = /(at|bl|iz)$/;
+        re3 = new RegExp("([^aeiouylsz])\\1$");
+        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+        if (re2.test(w))
+          w = w + "e";
+        else if (re3.test(w)) {
+          re = /.$/;
+          w = w.replace(re,"");
+        }
+        else if (re4.test(w))
+          w = w + "e";
+      }
+    }
+
+    // Step 1c
+    re = /^(.+?)y$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(s_v);
+      if (re.test(stem))
+        w = stem + "i";
+    }
+
+    // Step 2
+    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step2list[suffix];
+    }
+
+    // Step 3
+    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step3list[suffix];
+    }
+
+    // Step 4
+    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+    re2 = /^(.+?)(s|t)(ion)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      if (re.test(stem))
+        w = stem;
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1] + fp[2];
+      re2 = new RegExp(mgr1);
+      if (re2.test(stem))
+        w = stem;
+    }
+
+    // Step 5
+    re = /^(.+?)e$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      re2 = new RegExp(meq1);
+      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+        w = stem;
+    }
+    re = /ll$/;
+    re2 = new RegExp(mgr1);
+    if (re.test(w) && re2.test(w)) {
+      re = /.$/;
+      w = w.replace(re,"");
+    }
+
+    // and turn initial Y back to y
+    if (firstch == "y")
+      w = firstch.toLowerCase() + w.substr(1);
+    return w;
+  }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+  _index : null,
+  _queued_query : null,
+  _pulse_status : -1,
+
+  init : function() {
+      var params = $.getQueryParameters();
+      if (params.q) {
+          var query = params.q[0];
+          $('input[name="q"]')[0].value = query;
+          this.performSearch(query);
+      }
+  },
+
+  loadIndex : function(url) {
+    $.ajax({type: "GET", url: url, data: null, success: null,
+            dataType: "script", cache: true});
+  },
+
+  setIndex : function(index) {
+    var q;
+    this._index = index;
+    if ((q = this._queued_query) !== null) {
+      this._queued_query = null;
+      Search.query(q);
+    }
+  },
+
+  hasIndex : function() {
+      return this._index !== null;
+  },
+
+  deferQuery : function(query) {
+      this._queued_query = query;
+  },
+
+  stopPulse : function() {
+      this._pulse_status = 0;
+  },
+
+  startPulse : function() {
+    if (this._pulse_status >= 0)
+        return;
+    function pulse() {
+      Search._pulse_status = (Search._pulse_status + 1) % 4;
+      var dotString = '';
+      for (var i = 0; i < Search._pulse_status; i++)
+        dotString += '.';
+      Search.dots.text(dotString);
+      if (Search._pulse_status > -1)
+        window.setTimeout(pulse, 500);
+    };
+    pulse();
+  },
+
+  /**
+   * perform a search for something
+   */
+  performSearch : function(query) {
+    // create the required interface elements
+    this.out = $('#search-results');
+    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+    this.dots = $('<span></span>').appendTo(this.title);
+    this.status = $('<p style="display: none"></p>').appendTo(this.out);
+    this.output = $('<ul class="search"/>').appendTo(this.out);
+
+    $('#search-progress').text(_('Preparing search...'));
+    this.startPulse();
+
+    // index already loaded, the browser was quick!
+    if (this.hasIndex())
+      this.query(query);
+    else
+      this.deferQuery(query);
+  },
+
+  query : function(query) {
+    var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
+
+    // Stem the searchterms and add them to the correct list
+    var stemmer = new Stemmer();
+    var searchterms = [];
+    var excluded = [];
+    var hlterms = [];
+    var tmp = query.split(/\s+/);
+    var objectterms = [];
+    for (var i = 0; i < tmp.length; i++) {
+      if (tmp[i] != "") {
+          objectterms.push(tmp[i].toLowerCase());
+      }
+
+      if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+          tmp[i] == "") {
+        // skip this "word"
+        continue;
+      }
+      // stem the word
+      var word = stemmer.stemWord(tmp[i]).toLowerCase();
+      // select the correct list
+      if (word[0] == '-') {
+        var toAppend = excluded;
+        word = word.substr(1);
+      }
+      else {
+        var toAppend = searchterms;
+        hlterms.push(tmp[i].toLowerCase());
+      }
+      // only add if not already in the list
+      if (!$.contains(toAppend, word))
+        toAppend.push(word);
+    };
+    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+    // console.debug('SEARCH: searching for:');
+    // console.info('required: ', searchterms);
+    // console.info('excluded: ', excluded);
+
+    // prepare search
+    var filenames = this._index.filenames;
+    var titles = this._index.titles;
+    var terms = this._index.terms;
+    var fileMap = {};
+    var files = null;
+    // different result priorities
+    var importantResults = [];
+    var objectResults = [];
+    var regularResults = [];
+    var unimportantResults = [];
+    $('#search-progress').empty();
+
+    // lookup as object
+    for (var i = 0; i < objectterms.length; i++) {
+      var others = [].concat(objectterms.slice(0,i),
+                             objectterms.slice(i+1, objectterms.length))
+      var results = this.performObjectSearch(objectterms[i], others);
+      // Assume first word is most likely to be the object,
+      // other words more likely to be in description.
+      // Therefore put matches for earlier words first.
+      // (Results are eventually used in reverse order).
+      objectResults = results[0].concat(objectResults);
+      importantResults = results[1].concat(importantResults);
+      unimportantResults = results[2].concat(unimportantResults);
+    }
+
+    // perform the search on the required terms
+    for (var i = 0; i < searchterms.length; i++) {
+      var word = searchterms[i];
+      // no match but word was a required one
+      if ((files = terms[word]) == null)
+        break;
+      if (files.length == undefined) {
+        files = [files];
+      }
+      // create the mapping
+      for (var j = 0; j < files.length; j++) {
+        var file = files[j];
+        if (file in fileMap)
+          fileMap[file].push(word);
+        else
+          fileMap[file] = [word];
+      }
+    }
+
+    // now check if the files don't contain excluded terms
+    for (var file in fileMap) {
+      var valid = true;
+
+      // check if all requirements are matched
+      if (fileMap[file].length != searchterms.length)
+        continue;
+
+      // ensure that none of the excluded terms is in the
+      // search result.
+      for (var i = 0; i < excluded.length; i++) {
+        if (terms[excluded[i]] == file ||
+            $.contains(terms[excluded[i]] || [], file)) {
+          valid = false;
+          break;
+        }
+      }
+
+      // if we have still a valid result we can add it
+      // to the result list
+      if (valid)
+        regularResults.push([filenames[file], titles[file], '', null]);
+    }
+
+    // delete unused variables in order to not waste
+    // memory until list is retrieved completely
+    delete filenames, titles, terms;
+
+    // now sort the regular results descending by title
+    regularResults.sort(function(a, b) {
+      var left = a[1].toLowerCase();
+      var right = b[1].toLowerCase();
+      return (left > right) ? -1 : ((left < right) ? 1 : 0);
+    });
+
+    // combine all results
+    var results = unimportantResults.concat(regularResults)
+      .concat(objectResults).concat(importantResults);
+
+    // print the results
+    var resultCount = results.length;
+    function displayNextItem() {
+      // results left, load the summary and display it
+      if (results.length) {
+        var item = results.pop();
+        var listItem = $('<li style="display:none"></li>');
+        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
+          // dirhtml builder
+          var dirname = item[0] + '/';
+          if (dirname.match(/\/index\/$/)) {
+            dirname = dirname.substring(0, dirname.length-6);
+          } else if (dirname == 'index/') {
+            dirname = '';
+          }
+          listItem.append($('<a/>').attr('href',
+            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+            highlightstring + item[2]).html(item[1]));
+        } else {
+          // normal html builders
+          listItem.append($('<a/>').attr('href',
+            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+            highlightstring + item[2]).html(item[1]));
+        }
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
+                item[0] + '.txt', function(data) {
+            if (data != '') {
+              listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+              Search.output.append(listItem);
+            }
+            listItem.slideDown(5, function() {
+              displayNextItem();
+            });
+          }, "text");
+        } else {
+          // no source available, just display title
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        }
+      }
+      // search finished, update title and status message
+      else {
+        Search.stopPulse();
+        Search.title.text(_('Search Results'));
+        if (!resultCount)
+          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+        else
+            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+        Search.status.fadeIn(500);
+      }
+    }
+    displayNextItem();
+  },
+
+  performObjectSearch : function(object, otherterms) {
+    var filenames = this._index.filenames;
+    var objects = this._index.objects;
+    var objnames = this._index.objnames;
+    var titles = this._index.titles;
+
+    var importantResults = [];
+    var objectResults = [];
+    var unimportantResults = [];
+
+    for (var prefix in objects) {
+      for (var name in objects[prefix]) {
+        var fullname = (prefix ? prefix + '.' : '') + name;
+        if (fullname.toLowerCase().indexOf(object) > -1) {
+          var match = objects[prefix][name];
+          var objname = objnames[match[1]][2];
+          var title = titles[match[0]];
+          // If more than one term searched for, we require other words to be
+          // found in the name/title/description
+          if (otherterms.length > 0) {
+            var haystack = (prefix + ' ' + name + ' ' +
+                            objname + ' ' + title).toLowerCase();
+            var allfound = true;
+            for (var i = 0; i < otherterms.length; i++) {
+              if (haystack.indexOf(otherterms[i]) == -1) {
+                allfound = false;
+                break;
+              }
+            }
+            if (!allfound) {
+              continue;
+            }
+          }
+          var descr = objname + _(', in ') + title;
+          anchor = match[3];
+          if (anchor == '')
+            anchor = fullname;
+          else if (anchor == '-')
+            anchor = objnames[match[1]][1] + '-' + fullname;
+          result = [filenames[match[0]], fullname, '#'+anchor, descr];
+          switch (match[2]) {
+          case 1: objectResults.push(result); break;
+          case 0: importantResults.push(result); break;
+          case 2: unimportantResults.push(result); break;
+          }
+        }
+      }
+    }
+
+    // sort results descending
+    objectResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    importantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    unimportantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    return [importantResults, objectResults, unimportantResults]
+  }
+}
+
+$(document).ready(function() {
+  Search.init();
+});
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/sidebar.js b/architecture/httpdlib/html/js/svg/api/build/html/_static/sidebar.js
new file mode 100644
index 0000000..a45e192
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/sidebar.js
@@ -0,0 +1,151 @@
+/*
+ * sidebar.js
+ * ~~~~~~~~~~
+ *
+ * This script makes the Sphinx sidebar collapsible.
+ *
+ * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
+ * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
+ * used to collapse and expand the sidebar.
+ *
+ * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
+ * and the width of the sidebar and the margin-left of the document
+ * are decreased. When the sidebar is expanded the opposite happens.
+ * This script saves a per-browser/per-session cookie used to
+ * remember the position of the sidebar among the pages.
+ * Once the browser is closed the cookie is deleted and the position
+ * reset to the default (expanded).
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+$(function() {
+  // global elements used by the functions.
+  // the 'sidebarbutton' element is defined as global after its
+  // creation, in the add_sidebar_button function
+  var bodywrapper = $('.bodywrapper');
+  var sidebar = $('.sphinxsidebar');
+  var sidebarwrapper = $('.sphinxsidebarwrapper');
+
+  // for some reason, the document has no sidebar; do not run into errors
+  if (!sidebar.length) return;
+
+  // original margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar expanded
+  var bw_margin_expanded = bodywrapper.css('margin-left');
+  var ssb_width_expanded = sidebar.width();
+
+  // margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar collapsed
+  var bw_margin_collapsed = '.8em';
+  var ssb_width_collapsed = '.8em';
+
+  // colors used by the current theme
+  var dark_color = $('.related').css('background-color');
+  var light_color = $('.document').css('background-color');
+
+  function sidebar_is_collapsed() {
+    return sidebarwrapper.is(':not(:visible)');
+  }
+
+  function toggle_sidebar() {
+    if (sidebar_is_collapsed())
+      expand_sidebar();
+    else
+      collapse_sidebar();
+  }
+
+  function collapse_sidebar() {
+    sidebarwrapper.hide();
+    sidebar.css('width', ssb_width_collapsed);
+    bodywrapper.css('margin-left', bw_margin_collapsed);
+    sidebarbutton.css({
+        'margin-left': '0',
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('»');
+    sidebarbutton.attr('title', _('Expand sidebar'));
+    document.cookie = 'sidebar=collapsed';
+  }
+
+  function expand_sidebar() {
+    bodywrapper.css('margin-left', bw_margin_expanded);
+    sidebar.css('width', ssb_width_expanded);
+    sidebarwrapper.show();
+    sidebarbutton.css({
+        'margin-left': ssb_width_expanded-12,
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('«');
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    document.cookie = 'sidebar=expanded';
+  }
+
+  function add_sidebar_button() {
+    sidebarwrapper.css({
+        'float': 'left',
+        'margin-right': '0',
+        'width': ssb_width_expanded - 28
+    });
+    // create the button
+    sidebar.append(
+        '<div id="sidebarbutton"><span>«</span></div>'
+    );
+    var sidebarbutton = $('#sidebarbutton');
+    light_color = sidebarbutton.css('background-color');
+    // find the height of the viewport to center the '<<' in the page
+    var viewport_height;
+    if (window.innerHeight)
+ 	  viewport_height = window.innerHeight;
+    else
+	  viewport_height = $(window).height();
+    sidebarbutton.find('span').css({
+        'display': 'block',
+        'margin-top': (viewport_height - sidebar.position().top - 20) / 2
+    });
+
+    sidebarbutton.click(toggle_sidebar);
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    sidebarbutton.css({
+        'color': '#FFFFFF',
+        'border-left': '1px solid ' + dark_color,
+        'font-size': '1.2em',
+        'cursor': 'pointer',
+        'height': bodywrapper.height(),
+        'padding-top': '1px',
+        'margin-left': ssb_width_expanded - 12
+    });
+
+    sidebarbutton.hover(
+      function () {
+          $(this).css('background-color', dark_color);
+      },
+      function () {
+          $(this).css('background-color', light_color);
+      }
+    );
+  }
+
+  function set_position_from_cookie() {
+    if (!document.cookie)
+      return;
+    var items = document.cookie.split(';');
+    for(var k=0; k<items.length; k++) {
+      var key_val = items[k].split('=');
+      var key = key_val[0];
+      if (key == 'sidebar') {
+        var value = key_val[1];
+        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
+          collapse_sidebar();
+        else if ((value == 'expanded') && (sidebar_is_collapsed()))
+          expand_sidebar();
+      }
+    }
+  }
+
+  add_sidebar_button();
+  var sidebarbutton = $('#sidebarbutton');
+  set_position_from_cookie();
+});
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/sphinxdoc.css b/architecture/httpdlib/html/js/svg/api/build/html/_static/sphinxdoc.css
new file mode 100644
index 0000000..b680a95
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/sphinxdoc.css
@@ -0,0 +1,339 @@
+/*
+ * sphinxdoc.css_t
+ * ~~~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- sphinxdoc theme.  Originally created by
+ * Armin Ronacher for Werkzeug.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+ at import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+    font-size: 14px;
+    letter-spacing: -0.01em;
+    line-height: 150%;
+    text-align: center;
+    background-color: #BFD1D4;
+    color: black;
+    padding: 0;
+    border: 1px solid #aaa;
+
+    margin: 0px 80px 0px 80px;
+    min-width: 740px;
+}
+
+div.document {
+    background-color: white;
+    text-align: left;
+    background-image: url(contents.png);
+    background-repeat: repeat-x;
+}
+
+div.bodywrapper {
+    margin: 0 240px 0 0;
+    border-right: 1px solid #ccc;
+}
+
+div.body {
+    margin: 0;
+    padding: 0.5em 20px 20px 20px;
+}
+
+div.related {
+    font-size: 1em;
+}
+
+div.related ul {
+    background-image: url(navigation.png);
+    height: 2em;
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+}
+
+div.related ul li {
+    margin: 0;
+    padding: 0;
+    height: 2em;
+    float: left;
+}
+
+div.related ul li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+div.related ul li a {
+    margin: 0;
+    padding: 0 5px 0 5px;
+    line-height: 1.75em;
+    color: #EE9816;
+}
+
+div.related ul li a:hover {
+    color: #3CA8E7;
+}
+
+div.sphinxsidebarwrapper {
+    padding: 0;
+}
+
+div.sphinxsidebar {
+    margin: 0;
+    padding: 0.5em 15px 15px 0;
+    width: 210px;
+    float: right;
+    font-size: 1em;
+    text-align: left;
+}
+
+div.sphinxsidebar h3, div.sphinxsidebar h4 {
+    margin: 1em 0 0.5em 0;
+    font-size: 1em;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border: 1px solid #86989B;
+    background-color: #AFC1C4;
+}
+
+div.sphinxsidebar h3 a {
+    color: white;
+}
+
+div.sphinxsidebar ul {
+    padding-left: 1.5em;
+    margin-top: 7px;
+    padding: 0;
+    line-height: 130%;
+}
+
+div.sphinxsidebar ul ul {
+    margin-left: 20px;
+}
+
+div.footer {
+    background-color: #E3EFF1;
+    color: #86989B;
+    padding: 3px 8px 3px 0;
+    clear: both;
+    font-size: 0.8em;
+    text-align: right;
+}
+
+div.footer a {
+    color: #86989B;
+    text-decoration: underline;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+p {    
+    margin: 0.8em 0 0.5em 0;
+}
+
+a {
+    color: #CA7900;
+    text-decoration: none;
+}
+
+a:hover {
+    color: #2491CF;
+}
+
+div.body a {
+    text-decoration: underline;
+}
+
+h1 {
+    margin: 0;
+    padding: 0.7em 0 0.3em 0;
+    font-size: 1.5em;
+    color: #11557C;
+}
+
+h2 {
+    margin: 1.3em 0 0.2em 0;
+    font-size: 1.35em;
+    padding: 0;
+}
+
+h3 {
+    margin: 1em 0 -0.3em 0;
+    font-size: 1.2em;
+}
+
+div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
+    color: black!important;
+}
+
+h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
+    display: none;
+    margin: 0 0 0 0.3em;
+    padding: 0 0.2em 0 0.2em;
+    color: #aaa!important;
+}
+
+h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
+h5:hover a.anchor, h6:hover a.anchor {
+    display: inline;
+}
+
+h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
+h5 a.anchor:hover, h6 a.anchor:hover {
+    color: #777;
+    background-color: #eee;
+}
+
+a.headerlink {
+    color: #c60f0f!important;
+    font-size: 1em;
+    margin-left: 6px;
+    padding: 0 4px 0 4px;
+    text-decoration: none!important;
+}
+
+a.headerlink:hover {
+    background-color: #ccc;
+    color: white!important;
+}
+
+cite, code, tt {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.01em;
+}
+
+tt {
+    background-color: #f2f2f2;
+    border-bottom: 1px solid #ddd;
+    color: #333;
+}
+
+tt.descname, tt.descclassname, tt.xref {
+    border: 0;
+}
+
+hr {
+    border: 1px solid #abc;
+    margin: 2em;
+}
+
+a tt {
+    border: 0;
+    color: #CA7900;
+}
+
+a tt:hover {
+    color: #2491CF;
+}
+
+pre {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.015em;
+    line-height: 120%;
+    padding: 0.5em;
+    border: 1px solid #ccc;
+    background-color: #f8f8f8;
+}
+
+pre a {
+    color: inherit;
+    text-decoration: underline;
+}
+
+td.linenos pre {
+    padding: 0.5em 0;
+}
+
+div.quotebar {
+    background-color: #f8f8f8;
+    max-width: 250px;
+    float: right;
+    padding: 2px 7px;
+    border: 1px solid #ccc;
+}
+
+div.topic {
+    background-color: #f8f8f8;
+}
+
+table {
+    border-collapse: collapse;
+    margin: 0 -0.5em 0 -0.5em;
+}
+
+table td, table th {
+    padding: 0.2em 0.5em 0.2em 0.5em;
+}
+
+div.admonition, div.warning {
+    font-size: 0.9em;
+    margin: 1em 0 1em 0;
+    border: 1px solid #86989B;
+    background-color: #f7f7f7;
+    padding: 0;
+}
+
+div.admonition p, div.warning p {
+    margin: 0.5em 1em 0.5em 1em;
+    padding: 0;
+}
+
+div.admonition pre, div.warning pre {
+    margin: 0.4em 1em 0.4em 1em;
+}
+
+div.admonition p.admonition-title,
+div.warning p.admonition-title {
+    margin: 0;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border-bottom: 1px solid #86989B;
+    font-weight: bold;
+    background-color: #AFC1C4;
+}
+
+div.warning {
+    border: 1px solid #940000;
+}
+
+div.warning p.admonition-title {
+    background-color: #CF0000;
+    border-bottom-color: #940000;
+}
+
+div.admonition ul, div.admonition ol,
+div.warning ul, div.warning ol {
+    margin: 0.1em 0.5em 0.5em 3em;
+    padding: 0;
+}
+
+div.versioninfo {
+    margin: 1em 0 0 0;
+    border: 1px solid #ccc;
+    background-color: #DDEAF0;
+    padding: 8px;
+    line-height: 1.3em;
+    font-size: 0.9em;
+}
+
+.viewcode-back {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/underscore.js b/architecture/httpdlib/html/js/svg/api/build/html/_static/underscore.js
new file mode 100644
index 0000000..5d89914
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/underscore.js
@@ -0,0 +1,23 @@
+// Underscore.js 0.5.5
+// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the terms of the MIT license.
+// Portions of Underscore are inspired by or borrowed from Prototype.js,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore/
+(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
+a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
+var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
+d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
+function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
+function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
+0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
+e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
+a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
+return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
+var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
+if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
+0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
+a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
+" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
+o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/up-pressed.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/up-pressed.png
new file mode 100644
index 0000000..8bd587a
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/up-pressed.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/up.png b/architecture/httpdlib/html/js/svg/api/build/html/_static/up.png
new file mode 100644
index 0000000..b946256
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/_static/up.png differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/_static/websupport.js b/architecture/httpdlib/html/js/svg/api/build/html/_static/websupport.js
new file mode 100644
index 0000000..e9bd1b8
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/_static/websupport.js
@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+  $.fn.autogrow = function() {
+    return this.each(function() {
+    var textarea = this;
+
+    $.fn.autogrow.resize(textarea);
+
+    $(textarea)
+      .focus(function() {
+        textarea.interval = setInterval(function() {
+          $.fn.autogrow.resize(textarea);
+        }, 500);
+      })
+      .blur(function() {
+        clearInterval(textarea.interval);
+      });
+    });
+  };
+
+  $.fn.autogrow.resize = function(textarea) {
+    var lineHeight = parseInt($(textarea).css('line-height'), 10);
+    var lines = textarea.value.split('\n');
+    var columns = textarea.cols;
+    var lineCount = 0;
+    $.each(lines, function() {
+      lineCount += Math.ceil(this.length / columns) || 1;
+    });
+    var height = lineHeight * (lineCount + 1);
+    $(textarea).css('height', height);
+  };
+})(jQuery);
+
+(function($) {
+  var comp, by;
+
+  function init() {
+    initEvents();
+    initComparator();
+  }
+
+  function initEvents() {
+    $('a.comment-close').live("click", function(event) {
+      event.preventDefault();
+      hide($(this).attr('id').substring(2));
+    });
+    $('a.vote').live("click", function(event) {
+      event.preventDefault();
+      handleVote($(this));
+    });
+    $('a.reply').live("click", function(event) {
+      event.preventDefault();
+      openReply($(this).attr('id').substring(2));
+    });
+    $('a.close-reply').live("click", function(event) {
+      event.preventDefault();
+      closeReply($(this).attr('id').substring(2));
+    });
+    $('a.sort-option').live("click", function(event) {
+      event.preventDefault();
+      handleReSort($(this));
+    });
+    $('a.show-proposal').live("click", function(event) {
+      event.preventDefault();
+      showProposal($(this).attr('id').substring(2));
+    });
+    $('a.hide-proposal').live("click", function(event) {
+      event.preventDefault();
+      hideProposal($(this).attr('id').substring(2));
+    });
+    $('a.show-propose-change').live("click", function(event) {
+      event.preventDefault();
+      showProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.hide-propose-change').live("click", function(event) {
+      event.preventDefault();
+      hideProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.accept-comment').live("click", function(event) {
+      event.preventDefault();
+      acceptComment($(this).attr('id').substring(2));
+    });
+    $('a.delete-comment').live("click", function(event) {
+      event.preventDefault();
+      deleteComment($(this).attr('id').substring(2));
+    });
+    $('a.comment-markup').live("click", function(event) {
+      event.preventDefault();
+      toggleCommentMarkupBox($(this).attr('id').substring(2));
+    });
+  }
+
+  /**
+   * Set comp, which is a comparator function used for sorting and
+   * inserting comments into the list.
+   */
+  function setComparator() {
+    // If the first three letters are "asc", sort in ascending order
+    // and remove the prefix.
+    if (by.substring(0,3) == 'asc') {
+      var i = by.substring(3);
+      comp = function(a, b) { return a[i] - b[i]; };
+    } else {
+      // Otherwise sort in descending order.
+      comp = function(a, b) { return b[by] - a[by]; };
+    }
+
+    // Reset link styles and format the selected sort option.
+    $('a.sel').attr('href', '#').removeClass('sel');
+    $('a.by' + by).removeAttr('href').addClass('sel');
+  }
+
+  /**
+   * Create a comp function. If the user has preferences stored in
+   * the sortBy cookie, use those, otherwise use the default.
+   */
+  function initComparator() {
+    by = 'rating'; // Default to sort by rating.
+    // If the sortBy cookie is set, use that instead.
+    if (document.cookie.length > 0) {
+      var start = document.cookie.indexOf('sortBy=');
+      if (start != -1) {
+        start = start + 7;
+        var end = document.cookie.indexOf(";", start);
+        if (end == -1) {
+          end = document.cookie.length;
+          by = unescape(document.cookie.substring(start, end));
+        }
+      }
+    }
+    setComparator();
+  }
+
+  /**
+   * Show a comment div.
+   */
+  function show(id) {
+    $('#ao' + id).hide();
+    $('#ah' + id).show();
+    var context = $.extend({id: id}, opts);
+    var popup = $(renderTemplate(popupTemplate, context)).hide();
+    popup.find('textarea[name="proposal"]').hide();
+    popup.find('a.by' + by).addClass('sel');
+    var form = popup.find('#cf' + id);
+    form.submit(function(event) {
+      event.preventDefault();
+      addComment(form);
+    });
+    $('#s' + id).after(popup);
+    popup.slideDown('fast', function() {
+      getComments(id);
+    });
+  }
+
+  /**
+   * Hide a comment div.
+   */
+  function hide(id) {
+    $('#ah' + id).hide();
+    $('#ao' + id).show();
+    var div = $('#sc' + id);
+    div.slideUp('fast', function() {
+      div.remove();
+    });
+  }
+
+  /**
+   * Perform an ajax request to get comments for a node
+   * and insert the comments into the comments tree.
+   */
+  function getComments(id) {
+    $.ajax({
+     type: 'GET',
+     url: opts.getCommentsURL,
+     data: {node: id},
+     success: function(data, textStatus, request) {
+       var ul = $('#cl' + id);
+       var speed = 100;
+       $('#cf' + id)
+         .find('textarea[name="proposal"]')
+         .data('source', data.source);
+
+       if (data.comments.length === 0) {
+         ul.html('<li>No comments yet.</li>');
+         ul.data('empty', true);
+       } else {
+         // If there are comments, sort them and put them in the list.
+         var comments = sortComments(data.comments);
+         speed = data.comments.length * 100;
+         appendComments(comments, ul);
+         ul.data('empty', false);
+       }
+       $('#cn' + id).slideUp(speed + 200);
+       ul.slideDown(speed);
+     },
+     error: function(request, textStatus, error) {
+       showError('Oops, there was a problem retrieving the comments.');
+     },
+     dataType: 'json'
+    });
+  }
+
+  /**
+   * Add a comment via ajax and insert the comment into the comment tree.
+   */
+  function addComment(form) {
+    var node_id = form.find('input[name="node"]').val();
+    var parent_id = form.find('input[name="parent"]').val();
+    var text = form.find('textarea[name="comment"]').val();
+    var proposal = form.find('textarea[name="proposal"]').val();
+
+    if (text == '') {
+      showError('Please enter a comment.');
+      return;
+    }
+
+    // Disable the form that is being submitted.
+    form.find('textarea,input').attr('disabled', 'disabled');
+
+    // Send the comment to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.addCommentURL,
+      dataType: 'json',
+      data: {
+        node: node_id,
+        parent: parent_id,
+        text: text,
+        proposal: proposal
+      },
+      success: function(data, textStatus, error) {
+        // Reset the form.
+        if (node_id) {
+          hideProposeChange(node_id);
+        }
+        form.find('textarea')
+          .val('')
+          .add(form.find('input'))
+          .removeAttr('disabled');
+	var ul = $('#cl' + (node_id || parent_id));
+        if (ul.data('empty')) {
+          $(ul).empty();
+          ul.data('empty', false);
+        }
+        insertComment(data.comment);
+        var ao = $('#ao' + node_id);
+        ao.find('img').attr({'src': opts.commentBrightImage});
+        if (node_id) {
+          // if this was a "root" comment, remove the commenting box
+          // (the user can get it back by reopening the comment popup)
+          $('#ca' + node_id).slideUp();
+        }
+      },
+      error: function(request, textStatus, error) {
+        form.find('textarea,input').removeAttr('disabled');
+        showError('Oops, there was a problem adding the comment.');
+      }
+    });
+  }
+
+  /**
+   * Recursively append comments to the main comment list and children
+   * lists, creating the comment tree.
+   */
+  function appendComments(comments, ul) {
+    $.each(comments, function() {
+      var div = createCommentDiv(this);
+      ul.append($(document.createElement('li')).html(div));
+      appendComments(this.children, div.find('ul.comment-children'));
+      // To avoid stagnating data, don't store the comments children in data.
+      this.children = null;
+      div.data('comment', this);
+    });
+  }
+
+  /**
+   * After adding a new comment, it must be inserted in the correct
+   * location in the comment tree.
+   */
+  function insertComment(comment) {
+    var div = createCommentDiv(comment);
+
+    // To avoid stagnating data, don't store the comments children in data.
+    comment.children = null;
+    div.data('comment', comment);
+
+    var ul = $('#cl' + (comment.node || comment.parent));
+    var siblings = getChildren(ul);
+
+    var li = $(document.createElement('li'));
+    li.hide();
+
+    // Determine where in the parents children list to insert this comment.
+    for(i=0; i < siblings.length; i++) {
+      if (comp(comment, siblings[i]) <= 0) {
+        $('#cd' + siblings[i].id)
+          .parent()
+          .before(li.html(div));
+        li.slideDown('fast');
+        return;
+      }
+    }
+
+    // If we get here, this comment rates lower than all the others,
+    // or it is the only comment in the list.
+    ul.append(li.html(div));
+    li.slideDown('fast');
+  }
+
+  function acceptComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.acceptCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        $('#cm' + id).fadeOut('fast');
+        $('#cd' + id).removeClass('moderate');
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem accepting the comment.');
+      }
+    });
+  }
+
+  function deleteComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.deleteCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        var div = $('#cd' + id);
+        if (data == 'delete') {
+          // Moderator mode: remove the comment and all children immediately
+          div.slideUp('fast', function() {
+            div.remove();
+          });
+          return;
+        }
+        // User mode: only mark the comment as deleted
+        div
+          .find('span.user-id:first')
+          .text('[deleted]').end()
+          .find('div.comment-text:first')
+          .text('[deleted]').end()
+          .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+                ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+          .remove();
+        var comment = div.data('comment');
+        comment.username = '[deleted]';
+        comment.text = '[deleted]';
+        div.data('comment', comment);
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem deleting the comment.');
+      }
+    });
+  }
+
+  function showProposal(id) {
+    $('#sp' + id).hide();
+    $('#hp' + id).show();
+    $('#pr' + id).slideDown('fast');
+  }
+
+  function hideProposal(id) {
+    $('#hp' + id).hide();
+    $('#sp' + id).show();
+    $('#pr' + id).slideUp('fast');
+  }
+
+  function showProposeChange(id) {
+    $('#pc' + id).hide();
+    $('#hc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val(textarea.data('source'));
+    $.fn.autogrow.resize(textarea[0]);
+    textarea.slideDown('fast');
+  }
+
+  function hideProposeChange(id) {
+    $('#hc' + id).hide();
+    $('#pc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val('').removeAttr('disabled');
+    textarea.slideUp('fast');
+  }
+
+  function toggleCommentMarkupBox(id) {
+    $('#mb' + id).toggle();
+  }
+
+  /** Handle when the user clicks on a sort by link. */
+  function handleReSort(link) {
+    var classes = link.attr('class').split(/\s+/);
+    for (var i=0; i<classes.length; i++) {
+      if (classes[i] != 'sort-option') {
+	by = classes[i].substring(2);
+      }
+    }
+    setComparator();
+    // Save/update the sortBy cookie.
+    var expiration = new Date();
+    expiration.setDate(expiration.getDate() + 365);
+    document.cookie= 'sortBy=' + escape(by) +
+                     ';expires=' + expiration.toUTCString();
+    $('ul.comment-ul').each(function(index, ul) {
+      var comments = getChildren($(ul), true);
+      comments = sortComments(comments);
+      appendComments(comments, $(ul).empty());
+    });
+  }
+
+  /**
+   * Function to process a vote when a user clicks an arrow.
+   */
+  function handleVote(link) {
+    if (!opts.voting) {
+      showError("You'll need to login to vote.");
+      return;
+    }
+
+    var id = link.attr('id');
+    if (!id) {
+      // Didn't click on one of the voting arrows.
+      return;
+    }
+    // If it is an unvote, the new vote value is 0,
+    // Otherwise it's 1 for an upvote, or -1 for a downvote.
+    var value = 0;
+    if (id.charAt(1) != 'u') {
+      value = id.charAt(0) == 'u' ? 1 : -1;
+    }
+    // The data to be sent to the server.
+    var d = {
+      comment_id: id.substring(2),
+      value: value
+    };
+
+    // Swap the vote and unvote links.
+    link.hide();
+    $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
+      .show();
+
+    // The div the comment is displayed in.
+    var div = $('div#cd' + d.comment_id);
+    var data = div.data('comment');
+
+    // If this is not an unvote, and the other vote arrow has
+    // already been pressed, unpress it.
+    if ((d.value !== 0) && (data.vote === d.value * -1)) {
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
+    }
+
+    // Update the comments rating in the local data.
+    data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
+    data.vote = d.value;
+    div.data('comment', data);
+
+    // Change the rating text.
+    div.find('.rating:first')
+      .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
+
+    // Send the vote information to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.processVoteURL,
+      data: d,
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem casting that vote.');
+      }
+    });
+  }
+
+  /**
+   * Open a reply form used to reply to an existing comment.
+   */
+  function openReply(id) {
+    // Swap out the reply link for the hide link
+    $('#rl' + id).hide();
+    $('#cr' + id).show();
+
+    // Add the reply li to the children ul.
+    var div = $(renderTemplate(replyTemplate, {id: id})).hide();
+    $('#cl' + id)
+      .prepend(div)
+      // Setup the submit handler for the reply form.
+      .find('#rf' + id)
+      .submit(function(event) {
+        event.preventDefault();
+        addComment($('#rf' + id));
+        closeReply(id);
+      })
+      .find('input[type=button]')
+      .click(function() {
+        closeReply(id);
+      });
+    div.slideDown('fast', function() {
+      $('#rf' + id).find('textarea').focus();
+    });
+  }
+
+  /**
+   * Close the reply form opened with openReply.
+   */
+  function closeReply(id) {
+    // Remove the reply div from the DOM.
+    $('#rd' + id).slideUp('fast', function() {
+      $(this).remove();
+    });
+
+    // Swap out the hide link for the reply link
+    $('#cr' + id).hide();
+    $('#rl' + id).show();
+  }
+
+  /**
+   * Recursively sort a tree of comments using the comp comparator.
+   */
+  function sortComments(comments) {
+    comments.sort(comp);
+    $.each(comments, function() {
+      this.children = sortComments(this.children);
+    });
+    return comments;
+  }
+
+  /**
+   * Get the children comments from a ul. If recursive is true,
+   * recursively include childrens' children.
+   */
+  function getChildren(ul, recursive) {
+    var children = [];
+    ul.children().children("[id^='cd']")
+      .each(function() {
+        var comment = $(this).data('comment');
+        if (recursive)
+          comment.children = getChildren($(this).find('#cl' + comment.id), true);
+        children.push(comment);
+      });
+    return children;
+  }
+
+  /** Create a div to display a comment in. */
+  function createCommentDiv(comment) {
+    if (!comment.displayed && !opts.moderator) {
+      return $('<div class="moderate">Thank you!  Your comment will show up '
+               + 'once it is has been approved by a moderator.</div>');
+    }
+    // Prettify the comment rating.
+    comment.pretty_rating = comment.rating + ' point' +
+      (comment.rating == 1 ? '' : 's');
+    // Make a class (for displaying not yet moderated comments differently)
+    comment.css_class = comment.displayed ? '' : ' moderate';
+    // Create a div for this comment.
+    var context = $.extend({}, opts, comment);
+    var div = $(renderTemplate(commentTemplate, context));
+
+    // If the user has voted on this comment, highlight the correct arrow.
+    if (comment.vote) {
+      var direction = (comment.vote == 1) ? 'u' : 'd';
+      div.find('#' + direction + 'v' + comment.id).hide();
+      div.find('#' + direction + 'u' + comment.id).show();
+    }
+
+    if (opts.moderator || comment.text != '[deleted]') {
+      div.find('a.reply').show();
+      if (comment.proposal_diff)
+        div.find('#sp' + comment.id).show();
+      if (opts.moderator && !comment.displayed)
+        div.find('#cm' + comment.id).show();
+      if (opts.moderator || (opts.username == comment.username))
+        div.find('#dc' + comment.id).show();
+    }
+    return div;
+  }
+
+  /**
+   * A simple template renderer. Placeholders such as <%id%> are replaced
+   * by context['id'] with items being escaped. Placeholders such as <#id#>
+   * are not escaped.
+   */
+  function renderTemplate(template, context) {
+    var esc = $(document.createElement('div'));
+
+    function handle(ph, escape) {
+      var cur = context;
+      $.each(ph.split('.'), function() {
+        cur = cur[this];
+      });
+      return escape ? esc.text(cur || "").html() : cur;
+    }
+
+    return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+      return handle(arguments[2], arguments[1] == '%' ? true : false);
+    });
+  }
+
+  /** Flash an error message briefly. */
+  function showError(message) {
+    $(document.createElement('div')).attr({'class': 'popup-error'})
+      .append($(document.createElement('div'))
+               .attr({'class': 'error-message'}).text(message))
+      .appendTo('body')
+      .fadeIn("slow")
+      .delay(2000)
+      .fadeOut("slow");
+  }
+
+  /** Add a link the user uses to open the comments popup. */
+  $.fn.comment = function() {
+    return this.each(function() {
+      var id = $(this).attr('id').substring(1);
+      var count = COMMENT_METADATA[id];
+      var title = count + ' comment' + (count == 1 ? '' : 's');
+      var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+      var addcls = count == 0 ? ' nocomment' : '';
+      $(this)
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-open' + addcls,
+            id: 'ao' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: image,
+              alt: 'comment',
+              title: title
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              show($(this).attr('id').substring(2));
+            })
+        )
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-close hidden',
+            id: 'ah' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: opts.closeCommentImage,
+              alt: 'close',
+              title: 'close'
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              hide($(this).attr('id').substring(2));
+            })
+        );
+    });
+  };
+
+  var opts = {
+    processVoteURL: '/_process_vote',
+    addCommentURL: '/_add_comment',
+    getCommentsURL: '/_get_comments',
+    acceptCommentURL: '/_accept_comment',
+    deleteCommentURL: '/_delete_comment',
+    commentImage: '/static/_static/comment.png',
+    closeCommentImage: '/static/_static/comment-close.png',
+    loadingImage: '/static/_static/ajax-loader.gif',
+    commentBrightImage: '/static/_static/comment-bright.png',
+    upArrow: '/static/_static/up.png',
+    downArrow: '/static/_static/down.png',
+    upArrowPressed: '/static/_static/up-pressed.png',
+    downArrowPressed: '/static/_static/down-pressed.png',
+    voting: false,
+    moderator: false
+  };
+
+  if (typeof COMMENT_OPTIONS != "undefined") {
+    opts = jQuery.extend(opts, COMMENT_OPTIONS);
+  }
+
+  var popupTemplate = '\
+    <div class="sphinx-comments" id="sc<%id%>">\
+      <p class="sort-options">\
+        Sort by:\
+        <a href="#" class="sort-option byrating">best rated</a>\
+        <a href="#" class="sort-option byascage">newest</a>\
+        <a href="#" class="sort-option byage">oldest</a>\
+      </p>\
+      <div class="comment-header">Comments</div>\
+      <div class="comment-loading" id="cn<%id%>">\
+        loading comments... <img src="<%loadingImage%>" alt="" /></div>\
+      <ul id="cl<%id%>" class="comment-ul"></ul>\
+      <div id="ca<%id%>">\
+      <p class="add-a-comment">Add a comment\
+        (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
+      <div class="comment-markup-box" id="mb<%id%>">\
+        reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+        <tt>``code``</tt>, \
+        code blocks: <tt>::</tt> and an indented block after blank line</div>\
+      <form method="post" id="cf<%id%>" class="comment-form" action="">\
+        <textarea name="comment" cols="80"></textarea>\
+        <p class="propose-button">\
+          <a href="#" id="pc<%id%>" class="show-propose-change">\
+            Propose a change ▹\
+          </a>\
+          <a href="#" id="hc<%id%>" class="hide-propose-change">\
+            Propose a change ▿\
+          </a>\
+        </p>\
+        <textarea name="proposal" id="pt<%id%>" cols="80"\
+                  spellcheck="false"></textarea>\
+        <input type="submit" value="Add comment" />\
+        <input type="hidden" name="node" value="<%id%>" />\
+        <input type="hidden" name="parent" value="" />\
+      </form>\
+      </div>\
+    </div>';
+
+  var commentTemplate = '\
+    <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
+      <div class="vote">\
+        <div class="arrow">\
+          <a href="#" id="uv<%id%>" class="vote" title="vote up">\
+            <img src="<%upArrow%>" />\
+          </a>\
+          <a href="#" id="uu<%id%>" class="un vote" title="vote up">\
+            <img src="<%upArrowPressed%>" />\
+          </a>\
+        </div>\
+        <div class="arrow">\
+          <a href="#" id="dv<%id%>" class="vote" title="vote down">\
+            <img src="<%downArrow%>" id="da<%id%>" />\
+          </a>\
+          <a href="#" id="du<%id%>" class="un vote" title="vote down">\
+            <img src="<%downArrowPressed%>" />\
+          </a>\
+        </div>\
+      </div>\
+      <div class="comment-content">\
+        <p class="tagline comment">\
+          <span class="user-id"><%username%></span>\
+          <span class="rating"><%pretty_rating%></span>\
+          <span class="delta"><%time.delta%></span>\
+        </p>\
+        <div class="comment-text comment"><#text#></div>\
+        <p class="comment-opts comment">\
+          <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\
+          <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\
+          <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\
+          <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\
+          <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
+          <span id="cm<%id%>" class="moderation hidden">\
+            <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
+          </span>\
+        </p>\
+        <pre class="proposal" id="pr<%id%>">\
+<#proposal_diff#>\
+        </pre>\
+          <ul class="comment-children" id="cl<%id%>"></ul>\
+        </div>\
+        <div class="clearleft"></div>\
+      </div>\
+    </div>';
+
+  var replyTemplate = '\
+    <li>\
+      <div class="reply-div" id="rd<%id%>">\
+        <form id="rf<%id%>">\
+          <textarea name="comment" cols="80"></textarea>\
+          <input type="submit" value="Add reply" />\
+          <input type="button" value="Cancel" />\
+          <input type="hidden" name="parent" value="<%id%>" />\
+          <input type="hidden" name="node" value="" />\
+        </form>\
+      </div>\
+    </li>';
+
+  $(document).ready(function() {
+    init();
+  });
+})(jQuery);
+
+$(document).ready(function() {
+  // add comment anchors for all paragraphs that are commentable
+  $('.sphinx-has-comment').comment();
+
+  // highlight search words in search results
+  $("div.context").each(function() {
+    var params = $.getQueryParameters();
+    var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+    var result = $(this);
+    $.each(terms, function() {
+      result.highlightText(this.toLowerCase(), 'highlighted');
+    });
+  });
+
+  // directly open comment window if requested
+  var anchor = document.location.hash;
+  if (anchor.substring(0, 9) == '#comment-') {
+    $('#ao' + anchor.substring(9)).click();
+    document.location.hash = '#s' + anchor.substring(9);
+  }
+});
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/constants.html b/architecture/httpdlib/html/js/svg/api/build/html/constants.html
new file mode 100644
index 0000000..c533fa4
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/constants.html
@@ -0,0 +1,219 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Constants — Faust Web UI API 0.0.0 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.0',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Faust Web UI API 0.0.0 documentation" href="index.html" />
+    <link rel="next" title="Customizing the Web UI" href="customizing.html" />
+    <link rel="prev" title="Overview" href="overview.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="customizing.html" title="Customizing the Web UI"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="overview.html" title="Overview"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="overview.html"
+                        title="previous chapter">Overview</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="customizing.html"
+                        title="next chapter">Customizing the Web UI</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/constants.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="constants">
+<h1>Constants<a class="headerlink" href="#constants" title="Permalink to this headline">¶</a></h1>
+<p>Certain constants are defined in the Web UI API to facilitate customization.
+As explained in the next chapter, these constants can be used directly in
+external JS files or in the URL itself to control the look and feel of the
+faust application.  Examples of this are given in the next chapter as well.</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="26%" />
+<col width="44%" />
+<col width="30%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Value of internal representation</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.TEXT_HEIGHT</td>
+<td>Estimation of the height of text</td>
+<td>20</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.TEXT_PADDING</td>
+<td>Padding between an object and its label</td>
+<td>10</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.VALUE_BOX_W</td>
+<td>Width of the value box of an object</td>
+<td>60</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.VALUE_BOX_H</td>
+<td>Height of the value box of an object</td>
+<td>60</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.TEXT_BOX_PADDING</td>
+<td>Padding between an object and its value box</td>
+<td>3</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.X_AXIS</td>
+<td>Enum-like constant for the X axis</td>
+<td>0</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.Y_AXIS</td>
+<td>Enum-like constant for the Y axis</td>
+<td>1</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.NO_AXES</td>
+<td>Enum-like constant for the end of axis iterators</td>
+<td>2</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.LEFT</td>
+<td>Enum-like constant for left</td>
+<td>-1</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.RIGHT</td>
+<td>Enum-like constant for rifght</td>
+<td>1</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.UP</td>
+<td>Enum-like constant for up</td>
+<td>-1</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.DOWN</td>
+<td>Enum-like constant for down</td>
+<td>1</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.CENTER</td>
+<td>Enum-like constant for center</td>
+<td>0</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.NONE</td>
+<td>Representation of JS null</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.BLACK</td>
+<td>The color black</td>
+<td>[0,0,0]</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.WHITE</td>
+<td>The color white</td>
+<td>[255,255,255]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.CYAN</td>
+<td>The color cyan</td>
+<td>[0,255,255]</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.GREY</td>
+<td>The color grey</td>
+<td>[100,100,100]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.PINK</td>
+<td>The color pink</td>
+<td>[233,150,122]</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.GREEN</td>
+<td>The color green</td>
+<td>[173,255,47]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.KERMIT</td>
+<td>The color kermit</td>
+<td>[47,243,160]</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.PALEGREEN</td>
+<td>The color pale green</td>
+<td>[152,251,152]</td>
+</tr>
+</tbody>
+</table>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="customizing.html" title="Customizing the Web UI"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="overview.html" title="Overview"
+             >previous</a> |</li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © Copyright 2013, Grame.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/customizing.html b/architecture/httpdlib/html/js/svg/api/build/html/customizing.html
new file mode 100644
index 0000000..ef33d58
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/customizing.html
@@ -0,0 +1,1128 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Customizing the Web UI — Faust Web UI API 0.0.0 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.0',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Faust Web UI API 0.0.0 documentation" href="index.html" />
+    <link rel="prev" title="Constants" href="constants.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="constants.html" title="Constants"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Customizing the Web UI</a><ul>
+<li><a class="reference internal" href="#external-css-files">External CSS files</a><ul>
+<li><a class="reference internal" href="#rotating-button">Rotating Button</a></li>
+<li><a class="reference internal" href="#slider-both-horizontal-and-vertical">Slider (both horizontal and vertical)</a></li>
+<li><a class="reference internal" href="#bar-graph-both-horizontal-and-vertical">Bar Graph (both horizontal and vertical)</a></li>
+<li><a class="reference internal" href="#checkbox">Checkbox</a></li>
+<li><a class="reference internal" href="#button">Button</a></li>
+<li><a class="reference internal" href="#numerical-entry">Numerical Entry</a></li>
+<li><a class="reference internal" href="#value-box">Value Box</a></li>
+<li><a class="reference internal" href="#layout-manager-both-horizontal-and-vertical">Layout Manager (both horizontal and vertical)</a></li>
+<li><a class="reference internal" href="#tab-group">Tab Group</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#external-js-files">External JS files</a><ul>
+<li><a class="reference internal" href="#id1">Rotating Button</a></li>
+<li><a class="reference internal" href="#slider">Slider</a></li>
+<li><a class="reference internal" href="#bar-graph">Bar Graph</a></li>
+<li><a class="reference internal" href="#id2">Numerical Entry</a></li>
+<li><a class="reference internal" href="#id3">Checkbox</a></li>
+<li><a class="reference internal" href="#id4">Button</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#url-parameter-specification">URL Parameter Specification</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="constants.html"
+                        title="previous chapter">Constants</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/customizing.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="customizing-the-web-ui">
+<h1>Customizing the Web UI<a class="headerlink" href="#customizing-the-web-ui" title="Permalink to this headline">¶</a></h1>
+<p>The Web UI has a built-in customization system that allows users to specify
+the look of certain objects in the interface.  This spefication can take one
+of three forms:</p>
+<ul class="simple">
+<li>The inclusion of external CSS files</li>
+<li>The inclusion of external JavaScript files</li>
+<li>The specification of parameters in the URL</li>
+</ul>
+<div class="section" id="external-css-files">
+<h2>External CSS files<a class="headerlink" href="#external-css-files" title="Permalink to this headline">¶</a></h2>
+<p>External CSS files can be used to style the Faust Web UI by setting the css
+argument in the url.  For example, to include the CSS file
+<tt class="docutils literal"><span class="pre">http://www.ensemble101.fr/foo.css</span></tt> on the previously mentioned application,
+one would use the link:</p>
+<div class="highlight-python"><pre>http://www.ensemble101.fr:8000/#css=http://www.ensemble101.fr/foo.css</pre>
+</div>
+<p>The css argument can be specified multiple times for multiple CSS files.</p>
+<p>Below is a list of all customizable CSS parameters for all objects. Information
+on all of these parameters, as well as information on SVG CSS, can be found on
+<a class="reference external" href="http://www.w3.org/TR/SVG/styling.html">http://www.w3.org/TR/SVG/styling.html</a>.</p>
+<ul class="simple">
+<li>Clipping, Masking and Compositing properties<ul>
+<li>opacity</li>
+</ul>
+</li>
+<li>Color and Painting properties<ul>
+<li>color-profile</li>
+<li>color-rendering</li>
+<li>fill</li>
+<li>fill-opacity</li>
+<li>fill-rule</li>
+<li>stroke</li>
+<li>stroke-dasharray</li>
+<li>stroke-dashoffset</li>
+<li>stroke-linecap</li>
+<li>stroke-linejoin</li>
+<li>stroke-miterlimit</li>
+<li>stroke-opacity</li>
+<li>stroke-width</li>
+</ul>
+</li>
+<li>Font properties<ul>
+<li>font</li>
+<li>font-family</li>
+<li>font-size</li>
+<li>font-size-adjust</li>
+<li>font-stretch</li>
+<li>font-style</li>
+<li>font-variant</li>
+<li>font-weight</li>
+</ul>
+</li>
+<li>Text properties<ul>
+<li>text-rendering</li>
+<li>alignment-baseline</li>
+<li>baseline-shift</li>
+<li>dominant-baseline</li>
+<li>glyph-orientation-horizontal</li>
+<li>glyph-orientation-vertical</li>
+<li>kerning</li>
+<li>text-anchor</li>
+<li>writing-mode</li>
+<li>direction</li>
+<li>letter-spacing</li>
+<li>text-decoration</li>
+<li>unicode-bidi</li>
+<li>word-spacing</li>
+</ul>
+</li>
+</ul>
+<p>None of these parameters are set by default, as all of them are set dynamically
+in the DOM via JavaScript as described below. However, customized CSS will
+take precedence over JavaScript when set.</p>
+<p>Below is a list of all faust objects with sublists indicating the CSS
+classes that compose the objects as well as the meaning of the class.</p>
+<div class="section" id="rotating-button">
+<h3>Rotating Button<a class="headerlink" href="#rotating-button" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-rbutton-joint</td>
+<td>The “joint” in which a rotating button rotates.</td>
+</tr>
+<tr class="row-odd"><td>faust-rbutton-knob</td>
+<td>The “knob” that does the actual rotating.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="slider-both-horizontal-and-vertical">
+<h3>Slider (both horizontal and vertical)<a class="headerlink" href="#slider-both-horizontal-and-vertical" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-slider-joint</td>
+<td>The “joint” in which a slider slides.</td>
+</tr>
+<tr class="row-odd"><td>faust-slider-knob</td>
+<td>The “knob” that does the actual sliding.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="bar-graph-both-horizontal-and-vertical">
+<h3>Bar Graph (both horizontal and vertical)<a class="headerlink" href="#bar-graph-both-horizontal-and-vertical" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="38%" />
+<col width="62%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-bargraph-joint</td>
+<td>The “joint” in which a bar graph moves.</td>
+</tr>
+<tr class="row-odd"><td>faust-bargraph-knob</td>
+<td>The “meter” that does the actual showing of information.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="checkbox">
+<h3>Checkbox<a class="headerlink" href="#checkbox" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-checkbox-box</td>
+<td>The box of a checkbox.</td>
+</tr>
+<tr class="row-odd"><td>faust-checkbox-check</td>
+<td>The check of a checkbox.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="button">
+<h3>Button<a class="headerlink" href="#button" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-button-box</td>
+<td>The box of a button.</td>
+</tr>
+<tr class="row-odd"><td>faust-button-text</td>
+<td>Text of a button.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="numerical-entry">
+<h3>Numerical Entry<a class="headerlink" href="#numerical-entry" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="39%" />
+<col width="61%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-nentry-operation</td>
+<td>The operation sign (plus/minus) of a numerical entry.</td>
+</tr>
+<tr class="row-odd"><td>faust-nentry-button</td>
+<td>The button on which the operation signs appear.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="value-box">
+<h3>Value Box<a class="headerlink" href="#value-box" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-button-box</td>
+<td>The box of a value box.</td>
+</tr>
+<tr class="row-odd"><td>faust-button-text</td>
+<td>Number of a value box.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="layout-manager-both-horizontal-and-vertical">
+<h3>Layout Manager (both horizontal and vertical)<a class="headerlink" href="#layout-manager-both-horizontal-and-vertical" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-group-background</td>
+<td>The background of a layout manager.</td>
+</tr>
+<tr class="row-odd"><td>faust-group-label</td>
+<td>The label of a layout manager.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="tab-group">
+<h3>Tab Group<a class="headerlink" href="#tab-group" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Class name</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>faust-tgroup-tab</td>
+<td>A tab of a tab group.</td>
+</tr>
+<tr class="row-odd"><td>faust-tgroup-label</td>
+<td>A label of a tab in a tab group.</td>
+</tr>
+</tbody>
+</table>
+<p>Below is a model CSS file setting several of the classes above</p>
+<div class="highlight-python"><pre>.faust-slider-joint {opacity:0.2;}
+.faust-rbutton-knob {stroke-linecap:percentage;}
+.faust-tgroup-label {font-weight:bold;}</pre>
+</div>
+</div>
+</div>
+<div class="section" id="external-js-files">
+<h2>External JS files<a class="headerlink" href="#external-js-files" title="Permalink to this headline">¶</a></h2>
+<p>As the CSS specification only allows the customization of parameters in the
+specification and disallows customized parameters, faust-specific parameters
+must be specified via JavaScript.  There are numerous parameters one can
+control: the width of sliders, the girth of a rotating button’s knob, and
+the height of a button, for example, can all be controlled via JavaScript.
+This is also true of more “traditional” parameters such as fill color.
+Where there is overlap in things that can be specified in both JS and CSS
+(fill and stroke, for example), the CSS will, if specified, take priority.</p>
+<p>Often times, a customizable parameter can be set that will interfere with the
+normal display of faust information. For example, one can specify the text
+of all checkbox labels, but this would interfere with the labels specified
+by the server.  Therefore, in the tables below, there is a “Touch?” parameter
+that, when specified as “No”, means that it should not be tinkered with.</p>
+<p>External JS files can be used to style the Faust Web UI by setting the js
+argument in the url.  For example, to include the JS file
+<tt class="docutils literal"><span class="pre">http://www.ensemble101.fr/foo.js</span></tt> on the previously mentioned application,
+one would use the link:</p>
+<div class="highlight-python"><pre>http://www.ensemble101.fr:8000/#js=http://www.ensemble101.fr/foo.js</pre>
+</div>
+<p>The js argument can be specified multiple times for multiple JS files.</p>
+<p>Below is a list of all faust objects with sublists indicating the JS
+variables that may be set as well as the meaning of these variables.</p>
+<div class="section" id="id1">
+<h3>Rotating Button<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="29%" />
+<col width="40%" />
+<col width="5%" />
+<col width="26%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Touch?</th>
+<th class="head">Default</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.rbutton_inits.mom</td>
+<td>Parent widget of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.label</td>
+<td>Label of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.ir</td>
+<td>The ideal radius of the button</td>
+<td>Yes</td>
+<td>50</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.a0</td>
+<td>The angle from which the button starts</td>
+<td>Yes</td>
+<td>180</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.sweep</td>
+<td>The degrees that the button sweeps</td>
+<td>Yes</td>
+<td>180</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.sp</td>
+<td>The fraction of the sweep taken up by the knob</td>
+<td>Yes</td>
+<td>0.1</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.unit</td>
+<td>Units of the button</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.min</td>
+<td>Min value of the button</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.max</td>
+<td>Max value of the button</td>
+<td>No</td>
+<td>100</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.init</td>
+<td>Initial value of the button</td>
+<td>No</td>
+<td>50</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.step</td>
+<td>Step over the range</td>
+<td>No</td>
+<td>1</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.integer</td>
+<td>True of the initial value is an integer</td>
+<td>No</td>
+<td>false</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.ndec</td>
+<td>Number of decimal places to show</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.lpadding_y</td>
+<td>Padding between text box and label</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_HEIGHT</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.box_padding</td>
+<td>Padding between object and text box</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_BOX_PADDING</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.gravity</td>
+<td>X,Y placement in the parent widget</td>
+<td>Yes</td>
+<td>[_f4u$t.CENTER _f4u$t.CENTER]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.joint_fill</td>
+<td>Fill of the joint</td>
+<td>Yes</td>
+<td>_f4u$t.PALEGREEN</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.knob_fill</td>
+<td>Fill of the knob</td>
+<td>Yes</td>
+<td>_f4u$t.GREY</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.joint_stroke</td>
+<td>Stroke of the joint</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.knob_stroke</td>
+<td>Stroke of the knob</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.value_box_w</td>
+<td>Width of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_W</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.rbutton_inits.value_box_h</td>
+<td>Height of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_H</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.rbutton_inits.address</td>
+<td>Address on the server</td>
+<td>No</td>
+<td>null</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="slider">
+<h3>Slider<a class="headerlink" href="#slider" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="29%" />
+<col width="40%" />
+<col width="5%" />
+<col width="26%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Touch?</th>
+<th class="head">Default</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.slider_inits.mom</td>
+<td>Parent widget of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.label</td>
+<td>Label of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.axis</td>
+<td>Orientation of the object</td>
+<td>No</td>
+<td>_f4u$t.X_AXIS</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.girth</td>
+<td>Width of the object</td>
+<td>Yes</td>
+<td>40</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.length</td>
+<td>Length of the object</td>
+<td>Yes</td>
+<td>200</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.sp</td>
+<td>The fraction of the slider taken up by the knob</td>
+<td>Yes</td>
+<td>0.1</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.unit</td>
+<td>Units of the slider</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.min</td>
+<td>Min value of the button</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.max</td>
+<td>Max value of the button</td>
+<td>No</td>
+<td>100</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.init</td>
+<td>Initial value of the button</td>
+<td>No</td>
+<td>50</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.step</td>
+<td>Step over the range</td>
+<td>No</td>
+<td>1</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.integer</td>
+<td>True of the initial value is an integer</td>
+<td>No</td>
+<td>false</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.ndec</td>
+<td>Number of decimal places to show</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.lpadding_y</td>
+<td>Padding between text box and label</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_HEIGHT</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.box_padding</td>
+<td>Padding between object and text box</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_BOX_PADDING</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.gravity</td>
+<td>X,Y placement in the parent widget</td>
+<td>Yes</td>
+<td>[_f4u$t.CENTER _f4u$t.CENTER]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.joint_fill</td>
+<td>Fill of the joint</td>
+<td>Yes</td>
+<td>_f4u$t.PALEGREEN</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.knob_fill</td>
+<td>Fill of the knob</td>
+<td>Yes</td>
+<td>_f4u$t.GREY</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.joint_stroke</td>
+<td>Stroke of the joint</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.knob_stroke</td>
+<td>Stroke of the knob</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.value_box_w</td>
+<td>Width of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_W</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.slider_inits.value_box_h</td>
+<td>Height of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_H</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.slider_inits.address</td>
+<td>Address on the server</td>
+<td>No</td>
+<td>null</td>
+</tr>
+</tbody>
+</table>
+<p>In order to customize horizontal and vertical sliders individually, the
+properties above may be set by adding v or h before slider (i.e. _f4u$t.vslider_inits.joint_stroke).</p>
+</div>
+<div class="section" id="bar-graph">
+<h3>Bar Graph<a class="headerlink" href="#bar-graph" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="29%" />
+<col width="40%" />
+<col width="5%" />
+<col width="26%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Touch?</th>
+<th class="head">Default</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.bargraph_inits.mom</td>
+<td>Parent widget of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.label</td>
+<td>Label of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.axis</td>
+<td>Orientation of the object</td>
+<td>No</td>
+<td>_f4u$t.X_AXIS</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.girth</td>
+<td>Width of the object</td>
+<td>Yes</td>
+<td>40</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.length</td>
+<td>Length of the object</td>
+<td>Yes</td>
+<td>200</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.unit</td>
+<td>Units of the slider</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.min</td>
+<td>Min value of the button</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.max</td>
+<td>Max value of the button</td>
+<td>No</td>
+<td>100</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.init</td>
+<td>Initial value of the button</td>
+<td>No</td>
+<td>50</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.step</td>
+<td>Step over the range</td>
+<td>No</td>
+<td>1</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.integer</td>
+<td>True of the initial value is an integer</td>
+<td>No</td>
+<td>false</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.ndec</td>
+<td>Number of decimal places to show</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.lpadding_y</td>
+<td>Padding between text box and label</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_HEIGHT</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.box_padding</td>
+<td>Padding between object and text box</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_BOX_PADDING</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.gravity</td>
+<td>X,Y placement in the parent widget</td>
+<td>Yes</td>
+<td>[_f4u$t.CENTER _f4u$t.CENTER]</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.joint_fill</td>
+<td>Fill of the joint</td>
+<td>Yes</td>
+<td>_f4u$t.PALEGREEN</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.meter_fill</td>
+<td>Fill of the meter</td>
+<td>Yes</td>
+<td>_f4u$t.GREY</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.joint_stroke</td>
+<td>Stroke of the joint</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.meter_stroke</td>
+<td>Stroke of the meter</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.value_box_w</td>
+<td>Width of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_W</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.bargraph_inits.value_box_h</td>
+<td>Height of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_H</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.bargraph_inits.address</td>
+<td>Address on the server</td>
+<td>No</td>
+<td>null</td>
+</tr>
+</tbody>
+</table>
+<p>In order to customize horizontal and vertical bar graphs individually, the
+properties above may be set by adding v or h before bar graph (i.e. _f4u$t.vbargraph_inits.joint_stroke).</p>
+</div>
+<div class="section" id="id2">
+<h3>Numerical Entry<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="30%" />
+<col width="39%" />
+<col width="5%" />
+<col width="25%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Touch?</th>
+<th class="head">Default</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.nentry_inits.mom</td>
+<td>Parent widget of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.label</td>
+<td>Label of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.length</td>
+<td>Length of the object</td>
+<td>Yes</td>
+<td>200</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.unit</td>
+<td>Units of the slider</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.min</td>
+<td>Min value of the button</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.max</td>
+<td>Max value of the button</td>
+<td>No</td>
+<td>100</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.init</td>
+<td>Initial value of the button</td>
+<td>No</td>
+<td>50</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.step</td>
+<td>Step over the range</td>
+<td>No</td>
+<td>1</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.integer</td>
+<td>True of the initial value is an integer</td>
+<td>No</td>
+<td>false</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.ndec</td>
+<td>Number of decimal places to show</td>
+<td>No</td>
+<td>0</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.lpadding_y</td>
+<td>Padding between text box and label</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_HEIGHT</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.box_padding</td>
+<td>Padding between object and text box</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_BOX_PADDING</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.padding</td>
+<td>Padding around an operation in a button</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_BOX_PADDING</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.gravity</td>
+<td>X,Y placement in the parent widget</td>
+<td>Yes</td>
+<td>[_f4u$t.CENTER _f4u$t.CENTER]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.operation_fill</td>
+<td>Fill of the operation symbol</td>
+<td>Yes</td>
+<td>_f4u$t.PALEGREEN</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.button_fill</td>
+<td>Fill of the operation button</td>
+<td>Yes</td>
+<td>_f4u$t.GREY</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.operation_stroke</td>
+<td>Stroke of the operation symbol</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.button_stroke</td>
+<td>Stroke of the operation button</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.value_box_w</td>
+<td>Width of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_W</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.nentry_inits.value_box_h</td>
+<td>Height of the value box</td>
+<td>Yes</td>
+<td>_f4u$t.VALUE_BOX_H</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.nentry_inits.address</td>
+<td>Address on the server</td>
+<td>No</td>
+<td>null</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="id3">
+<h3>Checkbox<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="32%" />
+<col width="33%" />
+<col width="6%" />
+<col width="29%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Touch?</th>
+<th class="head">Default</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.checkbox_inits.mom</td>
+<td>Parent widget of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.checkbox_inits.label</td>
+<td>Label of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.checkbox_inits.d</td>
+<td>Dimension</td>
+<td>Yes</td>
+<td>19</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.checkbox_inits.gravity</td>
+<td>X,Y placement in the parent widget</td>
+<td>Yes</td>
+<td>[_f4u$t.CENTER, _f4u$t.CENTER]</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.checkbox_inits.check_fill</td>
+<td>Fill of the check</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.checkbox_inits.check_stroke</td>
+<td>Stroke of the check</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.checkbox_inits.box_fill</td>
+<td>Fill of the box</td>
+<td>Yes</td>
+<td>_f4u$t.WHITE</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.checkbox_inits.box_stroke</td>
+<td>Stroke of the box</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.checkbox_inits.init</td>
+<td>Initial value of the checkbox</td>
+<td>No</td>
+<td>false</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.checkbox_inits.lpadding_y</td>
+<td>Padding between object and label</td>
+<td>Yes</td>
+<td>_f4u$t.TEXT_HEIGHT</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.checkbox_inits.address</td>
+<td>Address on the server</td>
+<td>No</td>
+<td>null</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="id4">
+<h3>Button<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<table border="1" class="docutils">
+<colgroup>
+<col width="32%" />
+<col width="35%" />
+<col width="6%" />
+<col width="28%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Property name</th>
+<th class="head">Description</th>
+<th class="head">Touch?</th>
+<th class="head">Default</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>_f4u$t.button_inits.mom</td>
+<td>Parent widget of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.button_inits.label</td>
+<td>Label of the object</td>
+<td>No</td>
+<td>null</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.button_inits.ideal_width</td>
+<td>Ideal width <a class="footnote-reference" href="#f1" id="id5">[1]</a></td>
+<td>Yes</td>
+<td>80</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.button_inits.ideal_height</td>
+<td>Ideal height <a class="footnote-reference" href="#f1" id="id6">[1]</a></td>
+<td>Yes</td>
+<td>40</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.button_inits.gravity</td>
+<td>X,Y placement in the parent widget</td>
+<td>Yes</td>
+<td>[_f4u$t.CENTER _f4u$t.CENTER]</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.button_inits.fill_on</td>
+<td>Fill when the button is on</td>
+<td>Yes</td>
+<td>_f4u$t.PINK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.button_inits.fill_off</td>
+<td>Fill when the button is off</td>
+<td>Yes</td>
+<td>_f4u$t.GREEN</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.button_inits.stroke</td>
+<td>Stroke of the button box</td>
+<td>Yes</td>
+<td>_f4u$t.BLACK</td>
+</tr>
+<tr class="row-even"><td>_f4u$t.button_inits.baseline_skip</td>
+<td>Gap between bottom of button and label</td>
+<td>Yes</td>
+<td>5</td>
+</tr>
+<tr class="row-odd"><td>_f4u$t.button_inits.address</td>
+<td>Address on the server</td>
+<td>No</td>
+<td>null</td>
+</tr>
+</tbody>
+</table>
+<p>Below is a model JS file setting several of the variables above</p>
+<div class="highlight-python"><pre>_f4u$t.button_inits.stroke = _f4u$t.BLACK;
+_f4u$t.checkbox_inits.d = 40;
+_f4u$t.hslider_inits.sp = 0.3;</pre>
+</div>
+</div>
+</div>
+<div class="section" id="url-parameter-specification">
+<h2>URL Parameter Specification<a class="headerlink" href="#url-parameter-specification" title="Permalink to this headline">¶</a></h2>
+<p>JS parameters can also be specified in the URL.  For example, the model
+JS file above can be embeded in the URL as follows</p>
+<div class="highlight-python"><pre>http://www.ensemble101.fr:8000/#button_inits.stroke=_f4u$t.BLACK&checkbox_inits.d=40&hslider_inits.sp=0.3</pre>
+</div>
+<p class="rubric">Footnotes</p>
+<table class="docutils footnote" frame="void" id="f1" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label">[1]</td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id6">2</a>)</em> Ideal because it will adapt to the size of the bounded text if necessary.</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="constants.html" title="Constants"
+             >previous</a> |</li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © Copyright 2013, Grame.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/genindex.html b/architecture/httpdlib/html/js/svg/api/build/html/genindex.html
new file mode 100644
index 0000000..e7edfce
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/genindex.html
@@ -0,0 +1,95 @@
+
+
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Index — Faust Web UI API 0.0.0 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.0',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Faust Web UI API 0.0.0 documentation" href="index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="#" title="General Index"
+             accesskey="I">index</a></li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+
+   
+
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+
+<h1 id="index">Index</h1>
+
+<div class="genindex-jumpbox">
+ 
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="#" title="General Index"
+             >index</a></li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © Copyright 2013, Grame.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/index.html b/architecture/httpdlib/html/js/svg/api/build/html/index.html
new file mode 100644
index 0000000..198a498
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/index.html
@@ -0,0 +1,134 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Welcome to Faust Web UI API’s documentation! — Faust Web UI API 0.0.0 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.0',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Faust Web UI API 0.0.0 documentation" href="#" />
+    <link rel="next" title="Overview" href="overview.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="overview.html" title="Overview"
+             accesskey="N">next</a> |</li>
+        <li><a href="#">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="#">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Welcome to Faust Web UI API’s documentation!</a><ul>
+</ul>
+</li>
+<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
+</ul>
+
+  <h4>Next topic</h4>
+  <p class="topless"><a href="overview.html"
+                        title="next chapter">Overview</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/index.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="welcome-to-faust-web-ui-api-s-documentation">
+<h1>Welcome to Faust Web UI API’s documentation!<a class="headerlink" href="#welcome-to-faust-web-ui-api-s-documentation" title="Permalink to this headline">¶</a></h1>
+<p>Contents:</p>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="overview.html">Overview</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="overview.html#using-the-web-ui">Using the Web UI</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="constants.html">Constants</a></li>
+<li class="toctree-l1"><a class="reference internal" href="customizing.html">Customizing the Web UI</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="customizing.html#external-css-files">External CSS files</a></li>
+<li class="toctree-l2"><a class="reference internal" href="customizing.html#external-js-files">External JS files</a></li>
+<li class="toctree-l2"><a class="reference internal" href="customizing.html#url-parameter-specification">URL Parameter Specification</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" id="indices-and-tables">
+<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
+<ul class="simple">
+<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
+<li><a class="reference internal" href="py-modindex.html"><em>Module Index</em></a></li>
+<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
+</ul>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="overview.html" title="Overview"
+             >next</a> |</li>
+        <li><a href="#">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © Copyright 2013, Grame.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/objects.inv b/architecture/httpdlib/html/js/svg/api/build/html/objects.inv
new file mode 100644
index 0000000..d9d4396
Binary files /dev/null and b/architecture/httpdlib/html/js/svg/api/build/html/objects.inv differ
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/overview.html b/architecture/httpdlib/html/js/svg/api/build/html/overview.html
new file mode 100644
index 0000000..dc215cb
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/overview.html
@@ -0,0 +1,138 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Overview — Faust Web UI API 0.0.0 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.0',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Faust Web UI API 0.0.0 documentation" href="index.html" />
+    <link rel="next" title="Customizing the Web UI" href="customizing.html" />
+    <link rel="prev" title="Welcome to Faust Web UI API’s documentation!" href="index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="customizing.html" title="Customizing the Web UI"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Welcome to Faust Web UI API’s documentation!"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Overview</a><ul>
+<li><a class="reference internal" href="#using-the-web-ui">Using the Web UI</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="index.html"
+                        title="previous chapter">Welcome to Faust Web UI API’s documentation!</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="customizing.html"
+                        title="next chapter">Customizing the Web UI</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/overview.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="overview">
+<h1>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h1>
+<p>This page provides an overview of the Faust Web UI.  The Faust Web UI can be
+used to control Faust applications running on a server via GET requests.
+An experimental version of WebKit also provides a serverless version of the
+Web UI.</p>
+<div class="section" id="using-the-web-ui">
+<h2>Using the Web UI<a class="headerlink" href="#using-the-web-ui" title="Permalink to this headline">¶</a></h2>
+<p>In order to use the Faust Web UI, one may access a server running a Faust
+application over the appropriate port via a browser that visualizes SVG
+according to the W3C specification (<a class="reference external" href="http://www.w3.org/2000/svg">http://www.w3.org/2000/svg</a>).  Once the
+URL is composed, the graphical UI for the application will be displayed in
+the browser.  So, for example, if the website www.ensemble101.fr is running
+a faust application on port 8000, the URL <a class="reference external" href="http://www.ensemble101.fr:8000">http://www.ensemble101.fr:8000</a> would
+be used to access the application.</p>
+<p>The goal of Faust Web UI is to provide a robust graphical UI similar to that
+of other Faust interfaces (Qt, gtk+, etc.). Should a Faust Web UI fail to
+parallel one of these interfaces in the objects drawn or their responsiveness,
+an e-mail can be sent to <a class="reference external" href="mailto:faustwebui%40grame.fr">faustwebui<span>@</span>grame<span>.</span>fr</a>.</p>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="customizing.html" title="Customizing the Web UI"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Welcome to Faust Web UI API’s documentation!"
+             >previous</a> |</li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © Copyright 2013, Grame.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/search.html b/architecture/httpdlib/html/js/svg/api/build/html/search.html
new file mode 100644
index 0000000..763263a
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/search.html
@@ -0,0 +1,99 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Search — Faust Web UI API 0.0.0 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.0.0',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <script type="text/javascript" src="_static/searchtools.js"></script>
+    <link rel="top" title="Faust Web UI API 0.0.0 documentation" href="index.html" />
+  <script type="text/javascript">
+    jQuery(function() { Search.loadIndex("searchindex.js"); });
+  </script>
+   
+
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1 id="search-documentation">Search</h1>
+  <div id="fallback" class="admonition warning">
+  <script type="text/javascript">$('#fallback').hide();</script>
+  <p>
+    Please activate JavaScript to enable the search
+    functionality.
+  </p>
+  </div>
+  <p>
+    From here you can search these documents. Enter your search
+    words into the box below and click "search". Note that the search
+    function will automatically search for all of the words. Pages
+    containing fewer words won't appear in the result list.
+  </p>
+  <form action="" method="get">
+    <input type="text" name="q" value="" />
+    <input type="submit" value="search" />
+    <span id="search-progress" style="padding-left: 10px"></span>
+  </form>
+  
+  <div id="search-results">
+  
+  </div>
+
+          </div>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li><a href="index.html">Faust Web UI API 0.0.0 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © Copyright 2013, Grame.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/build/html/searchindex.js b/architecture/httpdlib/html/js/svg/api/build/html/searchindex.js
new file mode 100644
index 0000000..f3af65a
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/build/html/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({objects:{},terms:{represent:2,all:3,follow:3,content:0,graph:3,decim:3,descript:[2,3],init:3,sent:1,fals:3,slider_init:3,cyan:2,button:3,list:3,miterlimit:3,adjust:3,dimens:3,direct:3,sign:3,port:1,index:0,appear:3,joint_fil:3,access:1,spefic:3,experiment:1,widget:3,button_init:3,address:3,vertic:3,valu:[2,3],box:[2,3],search:0,shift:3,via:[1,3],modul:0,button_strok:3,api:[0,2],famili:3,unit:3,from:3,describ:3,would:[1,3],linecap:3,rbutton_init:3,next:2,websit:1,ideal_width:3,taken:3,more:3,visual:1,ensemble101:[1,3],webkit:1,operation_strok:3,must:3,none:[2,3],graphic:1,word:3,vslider_init:3,can:[1,2,3],control:[1,2,3],indic:[0,3],stroke:3,tab:3,pink:[2,3],tgroup:3,end:2,goal:1,write:3,css:[0,3],max:3,variant:3,befor:3,mai:[1,3],multipl:3,parallel:1,domin:3,inform:3,preced:3,green:[2,3],allow:3,order:[1,3],y_axi:2,checkbox:3,composit:3,rotat:3,over:[1,3],move:3,becaus:3,meter:3,ideal_height:3,dynam:3,paramet:[0,3],style:3,group:3,render:3,gtk:1,mail:1,therefor:3,them:3,initi:3,mention:3,facilit:2,name:[2,3],kern:3,slide:3,mode:3,found:3,unicod:3,mean:3,weight:3,individu:3,iter:2,orient:3,baselin:3,variabl:3,fill_on:3,space:3,box_strok:3,footnot:3,adapt:3,w3c:1,org:[1,3],angl:3,thing:3,length:3,place:3,oper:3,rang:3,directli:2,feel:2,onc:1,number:3,size:3,prioriti:3,given:2,start:3,system:3,paint:3,white:[2,3],specifi:3,slider:3,provid:1,horizont:3,checkbox_init:3,browser:1,button_fil:3,clip:3,argument:3,joint_strok:3,dashoffset:3,"null":[2,3],minu:3,built:3,min:3,also:[1,3],ideal:3,take:3,which:3,graviti:3,normal:3,object:[1,2,3],letter:3,"class":3,knob_strok:3,tradit:3,placement:3,dom:3,url:[0,1,2,3],request:1,doe:3,grame:1,axi:[2,3],bargraph:3,show:3,text:[2,3],sublist:3,radiu:3,text_height:[2,3],font:3,onli:3,layout:3,explain:2,should:[1,3],version:1,black:[2,3],get:1,joint:3,fill_off:3,bar:3,check_fil:3,box_pad:3,where:3,set:3,kermit:2,respons:1,fail:1,label:[2,3],baseline_skip:3,between:[2,3],drawn:1,accord:1,parent:3,numer:3,javascript:3,disallow:3,linejoin:3,both:3,opac:3,howev:3,grei:[2,3],etc:1,color:[2,3],overview:[0,1],sweep:3,height:[2,3],palegreen:[2,3],stretch:3,compos:[1,3],knob_fil:3,dasharrai:3,box_fil:3,rbutton:3,gap:3,look:[2,3],align:3,properti:[2,3],defin:2,text_box_pad:[2,3],abov:3,anchor:3,"_f4u":[2,3],girth:3,knob:3,customiz:3,meter_strok:3,tabl:[0,3],itself:2,sever:3,decor:3,welcom:0,html:3,pad:[2,3],document:0,http:[1,3],user:3,extern:[0,2,3],robust:1,appropri:1,off:3,center:[2,3],entri:3,well:[2,3],vbargraph_init:3,exampl:[1,2,3],thi:[1,2,3],model:3,left:2,nentry_init:3,mom:3,lpadding_i:3,touch:3,previous:3,web:[0,1,2,3],interfer:3,x_axi:[2,3],other:1,nentri:3,applic:[1,2,3],around:3,meter_fil:3,background:3,like:2,specif:[0,1,3],integ:3,server:[1,3],necessari:3,hslider_init:3,manag:3,www:[1,3],right:2,often:3,percentag:3,intern:2,pale:2,glyph:3,bottom:3,value_box_h:[2,3],overlap:3,estim:2,value_box_w:[2,3],foo:3,plu:3,run:1,bold:3,"enum":2,step:3,tinker:3,operation_fil:3,chapter:2,actual:3,ndec:3,page:[0,1],degre:3,faust:[0,1,2,3],bound:3,three:3,down:2,inclus:3,custom:[0,2,3],width:[2,3],interfac:[1,3],includ:3,fraction:3,form:3,link:3,"true":3,check_strok:3,"default":3,displai:[1,3],below:3,bidi:3,faustwebui:1,embed:3,similar:1,constant:[0,2],certain:[2,3],file:[0,2,3],text_pad:2,check:3,fill:3,when:3,rifght:2,no_ax:2,bargraph_init:3,serverless:1,symbol:3,svg:[1,3],mask:3,rule:3,time:3,profil:3},objtypes:{},titles:["Welcome to Faust Web UI API’s documentation!","Overview","Constants","Customizing the Web UI"],objnames:{},filenames:["index","overview","constants","customizing"]})
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/api/make.bat b/architecture/httpdlib/html/js/svg/api/make.bat
new file mode 100644
index 0000000..6575321
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/make.bat
@@ -0,0 +1,190 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+set I18NSPHINXOPTS=%SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  texinfo    to make Texinfo files
+	echo.  gettext    to make PO message catalogs
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\FaustWebUIAPI.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\FaustWebUIAPI.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "texinfo" (
+	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+	goto end
+)
+
+if "%1" == "gettext" (
+	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
diff --git a/architecture/httpdlib/html/js/svg/api/source/conf.py b/architecture/httpdlib/html/js/svg/api/source/conf.py
new file mode 100644
index 0000000..16b2b84
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/source/conf.py
@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+#
+# Faust Web UI API documentation build configuration file, created by
+# sphinx-quickstart on Tue Jan  1 15:41:15 2013.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Faust Web UI API'
+copyright = u'2013, Grame'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.0.0'
+# The full version, including alpha/beta/rc tags.
+release = '0.0.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'sphinxdoc'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'FaustWebUIAPIdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'FaustWebUIAPI.tex', u'Faust Web UI API Documentation',
+   u'Grame', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'faustwebuiapi', u'Faust Web UI API Documentation',
+     [u'Grame'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'FaustWebUIAPI', u'Faust Web UI API Documentation',
+   u'Grame', 'FaustWebUIAPI', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
diff --git a/architecture/httpdlib/html/js/svg/api/source/constants.rst b/architecture/httpdlib/html/js/svg/api/source/constants.rst
new file mode 100644
index 0000000..3f8e890
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/source/constants.rst
@@ -0,0 +1,34 @@
+Constants
+=========
+
+Certain constants are defined in the Web UI API to facilitate customization.
+As explained in the next chapter, these constants can be used directly in
+external JS files or in the URL itself to control the look and feel of the
+faust application.  Examples of this are given in the next chapter as well.
+
+============================  ================================================  ================================
+Property name                 Description                                       Value of internal representation
+============================  ================================================  ================================
+_f4u$t.TEXT_HEIGHT            Estimation of the height of text                  20
+_f4u$t.TEXT_PADDING           Padding between an object and its label           10
+_f4u$t.VALUE_BOX_W            Width of the value box of an object               60
+_f4u$t.VALUE_BOX_H            Height of the value box of an object              60
+_f4u$t.TEXT_BOX_PADDING       Padding between an object and its value box       3
+_f4u$t.X_AXIS                 Enum-like constant for the X axis                 0
+_f4u$t.Y_AXIS                 Enum-like constant for the Y axis                 1
+_f4u$t.NO_AXES                Enum-like constant for the end of axis iterators  2
+_f4u$t.LEFT                   Enum-like constant for left                       -1
+_f4u$t.RIGHT                  Enum-like constant for rifght                     1
+_f4u$t.UP                     Enum-like constant for up                         -1
+_f4u$t.DOWN                   Enum-like constant for down                       1
+_f4u$t.CENTER                 Enum-like constant for center                     0
+_f4u$t.NONE                   Representation of JS null                         null
+_f4u$t.BLACK                  The color black                                   [0,0,0]
+_f4u$t.WHITE                  The color white                                   [255,255,255]
+_f4u$t.CYAN                   The color cyan                                    [0,255,255]
+_f4u$t.GREY                   The color grey                                    [100,100,100]
+_f4u$t.PINK                   The color pink                                    [233,150,122]
+_f4u$t.GREEN                  The color green                                   [173,255,47]
+_f4u$t.KERMIT                 The color kermit                                  [47,243,160]
+_f4u$t.PALEGREEN              The color pale green                              [152,251,152]
+============================  ================================================  ================================
diff --git a/architecture/httpdlib/html/js/svg/api/source/customizing.rst b/architecture/httpdlib/html/js/svg/api/source/customizing.rst
new file mode 100644
index 0000000..f0ed94c
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/source/customizing.rst
@@ -0,0 +1,373 @@
+Customizing the Web UI
+======================
+
+The Web UI has a built-in customization system that allows users to specify
+the look of certain objects in the interface.  This spefication can take one
+of three forms:
+
+- The inclusion of external CSS files
+- The inclusion of external JavaScript files
+- The specification of parameters in the URL
+
+External CSS files
+------------------
+
+External CSS files can be used to style the Faust Web UI by setting the css
+argument in the url.  For example, to include the CSS file
+``http://www.ensemble101.fr/foo.css`` on the previously mentioned application,
+one would use the link::
+
+  http://www.ensemble101.fr:8000/#css=http://www.ensemble101.fr/foo.css
+
+The css argument can be specified multiple times for multiple CSS files.
+
+Below is a list of all customizable CSS parameters for all objects. Information
+on all of these parameters, as well as information on SVG CSS, can be found on
+http://www.w3.org/TR/SVG/styling.html.
+
+* Clipping, Masking and Compositing properties
+
+  * opacity
+
+* Color and Painting properties
+
+  * color-profile
+  * color-rendering
+  * fill
+  * fill-opacity
+  * fill-rule
+  * stroke
+  * stroke-dasharray
+  * stroke-dashoffset
+  * stroke-linecap
+  * stroke-linejoin
+  * stroke-miterlimit
+  * stroke-opacity
+  * stroke-width
+
+* Font properties
+
+  * font
+  * font-family
+  * font-size
+  * font-size-adjust
+  * font-stretch
+  * font-style
+  * font-variant
+  * font-weight
+
+* Text properties
+
+  * text-rendering
+  * alignment-baseline
+  * baseline-shift
+  * dominant-baseline
+  * glyph-orientation-horizontal
+  * glyph-orientation-vertical
+  * kerning
+  * text-anchor
+  * writing-mode
+  * direction
+  * letter-spacing
+  * text-decoration
+  * unicode-bidi
+  * word-spacing
+
+None of these parameters are set by default, as all of them are set dynamically
+in the DOM via JavaScript as described below. However, customized CSS will
+take precedence over JavaScript when set.
+
+Below is a list of all faust objects with sublists indicating the CSS
+classes that compose the objects as well as the meaning of the class.
+
+Rotating Button
+^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-rbutton-joint                  The "joint" in which a rotating button rotates.
+faust-rbutton-knob                   The "knob" that does the actual rotating.
+==================================   ===================================================
+
+Slider (both horizontal and vertical)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-slider-joint                   The "joint" in which a slider slides.
+faust-slider-knob                    The "knob" that does the actual sliding.
+==================================   ===================================================
+
+Bar Graph (both horizontal and vertical)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==================================   ========================================================
+Class name                           Description                        
+==================================   ========================================================
+faust-bargraph-joint                 The "joint" in which a bar graph moves.
+faust-bargraph-knob                  The "meter" that does the actual showing of information.
+==================================   ========================================================
+
+Checkbox
+^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-checkbox-box                   The box of a checkbox.
+faust-checkbox-check                 The check of a checkbox.
+==================================   ===================================================
+
+Button
+^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-button-box                     The box of a button.
+faust-button-text                    Text of a button.
+==================================   ===================================================
+
+Numerical Entry
+^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-nentry-operation               The operation sign (plus/minus) of a numerical entry.
+faust-nentry-button                  The button on which the operation signs appear.
+==================================   ===================================================
+
+Value Box
+^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-button-box                     The box of a value box.
+faust-button-text                    Number of a value box.
+==================================   ===================================================
+
+Layout Manager (both horizontal and vertical)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-group-background               The background of a layout manager.
+faust-group-label                    The label of a layout manager.
+==================================   ===================================================
+
+Tab Group
+^^^^^^^^^
+==================================   ===================================================
+Class name                           Description                        
+==================================   ===================================================
+faust-tgroup-tab                     A tab of a tab group.
+faust-tgroup-label                   A label of a tab in a tab group.
+==================================   ===================================================
+
+Below is a model CSS file setting several of the classes above ::
+
+  .faust-slider-joint {opacity:0.2;}
+  .faust-rbutton-knob {stroke-linecap:percentage;}
+  .faust-tgroup-label {font-weight:bold;}
+
+External JS files
+-----------------
+
+As the CSS specification only allows the customization of parameters in the
+specification and disallows customized parameters, faust-specific parameters
+must be specified via JavaScript.  There are numerous parameters one can
+control: the width of sliders, the girth of a rotating button's knob, and
+the height of a button, for example, can all be controlled via JavaScript.
+This is also true of more "traditional" parameters such as fill color.
+Where there is overlap in things that can be specified in both JS and CSS
+(fill and stroke, for example), the CSS will, if specified, take priority.
+
+Often times, a customizable parameter can be set that will interfere with the
+normal display of faust information. For example, one can specify the text
+of all checkbox labels, but this would interfere with the labels specified
+by the server.  Therefore, in the tables below, there is a "Touch?" parameter
+that, when specified as "No", means that it should not be tinkered with.
+
+External JS files can be used to style the Faust Web UI by setting the js
+argument in the url.  For example, to include the JS file
+``http://www.ensemble101.fr/foo.js`` on the previously mentioned application,
+one would use the link::
+
+  http://www.ensemble101.fr:8000/#js=http://www.ensemble101.fr/foo.js
+
+The js argument can be specified multiple times for multiple JS files.
+
+Below is a list of all faust objects with sublists indicating the JS
+variables that may be set as well as the meaning of these variables.
+
+Rotating Button
+^^^^^^^^^^^^^^^
+==================================   ==============================================   ======   ==============================
+Property name                        Description                                      Touch?   Default
+==================================   ==============================================   ======   ==============================
+_f4u$t.rbutton_inits.mom             Parent widget of the object                      No       null
+_f4u$t.rbutton_inits.label           Label of the object                              No       null
+_f4u$t.rbutton_inits.ir              The ideal radius of the button                   Yes      50
+_f4u$t.rbutton_inits.a0              The angle from which the button starts           Yes      180
+_f4u$t.rbutton_inits.sweep           The degrees that the button sweeps               Yes      180
+_f4u$t.rbutton_inits.sp              The fraction of the sweep taken up by the knob   Yes      0.1
+_f4u$t.rbutton_inits.unit            Units of the button                              No       null
+_f4u$t.rbutton_inits.min             Min value of the button                          No       0
+_f4u$t.rbutton_inits.max             Max value of the button                          No       100
+_f4u$t.rbutton_inits.init            Initial value of the button                      No       50
+_f4u$t.rbutton_inits.step            Step over the range                              No       1
+_f4u$t.rbutton_inits.integer         True of the initial value is an integer          No       false
+_f4u$t.rbutton_inits.ndec            Number of decimal places to show                 No       0
+_f4u$t.rbutton_inits.lpadding_y      Padding between text box and label               Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.rbutton_inits.box_padding     Padding between object and text box              Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.rbutton_inits.gravity         X,Y placement in the parent widget               Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.rbutton_inits.joint_fill      Fill of the joint                                Yes      _f4u$t.PALEGREEN
+_f4u$t.rbutton_inits.knob_fill       Fill of the knob                                 Yes      _f4u$t.GREY
+_f4u$t.rbutton_inits.joint_stroke    Stroke of the joint                              Yes      _f4u$t.BLACK
+_f4u$t.rbutton_inits.knob_stroke     Stroke of the knob                               Yes      _f4u$t.BLACK
+_f4u$t.rbutton_inits.value_box_w     Width of the value box                           Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.rbutton_inits.value_box_h     Height of the value box                          Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.rbutton_inits.address         Address on the server                            No       null
+==================================   ==============================================   ======   ==============================
+
+Slider
+^^^^^^
+==================================   ===============================================   ======   ==============================
+Property name                        Description                                       Touch?   Default
+==================================   ===============================================   ======   ==============================
+_f4u$t.slider_inits.mom              Parent widget of the object                       No       null
+_f4u$t.slider_inits.label            Label of the object                               No       null
+_f4u$t.slider_inits.axis             Orientation of the object                         No       _f4u$t.X_AXIS
+_f4u$t.slider_inits.girth            Width of the object                               Yes      40
+_f4u$t.slider_inits.length           Length of the object                              Yes      200
+_f4u$t.slider_inits.sp               The fraction of the slider taken up by the knob   Yes      0.1
+_f4u$t.slider_inits.unit             Units of the slider                               No       null
+_f4u$t.slider_inits.min              Min value of the button                           No       0
+_f4u$t.slider_inits.max              Max value of the button                           No       100
+_f4u$t.slider_inits.init             Initial value of the button                       No       50
+_f4u$t.slider_inits.step             Step over the range                               No       1
+_f4u$t.slider_inits.integer          True of the initial value is an integer           No       false
+_f4u$t.slider_inits.ndec             Number of decimal places to show                  No       0
+_f4u$t.slider_inits.lpadding_y       Padding between text box and label                Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.slider_inits.box_padding      Padding between object and text box               Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.slider_inits.gravity          X,Y placement in the parent widget                Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.slider_inits.joint_fill       Fill of the joint                                 Yes      _f4u$t.PALEGREEN
+_f4u$t.slider_inits.knob_fill        Fill of the knob                                  Yes      _f4u$t.GREY
+_f4u$t.slider_inits.joint_stroke     Stroke of the joint                               Yes      _f4u$t.BLACK
+_f4u$t.slider_inits.knob_stroke      Stroke of the knob                                Yes      _f4u$t.BLACK
+_f4u$t.slider_inits.value_box_w      Width of the value box                            Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.slider_inits.value_box_h      Height of the value box                           Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.slider_inits.address          Address on the server                             No       null
+==================================   ===============================================   ======   ==============================
+
+In order to customize horizontal and vertical sliders individually, the
+properties above may be set by adding v or h before slider (i.e. _f4u$t.vslider_inits.joint_stroke).
+
+Bar Graph
+^^^^^^^^^
+==================================     ===============================================   ======   ==============================
+Property name                          Description                                       Touch?   Default
+==================================     ===============================================   ======   ==============================
+_f4u$t.bargraph_inits.mom              Parent widget of the object                       No       null
+_f4u$t.bargraph_inits.label            Label of the object                               No       null
+_f4u$t.bargraph_inits.axis             Orientation of the object                         No       _f4u$t.X_AXIS
+_f4u$t.bargraph_inits.girth            Width of the object                               Yes      40
+_f4u$t.bargraph_inits.length           Length of the object                              Yes      200
+_f4u$t.bargraph_inits.unit             Units of the slider                               No       null
+_f4u$t.bargraph_inits.min              Min value of the button                           No       0
+_f4u$t.bargraph_inits.max              Max value of the button                           No       100
+_f4u$t.bargraph_inits.init             Initial value of the button                       No       50
+_f4u$t.bargraph_inits.step             Step over the range                               No       1
+_f4u$t.bargraph_inits.integer          True of the initial value is an integer           No       false
+_f4u$t.bargraph_inits.ndec             Number of decimal places to show                  No       0
+_f4u$t.bargraph_inits.lpadding_y       Padding between text box and label                Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.bargraph_inits.box_padding      Padding between object and text box               Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.bargraph_inits.gravity          X,Y placement in the parent widget                Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.bargraph_inits.joint_fill       Fill of the joint                                 Yes      _f4u$t.PALEGREEN
+_f4u$t.bargraph_inits.meter_fill       Fill of the meter                                 Yes      _f4u$t.GREY
+_f4u$t.bargraph_inits.joint_stroke     Stroke of the joint                               Yes      _f4u$t.BLACK
+_f4u$t.bargraph_inits.meter_stroke     Stroke of the meter                               Yes      _f4u$t.BLACK
+_f4u$t.bargraph_inits.value_box_w      Width of the value box                            Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.bargraph_inits.value_box_h      Height of the value box                           Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.bargraph_inits.address          Address on the server                             No       null
+==================================     ===============================================   ======   ==============================
+
+In order to customize horizontal and vertical bar graphs individually, the
+properties above may be set by adding v or h before bar graph (i.e. _f4u$t.vbargraph_inits.joint_stroke).
+
+Numerical Entry
+^^^^^^^^^^^^^^^
+====================================     ===============================================   ======   ==============================
+Property name                            Description                                       Touch?   Default
+====================================     ===============================================   ======   ==============================
+_f4u$t.nentry_inits.mom                  Parent widget of the object                       No       null
+_f4u$t.nentry_inits.label                Label of the object                               No       null
+_f4u$t.nentry_inits.length               Length of the object                              Yes      200
+_f4u$t.nentry_inits.unit                 Units of the slider                               No       null
+_f4u$t.nentry_inits.min                  Min value of the button                           No       0
+_f4u$t.nentry_inits.max                  Max value of the button                           No       100
+_f4u$t.nentry_inits.init                 Initial value of the button                       No       50
+_f4u$t.nentry_inits.step                 Step over the range                               No       1
+_f4u$t.nentry_inits.integer              True of the initial value is an integer           No       false
+_f4u$t.nentry_inits.ndec                 Number of decimal places to show                  No       0
+_f4u$t.nentry_inits.lpadding_y           Padding between text box and label                Yes      _f4u$t.TEXT_HEIGHT
+_f4u$t.nentry_inits.box_padding          Padding between object and text box               Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.nentry_inits.padding              Padding around an operation in a button           Yes      _f4u$t.TEXT_BOX_PADDING
+_f4u$t.nentry_inits.gravity              X,Y placement in the parent widget                Yes      [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.nentry_inits.operation_fill       Fill of the operation symbol                      Yes      _f4u$t.PALEGREEN
+_f4u$t.nentry_inits.button_fill          Fill of the operation button                      Yes      _f4u$t.GREY
+_f4u$t.nentry_inits.operation_stroke     Stroke of the operation symbol                    Yes      _f4u$t.BLACK
+_f4u$t.nentry_inits.button_stroke        Stroke of the operation button                    Yes      _f4u$t.BLACK
+_f4u$t.nentry_inits.value_box_w          Width of the value box                            Yes      _f4u$t.VALUE_BOX_W
+_f4u$t.nentry_inits.value_box_h          Height of the value box                           Yes      _f4u$t.VALUE_BOX_H
+_f4u$t.nentry_inits.address              Address on the server                             No       null
+====================================     ===============================================   ======   ==============================
+
+Checkbox
+^^^^^^^^
+==================================   ===================================  ======  ==============================
+Property name                        Description                          Touch?  Default
+==================================   ===================================  ======  ==============================
+_f4u$t.checkbox_inits.mom            Parent widget of the object          No      null
+_f4u$t.checkbox_inits.label          Label of the object                  No      null
+_f4u$t.checkbox_inits.d              Dimension                            Yes     19
+_f4u$t.checkbox_inits.gravity        X,Y placement in the parent widget   Yes     [_f4u$t.CENTER, _f4u$t.CENTER]
+_f4u$t.checkbox_inits.check_fill     Fill of the check                    Yes     _f4u$t.BLACK
+_f4u$t.checkbox_inits.check_stroke   Stroke of the check                  Yes     _f4u$t.BLACK
+_f4u$t.checkbox_inits.box_fill       Fill of the box                      Yes     _f4u$t.WHITE
+_f4u$t.checkbox_inits.box_stroke     Stroke of the box                    Yes     _f4u$t.BLACK
+_f4u$t.checkbox_inits.init           Initial value of the checkbox        No      false
+_f4u$t.checkbox_inits.lpadding_y     Padding between object and label     Yes     _f4u$t.TEXT_HEIGHT
+_f4u$t.checkbox_inits.address        Address on the server                No      null
+==================================   ===================================  ======  ==============================
+
+Button
+^^^^^^
+===================================  ======================================  ======  ==============================
+Property name                        Description                             Touch?  Default
+===================================  ======================================  ======  ==============================
+_f4u$t.button_inits.mom              Parent widget of the object             No      null
+_f4u$t.button_inits.label            Label of the object                     No      null
+_f4u$t.button_inits.ideal_width      Ideal width [#f1]_                      Yes     80
+_f4u$t.button_inits.ideal_height     Ideal height [#f1]_                     Yes     40
+_f4u$t.button_inits.gravity          X,Y placement in the parent widget      Yes     [_f4u$t.CENTER _f4u$t.CENTER]
+_f4u$t.button_inits.fill_on          Fill when the button is on              Yes     _f4u$t.PINK
+_f4u$t.button_inits.fill_off         Fill when the button is off             Yes     _f4u$t.GREEN
+_f4u$t.button_inits.stroke           Stroke of the button box                Yes     _f4u$t.BLACK
+_f4u$t.button_inits.baseline_skip    Gap between bottom of button and label  Yes     5
+_f4u$t.button_inits.address          Address on the server                   No      null
+===================================  ======================================  ======  ==============================
+
+Below is a model JS file setting several of the variables above ::
+
+  _f4u$t.button_inits.stroke = _f4u$t.BLACK;
+  _f4u$t.checkbox_inits.d = 40;
+  _f4u$t.hslider_inits.sp = 0.3;
+
+URL Parameter Specification
+---------------------------
+
+JS parameters can also be specified in the URL.  For example, the model
+JS file above can be embeded in the URL as follows ::
+
+  http://www.ensemble101.fr:8000/#button_inits.stroke=_f4u$t.BLACK&checkbox_inits.d=40&hslider_inits.sp=0.3
+
+.. rubric:: Footnotes
+.. [#f1] Ideal because it will adapt to the size of the bounded text if necessary.
diff --git a/architecture/httpdlib/html/js/svg/api/source/index.rst b/architecture/httpdlib/html/js/svg/api/source/index.rst
new file mode 100644
index 0000000..90023f0
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/source/index.rst
@@ -0,0 +1,26 @@
+.. Faust Web UI API documentation master file, created by
+   sphinx-quickstart on Tue Jan  1 15:41:15 2013.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to Faust Web UI API's documentation!
+============================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   overview
+   constants
+   customizing
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/architecture/httpdlib/html/js/svg/api/source/overview.rst b/architecture/httpdlib/html/js/svg/api/source/overview.rst
new file mode 100644
index 0000000..acb2207
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/api/source/overview.rst
@@ -0,0 +1,23 @@
+Overview
+========
+
+This page provides an overview of the Faust Web UI.  The Faust Web UI can be
+used to control Faust applications running on a server via GET requests.
+An experimental version of WebKit also provides a serverless version of the
+Web UI.
+
+Using the Web UI
+----------------
+
+In order to use the Faust Web UI, one may access a server running a Faust
+application over the appropriate port via a browser that visualizes SVG
+according to the W3C specification (http://www.w3.org/2000/svg).  Once the
+URL is composed, the graphical UI for the application will be displayed in
+the browser.  So, for example, if the website www.ensemble101.fr is running
+a faust application on port 8000, the URL http://www.ensemble101.fr:8000 would
+be used to access the application.
+
+The goal of Faust Web UI is to provide a robust graphical UI similar to that
+of other Faust interfaces (Qt, gtk+, etc.). Should a Faust Web UI fail to
+parallel one of these interfaces in the objects drawn or their responsiveness,
+an e-mail can be sent to faustwebui at grame.fr.
diff --git a/architecture/httpdlib/html/js/svg/faust_css.css b/architecture/httpdlib/html/js/svg/faust_css.css
new file mode 100644
index 0000000..e9763cf
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_css.css
@@ -0,0 +1,238 @@
+body {
+	background-color: #000000;
+}
+
+/* WEBKIT */
+text {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.faust-group-label {
+	font-family: Arial, Verdana, Helvetica, sans;
+	font-size: 13px;
+	fill: rgba(199,190,162,0.6);
+}
+
+.faust-tooltip-text {
+	font-family: Arial, Verdana, Helvetica, sans;
+	font-size: 13px;
+}
+
+.faust-button-label {
+	font-family: Arial, Verdana, Helvetica, sans;
+	font-size: 13px;
+	fill: rgba(0,182,253,0.6);
+}
+
+.faust-tgroup-label {
+	font-family: Arial, Verdana, Helvetica, sans;
+	font-size: 13px;
+	fill: rgba(0,182,253,0.6);
+}
+
+.faust-label {
+	font-family: Arial, Verdana, Helvetica, sans;
+	font-size: 13px;
+	fill: rgba(0,182,253,0.6);
+}
+
+.faust-value-text {
+	font-family: Arial, Verdana, Helvetica, sans;
+	font-size: 11px;
+	font-weight: bold;
+	fill: rgb(82,79,79);
+}
+
+path {
+  -webkit-user-select: none;
+}
+
+rect {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
+}
+
+}
+
+circle {
+  -webkit-user-select: none;
+}
+
+text:hover {
+  cursor: default;
+}
+
+path.faust-vbox {
+  fill : white;
+  stroke : black;
+}
+
+path.faust-rbutton-groove {
+  fill : rgb(152,251,152);
+  stroke : black;
+}
+
+path.faust-rbutton-handle {
+  fill : grey;
+  stroke : black;
+}
+
+rect.faust-hslider-meter {
+  fill : url(#horizontalSliderMeterGradient);
+}
+
+rect.faust-hslider-groove {
+  fill : rgba(28,126,192,0.65);
+  stroke : rgba(0,182,253,0.9);
+}
+
+rect.faust-hslider-handle {
+  fill : url(#horizontalSliderHandleGradient);
+  stroke : black;
+}
+
+rect.faust-vslider-meter {
+  fill : url(#verticalSliderMeterGradient);
+}
+
+rect.faust-vslider-groove {
+  fill : rgba(28,126,192, 0.65);
+  stroke : rgba(0,182,253,0.9);
+}
+
+rect.faust-vslider-handle {
+  fill : url(#verticalSliderHandleGradient);
+  stroke : black;
+}
+
+rect.faust-hbargraph-curtain {
+  fill : rgb(20,20,20);
+  stroke : black;
+}
+
+// hbargraph meters cannot be defined via CSS because their widths and
+// heights are dynamic
+
+rect.faust-hbargraph-meter {
+  fill : url(#horizontalBarGraphMeterGradient);
+  stroke : black;
+}
+
+rect.faust-vbargraph-curtain {
+  fill : rgb(20,20,20);
+  stroke : black;
+}
+
+rect.faust-vbargraph-meter {
+  fill : url(#verticalBarGraphMeterGradient);
+  stroke : black;
+}
+
+rect.faust-checkbox-box {
+  fill : white;
+  stroke : black;
+}
+
+path.faust-checkbox-check {
+  fill : black;
+  stroke : black;
+}
+
+rect.faust-nentry-box {
+  fill : url(#numericalEntryUpGradient);
+  stroke : black;
+}
+
+path.faust-nentry-operation {
+  stroke : black;
+}
+
+rect.faust-button-box {
+  fill : url(#buttonUpGradient);
+  stroke : black;
+ }
+
+rect.faust-tgroup-box {
+  fill : url(#tabGroupUpGradient);
+  stroke : black;
+}
+
+circle.faust-rbutton-groove {
+  fill : url(#rotatingButtonHandleGradient);
+}
+
+circle.faust-rbutton-dot {
+  fill : pink;
+  stroke : black;
+}
+
+path.faust-rbutton-meter {
+  fill : rgb(50,50,50);
+}
+
+path.faust-rbutton-mgroove {
+  fill : url(#rotatingButtonMeterGradient);
+}
+
+// as all of the above rectangles could be implemented as paths, we duplicate the definitions for paths
+
+path.faust-hslider-groove {
+  fill : red;
+  stroke : black;
+}
+
+path.faust-hslider-handle {
+  fill : url(#horizontalSliderHandleGradient);
+  stroke : black;
+}
+
+path.faust-vslider-groove {
+  fill : red;
+  stroke : black;
+}
+
+path.faust-vslider-handle {
+  fill : url(#verticalSliderHandleGradient);
+  stroke : black;
+}
+
+path.faust-hbargraph-curtain {
+  fill : rgb(0,255,255);
+  stroke : black;
+}
+
+path.faust-hbargraph-meter {
+  fill : grey;
+  stroke : black;
+}
+
+path.faust-vbargraph-curtain {
+  fill : rgb(0,255,255);
+  stroke : black;
+}
+
+path.faust-vbargraph-meter {
+  fill : grey;
+  stroke : black;
+}
+
+path.faust-checkbox-box {
+  fill : white;
+  stroke : black;
+}
+
+path.faust-nentry-box {
+  fill : url(#numericalEntryUpGradient);
+  stroke : black;
+}
+
+path.faust-button-box {
+  fill : #B0B0B0;
+  stroke : black;
+}
diff --git a/architecture/httpdlib/html/js/svg/faust_jquery_svg_backend.js b/architecture/httpdlib/html/js/svg/faust_jquery_svg_backend.js
new file mode 100644
index 0000000..0ee4d15
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_jquery_svg_backend.js
@@ -0,0 +1,58 @@
+// faust_jquery_svg_backend.js
+
+_f4u$t.make_rectangle_via_rect = function(svg, parent, rf, x, y, w, h, ops) {
+  return svg.rect(parent, x, y, w, h, rf, rf, ops);
+}
+
+_f4u$t.make_text = function(svg, parent, x, y, text, opts) {
+  opts = opts ? opts : {};
+  return svg.text(parent,x,y,text,opts);
+}
+
+_f4u$t.make_circle = function(svg, parent, cx, cy, radius, opts) {
+  opts = opts ? opts : {};
+  return svg.circle(parent,cx,cy,radius,opts);
+}
+
+_f4u$t.make_g = function(svg, parent, id, opts) {
+  opts = opts ? opts : {};
+  return svg.group(parent, id, opts);
+}
+
+_f4u$t.make_path = function(svg, parent, d, opts) {
+  opts = opts ? opts : {};
+  return svg.path(parent, d, opts);
+}
+
+_f4u$t.make_line = function(svg, parent, x1, y1, x2, y2, opts) {
+  opts = opts ? opts : {};
+  return svg.line(parent, x1, y1, x2, y2, opts);
+}
+
+_f4u$t.configure_svg = function(svg, opts, wipe) {
+  svg.configure(opts, wipe ? wipe : false);
+}
+
+_f4u$t.get_svg_defs = function(svg) {
+  return svg.defs();
+}
+
+_f4u$t.make_linear_gradient = function(svg, defs, gradient, stops, x1, y1, x2, y2, opts) {
+  opts = opts ? opts : {};
+  svg.linearGradient(defs, gradient, stops, x1, y1, x2, y2, opts);
+}
+
+_f4u$t.make_radial_gradient = function(svg, defs, gradient, stops, cx, cy, r, fx, fy, opts) {
+  opts = opts ? opts : {};
+  svg.radialGradient(defs, gradient, stops, cx, cy, r, fx, fy, opts);
+}
+
+_f4u$t.svg_remove = function(svg, dummy) {
+  svg.remove(dummy);
+}
+
+_f4u$t.add_svg_and_onload_to_div = function(div, raw_json, width, height, hash) {
+  div.svg({onLoad: function (svg) {
+          _f4u$t.make_ui(svg, raw_json, width, height, hash);
+          }});
+}
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/faust_load_external_file.js b/architecture/httpdlib/html/js/svg/faust_load_external_file.js
new file mode 100644
index 0000000..50b546b
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_load_external_file.js
@@ -0,0 +1,53 @@
+// FROM http://stackoverflow.com/questions/814613/how-to-read-get-data-from-a-url-using-javascript
+
+_f4u$t.parseURLParams = function(url) {
+  //var queryStart = url.indexOf("?") + 1;
+  //var queryEnd   = url.indexOf("#") + 1 || url.length + 1;
+  var queryStart = url.indexOf("#") + 1;
+  var queryEnd   = url.length + 1;
+  var query      = url.slice(queryStart, queryEnd - 1);
+  var params  = {};
+
+  if (query === url || query === "")
+    return params;
+
+  var nvPairs = query.replace(/\+/g, " ").toString().split("&");
+
+  for (var i=0; i<nvPairs.length; i++) {
+    var nv = nvPairs[i].toString().split("=");
+    var n  = decodeURIComponent(nv[0]);
+    var v  = decodeURIComponent(nv[1]);
+    if (!(n in params)) {
+      params[n] = [];
+    }
+    params[n].push(nv.length === 2 ? v : null);
+  }
+  return params;
+}
+
+_f4u$t.load_css_and_then_js = function(css, js) {
+  if (!css || (css.length == 0)) {
+    _f4u$t.load_js(js);
+  }
+  else {
+    var headID = document.getElementsByTagName("head")[0];
+    var cssNode = document.createElement('link');
+    cssNode.type = 'text/css';
+    cssNode.rel = 'stylesheet';
+    cssNode.href = css[0];
+    cssNode.media = 'screen';
+    headID.appendChild(cssNode);
+    _f4u$t.load_css_and_then_js(css.slice(1), js);
+  }
+}
+
+_f4u$t.load_js = function(js) {
+  if (!js || (js.length == 0)) {
+    return;
+  }
+  else {
+    $.getScript(js[0], function () {
+      _f4u$t.load_js(js.slice(1));
+    });
+  }
+}
diff --git a/architecture/httpdlib/html/js/svg/faust_mobile.js b/architecture/httpdlib/html/js/svg/faust_mobile.js
new file mode 100644
index 0000000..9be7768
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_mobile.js
@@ -0,0 +1,32 @@
+_f4u$t.detect_mobile_device = {
+    Android: function() {
+        return navigator.userAgent.match(/Android/i);
+    },
+    BlackBerry: function() {
+        return navigator.userAgent.match(/BlackBerry/i);
+    },
+    iOS: function() {
+        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
+    },
+    Opera: function() {
+        return navigator.userAgent.match(/Opera Mini/i);
+    },
+    Windows: function() {
+        return navigator.userAgent.match(/IEMobile/i);
+    },
+    any: function() {
+        return (_f4u$t.detect_mobile_device.Android()
+                || _f4u$t.detect_mobile_device.BlackBerry()
+                || _f4u$t.detect_mobile_device.iOS()
+                || _f4u$t.detect_mobile_device.Opera()
+                || _f4u$t.detect_mobile_device.Windows());
+    }
+};
+
+_f4u$t.disable_zoom = function() {
+  var headID = document.getElementsByTagName("head")[0];
+  var metaNode = document.createElement('meta');
+  metaNode.name = 'viewport';
+  metaNode.content = "target-densitydpi=device-dpi, initial-scale=1.0, user-scalable=no";
+  headID.appendChild(metaNode);
+}
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/faust_proto.js b/architecture/httpdlib/html/js/svg/faust_proto.js
new file mode 100644
index 0000000..5d674eb
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_proto.js
@@ -0,0 +1,1345 @@
+/**
+This module provides classes for the parsing of a JSON describing
+a faust interface and the realization of that interface in SVG.
+
+It also allows for interaction between this interface and a server.
+
+ at module Faust Web UI
+ at main Faust Web UI
+**/
+
+/**
+Extension of the JavaScript String class.
+
+ at class String
+ at for
+ at constructor
+**/
+
+/**
+Formats a string in a pythonic way.  See
+http://docs.python.org/2/library/string.html.
+
+ at method format
+ at for String
+ at param {Array} args The arguments to be inserted into the string.
+ at return {String} The formatted string.
+**/
+String.prototype.format = function (args) {
+  var str = this;
+  return str.replace(String.prototype.format_regex, function(item) {
+    var intVal = parseInt(item.substring(1, item.length - 1));
+    var replace;
+    if (intVal >= 0) {
+      replace = args[intVal];
+    }
+    else if (intVal === -1) {
+      replace = "{";
+    }
+    else if (intVal === -2) {
+      replace = "}";
+    }
+    else {
+      replace = "";
+    }
+    return replace;
+  });
+}
+
+/**
+The regular expression used to find the insertion points
+in a string that needs formatting.
+
+ at property format_regex
+ at for String
+ at type RegExp
+**/
+String.prototype.format_regex = new RegExp("{-?[0-9]+}", "g");
+
+/**
+Extension of the JavaScript Array class.
+
+ at class Array
+ at for
+ at constructor
+**/
+
+/**
+Finds the maximum of a numerical array.
+
+ at method max
+ at for Array
+ at return {Number} The maximum of the array.
+**/
+Array.prototype.max = function() {
+  var max = this[0];
+  var len = this.length;
+  for (var i = 1; i < len; i++) {
+    if (this[i] > max) {
+      max = this[i];
+    }
+  }
+  return max;
+}
+
+/**
+Finds the minimum of a numerical array.
+
+ at method min
+ at for Array
+ at return {Number} The minimum of the array.
+**/
+Array.prototype.min = function() {
+  var min = this[0];
+  var len = this.length;
+  for (var i = 1; i < len; i++) {
+    if (this[i] < min) {
+      min = this[i];
+    }
+  }
+  return min;
+}
+
+/**
+Finds the sum of a numerical array.
+
+ at method sum
+ at for Array
+ at return {Number} The sum of the array.
+**/
+Array.prototype.sum = function() {
+  var sum = 0;
+  for(var i = 0; i < this.length; i++) {
+    sum += this[i];
+  }
+  return sum;
+}
+
+/**
+Provides the base class for the creation of a _f4u$t UI.
+It functions more like a namespace than an object, so it
+does not have a constructer and only contains classes and
+static methods.
+
+ at class _f4u$t
+ at static
+**/
+var _f4u$t = {};
+
+/**
+Estimation of text height in layout computations.
+
+ at property TEXT_HEIGHT
+ at for _f4u$t
+ at type Number
+ at default 20
+**/
+_f4u$t.TEXT_HEIGHT = 20;
+
+/**
+Padding between text and other objects.
+
+ at property TEXT_PADDING
+ at for _f4u$t
+ at type Number
+ at default 10
+**/
+_f4u$t.TEXT_PADDING = 10;
+
+/**
+Width of value boxes.
+
+ at property VALUE_BOX_W
+ at for _f4u$t
+ at type Number
+ at default 60
+**/
+_f4u$t.VALUE_BOX_W = 60;
+
+/**
+Height of value boxes.
+
+ at property VALUE_BOX_H
+ at for _f4u$t
+ at type Number
+ at default 20
+**/
+_f4u$t.VALUE_BOX_H = _f4u$t.TEXT_HEIGHT;
+
+/**
+Padding between the bottom of the space an object occupies
+and its text-box.
+
+ at property TEXT_BOX_PADDING
+ at for _f4u$t
+ at type Number
+ at default 3
+**/
+_f4u$t.TEXT_BOX_PADDING = 3;
+
+// some convenience methods for inheritence
+
+/**
+Used as a placeholder to define constructors via
+_f4u$t.extend
+
+ at method surrogateCtor
+ at for _f4u$t
+ at static
+**/
+_f4u$t.surrogateCtor = function() {}
+
+/**
+Used to make one class inherit from another.
+
+ at method extend
+ at for _f4u$t
+ at static
+ at param {Object} base The base class to be inherited from.
+ at param {Object} sub The class doing the inheriting.
+**/
+_f4u$t.extend = function(base, sub) {
+  // Copy the prototype from the base to setup inheritance
+  _f4u$t.surrogateCtor.prototype = base.prototype;
+  sub.prototype = new _f4u$t.surrogateCtor();
+  // Remember the constructor property was set wrong, let's fix it
+  sub.prototype.constructor = sub;
+}
+
+/**
+Identity function.
+
+ at method identity
+ at for _f4u$t
+ at static
+ at param {Object} value The value to return
+ at return {Object} The input value
+**/
+_f4u$t.identity = function(value) {
+  return value;
+}
+
+/**
+Enum-like constant for the X axis.
+
+ at property X_AXIS
+ at for _f4u$t
+ at type Number
+ at default 0
+**/
+_f4u$t.X_AXIS = 0;
+
+/**
+Enum-like constant for the Y axis.
+
+ at property Y_AXIS
+ at for _f4u$t
+ at type Number
+ at default 1
+**/
+_f4u$t.Y_AXIS = 1;
+
+/**
+Enum-like constant for no axes left to consult,
+used in iterating.
+
+ at property NO_AXES
+ at for _f4u$t
+ at type Number
+ at default 2
+**/
+_f4u$t.NO_AXES = 2;
+
+/**
+Enum-like constant for the left side.
+
+ at property LEFT
+ at for _f4u$t
+ at type Number
+ at default -1
+**/
+_f4u$t.LEFT = -1;
+
+/**
+Enum-like constant for the right side.
+
+ at property RIGHT
+ at for _f4u$t
+ at type Number
+ at default 1
+**/
+_f4u$t.RIGHT = 1;
+
+/**
+Enum-like constant for the up side.
+
+ at property UP
+ at for _f4u$t
+ at type Number
+ at default -1
+**/
+_f4u$t.UP = -1;
+
+/**
+Enum-like constant for the down side.
+
+ at property DOWN
+ at for _f4u$t
+ at type Number
+ at default 1
+**/
+_f4u$t.DOWN = 1;
+_f4u$t.CENTER = 0;
+
+/**
+Representation of none, null, the abyss, the ether, etc..
+
+ at property NULL
+ at for _f4u$t
+ at default null
+**/
+_f4u$t.NONE = null;
+
+/**
+RGB value of the color black in an array.
+
+ at for _f4u$t
+ at property BLACK
+ at type Array
+ at default [0,0,0]
+**/
+_f4u$t.BLACK = [0,0,0];
+
+/**
+RGB value of the color white in an array.
+
+ at property WHITE
+ at for _f4u$t
+ at type Array
+ at default [255,255,255]
+**/
+_f4u$t.WHITE = [255,255,255];
+
+/**
+RGB value of the color cyan in an array.
+
+ at property CYAN
+ at for _f4u$t
+ at type Array
+ at default [0,255,255]
+**/
+_f4u$t.CYAN = [0,255,255];
+
+/**
+RGB value of the color cyan in an array.
+
+/**
+RGB value of the color grey in an array.
+
+ at property GREY
+ at for _f4u$t
+ at type Array
+ at default [100,100,100]
+**/
+_f4u$t.GREY = [100,100,100];
+
+/**
+RGB value of the color pink in an array.
+
+ at property PINK
+ at for _f4u$t
+ at type Array
+ at default [233,150,122]
+**/
+_f4u$t.PINK = [233,150,122];
+
+/**
+RGB value of the color green in an array.
+
+ at property GREEN
+ at for _f4u$t
+ at type Array
+ at default [173,255,47]
+**/
+_f4u$t.GREEN = [173,255,47];
+
+/**
+RGB value of the color kermit in an array.
+
+ at property KERMIT
+ at for _f4u$t
+ at type Array
+ at default [47,243,160]
+**/
+_f4u$t.KERMIT = [47,243,160];
+
+/**
+RGB value of the color pale green in an array.
+
+ at property PALEGREEN
+ at for _f4u$t
+ at type Array
+ at default [152,251,152]
+**/
+_f4u$t.PALEGREEN = [152,251,152];
+
+// INTERACTION WITH THE UI
+
+/**
+Information about the current objects being
+interacted with.  Holds subproperties id, moved
+and value.
+
+ at property _I
+ at for _f4u$t
+ at type Object
+ at default {}
+**/
+_f4u$t._I = {};
+
+/**
+Id of the current value box interacted with.
+
+ at property _N
+ at for _f4u$t
+ at type String
+ at default ""
+**/
+_f4u$t._N = "";
+
+/*
+ * SERVER INTERACTION
+ */
+
+/**
+Object that pairs paths of objects on the server
+with DOM ids.
+
+ at property PATHS_TO_IDS
+ at for _f4u$t
+ at type Object
+ at default {}
+**/
+_f4u$t.PATHS_TO_IDS = {};
+
+_f4u$t.path_to_id = function (path, id) {
+  _f4u$t.PATHS_TO_IDS[path] = id;
+}
+
+/**
+ Rather than using lots of global variables (clutters namespace)
+ or using this.attribute (dangerous depending on browser and libraries),
+ we use _f4u$t.IDS_TO_ATTRIBUTES to hold all information for faust UI objects.
+ That way, the impact on the namespace of the global session as well
+ as the objects is minimal.
+
+ at property IDS_TO_ATTRIBUTES
+ at for _f4u$t
+ at type Object
+ at default {}
+**/
+_f4u$t.IDS_TO_ATTRIBUTES = {};
+
+/**
+Returns a random, soft, pretty color, represented
+as 0-255 RGB values in an array, to act as a background
+for layout managers.
+
+ at method magic_color
+ at for _f4u$t
+ at static
+ at return {Array} An array of three values, 0-255 for RGB.
+**/
+_f4u$t.magic_color = function() {
+  var r = Math.floor(Math.random() * 100) + 156;
+  var g = Math.floor(Math.random() * 100) + 156;
+  var b = 530 - r - g;
+  var v = [r,g,b];
+  v.sort(function() {return 0.5 - Math.random()}) // shuffles
+  return v;
+}
+
+/**
+Returns a random string.
+
+ at method rand_string
+ at for _f4u$t
+ at static
+ at param {Number} n (optional) the length of the string to return
+ at return {String} a random string
+**/
+_f4u$t.rand_string = function(n)
+{
+  var text = "";
+  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+  if (!n) {
+    n = 8;
+  }
+
+  for( var i=0; i < n; i++ ) {
+    text += possible.charAt(Math.floor(Math.random() * possible.length));
+  }
+  return text;
+}
+
+/**
+Returns true if needle is the first part of haystack
+
+ at method first_part_matches
+ at for _f4u$t
+ at static
+ at param {String} haystack the string to search
+ at param {String} needle the search query
+ at return {Boolean} true if needle is the first part of the haystack
+**/
+_f4u$t.first_part_matches = function(haystack, needle) {
+  return haystack.indexOf(needle) == 0;
+}
+
+/**
+Removes needle from the head of haystack.
+
+ at method remove_from_head_of_string
+ at for _f4u$t
+ at static
+ at param {String} haystack the string to operate on
+ at param {String} needle remove
+ at return {String} the modified string without needle
+**/
+_f4u$t.remove_from_head_of_string = function(haystack, needle) {
+  if (_f4u$t.first_part_matches(haystack, needle)) {
+    return haystack.substr(needle.length);
+  }
+}
+
+/**
+The bounds for an accelerometer orientation.
+
+ at property orientation_bounds
+ at for _f4u$t
+ at type Object
+ at default {}
+**/
+_f4u$t.orientation_bounds = {
+  alpha : [0, 360],
+  beta : [-90, 90],
+  gamma : [-90, 90]
+};
+
+/**
+Parses a string into an orientation
+
+ at method parse_orientation
+ at for _f4u$t
+ at static
+ at return {Object}
+**/
+_f4u$t.parse_orientation = function(s) {
+  var split = s.toString().split(" ");
+  while (split.indexOf("") >= 0) {
+    split.splce(split.indexOf(""), 1);
+  }
+  if (split.length == 0) {
+    return {};
+  }
+  if (['alpha','beta','gamma'].indexOf(split[0]) < 0) {
+    return {};
+  }
+  var itor = {1 : _f4u$t.orientation_bounds[split[0]][0], 2 : _f4u$t.orientation_bounds[split[0]][1] };
+
+  // this loop creates the rest of the array
+  for (var i in itor) {
+    if (split.length == i) {
+      split.push(itor[i]);
+    }
+    else {
+      split[i] = parseFloat(split[i]);
+      if (isNaN(split[i])) {
+        split[i] = itor[i];
+      }
+    }
+  }
+
+  return {angle : split[0], low : split[1], high : split[2]};
+}
+
+/**
+Taking an axis _f4u$t.X_AXIS or _f4u$t.Y_AXIS, returns
+the opposite axis.
+
+ at method other_axis
+ at for _f4u$t
+ at static
+ at param {Number} axis An axis, either _f4u$t.X_AXIS or _f4u$t.Y_AXIS.
+ at return {Number} The opposite axis.
+**/
+_f4u$t.other_axis = function(axis) {
+  return (axis + 1) % _f4u$t.NO_AXES;
+}
+
+/**
+Remaps a value in a range to another range.
+
+ at method remap
+ at for _f4u$t
+ at static
+ at param {Number} v The value to remap.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum of the new range.
+ at param {Number} mx1 The maximum of the new range.
+ at return {Number} The value v remapped to the new range.
+**/
+_f4u$t.remap = function(v, mn0, mx0, mn1, mx1) {
+  var p = 1.0 * (v - mn0) / (mx0 - mn0);
+  return p * (mx1 - mn1) + mn1;
+}
+
+/**
+Bounds a value between two numbers.
+
+ at method bound
+ at for _f4u$t
+ at static
+ at param {Number} v The value to bound.
+ at param {Number} m One side of the bound (either the min or max).
+ at param {Number} n The other side of the bound (either min or max).
+ at return {Number} Bounded value, meaning either unchanged or cropped at the min/max.
+**/
+_f4u$t.bound = function(v,m,n) {
+  var mn = Math.min(m,n);
+  var mx = Math.max(m,n);
+  if (v < mn) { return mn; }
+  if (v > mx) { return mx; }
+  return v;
+}
+
+/**
+Bounds a value between two numbers, avoiding large leaps
+from a previous value
+
+ at method bound
+ at for _f4u$t
+ at static
+ at param {Number} aval The value to bound.
+ at param {Number} pval The previous value
+ at param {Number} l The lower bound
+ at param {Number} h The upper bound
+ at return {Number} The value bounded. If the previous value was the upper
+bound, we remain on this to avoid large leaps.
+**/
+_f4u$t.bound_and_avoid_large_leaps = function(aval, pval, l, h, epsilon) {
+  if (!epsilon) {
+    epsilon = 0;
+  }
+  if (l > aval) {
+    if (Math.abs(pval - h) <= epsilon) {
+      return l;
+    }
+  }
+
+  else if (aval > h) {
+    if (Math.abs(pval - l) <= epsilon) {
+      return h;
+    }
+  }
+
+  // if neither of the above are true, free to move by the difference
+  else {
+    return aval;
+  }
+
+  // corner case - we avoid large leaps
+  return pval;
+}
+
+/**
+Quantizes a value between two numbers at a given step.
+
+ at method quantize
+ at for _f4u$t
+ at static
+ at param {Number} v The value to quantize.
+ at param {Number} m One side of the quantizing range (either the min or max).
+ at param {Number} n The other side of the quantizing range (either min or max).
+ at param {Number} s The step value to which the number must be quantized.
+ at return {Number} ov quantized (and bounded if necessary)
+**/
+_f4u$t.quantize = function(ov,m,n,s) {
+  var v = _f4u$t.bound(ov, m, n);
+  var mn = Math.min(m,n);
+  var mx = Math.max(m,n);
+  out = Math.floor((v - mn) / s + 0.5) * s + mn;
+  return _f4u$t.bound(out, m, n);
+}
+
+/**
+Flips a value at the center of a range.
+
+ at method flip
+ at for _f4u$t
+ at static
+ at param {Number} v The value to flip.
+ at param {Number} m One side of the range (either the min or max).
+ at param {Number} n The other side of the range (either min or max).
+ at return {Number} v flipped over the axis at the middle of the given range.
+**/
+_f4u$t.flip = function(v,m,n) {
+  var mn = Math.min(m,n);
+  var mx = Math.max(m,n);
+  var offset = (mx - mn) / 2.0 + mn;
+  return -1.0 * (v - offset) + offset;
+}
+
+/**
+Remaps a value via _f4u$t.remap and then bounds it in the new
+range via _f4u$t.bound.
+
+ at method remap_and_bound
+ at for _f4u$t
+ at static
+ at param {Number} v The value to remap and bound.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum and bound of the new range.
+ at param {Number} mx1 The maximum and bound of the new range.
+ at return {Number} The value v remapped and bounded to the new range.
+**/
+_f4u$t.remap_and_bound = function(v, mn0, mx0, mn1, mx1) {
+  return _f4u$t.bound(_f4u$t.remap(v, mn0, mx0, mn1, mx1), mn1, mx1);
+}
+
+/**
+Remaps a value via _f4u$t.remap and then quantizes it in the new
+range via _f4u$t.quantize.
+
+ at method remap_and_quantize
+ at for _f4u$t
+ at static
+ at param {Number} v The value to remap and quantize.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum and bound of the new range.
+ at param {Number} mx1 The maximum and bound of the new range.
+ at param {Number} s The step value to which the number must be quantized.
+ at return {Number} The value v remapped and quantizeed to the new range.
+**/
+_f4u$t.remap_and_quantize = function(v, mn0, mx0, mn1, mx1, s) {
+  return _f4u$t.quantize(_f4u$t.remap(v, mn0, mx0, mn1, mx1), mn1, mx1, s);
+}
+
+/**
+Remaps a value via _f4u$t.remap and then bounds it in the new
+range via _f4u$t.bound and then flips it via _f4u$t.flip.
+
+ at method remap_and_bound_and_flip
+ at for _f4u$t
+ at static
+ at param {Number} v The value to remap and bound and flip.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum and bound of the new range.
+ at param {Number} mx1 The maximum and bound of the new range.
+ at return {Number} The value v remapped and bounded and flipped to the new range.
+**/
+_f4u$t.remap_and_bound_and_flip = function(v, mn0, mx0, mn1, mx1) {
+  return _f4u$t.flip(_f4u$t.bound(_f4u$t.remap(v, mn0, mx0, mn1, mx1), mn1, mx1), mn1, mx1);
+}
+
+/**
+Remaps a value via _f4u$t.remap and then quantizes it in the new
+range via _f4u$t.quantize and then flips it via _f4u$t.flip.
+
+ at method remap_and_quantize_and_flip
+ at for _f4u$t
+ at static
+ at param {Number} v The value to remap and quantize and flip.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum and bound of the new range.
+ at param {Number} mx1 The maximum and bound of the new range.
+ at return {Number} The value v remapped and quantized and flipped to the new range.
+**/
+_f4u$t.remap_and_quantize_and_flip = function(v, mn0, mx0, mn1, mx1, s) {
+  return _f4u$t.flip(_f4u$t.quantize(_f4u$t.remap(v, mn0, mx0, mn1, mx1), mn1, mx1, s), mn1, mx1);
+}
+
+/**
+Remaps a value via _f4u$t.remap and then flips it via _f4u$t.flip.
+
+ at method remap_and_flip
+ at for _f4u$t
+ at static
+ at param {Number} v The value to remap and flip.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum of the new range.
+ at param {Number} mx1 The maximum of the new range.
+ at return {Number} The value v remapped and flipped to the new range.
+**/
+_f4u$t.remap_and_flip = function(v, mn0, mx0, mn1, mx1) {
+  return _f4u$t.flip(_f4u$t.remap(v, mn0, mx0, mn1, mx1), mn1, mx1);
+}
+
+/**
+Bounds a value via _f4u$t.bound and then flips it via _f4u$t.flip.
+
+ at method bound_and_flip
+ at for _f4u$t
+ at static
+ at param {Number} v The value to bound and flip.
+ at param {Number} mn0 The minimum of the old range.
+ at param {Number} mx0 The maximum of the old range.
+ at param {Number} mn1 The minimum and bound of the new range.
+ at param {Number} mx1 The maximum and bound of the new range.
+ at return {Number} The value v bounded and and flipped to the new range.
+**/
+_f4u$t.bound_and_flip = function(v, mn1, mx1) {
+  return _f4u$t.flip(_f4u$t.bound(v, mn1, mx1), mn1, mx1);
+}
+
+/**
+Finds the sign of a number.
+
+ at method sign
+ at for _f4u$t
+ at static
+ at param {Number} x The number whose sign we want.
+ at return {Number} The sign, either -1, 1 or 0.
+**/
+_f4u$t.sign = function(x) {
+  return (x == 0 ? x : Math.floor(Math.abs(x) / x));
+}
+
+/**
+Chooses left, right, or center of range.
+
+ at method linear_combinatin
+ at for _f4u$t
+ at static
+ at param {Number} dir The direction indicating which number to use (left/right/center). Note that up is the same as left and down is the same as right.
+ at param {Number} v1 The first value of the range.
+ at param {Number} v2 The second value of the range.
+ at return {Number} The first value if left, the second value if right, or the center if center.
+**/
+_f4u$t.linear_combination = function(dir, v1, v2) {
+  if (dir == _f4u$t.LEFT) {
+    return v1;
+  }
+  if (dir == _f4u$t.RIGHT) {
+    return v2;
+  }
+  return (v1 + v2) / 2.0;
+}
+
+/**
+Chooses one of two values depending on the axis.
+
+ at method xy
+ at for _f4u$t
+ at static
+ at param {Number} a The axis, _f4u$t.X_AXIS or _f4u$t.Y_AXIS.
+ at param {Number} x The value to return if a is equal to _f4u$t.X_AXIS.
+ at param {Number} y The value to return if a is equal to _f4u$t.X_AXIS.
+ at return {Number} x or y, depending on what a is.
+**/
+_f4u$t.xy = function(a,x,y) {
+  return (a == _f4u$t.X_AXIS ? x : y);
+}
+
+/**
+Returns the trailing part of an id.  The faust naming convention gives
+all DOM ids a unique identifier at the end, called the trailing part, and
+this function returns it.
+
+ at method unique
+ at for _f4u$t
+ at static
+ at param {String} s An ID string
+ at return {String} The unique trailing part, if one exists.
+**/
+_f4u$t.unique = function(s) {
+  var spl = s.toString().split("_");
+  if (spl.length == 0) {
+    return s;
+  }
+  return spl[spl.length - 1];
+}
+
+/**
+Returns the type part of an id.  The faust naming convention gives
+all DOM ids a type as the second entry. Examples are vslider, hslider,
+rbutton.
+
+ at method unique
+ at for _f4u$t
+ at static
+ at param {String} s An ID string
+ at return {String} The unique type, if one exists.
+**/
+_f4u$t.type = function(s) {
+  var spl = s.toString().split("_");
+  if (spl.length == 0) {
+    console.log("incorrect naming of faust object");
+    return s;
+  }
+  return spl[1];
+}
+
+/**
+Takes an array of three values (R, G, and B) and returns a color
+useable by CSS.
+
+ at method color_to_css
+ at for _f4u$t
+ at static
+ at param {Array, String} rgb An array with three values for
+R, G, and B or a CSS string to bypass the conversion.
+ at return {String} An RGB value useable by CSS.
+**/
+_f4u$t.color_to_rgb = function(rgb) {
+  if (typeof rgb == 'string')
+    return rgb;
+  return (rgb ? "rgb("+rgb[0]+","+rgb[1]+","+rgb[2]+")" : 'none');
+}
+
+/**
+A function that generates a random 7-letter string.
+
+ at method randString
+ at for _f4u$t
+ at static
+ at return {String} A random 7-letter string.
+**/
+_f4u$t.randString = function() {
+  var result = '';
+  var length = 7;
+  var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  for (var i = length; i > 0; --i) {
+    result += chars[Math.round(Math.random() * (chars.length - 1))];
+  }
+  return result;
+}
+
+/**
+A function that returns either a given value or a default if
+the given is null
+
+ at method initifnull
+ at for _f4u$t
+ at static
+ at param {any} v The value to use.
+ at param {any} d The default to return if v is null.
+ at return {any} Either v or d.
+**/
+_f4u$t.initifnull = function(v,d) {
+  return (v == null ? d : v);
+}
+
+// TRIGONOMETRIC FUNCTIONS
+
+/**
+In a range, find all angles that fall at a multiple of 90 degrees.
+
+ at method find_all_90s
+ at for _f4u$t
+ at static
+ at param {Number} a0 The initial angle in degrees.
+ at param {Number} sweep The angle to sweep from the initial in degrees.
+ at return {Array} All multiples of 90 between a0 and a0 + sweep inclusive.
+**/
+_f4u$t.find_all_90s = function(a0, sweep) {
+  var total = 0;
+  var out = [];
+  while (a0 > total) {
+    total += 90;
+  }
+  while (total <= a0 + sweep) {
+    out.push(total);
+    total += 90;
+  }
+  return out;
+}
+
+/**
+Given a polar coordiante, find the cartesian point
+
+ at method point_from_polar
+ at for _f4u$t
+ at static
+ at param {Number} r Radius.
+ at param {Number} a Angle in radians.
+ at return {Array} The cartesian coordinate as [x,y].
+**/
+_f4u$t.point_from_polar = function(r, a) {
+  return [r * Math.cos(a), r * Math.sin(a)];
+}
+
+/**
+Adds two coordinates in the form [x0,y0] and [x1,y1].
+
+ at method coord_sub
+ at for _f4u$t
+ at static
+ at param {Array} c0 First cartesian coordinate.
+ at param {Array} c1 Second cartesian coordinate.
+ at return {Array} The sum of the two coordinates.
+**/
+_f4u$t.coord_add = function(c0, c1) {
+  return [c0[0] + c1[0], c0[1] + c1[1]];
+}
+
+/**
+Subtracts two coordinates in the form [x0,y0] and [x1,y1].
+
+ at method coord_sub
+ at for _f4u$t
+ at static
+ at param {Array} c0 First cartesian coordinate.
+ at param {Array} c1 Second cartesian coordinate, subtracted from first.
+ at return {Array} The difference of the two coordinates.
+**/
+_f4u$t.coord_sub = function(c0, c1) {
+  return [c0[0] - c1[0], c0[1] - c1[1]];
+}
+
+/**
+Converts radians to degrees.
+
+ at method r2d
+ at for _f4u$t
+ at static
+ at param {Number} Angle in radians.
+ at return {Number} Angle in degrees.
+**/
+_f4u$t.r2d = function(a) {
+  return a * 180 / Math.PI;
+}
+
+/**
+Converts degrees to radians.
+
+ at method r2d
+ at for _f4u$t
+ at static
+ at param {Number} Angle in degrees.
+ at return {Number} Angle in radians.
+**/
+_f4u$t.d2r = function(a) {
+  return a * Math.PI / 180.;
+}
+
+/**
+Ajax queue.
+
+ at property ajax_queue
+ at for _f4u$t
+ at type Object
+ at default {}
+**/
+_f4u$t.ajax_queue = {};
+
+/**
+Is the ajax queue busy?
+
+ at property ajax_queue_busy
+ at for _f4u$t
+ at type Boolean
+ at default false
+**/
+_f4u$t.ajax_queue_busy = false;
+
+/**
+Active addresses being sent to server.
+
+ at property active_addresses
+ at for _f4u$t
+ at type Array
+ at default []
+**/
+_f4u$t.active_addresses = [];
+
+/**
+A box class.
+
+ at class Box
+ at namespace _f4u$t
+ at constructor
+**/
+
+_f4u$t.Box = function() {
+  /**
+  Resets the x and y of a box to their defaults
+  
+  @method clear
+  @for _f4u$t.Box
+  **/
+  this.clear = function() {
+    /**
+    x range of a Box.
+    
+    @property x
+    @for _f4u$t.Box
+    @type Array
+    @default [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]
+    **/
+    this.x = [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];
+    /**
+    y range of a Box.
+    
+    @property y
+    @for _f4u$t.Box
+    @type Array
+    @default [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]
+    **/
+    this.y = [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];
+  }
+  this.clear();
+}
+
+/**
+Adds an array of points, with each point in the form [x,y], to the
+interior of the box.
+
+ at method add_points
+ at for _f4u$t.Box
+ at param {Array} pts An array of points.
+**/
+_f4u$t.Box.prototype.add_points = function(pts) {
+  for (var i = 0; i < pts.length; i++) {
+    this.add_point(pts[i]);
+  }
+}
+
+/**
+Adds a point in the form [x,y] to the
+interior of the box.
+
+ at method add_points
+ at for _f4u$t.Box
+ at param {Array} pt A point to add.
+**/
+_f4u$t.Box.prototype.add_point = function(pt) {
+  this.x = [Math.min(this.x[0], pt[0]), Math.max(this.x[1], pt[0])];
+  this.y = [Math.min(this.y[0], pt[1]), Math.max(this.y[1], pt[1])];
+}
+
+/**
+Returns the length of the box along the x and y axes.
+
+ at method lens
+ at for _f4u$t.Box
+ at return {Array} The length of the box along the x and y axes.
+**/
+_f4u$t.Box.prototype.lens = function(pt) {
+  return [this.x[1] - this.x[0], this.y[1] - this.y[0]];
+}
+
+/**
+Returns the corner points (minima and maxima) of the Box.
+
+ at method corners
+ at for _f4u$t.Box
+ at return {Array} The corner points of the box.
+**/
+_f4u$t.Box.prototype.corners = function(pt) {
+  return [[this.x[0], this.y[0]], [this.x[1], this.y[1]]];
+}
+
+/**
+Finds the bounding box of a text node in an svg.
+
+ at method get_text_bbox
+ at for _f4u$t
+ at param {Object} svg The svg node.
+ at param {Object} text The text node.
+ at return {Object} The bounding rectangle of the text node.
+**/
+_f4u$t.get_text_bbox = function(svg, text, kls) {
+  if (!kls) {
+    kls = 'faust-label';
+  }
+  var dummy = _f4u$t.make_text(svg,null,0,0,text, {'class' : kls});
+  var bbox = dummy.getBBox();
+  _f4u$t.svg_remove(svg, dummy);
+  return bbox;
+}
+
+_f4u$t.make_rectangle_via_path = function(svg, parent, rf, x, y, w, h, ops) {
+  var d = "M{0} {7}L{1} {7}C{2} {7} {2} {7} {2} {3}L{2} {4}C{2} {5} {2} {5} {1} {5}L{0} {5}C{6} {5} {6} {5} {6} {4}L{6} {3}C{6} {7} {6} {7} {0} {7}";
+  d = d.format([rf + x, w - rf + x, w + x, rf + y, h - rf + y, h + y, x, y]);
+  var rect = _f4u$t.make_path(
+    parent,
+    d,
+    ops
+  );
+
+  return rect;
+}
+
+/**
+Makes the UI for the faust application.
+
+ at method make_ui
+ at for _f4u$t
+ at param {Object} svg The root SVG node.
+ at param {Object} raw_json The raw JSON describing the UI to build.
+**/
+_f4u$t.make_ui = function(svg, raw_json, width, height, hash) {
+  var json = eval ("(" + raw_json + ")");
+  var faust_svg = new _f4u$t.SVG(
+    svg,
+    width,
+    height,
+    {
+      constrain : false,
+      title : json["ui"][0].label,
+      lm : _f4u$t.json_to_ui(json, hash)
+    }
+  );
+
+  faust_svg.defs();
+  faust_svg.lm.mom = faust_svg;
+  faust_svg.make();
+}
+
+_f4u$t.assign_parameters_to_values = function(URLParams) {
+  for (var index in URLParams) {
+    var split_index = index.toString().split('.');
+    if (split_index.length != 2) {
+      continue;
+    }
+    if (_f4u$t[split_index[0]]) {
+      if (_f4u$t[split_index[0]][split_index[1]]) {
+        _f4u$t[split_index[0]][split_index[1]] = eval(URLParams[index][URLParams[index].length - 1]);
+      }
+    }
+  }
+}
+
+/**
+The main function called to build the faust UI.
+Parses the URL to include any new documents and then builds the UI.
+
+ at method main
+ at for _f4u$t
+ at param {Object} raw_json A raw JSON object describing the UI to build.
+ at param {Object} div (optional) The div to place the object in.
+**/
+_f4u$t.main = function(raw_json, div, callback) {
+    
+    if (!div) {
+        div = $( "<div />" );
+        $("body").append(div);
+    }
+    // we create a hash for the object
+    var hash = $(div).attr('id') ? $(div).attr('id') :  _f4u$t.rand_string(8);
+    
+    // keep it in the div
+    $(div).attr('id', hash);  
+    
+    // first, we parse URL parameters to change UIs' style if necessary
+    var URLParams = _f4u$t.parseURLParams(document.URL);
+    // then we assign parameters
+    _f4u$t.assign_parameters_to_values(URLParams);
+    // we make sure all JS and CSS is loaded before we build the UI
+    _f4u$t.load_css_and_then_js(URLParams.css, URLParams.js);
+    
+    var width = $(div).width();
+    if (width == 0) {
+        // HUOM: this "- 15" is a kludge and should dealt with more elegantly
+        width = $(window).width() - 15;
+    }
+    var height = $(div).height();
+    if (height == 0) {
+        // HUOM: this "- 17" is a kludge and should dealt with more elegantly
+        height = $(window).height() - 17;
+    }
+    if (callback) {
+        _f4u$t.HANDLER_CALLBACKS.push(function(address, value) {
+                                      if (_f4u$t.first_part_matches(address, hash)) {
+                                      return callback(_f4u$t.remove_from_head_of_string(address, hash), value);
+                                      }
+                                      });
+    }
+
+    _f4u$t.add_svg_and_onload_to_div(div, raw_json, width, height, hash);
+
+    return function(address, value) {
+        return _f4u$t.update_value_at_address(hash+address, value);
+    }
+}
+
+/**
+  Deletes all references to this div in internal data structures, including
+  all bindings.  Note that this does NOT delete the div from the page, nor
+  does it delete the div's contents.  This is in case the div contains
+  other information that the person wants to complete.
+  
+  To delete the UI in the div, call _f4u$t.hard_delete()
+**/
+_f4u$t.delete = function(div) {
+  var id = $(div).attr('id');
+  if (!id) {
+    console.log("Can't delete because obj does not exist in the system.");
+    return;
+  }
+  var ids_to_delete = [];
+  var keys_to_delete = []
+  for (var key in _f4u$t.PATHS_TO_IDS) {
+    if (_f4u$t.first_part_matches(key, id)) {
+      ids_to_delete.push(_f4u$t.PATHS_TO_IDS[key]);
+      keys_to_delete.push(key);
+    }
+  }
+  for (var key_to_delete in keys_to_delete) {
+    delete _f4u$t.PATHS_TO_IDS[key_to_delete];
+  }
+  for (var id_to_delete in ids_to_delete) {
+    var slim = _f4u$t.unique(id_to_delete);
+    delete _f4u$t.IDS_TO_ATTRIBUTES[slim];
+  }
+}
+
+_f4u$t.hard_delete = function(div) {
+  _f4u$t.delete(div);
+  $(div).empty();
+}
+
+/**
+  To be called when used with the C++/LLVM libfaust based FaustNode.
+**/
+_f4u$t.make_audio_ui = function(dsp, svg) {
+  var json = eval ("(" + dsp.json() + ")");
+  var faust_svg = new _f4u$t.SVG(
+    svg,
+    // kludge to prevent scroll bars...
+    $(window).width() - 15,
+    // kludge to prevent scroll bars...
+    $(window).height() - 17,
+    {
+      constrain : false,
+      title : json["ui"][0].label,
+      lm : _f4u$t.json_to_ui(json)
+    }
+  );
+  
+  // Keep audio params in a table 
+  _f4u$t.controls = new Array();
+  for (var i = 0; i < dsp.numberOfAudioParams(); i++) {
+    var ctrl = dsp.getAudioParam(i);
+    _f4u$t.controls[ctrl.name] = ctrl;
+  }
+  
+  _f4u$t.fausthandler = function(dest, value) {
+    _f4u$t.controls[dest].value = value; 
+  }
+    
+  _f4u$t.main_loop = function() {}
+
+  faust_svg.defs();
+  faust_svg.lm.mom = faust_svg;
+  faust_svg.make();
+}
+
diff --git a/architecture/httpdlib/html/js/svg/faust_server_communication.js b/architecture/httpdlib/html/js/svg/faust_server_communication.js
new file mode 100644
index 0000000..5fdfb20
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_server_communication.js
@@ -0,0 +1,95 @@
+
+//-----------------------------------------------------------------------------
+// handlers to send a faust 'set' message
+// actually using a 'GET' method
+//-----------------------------------------------------------------------------
+_f4u$t.faust_server_handler = function(dest, value) {
+  if (!_f4u$t.ajax_queue[dest]) {
+    _f4u$t.ajax_queue[dest] = [];
+  }
+  _f4u$t.ajax_queue[dest].push({request : dest +"?value=" + value, time : new Date().getTime()});
+}
+
+_f4u$t.server_update_function = function(address, value) {
+  // do nothing - a stub that should be overwritten in toplevel html files
+}
+
+//-----------------------------------------------------------------------------
+// poll current values from the server
+//-----------------------------------------------------------------------------
+
+_f4u$t.dispatch = function(data) {
+  var lines = data.toString().split('\n');
+  var limit = lines.length;
+  for (i=0; i < limit; i++) {
+    var values = lines[i].toString().split(' ');
+    if (values.length > 1) {
+      var address = values[0];
+      // skip things being moved to avoid interference
+      if (_f4u$t.active_addresses.indexOf(address) != -1) {
+        continue;
+      }
+      var value = Math.round(values[1]*10000)/10000;
+      _f4u$t.server_update_function(address, value);
+    }
+  }
+}
+
+_f4u$t.ajax_queue_length = function() {
+  var l = 0;
+  for (var key in _f4u$t.ajax_queue) {
+    for (var i = 0; i < _f4u$t.ajax_queue[key].length; i++) {
+      l += 1;
+    }
+  }
+  return l;
+}
+
+_f4u$t.ajax_queue_get_request_and_trim = function () {
+  var t = Number.POSITIVE_INFINITY;
+  var request = '';
+  var mykey = '';
+  for (var key in _f4u$t.ajax_queue) {
+    for (var i = 0; i < _f4u$t.ajax_queue[key].length; i++) {
+      if (_f4u$t.ajax_queue[key][i].time < t) {
+        t = _f4u$t.ajax_queue[key][i].time;
+        request = _f4u$t.ajax_queue[key][i].request;
+        mykey = key;
+      }
+    }
+    // always trim
+    _f4u$t.ajax_queue[key] = _f4u$t.ajax_queue[key].slice(0,Math.min(5,_f4u$t.ajax_queue[key].length));
+  }
+  // trim first request off of successful array
+  _f4u$t.ajax_queue[mykey] = _f4u$t.ajax_queue[mykey].slice(1,Math.min(5,_f4u$t.ajax_queue[key].length));
+  return request;
+}
+
+// We update the user interface by polling the server every 40 ms
+// But this is done only when no updates are pending for the server
+_f4u$t.main_loop = function() {
+  if ((_f4u$t.ajax_queue_length() > 0) || _f4u$t.ajax_queue_busy) {
+    // we have pending updates to send to the server
+    //_f4u$t.ajax_queue_busy = true;
+    var request = _f4u$t.ajax_queue_get_request_and_trim();
+    $.get(request)
+      .done(function () {
+        //console.log("request succeeded", request);
+        _f4u$t.main_loop();
+      })
+      .fail(function () {
+        console.log("request failed", request);
+        _f4u$t.main_loop();
+      });/*
+      .always(function () {
+        console.log("request passed", request);
+      });*/
+  } else {
+    // regular polling
+    _f4u$t.ajax_queue_busy = false;
+    $.get(_f4u$t.ROOT, function(data) { _f4u$t.dispatch( data ); } );
+    setTimeout ( function() { _f4u$t.main_loop(); }, 40);
+  }		
+}
+
+$(document).ready(function() { _f4u$t.main_loop(); });
diff --git a/architecture/httpdlib/html/js/svg/faust_ui_audio_bridge.js b/architecture/httpdlib/html/js/svg/faust_ui_audio_bridge.js
new file mode 100644
index 0000000..30558ba
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_ui_audio_bridge.js
@@ -0,0 +1,96 @@
+/**
+ Each audio bridge reports a callback that the listener calls with an address of
+ a UI object and the value it is changing to.  The bridge is resonsible for
+ using this information in a useful way (sending it to a server, to a
+ JavaScript object, etc.).
+
+ at property HANDLER_CALLBACKS
+ at for _f4u$t
+ at type Array
+ at default []
+**/
+_f4u$t.HANDLER_CALLBACKS = [];
+
+/**
+ Triggers all callbacks.
+
+ at method fausthandler
+ at for _f4u$t
+ at static
+ at param {String} dest The destination address
+ at param {Number} value The value at that address.
+**/
+
+_f4u$t.fausthandler = function(dest, value) {
+  for (var i = 0; i < _f4u$t.HANDLER_CALLBACKS.length; i++) {
+    _f4u$t.HANDLER_CALLBACKS[i](dest, value);
+  }
+}
+
+// Functions to update UI via what's happening internally in the audio
+// processing.
+
+_f4u$t.update_incremental_object_value = function(address, value) {
+   var id = _f4u$t.PATHS_TO_IDS[address];
+  _f4u$t.dumb_label_update(_f4u$t.unique(id), value);
+  _f4u$t.actualize_incremental_object(_f4u$t.unique(id));
+}
+
+_f4u$t.update_hslider_value = function(address, value) {
+  _f4u$t.update_incremental_object_value(address, value);
+}
+
+_f4u$t.update_vslider_value = function(address, value) {
+  _f4u$t.update_incremental_object_value(address, value);
+}
+
+_f4u$t.update_hbargraph_value = function(address, value) {
+  _f4u$t.update_incremental_object_value(address, value);
+}
+
+_f4u$t.update_vbargraph_value = function(address, value) {
+  _f4u$t.update_incremental_object_value(address, value);
+}
+
+_f4u$t.update_rbutton_value = function(address, value) {
+  _f4u$t.update_incremental_object_value(address, value);
+}
+
+_f4u$t.update_nentry_value = function(address, value) {
+   var id = _f4u$t.PATHS_TO_IDS[address];
+  _f4u$t.dumb_label_update(id, value);
+}
+
+_f4u$t.update_checkbox_value = function(address, value) {
+  // perhaps too much UI here?
+  var id = _f4u$t.PATHS_TO_IDS[address];
+  // for latency issues...seems not to do anything, so commented out
+  /*if (now - _f4u$t.IDS_TO_ATTRIBUTES[id]["time"] < 2000) {
+    return;
+  }*/
+  var check = document.getElementById('faust_checkbox_check_'+id);
+  check.style.opacity = value;
+}
+
+_f4u$t.update_button_value = function(address, value) {
+  var id = _f4u$t.PATHS_TO_IDS[address];
+  if (value == 1) {
+    _f4u$t.button_fill_changer(id, true);
+  } else {
+    _f4u$t.button_fill_changer(id, false);
+  }
+}
+
+_f4u$t.update_value_at_address = function(address, value) {
+  var id = _f4u$t.PATHS_TO_IDS[address];
+  var kind = _f4u$t.IDS_TO_ATTRIBUTES[id] ? _f4u$t.IDS_TO_ATTRIBUTES[id].type : null ;
+  if (kind == 'vslider') { _f4u$t.update_vslider_value(address, value); }
+  else if (kind == 'hslider') { _f4u$t.update_hslider_value(address, value); }
+  else if (kind == 'rbutton') { _f4u$t.update_rbutton_value(address, value); }
+  else if (kind == 'checkbox') { _f4u$t.update_checkbox_value(address, value); }
+  else if (kind == 'button') { _f4u$t.update_button_value(address, value); }
+  else if (kind == 'nentry') { _f4u$t.update_nentry_value(address, value); }
+  else if (kind == 'vbargraph') { _f4u$t.update_vbargraph_value(address, value); }
+  else if (kind == 'hbargraph') { _f4u$t.update_hbargraph_value(address, value); }
+  else { if (0) { console.log("Unidentified Faust Object (UFO) "+id+" "+kind); }}
+}
diff --git a/architecture/httpdlib/html/js/svg/faust_ui_builder.js b/architecture/httpdlib/html/js/svg/faust_ui_builder.js
new file mode 100644
index 0000000..3b92c22
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_ui_builder.js
@@ -0,0 +1,439 @@
+_f4u$t.check_label = function(label) {
+  return (label.substring(0, 2) == "0x") ? "" : label;
+}
+
+_f4u$t.meta_info = function(dct, prop, def, fn) {
+  if (!dct['meta']) {
+    return def;
+  }
+  for (var i=0; i < dct['meta'].length; i++) {
+    if (dct['meta'][i][prop]) {
+      return fn(dct['meta'][i][prop]);
+    }
+  }
+  return def;
+}
+
+_f4u$t.has_knob = function(dct) {
+  return _f4u$t.meta_info(dct, 'style', false, function(prop) { return prop == 'knob'; });
+}
+
+_f4u$t.get_unit = function(dct) {
+  return _f4u$t.meta_info(dct, 'unit', '', _f4u$t.identity);
+}
+
+_f4u$t.get_tooltip = function(dct) {
+  return _f4u$t.meta_info(dct, 'tooltip', '', _f4u$t.identity);
+}
+
+_f4u$t.get_orientation_mode = function(dct) {
+  return _f4u$t.meta_info(dct, 'orientation-mode', 'absolute', _f4u$t.identity);
+}
+
+_f4u$t.get_orientation = function(dct) {
+  return _f4u$t.meta_info(dct, 'orientation', {}, _f4u$t.parse_orientation);
+}
+
+_f4u$t.is_panoramic = function(dct) {
+  return _f4u$t.meta_info(dct, 'panoramic', false, function(prop) { return prop === 'true'; });
+}
+
+_f4u$t.get_sweep = function(dct) {
+  return _f4u$t.meta_info(dct, 'sweep', _f4u$t.rbutton_inits.sweep, function(prop) { return parseFloat(prop) != null ? parseFloat(prop) : _f4u$t.rbutton_inits.sweep; });
+}
+
+_f4u$t.get_size = function(dct) {
+  return _f4u$t.meta_info(dct, 'size', 1, function(prop) { return [0.5,1,2,3,4][parseInt(prop)]; });
+}
+
+_f4u$t.getnumspecs = function(dct) {
+  var integer = false;
+  if((parseFloat(dct["max"]) == parseInt(dct["max"]))
+     && (parseFloat(dct["min"]) == parseInt(dct["min"]))
+     && (parseFloat(dct["step"]) == parseInt(dct["step"]))
+     && (parseFloat(dct["init"]) == parseInt(dct["init"]))
+     && !isNaN(dct["max"])
+     && !isNaN(dct["min"])
+     && !isNaN(dct["step"])
+     && !isNaN(dct["init"])) {
+    integer = true;
+  }
+
+  var maxsplit = dct["max"] ? dct["max"].toString().split('.') : ['',''];
+  var minsplit = dct["min"] ? dct["min"].toString().split('.') : ['',''];
+  var stepsplit = dct["step"] ? dct["step"].toString().split('.') : ['',''];
+  var initsplit = dct["init"] ? dct["init"].toString().split('.') : ['',''];
+  maxsplit[1] = maxsplit[1] || '';
+  minsplit[1] = minsplit[1] || '';
+  stepsplit[1] = stepsplit[1] || '';
+  initsplit[1] = initsplit[1] || '';
+  parser = integer ? parseInt : parseFloat;
+  return {
+    min : parser(dct["min"]),
+    max : parser(dct["max"]),
+    step : parser(dct["step"]),
+    init : parser(dct["init"]),
+    isint : integer,
+    ndec : Math.max(maxsplit[1].length, minsplit[1].length, stepsplit[1].length, initsplit[1].length)
+  };
+}
+
+_f4u$t.make_rbutton = function(dct, hash) {
+  var numspecs = _f4u$t.getnumspecs(dct);
+  var id = _f4u$t.randString();
+  var options = $.extend(true, {}, _f4u$t.rbutton_inits);
+  options.id = id;
+  options.min = numspecs["min"];
+  options.max = numspecs["max"];
+  options.step = numspecs["step"];
+  options.init = numspecs["init"];
+  options.integer = numspecs["integer"];
+  options.ndec = numspecs["ndec"];
+  options.address = hash+dct["address"];
+  options.unit = _f4u$t.get_unit(dct);
+  options.tooltip = _f4u$t.get_tooltip(dct);
+  options.orientation = _f4u$t.get_orientation(dct);
+  options.orientation_mode = _f4u$t.get_orientation_mode(dct);
+  if (_f4u$t.is_panoramic(dct)) {
+    options.a0 = 0;
+    options.sweep = 360;
+  }
+  var size = _f4u$t.get_size(dct);
+  options.ir *= size;
+
+  var vbox_options = $.extend(true, {}, _f4u$t.vbox_inits);
+  vbox_options.init = numspecs["init"];
+  vbox_options.id = id;
+  var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+  lm_options.axis = _f4u$t.Y_AXIS;
+  lm_options.stretchable = [false, false];
+
+  /* make faust ui objects */
+  var rbutton = new _f4u$t.RotatingButton(options);
+  var label = new _f4u$t.Label({label : _f4u$t.check_label(dct["label"]), id : id+"label", mom : null});
+  var vbox = new _f4u$t.ValueBox(vbox_options);
+
+  var lm = new _f4u$t.LayoutManager(lm_options);
+  lm.objs.push(label);
+  lm.objs.push(rbutton);
+  lm.objs.push(vbox);
+
+  return lm;
+}
+
+_f4u$t.make_hslider = function(dct, hash) {
+  return _f4u$t.make_slider(_f4u$t.HorizontalSlider, dct, hash);
+}
+
+_f4u$t.make_vslider = function(dct, hash) {
+  return _f4u$t.make_slider(_f4u$t.VerticalSlider, dct, hash);
+}
+
+_f4u$t.make_slider = function(kls, dct, hash) {
+  if (_f4u$t.has_knob(dct)) {
+    return _f4u$t.make_rbutton(dct, hash);
+  }
+  var numspecs = _f4u$t.getnumspecs(dct);
+  var horizontal = kls == _f4u$t.HorizontalSlider;
+  var id = _f4u$t.randString();
+  var options = $.extend(true, {}, _f4u$t[horizontal ? 'hslider_inits' : 'vslider_inits']);
+  options.id = id;
+  options.min = numspecs["min"];
+  options.max = numspecs["max"];
+  options.step = numspecs["step"];
+  options.init = numspecs["init"];
+  options.integer = numspecs["integer"];
+  options.ndec = numspecs["ndec"];
+  options.address = hash+dct["address"];
+  options.unit = _f4u$t.get_unit(dct);
+  options.orientation = _f4u$t.get_orientation(dct);
+  options.orientation_mode = _f4u$t.get_orientation_mode(dct);
+  options.tooltip = _f4u$t.get_tooltip(dct);
+  var size = _f4u$t.get_size(dct);
+  options.girth *= size;
+  options.length *= size;
+
+  var vbox_options = $.extend(true, {}, _f4u$t.vbox_inits);
+  vbox_options.init = numspecs["init"];
+  vbox_options.id = id;
+
+  /* make faust ui objects */
+  var slider = new kls(options);
+  var label = new _f4u$t.Label({label : _f4u$t.check_label(dct["label"]), id : id+"label", mom : null});
+  var vbox = new _f4u$t.ValueBox(vbox_options);
+
+  var lm = 0;
+  if (horizontal) {
+    var internal_lm_options = $.extend(true, {}, _f4u$t.hgroup_inits);
+    internal_lm_options.axis = _f4u$t.X_AXIS
+    internal_lm_options.draw_background = false;
+    internal_lm_options.other_axis_padding = 0;
+    var internal_lm = new _f4u$t.LayoutManager(internal_lm_options);
+    internal_lm.objs.push(vbox);
+    internal_lm.objs.push(slider);
+
+    var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+    lm_options.axis = _f4u$t.Y_AXIS;
+    lm_options.gravity = _f4u$t.LEFT;
+    lm_options.stretchable = [true, false];
+    lm = new _f4u$t.LayoutManager(lm_options);
+    lm.objs.push(label);
+    lm.objs.push(internal_lm);
+  } else {
+    var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+    lm_options.axis = _f4u$t.Y_AXIS;
+    lm_options.stretchable = [false, true];
+    lm = new _f4u$t.LayoutManager(lm_options);
+    lm.objs.push(label);
+    lm.objs.push(slider);
+    lm.objs.push(vbox);
+  }
+
+  return lm;
+}
+
+_f4u$t.make_hbargraph = function(dct, hash) {
+  return _f4u$t.make_bargraph(_f4u$t.HorizontalBarGraph, dct, hash);
+}
+
+_f4u$t.make_vbargraph = function(dct, hash) {
+  return _f4u$t.make_bargraph(_f4u$t.VerticalBarGraph, dct, hash);
+}
+
+_f4u$t.make_bargraph = function(kls, dct, hash) {
+  var horizontal = kls == _f4u$t.HorizontalBarGraph;
+  var id = _f4u$t.randString();
+  var options = $.extend(true, {}, _f4u$t[horizontal ? 'hbargraph_inits' : 'vbargraph_inits']);
+  options.id = id;
+  //var numspecs = _f4u$t.getnumspecs(dct);
+  options.min = parseFloat(dct["min"]);
+  options.max = parseFloat(dct["max"]);
+  options.address = hash+dct["address"];
+  options.unit = _f4u$t.get_unit(dct);
+  var size = _f4u$t.get_size(dct);
+  options.tooltip = _f4u$t.get_tooltip(dct);
+  options.girth *= size;
+  options.length *= size;
+
+  var vbox_options = $.extend(true, {}, _f4u$t.vbox_inits);
+  vbox_options.keysink = false;
+  vbox_options.id = id;
+  var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+  lm_options.axis = _f4u$t.Y_AXIS;
+
+  /* make faust ui objects */
+  var bargraph = new kls(options);
+  var label = new _f4u$t.Label({label : _f4u$t.check_label(dct["label"]), id : id+"_label", mom : null});
+  var vbox = new _f4u$t.ValueBox(vbox_options);
+
+  var lm = 0;
+  // ugh...code dup from slider...
+  if (horizontal) {
+    var internal_lm_options = $.extend(true, {}, _f4u$t.hgroup_inits);
+    internal_lm_options.axis = _f4u$t.X_AXIS
+    internal_lm_options.draw_background = false;
+    internal_lm_options.other_axis_padding = 0;
+    var internal_lm = new _f4u$t.LayoutManager(internal_lm_options);
+    internal_lm.objs.push(vbox);
+    internal_lm.objs.push(bargraph);
+
+    var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+    lm_options.axis = _f4u$t.Y_AXIS;
+    lm_options.gravity = _f4u$t.LEFT;
+    lm_options.stretchable = [true, false];
+    lm = new _f4u$t.LayoutManager(lm_options);
+    lm.objs.push(label);
+    lm.objs.push(internal_lm);
+  } else {
+    var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+    lm_options.axis = _f4u$t.Y_AXIS;
+    lm_options.stretchable = [false, true];
+    lm = new _f4u$t.LayoutManager(lm_options);
+    lm.objs.push(label);
+    lm.objs.push(bargraph);
+    lm.objs.push(vbox);
+  }
+
+  return lm;
+}
+
+_f4u$t.make_button = function(dct, hash) {
+  var id = _f4u$t.randString();
+  var options = $.extend(true, {}, _f4u$t.button_inits);
+  options.id = id;
+  options.label = dct.label;
+  options.address = hash+dct.address;
+  options.tooltip = _f4u$t.get_tooltip(dct);
+  return new _f4u$t.Button(options);
+}
+
+_f4u$t.make_checkbox = function(dct, hash) {
+  var id = _f4u$t.randString();
+  var options = $.extend(true, {}, _f4u$t.checkbox_inits);
+  options.id = id;
+  options.address = hash+dct.address;
+  options.init = (dct.init == "1" ? true : false);
+  var size = _f4u$t.get_size(dct);
+  options.tooltip = _f4u$t.get_tooltip(dct);
+  options.d *= size;
+
+  var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+  lm_options.axis = _f4u$t.X_AXIS;
+  lm_options.stretchable = [false, false];
+
+  /* make faust ui objects */
+  var checkbox = new _f4u$t.CheckBox(options);
+  var label = new _f4u$t.Label({label : _f4u$t.check_label(dct["label"]), id : id+"_label", mom : null});
+
+  var lm = new _f4u$t.LayoutManager(lm_options);
+  lm.objs.push(checkbox);
+  lm.objs.push(label);
+
+  return lm;
+}
+
+_f4u$t.make_nentry = function(dct, hash) {
+  if (_f4u$t.has_knob(dct)) {
+    return _f4u$t.make_rbutton(dct, hash);
+  }
+  var numspecs = _f4u$t.getnumspecs(dct);
+  var id = _f4u$t.randString();
+  var options = {
+    label : dct["label"],
+    min : numspecs["min"],
+    max : numspecs["max"],
+    step : numspecs["step"],
+    init : numspecs["init"],
+    integer : numspecs["integer"],
+    ndec : numspecs["ndec"],
+    address : hash+dct["address"],
+    unit : _f4u$t.get_unit(dct),
+    tooltip : _f4u$t.get_tooltip(dct)
+  };
+  options.id = id;
+
+  var nentry = new _f4u$t.NumericalEntry(options);
+
+  var vbox_options = $.extend(true, {}, _f4u$t.vbox_inits);
+  vbox_options.init = numspecs["init"];
+  vbox_options.id = id;
+  var lm_options = $.extend(true, {}, _f4u$t.vgroup_inits);
+  lm_options.axis = _f4u$t.Y_AXIS;
+  lm_options.stretchable = [false, false];
+
+  /* make faust ui objects */
+  var label = new _f4u$t.Label({label : _f4u$t.check_label(dct["label"]), id : id+"_label", mom : null});
+  var vbox = new _f4u$t.ValueBox(vbox_options);
+
+  var lm = new _f4u$t.LayoutManager(lm_options);
+  lm.objs.push(label);
+  lm.objs.push(nentry);
+  lm.objs.push(vbox);
+
+  return lm;
+}
+
+_f4u$t.make_hgroup = function(dct, hash) {
+  return _f4u$t.make_group(_f4u$t.X_AXIS, dct, hash);
+}
+
+_f4u$t.make_vgroup = function(dct, hash) {
+  return _f4u$t.make_group(_f4u$t.Y_AXIS, dct, hash);
+}
+
+_f4u$t.make_group = function(axis, dct, hash) {
+  var internal_options = $.extend(true, {}, _f4u$t.xy(axis, _f4u$t.hgroup_inits, _f4u$t.vgroup_inits));
+  internal_options.axis = axis;
+
+  internal_options.draw_background = false;
+  internal_options.other_axis_padding = 0;
+  var id = _f4u$t.randString();
+  internal_options.id = id;
+
+  var internal_lm = new _f4u$t.LayoutManager(internal_options);
+
+  for (var i = 0; i < dct["items"].length; i++) {
+    if (dct["items"][i]["type"] == "hgroup") {
+      internal_lm.objs.push(_f4u$t.make_hgroup(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "vgroup") {
+      internal_lm.objs.push(_f4u$t.make_vgroup(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "tgroup") {
+      internal_lm.objs.push(_f4u$t.make_tgroup(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "hslider") {
+      internal_lm.objs.push(_f4u$t.make_hslider(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "vslider") {
+      internal_lm.objs.push(_f4u$t.make_vslider(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "hbargraph") {
+      internal_lm.objs.push(_f4u$t.make_hbargraph(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "vbargraph") {
+      internal_lm.objs.push(_f4u$t.make_vbargraph(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "button") {
+      internal_lm.objs.push(_f4u$t.make_button(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "checkbox") {
+      internal_lm.objs.push(_f4u$t.make_checkbox(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "nentry") {
+      internal_lm.objs.push(_f4u$t.make_nentry(dct["items"][i], hash));
+    }
+    else {
+      console.log("UFO: Unidentified Faust Object");
+    }
+  }
+
+  var label = new _f4u$t.Label({label : _f4u$t.check_label(dct["label"]), id : id+"_label", mom : null});
+
+  var options = $.extend(true, {}, _f4u$t.vgroup_inits);
+  // needed for tab group
+  options.label = dct["label"];
+  options.axis = _f4u$t.Y_AXIS;
+
+  var lm = new _f4u$t.LayoutManager(options);
+  lm.objs.push(label);
+  lm.objs.push(internal_lm);
+  return lm;
+}
+
+_f4u$t.make_tgroup = function(dct, hash) {
+  var options = $.extend(true, {}, _f4u$t.tgroup_inits);
+  var tg = new _f4u$t.TabGroup(options);
+
+  for (var i = 0; i < dct["items"].length; i++) {
+    if (dct["items"][i]["type"] == "hgroup") {
+      tg.objs.push(_f4u$t.make_hgroup(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "vgroup") {
+      tg.objs.push(_f4u$t.make_vgroup(dct["items"][i], hash));
+    }
+    else if (dct["items"][i]["type"] == "tgroup") {
+      tg.objs.push(_f4u$t.make_tgroup(dct["items"][i], hash));
+    }
+    else {
+      console.log("UFO: Unidentified Faust Object");
+    }
+  }
+
+  return tg;
+}
+
+_f4u$t.json_to_ui = function(json, hash) {
+  if (json["ui"][0]["type"] == "vgroup") {
+    return _f4u$t.make_vgroup(json["ui"][0], hash);
+  }
+  else if (json["ui"][0]["type"] == "hgroup") {
+    return _f4u$t.make_hgroup(json["ui"][0], hash);
+  }
+  else if (json["ui"][0]["type"] == "tgroup") {
+    return _f4u$t.make_tgroup(json["ui"][0], hash);
+  }
+  else {
+    console.log("UFO: Unidentified Faust Object");
+  }
+}
diff --git a/architecture/httpdlib/html/js/svg/faust_ui_inits.js b/architecture/httpdlib/html/js/svg/faust_ui_inits.js
new file mode 100644
index 0000000..c4157e5
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_ui_inits.js
@@ -0,0 +1,380 @@
+_f4u$t.checkbox_inits = {
+  mom : null,
+  d : 19,
+  id : null,
+  label : '',
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  stretchable : [false, false],
+  check_fill : _f4u$t.BLACK,
+  check_stroke : _f4u$t.BLACK,
+  box_fill : _f4u$t.WHITE,
+  box_stroke : _f4u$t.BLACK,
+  init : false,
+  tooltip : '',
+  address : ''
+};
+
+_f4u$t.button_inits = {
+  mom : null,
+  label : '',
+  id : null,
+  stretchable : [false, false],
+  ideal_width : 80,
+  ideal_height : 40,
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  fill_on : "url(#buttonDownGradient)",
+  fill_off : "url(#buttonUpGradient)",
+  stroke : _f4u$t.GREY,
+  baseline_skip : 5,
+  tooltip : '',
+  address : ''
+};
+
+_f4u$t.tgroup_inits = {
+  mom : null,
+  headroom : 40,
+  headpadding : 10,
+  x_padding : 10,
+  x_width : 80,
+  objs : [],
+  init : 0,
+  stretchable : [false, false],
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  baseline_skip : 5,
+  stroke : 'orange',
+  stretchable : [true, true],
+  id : null,
+  fill_on : "url(#tabGroupDownGradient)",
+  fill_off : "url(#tabGroupUpGradient)"
+};
+
+_f4u$t.group_inits = {
+  mom : null,
+  axis : _f4u$t.X_AXIS,
+  padding : 10,
+  other_axis_padding : 10,
+  draw_background : true,
+  label : '',
+  objs : [],
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  label : '',
+  fill : 'url(#groupBoxGradient)',
+  stretchable : [false, false],
+  stroke : _f4u$t.GREY,
+  stretchable : [true, true]
+}
+
+_f4u$t.vgroup_inits = $.extend(true, {}, _f4u$t.group_inits);
+_f4u$t.hgroup_inits = $.extend(true, {}, _f4u$t.group_inits);
+
+_f4u$t.rbutton_inits = {
+  mom : null,
+  //ir : 50,
+  ir : 30,
+  a0 : 135,
+  sweep : 270,
+  sp : 0.9,
+  kp : 0.7,
+  id : null,
+  label : '',
+  unit : null,
+  min : 0,
+  max : 100,
+  init : 50,
+  step : 1,
+  integer : false,
+  ndec : 0,
+  stretchable : [false, false],
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  meter_fill : 'rgb(50,50,50)',
+  mgroove_fill : 'url(#rotatingButtonMeterGradient)',
+  dot_fill : _f4u$t.PINK,
+  groove_fill : 'url(#rotatingButtonHandleGradient)',
+  handle_fill : 'none',
+  mgroove_stroke : _f4u$t.BLACK,
+  dot_stroke : _f4u$t.BLACK,
+  groove_stroke : _f4u$t.BLACK,
+  handle_stroke : _f4u$t.WHITE,
+  meter_stroke : _f4u$t.BLACK,
+  handle_width : 6,
+  tooltip : '',
+  address : ''
+}
+
+_f4u$t.slidingobject_inits = {
+  mom : null,
+  id : null,
+  axis : _f4u$t.X_AXIS,
+  girth : 40,
+  length : 175,
+  label : '',
+  unit : null,
+  min : 0,
+  max : 100,
+  init : 50,
+  step : 1,
+  integer : false,
+  ndec : 0,
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  address :  '',
+  tooltip : '',
+  type : ''
+};
+
+_f4u$t.slider_inits = $.extend(true, {}, _f4u$t.slidingobject_inits);
+_f4u$t.slider_inits.sp = 30;
+_f4u$t.slider_inits.groove_fill = 'red';
+_f4u$t.slider_inits.groove_stroke = _f4u$t.BLACK;
+_f4u$t.slider_inits.handle_stroke = _f4u$t.BLACK;
+
+_f4u$t.hslider_inits = $.extend(true, {}, _f4u$t.slider_inits);
+_f4u$t.hslider_inits.handle_fill = 'url(#horizontalSliderHandleGradient)';
+_f4u$t.hslider_inits.meter_fill = 'url(#horizontalSliderMeterGradient)';
+_f4u$t.hslider_inits.stretchable = [true, false];
+_f4u$t.vslider_inits = $.extend(true, {}, _f4u$t.slider_inits);
+_f4u$t.vslider_inits.handle_fill = 'url(#verticalSliderHandleGradient)';
+_f4u$t.vslider_inits.meter_fill = 'url(#verticalSliderMeterGradient)';
+_f4u$t.vslider_inits.stretchable = [false, true];
+
+_f4u$t.bargraph_inits = $.extend(true, {}, _f4u$t.slidingobject_inits);
+_f4u$t.bargraph_inits.curtain_fill = _f4u$t.BLACK;
+_f4u$t.bargraph_inits.meter_fill = 'url(#barGraphMeterGradient)';
+_f4u$t.bargraph_inits.curtain_stroke = _f4u$t.BLACK;
+_f4u$t.bargraph_inits.meter_stroke = _f4u$t.BLACK;
+_f4u$t.bargraph_inits.init = null;
+_f4u$t.bargraph_inits.girth = 30;
+
+_f4u$t.hbargraph_inits = $.extend(true, {}, _f4u$t.bargraph_inits);
+_f4u$t.hbargraph_inits.meter_fill = 'url(#horizontalBarGraphMeterGradient)';
+_f4u$t.hbargraph_inits.stretchable = [true, false];
+_f4u$t.vbargraph_inits = $.extend(true, {}, _f4u$t.bargraph_inits);
+_f4u$t.vbargraph_inits.meter_fill = 'url(#verticalBarGraphMeterGradient)';
+_f4u$t.vbargraph_inits.stretchable = [false, true];
+
+_f4u$t.nentry_inits = {
+  mom : null,
+  id : null,
+  ideal_width : _f4u$t.VALUE_BOX_W,
+  ideal_height : _f4u$t.VALUE_BOX_H,
+  label : '',
+  unit : null,
+  min : 0,
+  max : 100,
+  init : 50,
+  step : 1,
+  integer : false,
+  ndec : 0,
+  stretchable : [false, false],
+  button_fill : _f4u$t.GREY,
+  operation_fill : _f4u$t.BLACK,
+  button_stroke : _f4u$t.BLACK,
+  operation_stroke : _f4u$t.BLACK,
+  padding : 1,
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  type : 'nentry',
+  tooltip : '',
+  address : ''
+}
+
+_f4u$t.vbox_inits = {
+  mom : null,
+  id : null,
+  width : _f4u$t.VALUE_BOX_W,
+  keysink : true,
+  height : _f4u$t.VALUE_BOX_H,
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  stretchable : [false, false],
+  init : 50
+}
+
+_f4u$t.label_inits = {
+  mom : null,
+  label : '',
+  id : null,
+  gravity : [_f4u$t.CENTER, _f4u$t.CENTER],
+  stretchable : [false, false]
+}
+
+_f4u$t.linear_gradient_inits = {
+  buttonDownGradient :
+    {
+      stops : [['0%', '#404040', 1],['100%', '#B0B0B0', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "0%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  buttonUpGradient :
+    {
+      stops : [['0%', '#B0B0B0', 1],['100%', '#404040', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  tabGroupDownGradient :
+    {
+      stops : [['0%', '#404040', 1],['100%', '#B0B0B0', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "0%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  tabGroupUpGradient :
+    {
+      stops : [['0%', '#B0B0B0', 1],['100%', '#404040', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  groupBoxGradient :
+    {
+      stops : [['0%', '#A0A0A0', 1],['100%', '#202020', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  verticalSliderHandleGradient :
+    {
+      stops : [['0%', '#AAAAAA', 1], ['5%' ,'#0A0A0A', 1], ['30%','#101010', 1], ['90%','#AAAAAA', 1], ['91%','#000000', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "0%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  horizontalSliderHandleGradient :
+    {
+      stops : [['0%', '#AAAAAA', 1], ['5%' ,'#0A0A0A', 1], ['30%','#101010', 1], ['90%','#AAAAAA', 1], ['91%','#000000', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "0%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  rotatingButtonMeterGradient :
+    {
+      stops : [['0%', 'rgb(255,255,0)', 1], ['100%', 'rgb(255,0,0)', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "0%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  horizontalSliderMeterGradient :
+    {
+      stops : [['0%', 'rgb(255,255,0)', 1], ['100%', 'rgb(255,0,0)', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "0%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  verticalSliderMeterGradient :
+    {
+      stops : [['0%', 'rgb(255,0,0)', 1], ['100%', 'rgb(255,255,0)', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "0%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  numericalEntryDownGradient :
+    {
+      stops : [['0%', '#404040', 1],['100%', '#B0B0B0', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "0%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  numericalEntryUpGradient :
+    {
+      stops : [['0%', '#B0B0B0', 1],['100%', '#404040', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  horizontalBarGraphMeterGradient :
+    {
+      stops : [['0%', 'rgb(0, 160, 40)', 1], ['50%', 'rgb(0, 160, 40)', 1],
+               ['50%', 'rgb(160, 220, 20)', 1], ['60%', 'rgb(160, 220, 20)', 1],
+               ['60%', 'rgb(220, 220, 20)', 1], ['70%', 'rgb(220, 220, 20)', 1],
+               ['70%', 'rgb(240, 160, 20)', 1], ['80%', 'rgb(240, 160, 20)', 1],
+               ['80%', 'rgb(240, 0, 20)', 1], ['100%', 'rgb(240, 0, 20)', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "100%",
+      y2 : "0%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    },
+  verticalBarGraphMeterGradient :
+    {
+      stops : [['0%', 'rgb(240, 0, 20)', 1], ['20%', 'rgb(240, 0, 20)', 1],
+               ['20%', 'rgb(240, 160, 20)', 1], ['30%', 'rgb(240, 160, 20)', 1],
+               ['30%', 'rgb(220, 220, 20)', 1], ['40%', 'rgb(220, 220, 20)', 1],
+               ['40%', 'rgb(160, 220, 20)', 1], ['50%', 'rgb(160, 220, 20)', 1],
+               ['80%', 'rgb(0, 160, 40)', 1], ['100%', 'rgb(0, 160, 40)', 1]],
+      x1 : "0%",
+      y1 : "0%",
+      x2 : "0%",
+      y2 : "100%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    }
+}
+
+_f4u$t.radial_gradient_inits = {
+  rotatingButtonHandleGradient :
+    {
+      stops : [['0%', 'rgb(255,255,255)', 0.8],['100%', 'rgb(110,110,110)', 1]],
+      cx : "40%",
+      cy : "35%",
+      r : "50%",
+      fx : "40%",
+      fy : "20%",
+      settings : {
+        gradientUnits:'objectBoundingBox'
+      }
+    }
+}
+
+_f4u$t.init_prop = function(instance, options, obj, prop) {
+  instance[prop] = _f4u$t.initifnull(options[prop], _f4u$t[obj+'_inits'][prop]);
+}
diff --git a/architecture/httpdlib/html/js/svg/faust_ui_interact.js b/architecture/httpdlib/html/js/svg/faust_ui_interact.js
new file mode 100644
index 0000000..06c9197
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_ui_interact.js
@@ -0,0 +1,995 @@
+/*
+ * look for the phrase
+ * UI2DSP to see where the UI sends messages to DSP
+ * obviously, the goal is to separate the two as much as possible
+ */
+
+
+/*
+  UTILITY FUNCTIONS
+*/
+_f4u$t.getOperativeX = function(e) {
+  return (e.clientX + $(document).scrollLeft()) / _f4u$t.VIEWPORT_SCALE;
+}
+
+_f4u$t.getOperativeY = function(e) {
+  return (e.clientY + $(document).scrollTop()) / _f4u$t.VIEWPORT_SCALE;
+}
+
+_f4u$t.move_to_ridiculous_negative = function(id) {
+  _f4u$t.generic_translate(id, -100000, -100000);
+}
+
+_f4u$t.devnull = function devnull() { }
+
+_f4u$t.generic_translate = function(id, x, y) {
+  var elt = document.getElementById(id);
+  var transform = _f4u$t.transform_to_array(elt.getAttribute("transform"));
+  // we assume that there is only one element and that it is a transform
+  // make sure to change this if things get more complicated
+  // actually, just make sure not to make things more complicated...
+
+  transform[0][1] = x;
+  transform[0][2] = y;
+  var movetothis = _f4u$t.array_to_transform(transform);
+  elt.setAttribute("transform", movetothis);
+}
+
+// parser of an object's transform
+
+_f4u$t.transform_to_array = function(transform) {
+  var out = [];
+  var flre = "[-+]?[0-9]*\\.?[0-9]*(?:[eE][-+]?[0-9]+)?";
+  var matrix = new RegExp("^\\s*matrix\\s*\\(\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*\\)");
+  var translate = new RegExp("^\\s*translate\\s*\\(\\s*("+flre+")\\s*(?:[,]\\s*("+flre+")\\s*)?\\)");
+  var scale = new RegExp("^\\s*scale\\s*\\(\\s*("+flre+")\\s*(?:[,]\\s*("+flre+")\\s*)?\\)");
+  var rotate = new RegExp("^\\s*rotate\\s*\\(\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*[,]\\s*("+flre+")\\s*\\)");
+  var skewX = new RegExp("^\\s*skewX\\s*\\(\\s*("+flre+")\\s*\\)");
+  var skewY = new RegExp("^\\s*skewY\\s*\\(\\s*("+flre+")\\s*\\)");
+  while(true) {
+    var match = matrix.exec(transform);
+    if (match != null) {
+      out.push(["matrix",parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4]), parseFloat(match[5]), parseFloat(match[6])]);
+      transform = transform.substr(match[0].length,transform.length-match[0].length);
+      continue;
+    }
+    match = translate.exec(transform);
+    if (match != null) {
+      var second = 0.0;
+      if (match[2] != undefined) { second = parseFloat(match[2]); }
+      out.push(["translate",parseFloat(match[1]),second]);
+      transform = transform.substr(match[0].length,transform.length-match[0].length);
+      continue;
+    }
+    match = scale.exec(transform);
+    if (match != null) {
+      var second = 0.0;
+      if (match[2] != undefined) { second = parseFloat(match[2]); }
+      out.push(["scale",parseFloat(match[1]), second]);
+      transform = transform.substr(match[0].length,transform.length-match[0].length);
+      continue;
+    }
+    match = rotate.exec(transform);
+    if (match != null) {
+      var second = 0.0;
+      if (match[2] != undefined) { second = parseFloat(match[2]); }
+      var third = 0.0;
+      if (match[2] != undefined) { third = parseFloat(match[2]); }
+      out.push(["rotate",parseFloat(match[1]), second, third]);
+      transform = transform.substr(match[0].length,transform.length-match[0].length);
+      continue;
+    }
+    match = skewX.exec(transform);
+    if (match != null) {
+      out.push(["skewX", parseFloat(match[1])]);
+      transform = transform.substr(match[0].length,transform.length-match[0].length);
+      continue;
+    }
+    match = skewY.exec(transform);
+    if (match != null) {
+      out.push(["skewY", parseFloat(match[1])]);
+      transform = transform.substr(match[0].length,transform.length-match[0].length);
+      continue;
+    }
+    break;
+  }
+  return out;
+}
+
+// takes an array, turns it to a transform
+
+_f4u$t.array_to_transform = function(array) {
+  var out = "";
+  while (array.length > 0)
+  {
+    out = out.concat(array[0][0]);
+    out = out.concat("(");
+    var i=1;
+    var arlen = array[0].length;
+    while(arlen > i) {
+      out = out.concat(array[0][i]+",");
+      i++;
+    }
+    out = out.substr(0,out.length-1);
+    out = out.concat(") ");
+    array.shift();
+  }
+  if (out.length > 0) { out = out.substr(0,out.length-1); }
+  return out;
+}
+
+/*
+  INITIALIZATION FUNCTIONS
+*/
+
+_f4u$t.initiate_nentry = function(fullid, minval, maxval, step, init, integer, ndec, label, unit, address) {
+  var id = _f4u$t.unique(fullid);
+  _f4u$t.IDS_TO_ATTRIBUTES[id] = {};
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["type"] = "nentry";
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"] = minval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"] = maxval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["step"] = step;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["init"] = init;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["integer"] = integer;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["ndec"] = ndec;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] = init;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["unit"] = unit;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["label"] = label;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["address"] = address;
+  _f4u$t.path_to_id(address, fullid);
+}
+
+_f4u$t.initiate_slider = function(axis, fullid, length, sliderlen, minval, maxval, step, init, integer, ndec, label, unit, orientation, orientation_mode, address) {
+  var id = _f4u$t.unique(fullid);
+  _f4u$t.IDS_TO_ATTRIBUTES[id] = {};
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["type"] = (axis == _f4u$t.X_AXIS ? "hslider" : "vslider");
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["axis"] = axis;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["length"] = length;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["sliderlen"] = sliderlen;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"] = minval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"] = maxval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["step"] = step;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["init"] = init;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["unit"] = unit;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["orientation"] = orientation;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["previousorientation"] = null;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["orientationmode"] = orientation_mode;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["integer"] = integer;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["ndec"] = ndec;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["label"] = label;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["address"] = address;
+  _f4u$t.path_to_id(address, fullid);
+}
+
+_f4u$t.initiate_hslider = function(fullid, weakaxis, strongaxis, minval, maxval, step, init, integer, ndec, label, unit, orientation, orientation_mode, address) {
+  _f4u$t.initiate_slider(_f4u$t.X_AXIS, fullid, weakaxis, strongaxis, minval, maxval, step, init, integer, ndec, label, unit, orientation, orientation_mode, address);
+}
+
+_f4u$t.initiate_vslider = function(fullid, weakaxis, strongaxis, minval, maxval, step, init, integer, ndec, label, unit, orientation, orientation_mode, address) {
+  _f4u$t.initiate_slider(_f4u$t.Y_AXIS, fullid, weakaxis, strongaxis, minval, maxval, step, init, integer, ndec, label, unit, orientation, orientation_mode, address);
+}
+
+_f4u$t.initiate_bargraph = function(axis, fullid, weakaxis, strongaxis, minval, maxval, step, init, label, unit, address) {
+  var id = _f4u$t.unique(fullid);
+  _f4u$t.IDS_TO_ATTRIBUTES[id] = {};
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["type"] = (axis == _f4u$t.X_AXIS ? "hbargraph" : "vbargraph");
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["axis"] = axis;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["weakaxis"] = weakaxis;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["strongaxis"] = strongaxis;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"] = minval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"] = maxval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["step"] = step;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["init"] = init;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["unit"] = unit;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["label"] = label;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["address"] = address;
+  _f4u$t.path_to_id(address, fullid);
+}
+
+_f4u$t.initiate_hbargraph = function(fullid, weakaxis, strongaxis, minval, maxval, step, init, label, unit, address) {
+  _f4u$t.initiate_bargraph(_f4u$t.X_AXIS, fullid, weakaxis, strongaxis, minval, maxval, step, init, label, unit, address);
+}
+
+_f4u$t.initiate_vbargraph = function(fullid, weakaxis, strongaxis, minval, maxval, step, init, label, unit, address) {
+  _f4u$t.initiate_bargraph(_f4u$t.Y_AXIS, fullid, weakaxis, strongaxis, minval, maxval, step, init, label, unit, address);
+}
+
+_f4u$t.initiate_rbutton = function(fullid,initangle,sweepangle,radius,knobpercentage,minval,maxval,step,init,integer,ndec,label,unit,orientation,orientation_mode,address) {
+  var id = _f4u$t.unique(fullid);
+  _f4u$t.IDS_TO_ATTRIBUTES[id] = {};
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["type"] = "rbutton";
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["initangle"] = initangle;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["sweepangle"] = sweepangle;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["radius"] = radius;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["knobpercentage"] = knobpercentage;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["label"] = label;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"] = minval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"] = maxval;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["step"] = step;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["init"] = init;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["unit"] = unit;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["orientation"] = orientation;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["previousorientation"] = null;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["orientationmode"] = orientation_mode;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["integer"] = integer;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["ndec"] = ndec;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["address"] = address;
+  _f4u$t.path_to_id(address, fullid);
+}
+
+_f4u$t.initiate_checkbox = function(fullid, address) {
+  var id = _f4u$t.unique(fullid);
+  _f4u$t.IDS_TO_ATTRIBUTES[id] = {};
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["type"] = "checkbox";
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["address"] = address;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["time"] = 0;new Date().getTime();
+  _f4u$t.path_to_id(address, fullid);
+}
+
+_f4u$t.initiate_button = function(fullid, upfill, downfill, address) {
+  var id = _f4u$t.unique(fullid);
+  _f4u$t.IDS_TO_ATTRIBUTES[id] = {};
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["type"] = "button";
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["upfill"] = upfill;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["downfill"] = downfill;
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["address"] = address;
+  _f4u$t.path_to_id(address, fullid);
+}
+
+_f4u$t.initiate_tab_group = function(index, ids) {
+  var strar = ids.toString().split('#');
+  // boo svg...tags
+  for (var i = 0; strar.length > i; i++) {
+    if (i != index) {
+      _f4u$t.move_to_ridiculous_negative(strar[i]);
+    }
+  }
+}
+
+/*
+  ACTIVATION FUNCTIONS
+  Activates UI objects as being in focus
+*/
+
+_f4u$t.nentry_down_minus = function(ee) {
+  _f4u$t.activate_nentry(ee, -1);
+}
+
+_f4u$t.nentry_down_plus = function(ee) {
+  _f4u$t.activate_nentry(ee, 1);
+}
+
+_f4u$t.nentry_up_minus = function(ee) {
+  _f4u$t.disactivate_nentry(ee, -1);
+}
+
+_f4u$t.nentry_up_plus = function(ee) {
+  _f4u$t.disactivate_nentry(ee, 1);
+}
+
+_f4u$t.disactivate_nentry = function(ee, dir) {
+  // it is possible that an object is touched by multiple fingers at the
+  // same time
+  // if the id is already being used, we ignore
+  // otherwise, use the first in the array...
+  var identifier = ee.originalEvent.changedTouches ? ee.originalEvent.changedTouches[0].identifier : 0;
+  var longid = ee.target.id;
+  var id = _f4u$t.unique(longid);
+  _f4u$t.nentry_fill_changer(id, false, dir);
+}
+
+_f4u$t.activate_nentry = function(ee, dir) {
+  // it is possible that an object is touched by multiple fingers at the
+  // same time
+  // if the id is already being used, we ignore
+  // otherwise, use the first in the array...
+  var identifier = ee.originalEvent.changedTouches ? ee.originalEvent.changedTouches[0].identifier : 0;
+  var longid = ee.target.id;
+  var id = _f4u$t.unique(longid);
+  _f4u$t.nentry_fill_changer(id, true, dir);
+  _f4u$t._I[identifier] = {id : longid, moved : false, value : null, address : _f4u$t.IDS_TO_ATTRIBUTES[id]["address"]};
+  _f4u$t.active_addresses.push(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"]);
+
+  var now = parseFloat(_f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"]);
+  if (dir == 1) {
+    now += _f4u$t.IDS_TO_ATTRIBUTES[id]["step"];
+  }
+  else {
+    now -= _f4u$t.IDS_TO_ATTRIBUTES[id]["step"];
+  }
+
+  now = _f4u$t.quantize(now, _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"], _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"], _f4u$t.IDS_TO_ATTRIBUTES[id]["step"]);
+  now = _f4u$t.dumb_label_update(_f4u$t.unique(_f4u$t._I[identifier].id), now);
+  _f4u$t.fausthandler(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"], now);
+  return now;
+}
+
+_f4u$t.activate_hslider = function(ee) {
+  _f4u$t.activate_slider(ee);
+}
+
+_f4u$t.activate_vslider = function(ee) {
+  _f4u$t.activate_slider(ee);
+}
+
+_f4u$t.activate_slider = function(ee) {
+  _f4u$t.activate_moving_object(ee);
+}
+
+_f4u$t.activate_rbutton = function(ee) {
+  _f4u$t.activate_moving_object(ee);
+}
+
+_f4u$t.activate_moving_object = function(ee) {
+  var touches = ee.changedTouches || [ee];
+  if (ee.originalEvent) {
+    touches = ee.originalEvent.changedTouches || [ee];
+  }
+  var identifier = touches[0].identifier || 0;
+  var longid = touches[0].target.id;
+  var id = _f4u$t.unique(longid);
+  _f4u$t._I[identifier] = {id : longid, moved : false, value : null, address : _f4u$t.IDS_TO_ATTRIBUTES[id]["address"]};
+  _f4u$t.active_addresses.push(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"]);
+  // turns off zoom for mobile devices
+  $('body').bind('touchmove', function(event) { event.preventDefault() });
+  // if we touch a groove, we want the object to snap to the correct position, so
+  // we need to call the move function.
+  _f4u$t.move_active_object(ee);
+}
+
+_f4u$t.activate_tgroup = function(x, y, goodid, badids) {
+  var strar = badids.toString().split('#');
+  for (var i = 0; strar.length > i; i++) {
+    _f4u$t.move_to_ridiculous_negative(strar[i]);
+    _f4u$t.tgroup_fill_changer(_f4u$t.unique(strar[i]), false);
+  }
+  _f4u$t.generic_translate(goodid, x, y);
+  _f4u$t.tgroup_fill_changer(_f4u$t.unique(goodid), true);
+}
+
+/*
+  MOVING FUNCTIONS.
+  Functions that take care of moving the active object on the screen.
+*/
+
+_f4u$t.tooltip_mouseover = function(e) {
+  var id = _f4u$t.unique(e.target.id);
+  var full_id = 'faust_tooltip_'+id;
+  document.getElementById(full_id).setAttribute("style","opacity:1.0");
+  setTimeout(function () {
+    _f4u$t.generic_translate(full_id, 0, 0);
+    var os = $(document.getElementById(full_id)).offset();
+    var my_x = os['left'] / _f4u$t.VIEWPORT_SCALE;
+    var my_y = os['top'] / _f4u$t.VIEWPORT_SCALE;
+    _f4u$t.generic_translate(full_id, _f4u$t.getOperativeX(e) - my_x, _f4u$t.getOperativeY(e) - my_y);
+  }, 500);
+}
+
+_f4u$t.tooltip_mouseout = function(e) {
+  var id = _f4u$t.unique(e.target.id);
+  var full_id = 'faust_tooltip_'+id
+  _f4u$t.move_to_ridiculous_negative(full_id);
+  document.getElementById(full_id).setAttribute("style","opacity:0.0");
+}
+
+// main function to move currently-selected slider
+_f4u$t.move_active_object = function(ee) {
+  for (var elt in _f4u$t._I) {
+    if (_f4u$t._I[elt] && (elt.indexOf('orientation') == -1)) {
+      var touches = ee.touches || [ee];
+      if (ee.originalEvent) {
+        touches = ee.originalEvent.touches || [ee];
+      }
+      for (var i = 0; i < touches.length; i++) {
+        _f4u$t.internal_move_active_object(touches[i], touches[0] == ee ? 0 : touches[i].identifier);
+      }
+      // breaks loop, as we just need one active element for this to work
+      return true;
+    }
+  }
+  return true;
+}
+
+// TODO
+// Does this really need to be a separate function.
+// Helps for readability, but not necessary
+_f4u$t.internal_move_active_object = function(e, identifier) {
+  _f4u$t.clog_key_sink();
+  var fn = _f4u$t['move_active_'+_f4u$t.type(_f4u$t._I[identifier]['id'])];
+  var now = null;
+  if (fn) {
+   now =  fn(e, identifier);
+  }
+
+  // UI2DSP
+  if (now != null && now != _f4u$t._I[identifier]['value']) {
+    var id = _f4u$t.unique(_f4u$t._I[identifier]['id']);
+    _f4u$t.fausthandler(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"], now);
+    _f4u$t._I[identifier]['value'] = now;
+  }
+
+  return now;
+}
+
+_f4u$t.redraw_slider_groove = function(id, axis, length, perc) {
+  perc = _f4u$t.bound(perc, 0, 1); // to avoid mouse spillover on either side of slider
+  var groove = document.getElementById('faust_'+(_f4u$t.xy(axis,'hslider','vslider'))+'_groove_'+id);
+  if (axis == _f4u$t.X_AXIS) {
+    groove.setAttribute('x', length * perc)
+    groove.setAttribute('width', length * (1 - perc));
+  }
+  if (axis == _f4u$t.Y_AXIS) {
+    groove.setAttribute('height', length * perc);
+  }
+}
+
+_f4u$t.move_active_slider = function(e,identifier)
+{
+  var id = _f4u$t.unique(_f4u$t._I[identifier].id);
+  var axis = _f4u$t.IDS_TO_ATTRIBUTES[id]["axis"];
+  var sliding_part = document.getElementById(_f4u$t.xy(axis, 'faust_hslider_handle_', 'faust_vslider_handle_')+id);
+  var anchor = document.getElementById(_f4u$t.xy(axis, 'faust_hslider_meter_', 'faust_vslider_meter_')+id);
+  var sliderlen = _f4u$t.IDS_TO_ATTRIBUTES[id]["sliderlen"];
+  var length = _f4u$t.IDS_TO_ATTRIBUTES[id]["length"];
+  var pos = -1;
+  var os = $(anchor).offset();
+  var my_x = os['left'] / _f4u$t.VIEWPORT_SCALE;
+  var my_y = os['top'] / _f4u$t.VIEWPORT_SCALE;
+  // we only care about the axis of the slider
+  if (axis == _f4u$t.X_AXIS) {
+    pos = _f4u$t.getOperativeX(e) - my_x;
+  }
+  else {
+    pos = _f4u$t.getOperativeY(e) - my_y;
+  }
+
+  pos -= (sliderlen / 2.0);
+  var transform = _f4u$t.transform_to_array(sliding_part.getAttribute("transform"));
+  // we assume that there is only one element and that it is a transform
+  // make sure to change this if things get more complicated
+  // actually, just make sure not to make things more complicated...
+
+  var aval = pos;//transform[0][axis + 1] + diff;
+  // minimum of the slider is to the bottom / left
+  transform[0][axis + 1] = _f4u$t.bound_and_avoid_large_leaps(aval, transform[0][axis + 1], 0, length - sliderlen);
+  _f4u$t.redraw_slider_groove(
+    id,
+    axis,
+    length,
+    aval / length
+  );
+  var now = _f4u$t[_f4u$t.xy(axis, "generic_label_update", "generic_flipped_label_update")](id, aval, 0, length - sliderlen);
+  var movetothis = _f4u$t.array_to_transform(transform);
+  sliding_part.setAttribute("transform", movetothis);
+  return now;
+}
+
+_f4u$t.move_active_vslider = _f4u$t.move_active_slider;
+_f4u$t.move_active_hslider = _f4u$t.move_active_slider;
+
+_f4u$t.touched = function(id) {
+  for (var identifier in _f4u$t._I) {
+    if ((identifier != ('orientation'+id))
+        && (_f4u$t._I[identifier].id.indexOf(id) != -1)) {
+      return true;
+    }
+  } 
+  return false;
+}
+
+_f4u$t.respondToOrientationChange = function(e) {
+  for (var id in _f4u$t.IDS_TO_ATTRIBUTES) {
+    if (_f4u$t.IDS_TO_ATTRIBUTES[id].orientation &&
+        _f4u$t.IDS_TO_ATTRIBUTES[id].orientation.angle)
+      {
+        if (!_f4u$t._I['orientation'+id]) {
+          _f4u$t._I['orientation'+id] = {id : id, moved : false, value : null, address : _f4u$t.IDS_TO_ATTRIBUTES[id]["address"]};
+        }
+        var now = null;
+        if (((_f4u$t.IDS_TO_ATTRIBUTES[id]["type"] == 'hslider')
+             || (_f4u$t.IDS_TO_ATTRIBUTES[id]["type"] == 'vslider'))
+            && !_f4u$t.touched(id)) {
+           // ugh...this means that they will not be disactivated...
+           _f4u$t.active_addresses.push(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"]);
+          now = _f4u$t.moveSliderViaAccelerometer(e, id);
+        }
+        // UI2DSP
+        if (now != null && now != _f4u$t._I['orientation'+id]['value']) {
+          _f4u$t.fausthandler(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"], now);
+          _f4u$t._I['orientation'+id]['value'] = now;
+        }
+      }
+  }
+}
+
+// TODO...combine this with above...
+// simplified version, so shouldn't be too hard
+_f4u$t.moveSliderViaAccelerometer = function(e, longid) {
+  var id = _f4u$t.unique(longid);
+  var axis = _f4u$t.IDS_TO_ATTRIBUTES[id]["axis"];
+  var sliding_part = document.getElementById(_f4u$t.xy(axis, 'faust_hslider_handle_', 'faust_vslider_handle_')+id);
+  var sliderlen = _f4u$t.IDS_TO_ATTRIBUTES[id]["sliderlen"];
+  var length = _f4u$t.IDS_TO_ATTRIBUTES[id]["length"];
+  var orientation = e[_f4u$t.IDS_TO_ATTRIBUTES[id].orientation.angle]
+                    ? e[_f4u$t.IDS_TO_ATTRIBUTES[id].orientation.angle]
+                    : 0;
+  var prev_orientation = _f4u$t.IDS_TO_ATTRIBUTES[id].previousorientation != null
+                         ? _f4u$t.IDS_TO_ATTRIBUTES[id].previousorientation
+                         : e[_f4u$t.IDS_TO_ATTRIBUTES[id].orientation.angle];
+  var transform = _f4u$t.transform_to_array(sliding_part.getAttribute("transform"));
+  _f4u$t.IDS_TO_ATTRIBUTES[id].previousorientation = e[_f4u$t.IDS_TO_ATTRIBUTES[id].orientation.angle];
+  var aval = 0;
+  if (_f4u$t.IDS_TO_ATTRIBUTES[id].orientationmode == 'relative') {
+    var nudge = (orientation - prev_orientation) * (length - sliderlen) / (_f4u$t.IDS_TO_ATTRIBUTES[id].orientation.high - _f4u$t.IDS_TO_ATTRIBUTES[id].orientation.low);
+    aval = transform[0][axis + 1] + nudge;
+    
+  } else {
+    aval = _f4u$t.remap(orientation,
+                        _f4u$t.IDS_TO_ATTRIBUTES[id].orientation.low,
+                        _f4u$t.IDS_TO_ATTRIBUTES[id].orientation.high,
+                        0,
+                        length - sliderlen);
+  }
+  // minimum of the slider is to the bottom / left
+  transform[0][axis + 1] = _f4u$t.bound_and_avoid_large_leaps(aval, transform[0][axis + 1], 0, length - sliderlen);
+  _f4u$t.redraw_slider_groove(
+    id,
+    axis,
+    length,
+    aval / length
+  );
+  var now = _f4u$t[_f4u$t.xy(axis, "generic_label_update", "generic_flipped_label_update")](id, aval, 0, length - sliderlen);
+  var movetothis = _f4u$t.array_to_transform(transform);
+  sliding_part.setAttribute("transform", movetothis);
+  return now;
+}
+
+_f4u$t.redrawRotatingButtonMeter = function(id, initangle, sweepangle, radius, knobpercentage, startp) {
+  var meter = document.getElementById('faust_rbutton_meter_'+id);
+  var xo = radius;
+  var yo = radius;
+
+  var d = "M{0} {1}A{2} {3} 0 {4} {5} {6} {7}L{8} {9}A{10} {11} 0 {12} {13} {14} {15}L{16} {17}";
+  d = d.format([
+    radius * Math.cos(_f4u$t.d2r(startp)) + xo, // outside X
+    radius * Math.sin(_f4u$t.d2r(startp)) + yo, // outside Y
+    radius, // radius X
+    radius, // radius Y
+    initangle + sweepangle - startp <= 180 ? 0 : 1, // large arc flag
+    1, // draw positive
+    radius * Math.cos(_f4u$t.d2r(initangle + sweepangle)) + xo, // endpoint X
+    radius * Math.sin(_f4u$t.d2r(initangle + sweepangle)) + yo, // endpoint Y
+    radius * knobpercentage * Math.cos(_f4u$t.d2r(initangle + sweepangle)) + xo, // inside endpoint X
+    radius * knobpercentage * Math.sin(_f4u$t.d2r(initangle + sweepangle)) + yo, // inside endpoint Y
+    radius * knobpercentage, // inside radiux X
+    radius * knobpercentage, // inside radiux Y
+    initangle + sweepangle - startp <= 180 ? 0 : 1, // large arc flag
+    0, // draw negative
+    radius * knobpercentage * Math.cos(_f4u$t.d2r(startp)) + xo, // inside X
+    radius * knobpercentage * Math.sin(_f4u$t.d2r(startp)) + yo, // inside Y
+    radius * Math.cos(_f4u$t.d2r(startp)) + xo, // outside X
+    radius * Math.sin(_f4u$t.d2r(startp)) + yo// outside Y
+  ]);
+
+  meter.setAttribute("d", d);
+}
+
+_f4u$t.move_active_rbutton = function(e, identifier)
+{
+  var id = _f4u$t.unique(_f4u$t._I[identifier].id);
+  var sliding_part = document.getElementById('faust_rbutton_handle_'+id);
+  var anchor = document.getElementById('faust_rbutton_anchor_'+id);
+  var initangle = _f4u$t.IDS_TO_ATTRIBUTES[id]["initangle"];
+  var sweepangle = _f4u$t.IDS_TO_ATTRIBUTES[id]["sweepangle"];
+  var os = $(anchor).offset();
+  var my_x = os['left'] / _f4u$t.VIEWPORT_SCALE;
+  var my_y = os['top'] / _f4u$t.VIEWPORT_SCALE;
+  var transform = _f4u$t.transform_to_array(sliding_part.getAttribute("transform"));
+
+  var diff = 180. * Math.atan2(_f4u$t.getOperativeY(e) - my_y, _f4u$t.getOperativeX(e) - my_x) / Math.PI;
+  while (diff < 0) {
+    diff += 360;
+  }
+  diff = diff % 360;
+  // put it between the values if necessary
+  if (((360 + diff) >= initangle) && ((360 + diff) <= (initangle + sweepangle))) {
+    diff += 360;
+  }
+
+  if (e.target.id.indexOf('dot') != -1) {
+    // if it is a panoramic dot, snap to the multiple of 45
+    diff = parseInt((diff / 45) + 0.5) * 45;
+  }
+  // we assume that there is only one element and that it is a transform
+  // make sure to change this if things get more complicated
+  // actually, just make sure not to make things more complicated...
+
+  var aval = diff;
+  var rotation = transform[2][1];
+  if ((aval >= initangle) && (aval <= (initangle + sweepangle))) {
+    // only change rotation if we're in bounds and the difference is small (choose 10 as epsilon)
+    rotation = _f4u$t.bound_and_avoid_large_leaps(aval, transform[2][1], initangle, initangle + sweepangle, 10);
+  }
+  transform[2][1] = rotation;
+  if (sweepangle != 360) {
+    _f4u$t.redrawRotatingButtonMeter(
+      id,
+      initangle,
+      sweepangle,
+      _f4u$t.IDS_TO_ATTRIBUTES[id]["radius"],
+      _f4u$t.IDS_TO_ATTRIBUTES[id]["knobpercentage"],
+      transform[2][1]
+    );
+  }
+  var now = _f4u$t.generic_label_update(id, rotation, initangle, initangle + sweepangle);
+  var movetothis = _f4u$t.array_to_transform(transform);
+  sliding_part.setAttribute("transform", movetothis);
+  return now;
+}
+
+// gets rid of the current thing being dragged
+_f4u$t.clearIdCache = function(ee) {
+  if (ee) {
+    // sometimes, there will be no event passed in (i.e. a button)
+    // if so, we can skip everything below
+    var touches = ee.changedTouches || [ee];
+    if (ee.originalEvent) {
+      touches = ee.originalEvent.changedTouches || ee;
+    }
+    for (var i = 0; i < touches.length; i++) {
+      if (_f4u$t._I[touches[i].identifier || 0]) {
+        var addr = _f4u$t._I[touches[i].identifier || 0].address;
+        while (_f4u$t.active_addresses.indexOf(addr) !== -1) {
+          _f4u$t.active_addresses.splice(_f4u$t.active_addresses.indexOf(addr), 1);
+        }
+        delete _f4u$t._I[touches[i].identifier || 0];
+      }
+    }
+    // exit function before unbinding if there are still active elements
+    for (var elt in _f4u$t._I) {
+      if (_f4u$t._I[elt]) {
+        return true;
+      }
+    }
+  }
+  // clear gunk out of cache
+  _f4u$t._I = {};
+  _f4u$t.active_addresses = [];
+  $('body').unbind('touchmove'); // turns on zooming for mobile devices
+}
+
+_f4u$t.onoff_property_changer = function(id, down, property, value_down, value_up) {
+  if (down) {
+    $('#'+id).css(property, value_down);
+  }
+  else {
+    $('#'+id).css(property, value_up);
+  }
+}
+
+_f4u$t.onoff_fill_changer = function(id, down, value_down, value_up) {
+  _f4u$t.onoff_property_changer(id, down, 'fill', value_down, value_up);
+}
+
+_f4u$t.button_fill_changer = function(id, down) {
+  _f4u$t.onoff_fill_changer('faust_button_box_'+_f4u$t.unique(id), down, 'url(#buttonDownGradient)', 'url(#buttonUpGradient)');
+}
+
+_f4u$t.tgroup_fill_changer = function(id, down) {
+  _f4u$t.onoff_fill_changer('faust_tab_'+_f4u$t.unique(id), down, 'url(#tabGroupDownGradient)', 'url(#tabGroupUpGradient)');
+}
+
+_f4u$t.nentry_fill_changer = function(id, down, dir) {
+  var dirtext = dir == -1 ? 'minus' : 'plus';
+  _f4u$t.onoff_fill_changer('faust_nentry_button_'+dirtext+'_'+_f4u$t.unique(id), down, 'url(#numericalEntryDownGradient)', 'url(#numericalEntryUpGradient)');
+}
+
+/*
+  Note that hovering does not make sense for mobile devices.
+  Unfortunately, some mobile device translate hover instructions
+  as a sort of onclick command.
+  So we remove this for mobile devices after the callback fires.
+*/
+
+_f4u$t.button_hover = function(id) {
+  if(! /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
+    $('#faust_button_box_'+_f4u$t.unique(id)).css('stroke', 'orange');
+    $('#faust_label_'+_f4u$t.unique(id)).css('fill', 'orange');
+  }
+}
+
+_f4u$t.button_unhover = function(id) {
+  if(! /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
+    $('#faust_button_box_'+_f4u$t.unique(id)).css('stroke', 'black');
+    $('#faust_label_'+_f4u$t.unique(id)).css('fill', 'black');
+  }
+}
+
+_f4u$t.button_up = function(I) {
+  var id = _f4u$t.unique(I);
+  _f4u$t.button_fill_changer(id, false);
+  _f4u$t.fausthandler(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"], 0);
+  _f4u$t.clearIdCache();
+}
+
+_f4u$t.button_down = function(I) {
+  var id = _f4u$t.unique(I);
+  _f4u$t.clog_key_sink();
+  _f4u$t.button_fill_changer(id, true);
+  _f4u$t.fausthandler(_f4u$t.IDS_TO_ATTRIBUTES[id]["address"], 1);
+}
+
+_f4u$t.click_checkbox = function(I) {
+  _f4u$t.change_checkbox(I, false);
+}
+_f4u$t.touch_checkbox = function(I) {
+  _f4u$t.change_checkbox(I, true);
+}
+
+_f4u$t.change_checkbox = function(I, touch) {
+  var id = _f4u$t.unique(I)
+  var now = new Date().getTime();
+  if (touch && ((now - _f4u$t.IDS_TO_ATTRIBUTES[id]["time"]) < 1000)) {
+    return;
+  }
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["time"] = now;
+  _f4u$t.clog_key_sink();
+  var address = _f4u$t.IDS_TO_ATTRIBUTES[id]["address"];
+  var box = document.getElementById('faust_checkbox_check_'+id);
+  var opacity = 0;
+  if (box.style.opacity == 1.0) {
+    opacity = 0;
+  }
+  else if (box.style.opacity == 0.0) {
+    opacity = 1;
+  }
+  else {
+    alert("malfunctional checkbox");
+  }
+  box.style.opacity = opacity;
+  // UI2DSP
+  _f4u$t.fausthandler(address, opacity);
+}
+
+/*
+  TEXT UPDATES
+  Functions that take care of updating text based either on
+  keyboard input or objects' moving.
+*/
+
+_f4u$t.generic_label_update = function(id, c, l, h) {
+  var now = _f4u$t.remap_and_quantize(c, l, h, _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"], _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"], _f4u$t.IDS_TO_ATTRIBUTES[id]["step"]);
+  return _f4u$t.dumb_label_update(id, now);
+}
+
+_f4u$t.generic_flipped_label_update = function(id, c, l, h) {
+  var now = _f4u$t.remap_and_quantize_and_flip(c, l, h, _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"], _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"], _f4u$t.IDS_TO_ATTRIBUTES[id]["step"]);
+  return _f4u$t.dumb_label_update(id, now);
+}
+
+_f4u$t.change_label_text = function(label, id)
+{
+  label.textContent = _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] + _f4u$t.IDS_TO_ATTRIBUTES[id]["unit"];
+}
+
+_f4u$t.dumb_label_update = function(id, c) {
+  var label = document.getElementById("faust_value_value_"+id);
+  var integer = _f4u$t.IDS_TO_ATTRIBUTES[id]["integer"];
+  if (integer) {
+    c = (c + 0.49999).toString().parseInt();
+  }
+  else {
+    c = c.toFixed(_f4u$t.IDS_TO_ATTRIBUTES[id]["ndec"]);
+  }
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] = c;
+  _f4u$t.change_label_text(label, id);;
+  return c;
+}
+
+_f4u$t.clog_key_sink = function() {
+  if (_f4u$t._N != 0) {
+    var box = document.getElementById("faust_value_box_"+_f4u$t.unique(_f4u$t._N));
+    box.style.stroke = "black";
+    _f4u$t.ajax_queue_busy = false;
+  }
+  _f4u$t._N = 0;
+}
+
+_f4u$t.actualize_buffer = function() {
+  // get a valid number in there...
+  var id = _f4u$t.unique(_f4u$t._N);
+
+  var minval = _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"];
+  var maxval = _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"];
+  var address = _f4u$t.IDS_TO_ATTRIBUTES[id]["address"];
+
+  if (isNaN(_f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"])) {
+    _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] = ""+_f4u$t.IDS_TO_ATTRIBUTES[id]["init"];
+  }
+  var c = parseFloat(_f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"]);
+  var label = document.getElementById(_f4u$t._N);
+  var now = _f4u$t.bound(c, minval, maxval);
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] = ""+now;
+  _f4u$t.change_label_text(label, id);
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["init"] = _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"]; // prevents bad snaps of values
+
+  // UI2DSP
+  _f4u$t.fausthandler(address, now);
+
+  _f4u$t.actualize_incremental_object(id);
+}
+
+_f4u$t.buffer_backspace = function() {
+  var id = _f4u$t.unique(_f4u$t._N);
+  if (_f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"].length == 0) {
+    return 0;
+  }
+  _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] = _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"].substring(0, _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"].length - 1);
+  var label = document.getElementById(_f4u$t._N);
+  _f4u$t.change_label_text(label, id);;
+}
+
+_f4u$t.make_delete_key_work = function(e) {
+  if (e.keyCode == 8) {
+    _f4u$t.buffer_backspace();
+  }
+}
+
+_f4u$t.keys_to_sink = function(e) {
+  if (_f4u$t._N == "") {
+    return 0;
+  }
+  var id = _f4u$t.unique(_f4u$t._N);
+  if (e.keyCode == 13) {
+    _f4u$t.actualize_buffer();
+    _f4u$t.clog_key_sink();
+    return;
+  }
+  else {
+    var key = e.keyCode;
+    var str = String.fromCharCode(key)
+    _f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"] += str;
+  }
+  var label = document.getElementById(_f4u$t._N);
+  _f4u$t.change_label_text(label, id);;
+}
+
+_f4u$t.make_key_sink = function(I) {
+  if (_f4u$t.ajax_queue_busy) {
+    return false;
+  }
+  _f4u$t._N = 'faust_value_value_'+I;
+  _f4u$t.IDS_TO_ATTRIBUTES[I]["buffer"] = "";
+  var box = document.getElementById("faust_value_box_"+I);
+  box.style.stroke = "red";
+  _f4u$t.ajax_queue_busy = true;
+  // below is a hack for text inputs that should only be activated
+  // after some work is done to figure out how to prevent auto zooming
+  // in mobile devices
+  //document.getElementById('faust-text-input-dummy').focus();
+}
+
+_f4u$t.generic_key_sink = function(I) {
+  var id = _f4u$t.unique(I);
+  _f4u$t.make_key_sink(id);
+  _f4u$t._I = {};
+  _f4u$t.active_addresses = [];
+}
+
+_f4u$t.hslider_key_sink = function(I) {
+  _f4u$t.generic_key_sink(I);
+}
+
+_f4u$t.vslider_key_sink = function(I) {
+  _f4u$t.generic_key_sink(I);
+}
+
+_f4u$t.rotating_button_key_sink = function(I) {
+  _f4u$t.generic_key_sink(I);
+}
+
+_f4u$t.nentry_key_sink = function(I) {
+  _f4u$t.generic_key_sink(I);
+}
+
+// if a numerical entry is linked to an incremental object,
+// actualize it
+
+_f4u$t.actualize_incremental_object = function(id) {
+  var hslider_id = "faust_hslider_handle_"+id;
+  var vslider_id = "faust_vslider_handle_"+id;
+  var rotating_button_id = "faust_rbutton_handle_"+id;
+  var hbargraph_id = "faust_hbargraph_curtain_"+id;
+  var vbargraph_id = "faust_vbargraph_curtain_"+id;
+  var val = parseFloat(_f4u$t.IDS_TO_ATTRIBUTES[id]["buffer"]);
+  var maybe_slider = document.getElementById(hslider_id);
+  if (maybe_slider == null) {
+    maybe_slider = document.getElementById(vslider_id);
+  }
+  var maybe_button = document.getElementById(rotating_button_id);
+  var maybe_bargraph = document.getElementById(hbargraph_id);
+  if (maybe_bargraph == null) {
+    maybe_bargraph = document.getElementById(vbargraph_id);
+  }
+  if (maybe_slider != null) {
+    // ugh...code dups
+    var minval = _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"];
+    var maxval = _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"];
+    var length = _f4u$t.IDS_TO_ATTRIBUTES[id]["length"];
+    var sliderlen = _f4u$t.IDS_TO_ATTRIBUTES[id]["sliderlen"];
+    var axis = _f4u$t.IDS_TO_ATTRIBUTES[id]["axis"];
+    val = _f4u$t[_f4u$t.xy(axis, "remap", "remap_and_flip")](val, minval, maxval, 0, length - sliderlen);
+    var transform = _f4u$t.transform_to_array(maybe_slider.getAttribute("transform"));
+    transform[0][axis + 1] = val;
+    _f4u$t.redraw_slider_groove(
+      id,
+      axis,
+      length,
+      val / length
+    );
+    var movetothis = _f4u$t.array_to_transform(transform);
+    maybe_slider.setAttribute("transform", movetothis);
+    return 0;
+  }
+  else if (maybe_button != null) {
+    var minval = _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"];
+    var maxval = _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"];
+    var initangle = _f4u$t.IDS_TO_ATTRIBUTES[id]["initangle"];
+    var sweepangle = _f4u$t.IDS_TO_ATTRIBUTES[id]["sweepangle"];
+    val = _f4u$t.remap(val, minval, maxval, initangle, initangle + sweepangle);
+    var transform = _f4u$t.transform_to_array(maybe_button.getAttribute("transform"));
+    transform[2][1] = val;
+    if (sweepangle != 360) {
+      _f4u$t.redrawRotatingButtonMeter(
+        id,
+        _f4u$t.IDS_TO_ATTRIBUTES[id]["initangle"],
+        _f4u$t.IDS_TO_ATTRIBUTES[id]["sweepangle"],
+        _f4u$t.IDS_TO_ATTRIBUTES[id]["radius"],
+        _f4u$t.IDS_TO_ATTRIBUTES[id]["knobpercentage"],
+        transform[2][1]
+      );
+    }
+    var movetothis = _f4u$t.array_to_transform(transform);
+    maybe_button.setAttribute("transform", movetothis);
+    return 0;
+  }
+  else if (maybe_bargraph != null) {
+    // ugh...code dups
+    var minval = _f4u$t.IDS_TO_ATTRIBUTES[id]["minval"];
+    var maxval = _f4u$t.IDS_TO_ATTRIBUTES[id]["maxval"];
+    var axis = _f4u$t.IDS_TO_ATTRIBUTES[id]["axis"];
+    var weakaxis = _f4u$t.IDS_TO_ATTRIBUTES[id]["weakaxis"];
+    var strongaxis = _f4u$t.IDS_TO_ATTRIBUTES[id]["strongaxis"];
+    val = _f4u$t[_f4u$t.xy(axis, "remap_and_flip", "remap_and_flip")](val, minval, maxval, 0, strongaxis);
+    val = _f4u$t.bound(val, 0, strongaxis);
+    /*
+    // for paths...
+    var newd = _f4u$t.xy(
+      axis,
+      'M 0 0L'+val+' 0L'+val+' '+weakaxis+'L0 '+weakaxis+'L0 0',
+      'M 0 '+strongaxis+'L'+weakaxis+' '+strongaxis+'L'+weakaxis+' '+val+'L0 '+val+'L0 '+strongaxis
+    );
+    maybe_bargraph.setAttribute("d", newd);
+    */
+    maybe_bargraph.setAttribute("width", Math.max(0,_f4u$t.xy(axis, val, weakaxis)));
+    maybe_bargraph.setAttribute("height", Math.max(0, _f4u$t.xy(axis, weakaxis, val)));
+    return 0;
+  }
+  // no corresponding incremental object
+  return 0;
+}
+
+
+/*
+ DOCUMENT-WIDE DECLARATIONS
+*/
+_f4u$t.alert = function () { alert("moved"); }
+document.onkeypress = _f4u$t.keys_to_sink;
+document.onkeydown = _f4u$t.make_delete_key_work;
+document.onmouseup = _f4u$t.clearIdCache;
+document.onmousemove = _f4u$t.move_active_object;
+document.ontouchend = _f4u$t.clearIdCache;
+document.ontouchmove = _f4u$t.move_active_object;
+window.ondeviceorientation = _f4u$t.respondToOrientationChange;
+// make the entire document clickable for mobile devices
+document.onclick = _f4u$t.devnull;
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/faust_ui_objects.js b/architecture/httpdlib/html/js/svg/faust_ui_objects.js
new file mode 100644
index 0000000..9cd8d39
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/faust_ui_objects.js
@@ -0,0 +1,1646 @@
+// all onload need to be pushed to the end of the creation
+
+/*
+  DEFINES THE FAUST OBJECT CLASS.
+  All graphical objects inherit from this.
+*/
+
+_f4u$t.UIObject = function() {
+  this.x = 0.0;
+  this.y = 0.0;
+}
+
+_f4u$t.UIObject.prototype.make_group = function(svg, parent, id, opts) {
+  opts = opts ? opts : {};
+  opts.transform = 'translate('+this.x+','+this.y+')';
+  var out = _f4u$t.make_g(
+    svg,
+    parent,
+    id,
+    opts);
+
+  return out;
+}
+
+_f4u$t.UIObject.prototype.get_x_offset = function() {
+  if (!this.mom) {
+    return this.x;
+  }
+  return this.x + this.mom.get_x_offset();
+}
+
+_f4u$t.UIObject.prototype.get_y_offset = function() {
+  if (!this.mom) {
+    return this.y;
+  }
+  return this.y + this.mom.get_y_offset();
+}
+
+_f4u$t.UIObject.prototype.setX = function(x) {
+  this.x = x
+}
+
+_f4u$t.UIObject.prototype.setY = function(y) {
+  this.y = y
+}
+
+_f4u$t.UIObject.prototype.do_spacing = function(leaf) { }
+
+_f4u$t.UIObject.prototype.stretch = function(x,y) {
+  /*
+    the whole family
+    all with white hair and canes
+    visiting graves
+  */
+}
+
+_f4u$t.UIObject.prototype.get_root_svg = function() {
+  if (!this.mom) {
+    return null;
+  }
+  return (this.mom.svg ? this.mom.svg : this.mom.get_root_svg());
+}
+
+_f4u$t.UIObject.prototype.get_root_tooltip_group = function() {
+  if (!this.mom) {
+    return null;
+  }
+  return (this.mom.tooltip_group ? this.mom.tooltip_group : this.mom.get_root_tooltip_group());
+}
+
+_f4u$t.UIObject.prototype.get_layout_manager = function() {
+  if (!this.mom) {
+    return null;
+  }
+  return (this.mom instanceof _f4u$t.LayoutManager ? this.mom : this.mom.get_layout_manager());
+}
+
+_f4u$t.UIObject.prototype.make_delayed_tooltips = function(svg) {
+  for (var i = 0; i < svg._delayed_tooltip_list.length; i++) {
+    svg._delayed_tooltip_list[i][0].make_tooltip(
+      svg,
+      svg._delayed_tooltip_list[i][1],
+      svg._delayed_tooltip_list[i][2]
+    );
+  }
+}
+
+_f4u$t.UIObject.prototype.tooltip_text = function() {
+  return this.tooltip;
+}
+
+_f4u$t.UIObject.prototype.tooltip_text_dims = function() {
+  return _f4u$t.get_text_bbox(this.get_root_svg(), this.tooltip_text());
+}
+
+_f4u$t.UIObject.prototype.make_tooltip_text = function(svg, parent, id) {
+  var text = this.tooltip_text();
+  var full_id = 'faust_tooltip_text_'+id;
+  var tttext = _f4u$t.make_text(
+    svg,
+    parent,
+    0,
+    0,
+    text,
+    {
+      id: full_id,
+      'class': 'faust-tooltip-text'
+    }
+  );
+
+  return tttext;
+}
+
+_f4u$t.UIObject.prototype.make_tooltip_box = function(svg, parent, id) {
+  var full_id = 'faust_tooltip_box_'+id;
+  var textdims = this.tooltip_text_dims();
+  var ttbox = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    2,
+    -textdims.width*0.05,
+    -(textdims.height*1.1),
+    textdims.width*1.1,
+    textdims.height*1.3,
+    {
+      id: full_id,
+      fill : _f4u$t.color_to_rgb(_f4u$t.WHITE),
+      stroke : _f4u$t.color_to_rgb(_f4u$t.BLACK),
+      'class': 'faust-tooltip-box'
+    });
+
+  return ttbox;
+}
+
+_f4u$t.UIObject.prototype.make_delayed_tooltip = function(obj, svg, linked_obj_id, id) {
+  svg._delayed_tooltip_list.push([obj, linked_obj_id, id]);
+}
+
+_f4u$t.UIObject.prototype.make_tooltip = function(svg, linked_obj_id, id) {
+  if (this.tooltip != "") {
+    var full_id = 'faust_tooltip_'+id;
+    var root = this.get_root_tooltip_group();
+    var g = this.make_group(svg, root, full_id)
+    var box = this.make_tooltip_box(svg, g, id);
+    var text = this.make_tooltip_text(svg, g, id);
+    _f4u$t.move_to_ridiculous_negative(full_id);
+    $('#'+linked_obj_id).bind('mouseover', _f4u$t.tooltip_mouseover);
+    $('#'+linked_obj_id).bind('mouseout', _f4u$t.tooltip_mouseout);
+    return g;
+  }
+}
+
+// Basic UI objects used all over the place
+
+_f4u$t.ValueBox = function(options) {
+  _f4u$t.init_prop(this, options, 'vbox', 'mom');
+  _f4u$t.init_prop(this, options, 'vbox', 'init');
+  _f4u$t.init_prop(this, options, 'vbox', 'width');
+  _f4u$t.init_prop(this, options, 'vbox', 'height');
+  _f4u$t.init_prop(this, options, 'vbox', 'keysink');
+  _f4u$t.init_prop(this, options, 'vbox', 'gravity');
+  _f4u$t.init_prop(this, options, 'vbox', 'id');
+  _f4u$t.init_prop(this, options, 'label', 'stretchable');
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.ValueBox);
+
+_f4u$t.ValueBox.prototype.dims = function() {
+  return [this.width, this.height];
+}
+
+_f4u$t.ValueBox.prototype.make_box = function(svg, parent) {
+  var id = this.id;
+  var mousedown = this.keysink ? '_f4u$t.rotating_button_key_sink("'+id+'")' : '_f4u$t.devnull()';
+  var vb = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    2,
+    0,
+    0,
+    this.width,
+    this.height,
+    {
+      id: 'faust_value_box_'+id,
+      fill : _f4u$t.color_to_rgb(_f4u$t.WHITE),
+      stroke : _f4u$t.color_to_rgb(_f4u$t.BLACK),
+      'class': 'faust-vbox-box',
+      onmousedown : mousedown,
+      ontouchstart : mousedown
+    });
+
+  return vb;
+}
+
+_f4u$t.ValueBox.prototype.make_value = function(svg, parent) {
+  var id = this.id;
+  var mousedown = this.keysink ? '_f4u$t.rotating_button_key_sink("'+id+'")' : '_f4u$t.devnull()';
+  var vv = _f4u$t.make_text(
+    svg,
+    parent,
+    _f4u$t.xy(this.get_layout_manager().axis, 4, this.width  / 2.0),
+    this.height - 4,
+    this.init.toString(),
+    {
+      id: 'faust_value_value_'+id,
+      "text-anchor" : _f4u$t.xy(this.get_layout_manager().axis, 'left', 'middle'),
+      'class': 'faust-value-text',
+      onmousedown : mousedown,
+      ontouchstart : mousedown
+    }
+  );
+  return vv;
+}
+
+_f4u$t.ValueBox.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var g = this.make_group(svg, parent, id+"_vbox");
+
+  this.make_box(svg, g, id);
+  this.make_value(svg, g, id);
+
+  return g;
+}
+
+_f4u$t.Label = function(options) {
+  _f4u$t.init_prop(this, options, 'label', 'mom');
+  _f4u$t.init_prop(this, options, 'label', 'label');
+  _f4u$t.init_prop(this, options, 'label', 'id');
+  _f4u$t.init_prop(this, options, 'label', 'gravity');
+  _f4u$t.init_prop(this, options, 'label', 'stretchable');
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.Label);
+
+_f4u$t.Label.prototype.dims = function() {
+  var bbx = _f4u$t.get_text_bbox(this.get_root_svg(), this.label);
+  return [bbx.width, bbx.height];
+}
+
+_f4u$t.Label.prototype.label_text = function() {
+  var label = this.label;
+  if (this.unit) {/* // deprecated
+    label += this.unit;*/
+  }
+  return label;
+}
+
+_f4u$t.Label.prototype.make = function(svg, parent) {
+  var id = this.id;
+
+  var label = this.label_text();
+  var vl = _f4u$t.make_text(
+    svg,
+    parent,
+    0,
+    this.dims()[_f4u$t.Y_AXIS],
+    label,
+    {
+      id: 'faust_label_'+id,
+      "class" : "faust-label",
+    }
+  );
+
+}
+
+/*
+  DEFINES THE FAUST INCREMENTAL OBJECT CLASS.
+  All objects that go up in increments inherit from this.
+*/
+
+_f4u$t.IncrementalObject = function () {}
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.IncrementalObject);
+
+/*
+  DEFINES A ROTATING BUTTON.
+*/
+
+_f4u$t.RotatingButton = function(options) {
+  _f4u$t.init_prop(this, options, 'rbutton', 'mom');
+  _f4u$t.init_prop(this, options, 'rbutton', 'ir');
+  this._r = this.ir;
+  _f4u$t.init_prop(this, options, 'rbutton', 'a0');
+  _f4u$t.init_prop(this, options, 'rbutton', 'sweep');
+  if (this.sweep < 0) {
+    this.a0 += this.sweep;
+    this.sweep = Math.abs(this.sweep);
+  }
+  this.sweep = this.sweep % 360;
+  if (this.sweep == 0) {
+    this.sweep = 360;
+  }
+  _f4u$t.init_prop(this, options, 'rbutton', 'sp'); // percentage for white handle
+  _f4u$t.init_prop(this, options, 'rbutton', 'kp'); // knob percentage
+  _f4u$t.init_prop(this, options, 'rbutton', 'unit');
+  _f4u$t.init_prop(this, options, 'rbutton', 'min');
+  _f4u$t.init_prop(this, options, 'rbutton', 'max');
+  _f4u$t.init_prop(this, options, 'rbutton', 'init');
+  _f4u$t.init_prop(this, options, 'rbutton', 'step');
+  _f4u$t.init_prop(this, options, 'rbutton', 'integer');
+  _f4u$t.init_prop(this, options, 'rbutton', 'ndec');
+  _f4u$t.init_prop(this, options, 'rbutton', 'stretchable');
+  _f4u$t.init_prop(this, options, 'rbutton', 'orientation');
+  _f4u$t.init_prop(this, options, 'rbutton', 'orientation_mode');
+  _f4u$t.init_prop(this, options, 'rbutton', 'gravity');
+  _f4u$t.init_prop(this, options, 'rbutton', 'mgroove_fill');
+  _f4u$t.init_prop(this, options, 'rbutton', 'meter_fill');
+  _f4u$t.init_prop(this, options, 'rbutton', 'groove_fill');
+  _f4u$t.init_prop(this, options, 'rbutton', 'handle_fill');
+  _f4u$t.init_prop(this, options, 'rbutton', 'groove_stroke');
+  _f4u$t.init_prop(this, options, 'rbutton', 'handle_stroke');
+  _f4u$t.init_prop(this, options, 'rbutton', 'mgroove_stroke');
+  _f4u$t.init_prop(this, options, 'rbutton', 'meter_stroke');
+  _f4u$t.init_prop(this, options, 'rbutton', 'handle_width');
+  _f4u$t.init_prop(this, options, 'rbutton', 'tooltip');
+  _f4u$t.init_prop(this, options, 'rbutton', 'address');
+  _f4u$t.init_prop(this, options, 'rbutton', 'id');
+}
+
+_f4u$t.extend(_f4u$t.IncrementalObject, _f4u$t.RotatingButton);
+
+_f4u$t.RotatingButton.prototype.r = function() {
+  return this._r;
+}
+
+_f4u$t.RotatingButton.prototype.dims = function() {
+  return [this.r() * 2, this.r() * 2];
+}
+
+
+_f4u$t.RotatingButton.prototype.make_mgroove = function(svg, parent, id) {
+  var full_id = 'faust_rbutton_mgroove_'+id;
+  var mousedown = _f4u$t.activate_rbutton;
+  var xo = this.r();
+  var yo = this.r();
+  var d = "M{0} {1}A{2} {3} 0 {4} {5} {6} {7}L{8} {9}A{10} {11} 0 {12} {13} {14} {15}L{16} {17}";
+  d = d.format([
+    this.r() * Math.cos(_f4u$t.d2r(this.a0)) + xo, // outside X
+    this.r() * Math.sin(_f4u$t.d2r(this.a0)) + yo, // outside Y
+    this.r(), // radius X
+    this.r(), // radius Y
+    this.sweep <= 180 ? 0 : 1, // large arc flag
+    1, // draw positive
+    this.r() * Math.cos(_f4u$t.d2r(this.a0 + this.sweep)) + xo, // endpoint X
+    this.r() * Math.sin(_f4u$t.d2r(this.a0 + this.sweep)) + yo, // endpoint Y
+    this.r() * this.kp * Math.cos(_f4u$t.d2r(this.a0 + this.sweep)) + xo, // inside endpoint X
+    this.r() * this.kp * Math.sin(_f4u$t.d2r(this.a0 + this.sweep)) + yo, // inside endpoint Y
+    this.r() * this.kp, // inside radiux X
+    this.r() * this.kp, // inside radiux Y
+    this.sweep <= 180 ? 0 : 1, // large arc flag
+    0, // draw negative
+    this.r() * this.kp * Math.cos(_f4u$t.d2r(this.a0)) + xo, // inside X
+    this.r() * this.kp * Math.sin(_f4u$t.d2r(this.a0)) + yo, // inside Y
+    this.r() * Math.cos(_f4u$t.d2r(this.a0)) + xo, // outside X
+    this.r() * Math.sin(_f4u$t.d2r(this.a0)) + yo// outside Y
+  ]);
+  var mgroove = _f4u$t.make_path(
+    svg,
+    parent,
+    d,
+    {
+      fill : _f4u$t.color_to_rgb(this.mgroove_fill),
+      stroke : _f4u$t.color_to_rgb(this.mgroove_stroke),
+      id : full_id,
+      'class' : 'faust-rbutton-mgroove'
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return mgroove;
+}
+
+_f4u$t.RotatingButton.prototype.make_dot = function(svg, parent, id, rot) {
+  var full_id = 'faust_rbutton_dot'+(rot*45)+'_'+id;
+  var mousedown = _f4u$t.activate_rbutton;
+  var xo = this.r();
+  var yo = this.r();
+  var dot = _f4u$t.make_circle(
+    svg,
+    parent,
+    this.r() * (this.kp + 1) * 0.5 * Math.cos(_f4u$t.d2r(rot * 45)) + xo,
+    this.r() * (this.kp + 1) * 0.5 * Math.sin(_f4u$t.d2r(rot * 45)) + yo,
+    this.r() * (1 - this.kp) * 0.5,
+    {
+      fill : _f4u$t.color_to_rgb(this.dot_fill),
+      stroke : _f4u$t.color_to_rgb(this.dot_stroke),
+      id : full_id,
+      'class' : 'faust-rbutton-dot'
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return dot;
+}
+
+_f4u$t.RotatingButton.prototype.make_meter = function(svg, parent, id) {
+  var full_id = 'faust_rbutton_meter_'+id;
+  var mousedown = _f4u$t.activate_rbutton;
+  var xo = this.r();
+  var yo = this.r();
+  var startp = _f4u$t.remap(this.init, this.min, this.max, this.a0, this.a0 + this.sweep);
+  var d = "M{0} {1}A{2} {3} 0 {4} {5} {6} {7}L{8} {9}A{10} {11} 0 {12} {13} {14} {15}L{16} {17}";
+  d = d.format([
+    this.r() * Math.cos(_f4u$t.d2r(startp)) + xo, // outside X
+    this.r() * Math.sin(_f4u$t.d2r(startp)) + yo, // outside Y
+    this.r(), // radius X
+    this.r(), // radius Y
+    this.a0 + this.sweep - startp <= 180 ? 0 : 1, // large arc flag
+    1, // draw positive
+    this.r() * Math.cos(_f4u$t.d2r(this.a0 + this.sweep)) + xo, // endpoint X
+    this.r() * Math.sin(_f4u$t.d2r(this.a0 + this.sweep)) + yo, // endpoint Y
+    this.r() * this.kp * Math.cos(_f4u$t.d2r(this.a0 + this.sweep)) + xo, // inside endpoint X
+    this.r() * this.kp * Math.sin(_f4u$t.d2r(this.a0 + this.sweep)) + yo, // inside endpoint Y
+    this.r() * this.kp, // inside radiux X
+    this.r() * this.kp, // inside radiux Y
+    this.a0 + this.sweep - startp <= 180 ? 0 : 1, // large arc flag
+    0, // draw negative
+    this.r() * this.kp * Math.cos(_f4u$t.d2r(startp)) + xo, // inside X
+    this.r() * this.kp * Math.sin(_f4u$t.d2r(startp)) + yo, // inside Y
+    this.r() * Math.cos(_f4u$t.d2r(startp)) + xo, // outside X
+    this.r() * Math.sin(_f4u$t.d2r(startp)) + yo// outside Y
+  ]);
+  var meter = _f4u$t.make_path(
+    svg,
+    parent,
+    d,
+    {
+      fill : _f4u$t.color_to_rgb(this.meter_fill),
+      stroke : _f4u$t.color_to_rgb(this.meter_stroke),
+      id : full_id,
+      'class' : 'faust-rbutton-meter'
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return meter;
+}
+
+_f4u$t.RotatingButton.prototype.make_groove = function(svg, parent, id) {
+  var mousedown = _f4u$t.activate_rbutton;
+  var full_id = 'faust_rbutton_groove_'+id;
+  var groove = _f4u$t.make_circle(
+    svg,
+    parent,
+    this.r(),
+    this.r(),
+    this.r() * this.kp,    
+    {
+      fill : _f4u$t.color_to_rgb(this.groove_fill),
+      stroke : _f4u$t.color_to_rgb(this.groove_stroke),
+      id : full_id,
+      'class' : 'faust-rbutton-groove'
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return groove;
+}
+
+_f4u$t.RotatingButton.prototype.make_handle = function(svg, parent, id) {
+  var full_id = 'faust_rbutton_handle_'+id;
+  var origin = [this.r(), this.r()];
+  var startp = _f4u$t.remap(this.init, this.min, this.max, this.a0, this.a0 + this.sweep);
+  var mousedown = _f4u$t.activate_rbutton;
+  var handle = _f4u$t.make_line(
+    svg,
+    parent,
+    origin[0],
+    origin[1],
+    origin[0] + (this.r() * this.sp * this.kp) , // set at 0 degrees to start, then rotate below
+    origin[1],
+    {
+      fill : _f4u$t.color_to_rgb(this.handle_fill),
+      stroke : _f4u$t.color_to_rgb(this.handle_stroke),
+      "stroke-width" : this.handle_width,
+      'class' : 'faust-rbutton-handle',
+      id : full_id,
+      transform : 'translate(0,0) scale(1,1) rotate('+startp+','+origin[0]+','+origin[1]+')'
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return handle;
+}
+
+// anchor helps us get correct positioning for rotation
+_f4u$t.RotatingButton.prototype.make_anchor = function(svg, parent, id) {
+  var origin = [this.r(), this.r()];
+  var full_id = 'faust_rbutton_anchor_'+id;
+
+  var anchor = _f4u$t.make_path(
+    svg,
+    parent,
+    "M 0 0L0 1L1 1L1 0L0 0",
+    {
+      id : full_id,
+      style : 'opacity:0.0;',
+      transform : 'translate('+origin[0]+','+origin[1]+')',
+    }
+  );
+
+  return anchor;
+}
+
+_f4u$t.RotatingButton.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var g = this.make_group(svg, parent, id);
+  _f4u$t.initiate_rbutton(
+    id,
+    this.a0,
+    this.sweep,
+    this.r(),
+    this.kp,
+    this.min,
+    this.max,
+    this.step,
+    this.init,
+    this.integer,
+    this.ndec,
+    this.label,
+    this.unit,
+    this.orientation,
+    this.orientation_mode,
+    this.address
+  );
+
+  this.make_anchor(svg, g, id);
+  if (this.sweep != 360) {
+    this.make_mgroove(svg, g, id);
+    this.make_meter(svg, g, id);
+  } else {
+    for (var i = 0; i < 8; i++) {
+      this.make_dot(svg, g, id, i);
+    }
+  }
+  this.make_groove(svg, g, id);
+  this.make_handle(svg, g, id);
+  this.make_delayed_tooltip(this, svg, id, id);
+
+  return g;
+}
+
+/*
+  DEFINES A SLIDER.
+*/
+
+_f4u$t.SlidingObject = function(options, type) {
+  _f4u$t.init_prop(this, options, type, 'mom');
+  _f4u$t.init_prop(this, options, type, 'axis');
+  _f4u$t.init_prop(this, options, type, 'girth');
+  _f4u$t.init_prop(this, options, type, 'length');
+  _f4u$t.init_prop(this, options, type, 'unit');
+  _f4u$t.init_prop(this, options, type, 'min');
+  _f4u$t.init_prop(this, options, type, 'max');
+  _f4u$t.init_prop(this, options, type, 'init');
+  _f4u$t.init_prop(this, options, type, 'step');
+  _f4u$t.init_prop(this, options, type, 'integer');
+  _f4u$t.init_prop(this, options, type, 'ndec');
+  _f4u$t.init_prop(this, options, type, 'stretchable');
+  _f4u$t.init_prop(this, options, type, 'gravity');
+  _f4u$t.init_prop(this, options, type, 'address');
+  _f4u$t.init_prop(this, options, type, 'id');
+  _f4u$t.init_prop(this, options, type, 'type');
+  _f4u$t.init_prop(this, options, type, 'tooltip');
+}
+
+_f4u$t.extend(_f4u$t.IncrementalObject, _f4u$t.SlidingObject);
+
+_f4u$t.SlidingObject.prototype.dims = function() {
+  var x = _f4u$t.xy(this.axis, this.length, this.girth);
+  var y = _f4u$t.xy(this.axis, this.girth, this.length);
+  return [x,y];
+}
+
+_f4u$t.SlidingObject.prototype.stretch = function(x,y) {
+  if (this.stretchable[this.axis]) {
+    dims = this.dims();
+    this.length = Math.max(dims[this.axis], _f4u$t.xy(this.axis, x, y));
+  }
+}
+
+_f4u$t.Slider = function(options, type) {
+  _f4u$t.SlidingObject.call(this, options, type);
+  _f4u$t.init_prop(this, options, type,'sp');
+  _f4u$t.init_prop(this, options, type, 'orientation');
+  _f4u$t.init_prop(this, options, type, 'orientation_mode');
+  _f4u$t.init_prop(this, options, type, 'groove_fill');
+  _f4u$t.init_prop(this, options, type, 'groove_stroke');
+  _f4u$t.init_prop(this, options, type, 'handle_fill');
+  _f4u$t.init_prop(this, options, type, 'handle_stroke');
+}
+
+_f4u$t.extend(_f4u$t.SlidingObject, _f4u$t.Slider);
+
+_f4u$t.Slider.prototype.skinny_girth = function() {
+  return this.girth * 2.0 / 5.0;
+}
+
+_f4u$t.Slider.prototype.make_groove = function(svg, parent, id) {
+  var dims = this.dims();
+  var w = _f4u$t.xy(this.axis, this.length, this.skinny_girth());
+  var h = _f4u$t.xy(this.axis, this.skinny_girth(), this.length);
+  var xo = ((this.axis == _f4u$t.Y_AXIS) || (this instanceof _f4u$t.RotatingButton) ? (dims[0] - w) / 2.0 : 0.0);
+  var slider_girth = this.sp;
+  var half_slider_girth = slider_girth * 0.5;
+  var startp = _f4u$t.xy(this.axis, _f4u$t.remap, _f4u$t.remap_and_flip)(this.init, this.min, this.max, 0 + half_slider_girth, this.length - half_slider_girth);
+  var trans = _f4u$t.xy(this.axis, 'translate(0,'+((this.girth - this.skinny_girth()) / 2)+')', 'translate('+xo+',0)');
+  var full_id = 'faust_'+this.type+'_groove_'+id;
+  var activate_fn = "activate_"+this.type;
+  var mousedown = _f4u$t[activate_fn];
+  var groove = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    _f4u$t.xy(this.axis, startp, 0),
+    0,
+    _f4u$t.xy(this.axis, w - startp, w),
+    _f4u$t.xy(this.axis, h, startp),
+    {
+      fill : _f4u$t.color_to_rgb(this.groove_fill),
+      stroke : _f4u$t.color_to_rgb(this.groove_stroke),
+      id : full_id,
+      'class' : _f4u$t.xy(this.axis, 'faust-hslider-groove', 'faust-vslider-groove'),
+      transform : trans
+    });
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return groove;
+}
+
+_f4u$t.Slider.prototype.make_meter = function(svg, parent, id) {
+  var dims = this.dims();
+  var w = _f4u$t.xy(this.axis, this.length, this.skinny_girth());
+  var h = _f4u$t.xy(this.axis, this.skinny_girth(), this.length);
+  var xo = ((this.axis == _f4u$t.Y_AXIS) || (this instanceof _f4u$t.RotatingButton) ? (dims[0] - w) / 2.0 : 0.0);
+  var trans = _f4u$t.xy(this.axis, 'translate(0,'+((this.girth - this.skinny_girth()) / 2)+')', 'translate('+xo+',0)');
+  var full_id = 'faust_'+this.type+'_meter_'+id;
+  var activate_fn = "activate_"+this.type;
+  var mousedown = _f4u$t[activate_fn];
+  var groove = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      fill : _f4u$t.color_to_rgb(this.groove_fill),
+      stroke : _f4u$t.color_to_rgb(this.groove_stroke),
+      id : full_id,
+      'class' : _f4u$t.xy(this.axis, 'faust-hslider-meter', 'faust-vslider-meter'),
+      transform : trans
+    });
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return groove;
+}
+
+_f4u$t.Slider.prototype.make_handle = function(svg, parent, id) {
+  var dims = this.dims();
+  var slider_girth = this.sp;
+  var half_slider_girth = slider_girth * 0.5;
+  var startp = _f4u$t.xy(this.axis, _f4u$t.remap, _f4u$t.remap_and_flip)(this.init, this.min, this.max, 0 + half_slider_girth, this.length - half_slider_girth);
+  var bottom = startp - half_slider_girth;
+  var top = startp + half_slider_girth;
+  var w = _f4u$t.xy(this.axis, slider_girth, this.girth);
+  var h = _f4u$t.xy(this.axis, this.girth, slider_girth);
+  var xo = ((this.axis == _f4u$t.Y_AXIS) ? (dims[0] - w) / 2.0 : 0.0);
+  var x = _f4u$t.xy(this.axis, bottom, xo);
+  var y = _f4u$t.xy(this.axis, 0, bottom);
+  var full_id = 'faust_'+this.type+'_handle_'+id;
+  var activate_fn = "activate_"+this.type;
+  var mousedown = _f4u$t[activate_fn];
+
+  var handle = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      fill : _f4u$t.color_to_rgb(this.handle_fill),
+      stroke : _f4u$t.color_to_rgb(this.handle_stroke),
+      id : full_id,
+      'class' : _f4u$t.xy(this.axis, 'faust-hslider-handle', 'faust-vslider-handle'),
+      transform : 'translate('+x+','+y+')'
+    });
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  return handle;
+}
+
+_f4u$t.Slider.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var g = this.make_group(svg, parent, id);
+
+  _f4u$t["initiate_"+this.type](
+    id,
+    this.length,
+    this.sp,
+    this.min,
+    this.max,
+    this.step,
+    this.init,
+    this.integer,
+    this.ndec,
+    this.label,
+    this.unit,
+    this.orientation,
+    this.orientation_mode,
+    this.address
+  );
+
+  this.make_meter(svg, g, id);
+  this.make_groove(svg, g, id);
+  this.make_handle(svg, g, id);
+  this.make_delayed_tooltip(this, svg, id, id);
+  return g;
+}
+
+/*
+  DEFINES A HORIZONTAL SLIDER.
+*/
+
+_f4u$t.HorizontalSlider = function(options) {
+  options = options || {};
+  options["axis"] = _f4u$t.X_AXIS;
+  options["type"] = 'hslider';
+  _f4u$t.Slider.call(this, options, options["type"]);
+}
+
+_f4u$t.extend(_f4u$t.Slider, _f4u$t.HorizontalSlider);
+
+/*
+  DEFINES A VERTICAL SLIDER.
+*/
+
+_f4u$t.VerticalSlider = function(options) {
+  options = options || {};
+  options["axis"] = _f4u$t.Y_AXIS;
+  options["type"] = 'vslider';
+  _f4u$t.Slider.call(this, options, options["type"]);
+}
+
+_f4u$t.extend(_f4u$t.Slider, _f4u$t.VerticalSlider);
+
+_f4u$t.BarGraph = function(options, type) {
+  _f4u$t.SlidingObject.call(this, options, type);
+  this.curtain_fill = _f4u$t.initifnull(options.curtain_fill, _f4u$t.CYAN);
+  this.curtain_stroke = _f4u$t.initifnull(options.curtain_stroke, _f4u$t.CYAN);
+  this.meter_fill = _f4u$t.initifnull(options.meter_fill, _f4u$t.CYAN);
+  this.meter_stroke = _f4u$t.initifnull(options.meter_stroke, _f4u$t.CYAN);
+  this.init = this.init ? this.init : this.min;
+}
+
+_f4u$t.extend(_f4u$t.SlidingObject, _f4u$t.BarGraph);
+
+_f4u$t.BarGraph.prototype.make_curtain = function(svg, parent, id) {
+  var full_id = 'faust_'+this.type+'_curtain_'+id;
+  var def = _f4u$t.xy(this.axis, _f4u$t.remap, _f4u$t.remap_and_flip)(this.init, this.min, this.max, 0, this.length);
+  var dims = this.dims();
+  var w = _f4u$t.xy(this.axis, def, this.girth);
+  var h = _f4u$t.xy(this.axis, this.girth, def);
+  var xo = ((this.axis == _f4u$t.Y_AXIS) || (this instanceof _f4u$t.RotatingButton) ? (dims[0] - w) / 2.0 : 0.0);
+  var curtain = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      fill : _f4u$t.color_to_rgb(this.curtain_fill),
+      stroke : _f4u$t.color_to_rgb(this.curtain_stroke),
+      id : full_id,
+      transform : _f4u$t.xy(this.axis,'translate('+(xo + this.length)+',0) scale(-1,1)', 'translate('+xo+',0)'),
+      'class' : _f4u$t.xy(this.axis, 'faust-hbargraph-curtain', 'faust-vbargraph-curtain')
+    });
+
+  return curtain;
+}
+
+_f4u$t.BarGraph.prototype.make_meter = function(svg, parent, id) {
+  var dims = this.dims();
+  var w = _f4u$t.xy(this.axis, this.length, this.girth);
+  var h = _f4u$t.xy(this.axis, this.girth, this.length);
+  var xo = ((this.axis == _f4u$t.Y_AXIS) || (this instanceof _f4u$t.RotatingButton) ? (dims[0] - w) / 2.0 : 0.0);
+  var meter = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      fill : _f4u$t.color_to_rgb(this.meter_fill),
+      stroke : _f4u$t.color_to_rgb(this.meter_stroke),
+      id : 'faust_'+this.type+'_meter_'+id,
+      transform : 'translate('+xo+',0)',
+      'class' : _f4u$t.xy(this.axis, 'faust-hbargraph-meter', 'faust-vbargraph-meter')
+    });
+
+  return meter;
+}
+
+_f4u$t.BarGraph.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var g = this.make_group(svg, parent, id);
+
+  _f4u$t['initiate_'+this.type](
+    id,
+    this.girth,
+    this.length,
+    this.min,
+    this.max,
+    this.step,
+    this.init,
+    this.label,
+    this.unit,
+    this.address
+  );
+
+  this.make_meter(svg, g, id);
+  this.make_curtain(svg, g, id);
+
+  return g;
+}
+
+/*
+  DEFINES A HORIZONTAL BAR GRAPH.
+*/
+
+_f4u$t.HorizontalBarGraph = function(options) {
+  options = options || {};
+  options["axis"] = _f4u$t.X_AXIS;
+  options["type"] = 'hbargraph';
+  _f4u$t.BarGraph.call(this, options, options["type"]);
+}
+
+_f4u$t.extend(_f4u$t.BarGraph, _f4u$t.HorizontalBarGraph);
+
+/*
+  DEFINES A VERTICAL BAR GRAPH.
+*/
+
+_f4u$t.VerticalBarGraph = function(options) {
+  options = options || {};
+  options["axis"] = _f4u$t.Y_AXIS;
+  options["type"] = 'vbargraph';
+  _f4u$t.BarGraph.call(this, options, options["type"]);
+}
+
+_f4u$t.extend(_f4u$t.BarGraph, _f4u$t.VerticalBarGraph);
+
+_f4u$t.CheckBox = function(options) {
+  _f4u$t.init_prop(this, options, 'checkbox','mom');
+  _f4u$t.init_prop(this, options, 'checkbox','d');
+  _f4u$t.init_prop(this, options, 'checkbox','gravity');
+  _f4u$t.init_prop(this, options, 'checkbox','check_fill');
+  _f4u$t.init_prop(this, options, 'checkbox','check_stroke');
+  _f4u$t.init_prop(this, options, 'checkbox','box_fill');
+  _f4u$t.init_prop(this, options, 'checkbox','box_stroke');
+  _f4u$t.init_prop(this, options, 'checkbox','init');
+  _f4u$t.init_prop(this, options, 'checkbox', 'stretchable');
+  _f4u$t.init_prop(this, options, 'checkbox', 'tooltip');
+  _f4u$t.init_prop(this, options, 'checkbox','address');
+  _f4u$t.init_prop(this, options, 'checkbox', 'id');
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.CheckBox);
+
+_f4u$t.CheckBox.prototype.dims = function() {
+  return [this.d, this.d];
+}
+
+// DON'T FORGET TO SPECIFY CHECK IN CALLBACK
+_f4u$t.CheckBox.prototype.make_box = function(svg, parent, id) {
+  var full_id = 'faust_checkbox_box_'+id;
+  var w = this.d;
+  var h = this.d;
+  var dims = this.dims();
+  var xo = (dims[0] - w) / 2.0;
+  var mouseup = '_f4u$t.click_checkbox("'+full_id+'")';
+  var touchup = '_f4u$t.touch_checkbox("'+full_id+'")';
+
+  var box = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      fill : _f4u$t.color_to_rgb(this.box_fill),
+      stroke : _f4u$t.color_to_rgb(this.box_stroke),
+      id : full_id,
+      'class' : 'faust-checkbox-box',
+      transform : 'translate('+xo+',0)',
+      onmouseup : mouseup,
+      ontouchend : touchup
+    });
+
+  return box;
+}
+
+_f4u$t.CheckBox.prototype.make_check = function(svg, parent, id) {
+  var full_id = 'faust_checkbox_check_'+id;
+  var w = this.d;
+  var h = this.d;
+  var dims = this.dims();
+  var xo = (dims[0] - w) / 2.0;
+  var mouseup = '_f4u$t.change_checkbox("'+full_id+'")';
+  //var touchup = '_f4u$t.touch_checkbox("'+full_id+'")';
+  var box = _f4u$t.make_path(
+    svg,
+    parent,
+    "M0 0L"+this.d+" "+this.d+"M0 "+this.d+"L"+this.d+" 0",
+    {
+      id : full_id,
+      fill : _f4u$t.color_to_rgb(this.check_fill),
+      stroke : _f4u$t.color_to_rgb(this.check_stroke),
+      style : "opacity:"+(this.init == 1 ? 1.0 : 0.0),
+      onmouseup : mouseup,
+      //ontouchend : touchup, // deactivated so that touch doesn't trigger both box and check at the same time
+      'class' : 'faust-chekbox-check',
+      transform : 'translate('+xo+',0)'
+    }
+  );
+
+  return box;
+}
+
+_f4u$t.CheckBox.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var g = this.make_group(svg, parent, id);
+
+  _f4u$t.initiate_checkbox(id, this.address);
+
+  this.make_box(svg, g, id);
+  this.make_check(svg, g, id);
+  //this.make_label(svg, g, id);
+  this.make_delayed_tooltip(this, svg, id, id);
+
+  return g;
+}
+
+/*
+  Button in
+*/
+
+_f4u$t.Button = function(options) {
+  _f4u$t.init_prop(this, options, 'button','mom');
+  _f4u$t.init_prop(this, options, 'button','ideal_width');
+  _f4u$t.init_prop(this, options, 'button','ideal_height');
+  _f4u$t.init_prop(this, options, 'button', 'tooltip');
+  _f4u$t.init_prop(this, options, 'button', 'label');
+  this._w = this.ideal_width;
+  this._h = this.ideal_height;
+  _f4u$t.init_prop(this, options, 'button','gravity');
+  _f4u$t.init_prop(this, options, 'button','fill_on');
+  _f4u$t.init_prop(this, options, 'button','fill_off');
+  _f4u$t.init_prop(this, options, 'button','stroke');
+  _f4u$t.init_prop(this, options, 'button', 'stretchable');
+  _f4u$t.init_prop(this, options, 'button','baseline_skip');
+  _f4u$t.init_prop(this, options, 'button', 'id');
+  _f4u$t.init_prop(this, options, 'button','address');
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.Button);
+
+_f4u$t.Button.prototype.w = function() {
+  return Math.max(this._w,  _f4u$t.get_text_bbox(this.get_root_svg(), this.label).width + 6);
+}
+
+_f4u$t.Button.prototype.h = function() {
+  return this._h;
+}
+
+_f4u$t.Button.prototype.dims = function() {
+  return [this.w(), this.h()];
+}
+
+_f4u$t.Button.prototype.make_button_box = function(svg, parent, id) {
+  var full_id = 'faust_button_box_'+id;
+  var rf = 10;
+  var button = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    rf,
+    0,
+    0,
+    this.w(),
+    this.h(),
+    {
+      id : full_id,
+      fill : _f4u$t.color_to_rgb(this.fill_off),
+      stroke : _f4u$t.color_to_rgb(this.stroke),
+      'class' : 'faust-button-box',
+      onmouseover : '_f4u$t.button_hover("'+full_id+'")',
+      onmouseout : '_f4u$t.button_unhover("'+full_id+'")'
+    });
+
+  return button;
+}
+
+_f4u$t.Button.prototype.make_label = function(svg, parent, id) {
+  var vl = _f4u$t.make_text(
+    svg,
+    parent,
+    0,
+    0,
+    this.label,
+    {
+      "text-anchor" : 'middle',
+      id: 'faust_label_'+id,
+      class: 'faust-button-label',
+      transform: 'translate('+(this.w() / 2.0)+','+(this.h() / 2.0 + this.baseline_skip)+')',
+    }
+  );
+
+  return vl;
+}
+
+_f4u$t.Button.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var full_id = 'faust_button_box_'+id;
+  var mousedown = '_f4u$t.button_down("'+full_id+'")';
+  var mouseup = '_f4u$t.button_up("'+full_id+'")';
+  var g = this.make_group(svg, parent, id,
+    {
+      onmousedown : mousedown,
+      //ontouchstart : mousedown,
+      onmouseup : mouseup,
+      //ontouchend : mouseup
+    });
+
+  _f4u$t.initiate_button(
+    id,
+    _f4u$t.color_to_rgb(this.fill_off),
+    _f4u$t.color_to_rgb(this.fill_on),
+    this.address
+  );
+
+  this.make_button_box(svg, g, id);
+  this.make_label(svg, g, id);
+  this.make_delayed_tooltip(this, svg, id, id);
+
+  return g;
+}
+
+_f4u$t.NumericalEntry = function(options) {
+  _f4u$t.init_prop(this, options, 'nentry', 'mom');
+  _f4u$t.init_prop(this, options, 'nentry', 'unit');
+  _f4u$t.init_prop(this, options, 'nentry', 'ideal_width');
+  _f4u$t.init_prop(this, options, 'nentry', 'ideal_height');
+  this._w = this.ideal_width;
+  this._h = this.ideal_height;
+  _f4u$t.init_prop(this, options, 'nentry', 'min');
+  _f4u$t.init_prop(this, options, 'nentry', 'max');
+  _f4u$t.init_prop(this, options, 'nentry', 'init');
+  _f4u$t.init_prop(this, options, 'nentry', 'step');
+  _f4u$t.init_prop(this, options, 'nentry', 'integer');
+  _f4u$t.init_prop(this, options, 'nentry', 'ndec');
+  _f4u$t.init_prop(this, options, 'nentry', 'gravity');
+  _f4u$t.init_prop(this, options, 'nentry', 'address');
+  _f4u$t.init_prop(this, options, 'nentry', 'id');
+  _f4u$t.init_prop(this, options, 'nentry', 'type');
+  _f4u$t.init_prop(this, options, 'button', 'stretchable');
+  _f4u$t.init_prop(this, options, 'nentry', 'button_fill');
+  _f4u$t.init_prop(this, options, 'nentry', 'operation_fill');
+  _f4u$t.init_prop(this, options, 'nentry', 'button_stroke');
+  _f4u$t.init_prop(this, options, 'nentry', 'operation_stroke');
+  _f4u$t.init_prop(this, options, 'nentry', 'padding');
+  _f4u$t.init_prop(this, options, 'button', 'tooltip');
+}
+
+_f4u$t.extend(_f4u$t.IncrementalObject, _f4u$t.NumericalEntry);
+
+_f4u$t.NumericalEntry.prototype.w = function() {
+  return this._w;
+}
+
+_f4u$t.NumericalEntry.prototype.h = function() {
+  return this._h;
+}
+
+_f4u$t.NumericalEntry.prototype.dims = function() {
+  return [this.w(), this.h()];
+}
+
+_f4u$t.NumericalEntry.prototype.make_left_button = function(svg, parent, id) {
+  return this.make_button(svg, parent, id, 0, false);
+}
+
+_f4u$t.NumericalEntry.prototype.make_right_button = function(svg, parent, id) {
+  return this.make_button(svg, parent, id, this.w() / 2.0 + this.padding, true);
+}
+
+_f4u$t.NumericalEntry.prototype.make_button = function(svg, parent, id, xo, incr) {
+  var identifier = incr ? 'rbutton' : 'lbutton';
+  var tag = incr ? 'plus' : 'minus';
+  var full_id = 'faust_nentry_button_'+tag+'_'+id;
+  var w = this.w() / 2.0 - this.padding;
+  var h = this.h();
+  var mousedown = _f4u$t['nentry_down_'+tag]
+  var mouseup = _f4u$t['nentry_up_'+tag]
+  var button = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      
+      fill : _f4u$t.color_to_rgb(this.button_fill),
+      stroke : _f4u$t.color_to_rgb(this.button_stroke),
+      transform : 'translate('+xo+',0)',
+      id : full_id,
+      'class' : 'faust-nentry-box'
+    });
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  $('#'+full_id).bind('mouseup', mouseup);
+  $('#'+full_id).bind('touchend', mouseup);
+  return button;
+}
+
+_f4u$t.NumericalEntry.prototype.make_minus = function(svg, parent, id) {
+  var full_id = 'faust_nentry_minus_'+id;
+  var x0 = (this.w() / 2.0 - this.padding) / 4.0;
+  var y = this.h() / 2.0;
+  var x1 = (this.w() / 2.0 - this.padding) * 3.0 / 4.0;
+  var mousedown = _f4u$t.nentry_down_minus;
+  var mouseup = _f4u$t.nentry_up_minus;
+
+  var d = "M"+x0+" "+y+"L"+x1+" "+y;
+  var minus = _f4u$t.make_path(
+    svg,
+    parent,
+    d,
+    {
+      fill : _f4u$t.color_to_rgb(this.operation_fill),
+      stroke : _f4u$t.color_to_rgb(this.operation_stroke),
+      id : full_id,
+      'class' : 'faust-nentry-operation',
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  $('#'+full_id).bind('mouseup', mouseup);
+  $('#'+full_id).bind('touchend', mouseup);
+  return minus;
+}
+
+_f4u$t.NumericalEntry.prototype.make_plus = function(svg, parent, id) {
+  var full_id = 'faust_nentry_plus_'+id;
+  var x00 = (this.w() / 2.0 - this.padding) / 4.0;
+  var y0 = this.h() / 2.0;
+  var x01 = (this.w() / 2.0 - this.padding) * 3.0 / 4.0;
+  var x1 = (this.w() / 2.0 - this.padding) / 2.0;
+  var y10 = this.h() / 4.0;
+  var y11 = this.h() * 3.0 / 4.0;
+
+  var d = "M{0} {1}L{2} {1}M{3} {4}L{3} {5}";
+  d = d.format([x00, y0, x01, x1, y10, y11]);
+  var mousedown = _f4u$t.nentry_down_plus;
+  var mouseup = _f4u$t.nentry_up_plus;
+
+  var plus = _f4u$t.make_path(
+    svg,
+    parent,
+    d,
+    {
+      fill : _f4u$t.color_to_rgb(this.operation_fill),
+      stroke : _f4u$t.color_to_rgb(this.operation_stroke),
+      transform : 'translate('+(this.w() / 2.0 + this.padding)+',0)',
+      id : full_id,
+      'class' : 'faust-nentry-operation',
+      onmousedown : mousedown,
+      ontouchstart : mousedown
+    }
+  );
+
+  $('#'+full_id).bind('mousedown', mousedown);
+  $('#'+full_id).bind('touchstart', mousedown);
+  $('#'+full_id).bind('mouseup', mouseup);
+  $('#'+full_id).bind('touchend', mouseup);
+  return plus;
+}
+
+_f4u$t.NumericalEntry.prototype.make = function(svg, parent) {
+  var id = this.id;
+  var g = this.make_group(svg, parent, id);
+
+  _f4u$t.initiate_nentry(
+    id,
+    this.min,
+    this.max,
+    this.step,
+    this.init,
+    this.integer,
+    this.ndec,
+    this.label,
+    this.unit,
+    this.address
+  );
+
+  this.make_left_button(svg, g, id);
+  this.make_right_button(svg, g, id);
+  this.make_minus(svg, g, id);
+  this.make_plus(svg, g, id);
+  this.make_delayed_tooltip(this, svg, id, id);
+
+  return g;
+}
+
+_f4u$t.LayoutManager = function(options) {
+  var type = _f4u$t.xy(options.axis, 'hgroup','vgroup');
+  _f4u$t.init_prop(this, options, type, 'mom');
+  _f4u$t.init_prop(this, options, type, 'axis');
+  _f4u$t.init_prop(this, options, type, 'padding');
+  _f4u$t.init_prop(this, options, type, 'other_axis_padding');
+  _f4u$t.init_prop(this, options, type, 'draw_background');
+  _f4u$t.init_prop(this, options, type, 'label');
+  _f4u$t.init_prop(this, options, type, 'objs');
+  _f4u$t.init_prop(this, options, type, 'gravity');
+  _f4u$t.init_prop(this, options, type, 'stretchable');
+  _f4u$t.init_prop(this, options, type, 'fill');
+  _f4u$t.init_prop(this, options, type, 'stroke');
+  this.x = 0;
+  this.y = 0;
+  this.w = 0;
+  this.h = 0;
+  this.id = _f4u$t.randString();
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.LayoutManager);
+
+_f4u$t.LayoutManager.prototype.dims = function() {
+  var outx = [];
+  var outy = [];
+  for (var i = 0; i < this.objs.length; i++) {
+    var dim = this.objs[i].dims();
+    outx.push(dim[_f4u$t.X_AXIS]);
+    outy.push(dim[_f4u$t.Y_AXIS]);
+  }
+
+  var out = [outx, outy];
+
+  for (var i = _f4u$t.X_AXIS; i < _f4u$t.NO_AXES; i++) {
+    out[i] = (i == this.axis ? out[i].sum() : out[i].max());
+  }
+
+  // this adds in between padding for all objects as well as
+  // padding on the top and on the bottom
+  out[this.axis] += (this.padding * (this.objs.length + 1));
+  // this only adds padding on the sides
+  out[_f4u$t.other_axis(this.axis)] += (2 * this.other_axis_padding);
+  return out;
+}
+
+_f4u$t.LayoutManager.prototype.populate_objects = function() {
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].mom = this;
+    if ((this.objs[i] instanceof _f4u$t.LayoutManager)
+        || (this.objs[i] instanceof _f4u$t.TabGroup)) {
+      this.objs[i].populate_objects();
+    }
+  }
+}
+
+_f4u$t.LayoutManager.prototype.stretch = function(x,y) {
+  // This function could just do the dim change, but
+  // it would leave stuff clumped in the center.  We air
+  // things out if nothing stretches.
+  if (this.stretchable[this.axis]) {
+    var change_padding = true;
+    for (var i = 0; i < this.objs.length; i++) {
+      if (this.objs[i].stretchable[this.axis]) {
+        // if even a single object can be stretched,
+        // don't change the padding and let that object stretch
+        change_padding = false;
+        break;
+      }
+    }
+    if (change_padding) {
+      var dim = this.dims();
+      // if not a single object can be stretched, then we
+      // space objects out via the padding
+      this.padding = this.padding + Math.max(0,
+                      (_f4u$t.xy(this.axis,x,y)  - dim[this.axis]) / (this.objs.length + 1));
+    }
+  }
+
+  var dim = this.dims();
+  this.dims = function() { return [this.stretchable[_f4u$t.X_AXIS] ? x : dim[_f4u$t.X_AXIS],
+                                   this.stretchable[_f4u$t.Y_AXIS] ? y : dim[_f4u$t.Y_AXIS]]; };
+}
+
+_f4u$t.LayoutManager.prototype.get_stretchable_coefficient = function(total) {
+  var stretchable = 0.0;
+  var unstretchable = 0.0;
+  for (var i = 0; i < this.objs.length; i++) {
+    if (this.objs[i].stretchable[this.axis]) {
+      stretchable += this.objs[i].dims()[this.axis];
+    } else {
+      unstretchable += this.objs[i].dims()[this.axis];
+    }
+  }
+  return (total - (this.padding * (this.objs.length + 1)) - unstretchable) / stretchable;
+}
+
+_f4u$t.LayoutManager.prototype.do_spacing = function(leaf) {
+  var dims = this.dims();
+  var x = dims[_f4u$t.X_AXIS];
+  var y = dims[_f4u$t.Y_AXIS];
+  this.w = x;
+  this.h = y;
+  // increase padding by size
+  var padding = this.padding;
+  // the first padding will need to account for any additional space, thus
+  // use this.gravity, as object gravities will be used internally
+  var running_count = padding;
+  var stretchable_coefficient = this.get_stretchable_coefficient(_f4u$t.xy(this.axis,x,y));
+  for (var i = 0; i < this.objs.length; i++) {
+    var obj = this.objs[i];
+    // the first time we calc the dim, we do it so that we can pass
+    // a proposition for stretching to the stretching algorithm
+    // the is the maximum space allowable for stretching
+    var dim = obj.dims();
+    obj.stretch(_f4u$t.xy(this.axis, stretchable_coefficient * dim[_f4u$t.X_AXIS], x - (2 * this.other_axis_padding)), _f4u$t.xy(this.axis, y - (2 * this.other_axis_padding), stretchable_coefficient * dim[_f4u$t.Y_AXIS]));
+    // we need to calculate the dimensions a second time
+    // because they may have been stretched above
+    dim = obj.dims();
+    var xv1 = _f4u$t.xy(this.axis, running_count, 0);
+    var xv2 = _f4u$t.xy(this.axis, running_count, x - dim[_f4u$t.X_AXIS]);
+    obj.setX(_f4u$t.linear_combination(obj.gravity[_f4u$t.X_AXIS], xv1, xv2));
+    var yv1 = _f4u$t.xy(this.axis, 0, running_count);
+    var yv2 = _f4u$t.xy(this.axis, y - dim[_f4u$t.Y_AXIS], running_count);
+    obj.setY(_f4u$t.linear_combination(obj.gravity[_f4u$t.Y_AXIS], yv1, yv2));
+    obj.do_spacing(leaf + 1);
+    running_count += padding + _f4u$t.xy(this.axis, dim[_f4u$t.X_AXIS], dim[_f4u$t.Y_AXIS]);
+  }
+}
+
+_f4u$t.LayoutManager.prototype.make_background = function(svg, parent) {
+  var full_id = 'faust_background_'+this.id;
+  var dims = this.dims();
+  var w = dims[0];
+  var h = dims[1];
+  var background = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      fill : _f4u$t.color_to_rgb(this.fill),
+      stroke : _f4u$t.color_to_rgb(this.stroke),
+      'class' : 'faust-group-background',
+      id : full_id,
+      style: +'fill-opacity:0.2;'
+    });
+
+  return background;
+}
+
+// only for debugging
+_f4u$t.LayoutManager.prototype.make_dim_cross = function(svg, parent) {
+  var dims = this.dims();
+  _f4u$t.make_path(
+    svg,
+    parent,
+    "M0 0L"+dims[0]+' '+dims[1]
+  );
+
+  //return background;
+}
+
+_f4u$t.LayoutManager.prototype.make = function(svg, parent) {
+  var g = this.make_group(svg, parent, this.id);
+
+  if (this.draw_background) {
+    this.make_background(svg, g);
+  }
+  //this.make_label(svg, g);
+
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].make(svg, g);
+  }
+
+  //this.make_dim_cross(svg, g);
+  return g;
+}
+
+_f4u$t.TabGroup = function(options) {
+  _f4u$t.init_prop(this, options, 'tgroup', 'mom');
+  _f4u$t.init_prop(this, options, 'tgroup', 'headroom');
+  _f4u$t.init_prop(this, options, 'tgroup', 'headpadding');
+  _f4u$t.init_prop(this, options, 'tgroup', 'x_padding');
+  _f4u$t.init_prop(this, options, 'tgroup', 'x_width');
+  _f4u$t.init_prop(this, options, 'tgroup', 'objs');
+  _f4u$t.init_prop(this, options, 'tgroup', 'init');
+  _f4u$t.init_prop(this, options, 'tgroup', 'stretchable');
+  _f4u$t.init_prop(this, options, 'tgroup', 'gravity');
+  _f4u$t.init_prop(this, options, 'tgroup', 'baseline_skip');
+  _f4u$t.init_prop(this, options, 'tgroup', 'fill_on');
+  _f4u$t.init_prop(this, options, 'tgroup', 'fill_off');
+  _f4u$t.init_prop(this, options, 'tgroup', 'stroke');
+  this.x = 0;
+  this.y = 0;
+  this.id = _f4u$t.randString();
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.TabGroup);
+
+_f4u$t.TabGroup.prototype.setX = function(x) {
+  this.x = x;
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].x = x;
+  }
+}
+
+_f4u$t.TabGroup.prototype.setY = function(y) {
+  this.y = y;
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].y = y + this.headroom + this.headpadding;
+  }
+}
+
+_f4u$t.TabGroup.prototype.populate_objects = function() {
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].mom = this;
+    if ((this.objs[i] instanceof _f4u$t.LayoutManager)
+        || (this.objs[i] instanceof _f4u$t.TabGroup)) {
+      this.objs[i].populate_objects();
+    }
+  }
+}
+
+_f4u$t.TabGroup.prototype.dims = function() {
+  var x = 0;
+  var y = 0;
+  for (var i = 0; i < this.objs.length; i++) {
+    var dim = this.objs[i].dims();
+    x = Math.max(x, dim[0]);
+    y = Math.max(y, dim[1]);
+  }
+  return [Math.max(x, (this.x_width + this.x_padding) * this.objs.length - this.x_padding), y + this.headroom + this.headpadding];
+}
+
+_f4u$t.TabGroup.prototype.do_spacing = function(leaf) {
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].x = 0;
+    this.objs[i].y = this.headroom + this.headpadding;
+    this.objs[i].do_spacing(leaf + 1);
+  }
+}
+
+_f4u$t.TabGroup.prototype.make_label = function(svg, parent, x, y, l, goodid, badidstr) {
+  var mousedown = '_f4u$t.activate_tgroup(0,'+(this.headroom + this.headpadding)+',"'+goodid+'","'+badidstr+'")'
+  var vl = _f4u$t.make_text(
+    svg,
+    parent,
+    0,
+    0,
+    l,
+    {
+      "text-anchor" : 'middle',
+      'class' : 'faust-tgroup-label',
+      transform : 'translate('+x+','+y+')',
+      onmousedown : mousedown,
+      ontouchstart : mousedown
+    }
+  );
+
+  return vl;
+}
+
+_f4u$t.TabGroup.prototype.make_tab = function(svg, parent, w, h, x, y, goodid, badidstr, fill, down) {
+  var mousedown = '_f4u$t.activate_tgroup(0,'+(this.headroom + this.headpadding)+',"'+goodid+'","'+badidstr+'")';
+  var tab = _f4u$t.make_rectangle_via_rect(
+    svg,
+    parent,
+    4,
+    0,
+    0,
+    w,
+    h,
+    {
+      transform: 'translate('+x+','+y+')',
+      'class' : 'faust-tgroup-box',
+      fill : _f4u$t.color_to_rgb(fill),
+      stroke : _f4u$t.color_to_rgb(this.stroke),
+      id : 'faust_tab_'+_f4u$t.unique(goodid),
+      onmousedown : mousedown,
+      ontouchstart : mousedown
+    });
+
+  return tab;
+}
+
+_f4u$t.TabGroup.prototype.make_tabs = function(svg, parent) {
+  // we evenly space buttons across x axis
+  // was a bug...
+  var g = _f4u$t.make_g(svg, parent, 'faust_tabgroup_tabbar_'+this.id);
+
+  var running_count = 0;
+  for (var i = 0; i < this.objs.length; i++) {
+    var curobj = this.objs[i];
+    var badidstr = this.objs.filter(function(obj) {return obj != curobj}).map(function(obj) {return obj.id;}).join('#');
+    this.make_tab(
+      svg,
+      parent,
+      this.x_width,
+      this.headroom,
+      running_count,
+      0,
+      curobj.id,
+      badidstr,
+      this.fill_off,
+      i==0);
+    this.make_label(
+      svg,
+      parent,
+      running_count + this.x_width / 2.0,
+      this.headroom / 2.0 + this.baseline_skip,
+      // a bit of a hack...
+      curobj.label,
+      curobj.id,
+      badidstr);
+    running_count += this.x_width + this.x_padding;
+  }
+
+  return g;
+}
+
+_f4u$t.TabGroup.prototype.make = function(svg, parent) {
+  var g = this.make_group(svg, parent, this.id);
+
+  this.make_tabs(svg, g);
+  for (var i = 0; i < this.objs.length; i++) {
+    this.objs[i].make(svg, g);
+  }
+  // call initiate_tab_group after objects are created
+  _f4u$t.initiate_tab_group(this.init, this.objs.map(function(obj) {return obj.id;}).join('#'));
+
+  return g;
+}
+
+// rather than extending the jQuery svg object, we just create a wrapper around it
+_f4u$t.SVG = function(svg, w, h, options) {
+  this.svg = svg;
+  this.w = w;
+  this.h = h;
+  this.lm = _f4u$t.initifnull(options.lm, null);
+  this.title = _f4u$t.initifnull(options.title, '');
+  this.lm.mom = this;
+}
+
+_f4u$t.extend(_f4u$t.UIObject, _f4u$t.SVG);
+
+_f4u$t.SVG.prototype.get_x_offset = function() {
+  return 0;
+}
+
+_f4u$t.SVG.prototype.get_y_offset = function() {
+  return 0;
+}
+
+_f4u$t.SVG.prototype.defs = function() {
+  for (var gradient in _f4u$t.linear_gradient_inits) {
+    _f4u$t.make_linear_gradient(
+      this.svg,
+      gradient,
+      _f4u$t.linear_gradient_inits[gradient]['stops'],
+      _f4u$t.linear_gradient_inits[gradient]['x1'],
+      _f4u$t.linear_gradient_inits[gradient]['y1'],
+      _f4u$t.linear_gradient_inits[gradient]['x2'],
+      _f4u$t.linear_gradient_inits[gradient]['y2'],
+      _f4u$t.linear_gradient_inits[gradient]['settings']
+    );
+  }
+
+  for (var gradient in _f4u$t.radial_gradient_inits) {
+    _f4u$t.make_radial_gradient(
+      this.svg,
+      gradient,
+      _f4u$t.radial_gradient_inits[gradient]['stops'],
+      _f4u$t.radial_gradient_inits[gradient]['cx'],
+      _f4u$t.radial_gradient_inits[gradient]['cy'],
+      _f4u$t.radial_gradient_inits[gradient]['r'],
+      _f4u$t.radial_gradient_inits[gradient]['fx'],
+      _f4u$t.radial_gradient_inits[gradient]['fy'],
+      _f4u$t.radial_gradient_inits[gradient]['settings']
+    );
+  }
+}
+
+_f4u$t.SVG.prototype.make = function() {
+  _f4u$t.configure_svg(
+    this.svg,
+    {
+      width : this.w+'px',
+      height : this.h+'px'
+    },
+    true);
+  _f4u$t.ROOT = this.title;
+  this.svg._delayed_tooltip_list = [];
+  this.lm.populate_objects();
+  this.lm.do_spacing(0);
+  this.lm.make(this.svg, this.svg);
+  this.tooltip_group = _f4u$t.make_g(this.svg, this.svg,'faust_tooltip_group');
+  this.make_delayed_tooltips(this.svg);
+  // if there is no constrain, the viewport needs to be scaled
+  var viewport_dims = this.lm.dims();
+  _f4u$t.configure_svg(
+    this.svg,
+    {
+      viewBox: '0 0 '+viewport_dims[0]+' '+viewport_dims[1],
+      width : this.w+'px',
+      height: this.h+'px',
+    },
+    true);
+
+  _f4u$t.VIEWPORT_SCALE = Math.min(this.w/viewport_dims[0], this.h/viewport_dims[1]);
+}
diff --git a/architecture/httpdlib/html/js/svg/jquery-1.7.1.min.js b/architecture/httpdlib/html/js/svg/jquery-1.7.1.min.js
new file mode 100644
index 0000000..198b3ff
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquery-1.7.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
+f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
+{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.css b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.css
new file mode 100644
index 0000000..cbec5c5
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.css
@@ -0,0 +1,15 @@
+/* http://keith-wood.name/svg.html
+   SVG for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+svg\:svg {
+	display: none;
+}
+
+.svg_error {
+	color: red;
+	font-weight: bold;
+}
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.js
new file mode 100644
index 0000000..752138d
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.js
@@ -0,0 +1,1397 @@
+/* http://keith-wood.name/svg.html
+   SVG for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+/* SVG manager.
+   Use the singleton instance of this class, $.svg,
+   to interact with the SVG functionality. */
+function SVGManager() {
+	this._settings = []; // Settings to be remembered per SVG object
+	this._extensions = []; // List of SVG extensions added to SVGWrapper
+		// for each entry [0] is extension name, [1] is extension class (function)
+		// the function takes one parameter - the SVGWrapper instance
+	this.regional = []; // Localisations, indexed by language, '' for default (English)
+	this.regional[''] = {errorLoadingText: 'Error loading',
+		notSupportedText: 'This browser does not support SVG'};
+	this.local = this.regional['']; // Current localisation
+	this._uuid = new Date().getTime();
+	this._renesis = detectActiveX('RenesisX.RenesisCtrl');
+}
+
+/* Determine whether a given ActiveX control is available.
+   @param  classId  (string) the ID for the ActiveX control
+   @return  (boolean) true if found, false if not */
+function detectActiveX(classId) {
+	try {
+		return !!(window.ActiveXObject && new ActiveXObject(classId));
+	}
+	catch (e) {
+		return false;
+	}
+}
+
+var PROP_NAME = 'svgwrapper';
+
+$.extend(SVGManager.prototype, {
+	/* Class name added to elements to indicate already configured with SVG. */
+	markerClassName: 'hasSVG',
+
+	/* SVG namespace. */
+	svgNS: 'http://www.w3.org/2000/svg',
+	/* XLink namespace. */
+	xlinkNS: 'http://www.w3.org/1999/xlink',
+
+	/* SVG wrapper class. */
+	_wrapperClass: SVGWrapper,
+
+	/* Camel-case versions of attribute names containing dashes or are reserved words. */
+	_attrNames: {class_: 'class', in_: 'in',
+		alignmentBaseline: 'alignment-baseline', baselineShift: 'baseline-shift',
+		clipPath: 'clip-path', clipRule: 'clip-rule',
+		colorInterpolation: 'color-interpolation',
+		colorInterpolationFilters: 'color-interpolation-filters',
+		colorRendering: 'color-rendering', dominantBaseline: 'dominant-baseline',
+		enableBackground: 'enable-background', fillOpacity: 'fill-opacity',
+		fillRule: 'fill-rule', floodColor: 'flood-color',
+		floodOpacity: 'flood-opacity', fontFamily: 'font-family',
+		fontSize: 'font-size', fontSizeAdjust: 'font-size-adjust',
+		fontStretch: 'font-stretch', fontStyle: 'font-style',
+		fontVariant: 'font-variant', fontWeight: 'font-weight',
+		glyphOrientationHorizontal: 'glyph-orientation-horizontal',
+		glyphOrientationVertical: 'glyph-orientation-vertical',
+		horizAdvX: 'horiz-adv-x', horizOriginX: 'horiz-origin-x',
+		imageRendering: 'image-rendering', letterSpacing: 'letter-spacing',
+		lightingColor: 'lighting-color', markerEnd: 'marker-end',
+		markerMid: 'marker-mid', markerStart: 'marker-start',
+		stopColor: 'stop-color', stopOpacity: 'stop-opacity',
+		strikethroughPosition: 'strikethrough-position',
+		strikethroughThickness: 'strikethrough-thickness',
+		strokeDashArray: 'stroke-dasharray', strokeDashOffset: 'stroke-dashoffset',
+		strokeLineCap: 'stroke-linecap', strokeLineJoin: 'stroke-linejoin',
+		strokeMiterLimit: 'stroke-miterlimit', strokeOpacity: 'stroke-opacity',
+		strokeWidth: 'stroke-width', textAnchor: 'text-anchor',
+		textDecoration: 'text-decoration', textRendering: 'text-rendering',
+		underlinePosition: 'underline-position', underlineThickness: 'underline-thickness',
+		vertAdvY: 'vert-adv-y', vertOriginY: 'vert-origin-y',
+		wordSpacing: 'word-spacing', writingMode: 'writing-mode'},
+
+	/* Add the SVG object to its container. */
+	_attachSVG: function(container, settings) {
+		var svg = (container.namespaceURI == this.svgNS ? container : null);
+		var container = (svg ? null : container);
+		if ($(container || svg).hasClass(this.markerClassName)) {
+			return;
+		}
+		if (typeof settings == 'string') {
+			settings = {loadURL: settings};
+		}
+		else if (typeof settings == 'function') {
+			settings = {onLoad: settings};
+		}
+		$(container || svg).addClass(this.markerClassName);
+		try {
+			if (!svg) {
+				svg = document.createElementNS(this.svgNS, 'svg');
+				svg.setAttribute('version', '1.1');
+				if (container.clientWidth > 0) {
+					svg.setAttribute('width', container.clientWidth);
+				}
+				if (container.clientHeight > 0) {
+					svg.setAttribute('height', container.clientHeight);
+				}
+				container.appendChild(svg);
+			}
+			this._afterLoad(container, svg, settings || {});
+		}
+		catch (e) {
+			if ($.browser.msie) {
+				if (!container.id) {
+					container.id = 'svg' + (this._uuid++);
+				}
+				this._settings[container.id] = settings;
+				container.innerHTML = '<embed type="image/svg+xml" width="100%" ' +
+					'height="100%" src="' + (settings.initPath || '') + 'blank.svg" ' +
+					'pluginspage="http://www.adobe.com/svg/viewer/install/main.html"/>';
+			}
+			else {
+				container.innerHTML = '<p class="svg_error">' +
+					this.local.notSupportedText + '</p>';
+			}
+		}
+	},
+
+	/* SVG callback after loading - register SVG root. */
+	_registerSVG: function() {
+		for (var i = 0; i < document.embeds.length; i++) { // Check all
+			var container = document.embeds[i].parentNode;
+			if (!$(container).hasClass($.svg.markerClassName) || // Not SVG
+					$.data(container, PROP_NAME)) { // Already done
+				continue;
+			}
+			var svg = null;
+			try {
+				svg = document.embeds[i].getSVGDocument();
+			}
+			catch(e) {
+				setTimeout($.svg._registerSVG, 250); // Renesis takes longer to load
+				return;
+			}
+			svg = (svg ? svg.documentElement : null);
+			if (svg) {
+				$.svg._afterLoad(container, svg);
+			}
+		}
+	},
+
+	/* Post-processing once loaded. */
+	_afterLoad: function(container, svg, settings) {
+		var settings = settings || this._settings[container.id];
+		this._settings[container ? container.id : ''] = null;
+		var wrapper = new this._wrapperClass(svg, container);
+		$.data(container || svg, PROP_NAME, wrapper);
+		try {
+			if (settings.loadURL) { // Load URL
+				wrapper.load(settings.loadURL, settings);
+			}
+			if (settings.settings) { // Additional settings
+				wrapper.configure(settings.settings);
+			}
+			if (settings.onLoad && !settings.loadURL) { // Onload callback
+				settings.onLoad.apply(container || svg, [wrapper]);
+			}
+		}
+		catch (e) {
+			alert(e);
+		}
+	},
+
+	/* Return the SVG wrapper created for a given container.
+	   @param  container  (string) selector for the container or
+	                      (element) the container for the SVG object or
+	                      jQuery collection - first entry is the container
+	   @return  (SVGWrapper) the corresponding SVG wrapper element, or null if not attached */
+	_getSVG: function(container) {
+		container = (typeof container == 'string' ? $(container)[0] :
+			(container.jquery ? container[0] : container));
+		return $.data(container, PROP_NAME);
+	},
+
+	/* Remove the SVG functionality from a div.
+	   @param  container  (element) the container for the SVG object */
+	_destroySVG: function(container) {
+		var $container = $(container);
+		if (!$container.hasClass(this.markerClassName)) {
+			return;
+		}
+		$container.removeClass(this.markerClassName);
+		if (container.namespaceURI != this.svgNS) {
+			$container.empty();
+		}
+		$.removeData(container, PROP_NAME);
+	},
+
+	/* Extend the SVGWrapper object with an embedded class.
+	   The constructor function must take a single parameter that is
+	   a reference to the owning SVG root object. This allows the
+	   extension to access the basic SVG functionality.
+	   @param  name      (string) the name of the SVGWrapper attribute to access the new class
+	   @param  extClass  (function) the extension class constructor */
+	addExtension: function(name, extClass) {
+		this._extensions.push([name, extClass]);
+	},
+
+	/* Does this node belong to SVG?
+	   @param  node  (element) the node to be tested
+	   @return  (boolean) true if an SVG node, false if not */
+	isSVGElem: function(node) {
+		return (node.nodeType == 1 && node.namespaceURI == $.svg.svgNS);
+	}
+});
+
+/* The main SVG interface, which encapsulates the SVG element.
+   Obtain a reference from $().svg('get') */
+function SVGWrapper(svg, container) {
+	this._svg = svg; // The SVG root node
+	this._container = container; // The containing div
+	for (var i = 0; i < $.svg._extensions.length; i++) {
+		var extension = $.svg._extensions[i];
+		this[extension[0]] = new extension[1](this);
+	}
+}
+
+$.extend(SVGWrapper.prototype, {
+
+	/* Retrieve the width of the SVG object. */
+	_width: function() {
+		return (this._container ? this._container.clientWidth : this._svg.width);
+	},
+
+	/* Retrieve the height of the SVG object. */
+	_height: function() {
+		return (this._container ? this._container.clientHeight : this._svg.height);
+	},
+
+	/* Retrieve the root SVG element.
+	   @return  the top-level SVG element */
+	root: function() {
+		return this._svg;
+	},
+
+	/* Configure a SVG node.
+	   @param  node      (element, optional) the node to configure
+	   @param  settings  (object) additional settings for the root
+	   @param  clear     (boolean) true to remove existing attributes first,
+	                     false to add to what is already there (optional)
+	   @return  (SVGWrapper) this root */
+	configure: function(node, settings, clear) {
+		if (!node.nodeName) {
+			clear = settings;
+			settings = node;
+			node = this._svg;
+		}
+		if (clear) {
+			for (var i = node.attributes.length - 1; i >= 0; i--) {
+				var attr = node.attributes.item(i);
+				if (!(attr.nodeName == 'onload' || attr.nodeName == 'version' ||
+						attr.nodeName.substring(0, 5) == 'xmlns')) {
+					node.attributes.removeNamedItem(attr.nodeName);
+				}
+			}
+		}
+		for (var attrName in settings) {
+			node.setAttribute($.svg._attrNames[attrName] || attrName, settings[attrName]);
+		}
+		return this;
+	},
+
+	/* Locate a specific element in the SVG document.
+	   @param  id  (string) the element's identifier
+	   @return  (element) the element reference, or null if not found */
+	getElementById: function(id) {
+		return this._svg.ownerDocument.getElementById(id);
+	},
+
+	/* Change the attributes for a SVG node.
+	   @param  element   (SVG element) the node to change
+	   @param  settings  (object) the new settings
+	   @return  (SVGWrapper) this root */
+	change: function(element, settings) {
+		if (element) {
+			for (var name in settings) {
+				if (settings[name] == null) {
+					element.removeAttribute($.svg._attrNames[name] || name);
+				}
+				else {
+					element.setAttribute($.svg._attrNames[name] || name, settings[name]);
+				}
+			}
+		}
+		return this;
+	},
+
+	/* Check for parent being absent and adjust arguments accordingly. */
+	_args: function(values, names, optSettings) {
+		names.splice(0, 0, 'parent');
+		names.splice(names.length, 0, 'settings');
+		var args = {};
+		var offset = 0;
+		if (values[0] != null && values[0].jquery) {
+			values[0] = values[0][0];
+		}
+		if (values[0] != null && !(typeof values[0] == 'object' && values[0].nodeName)) {
+			args['parent'] = null;
+			offset = 1;
+		}
+		for (var i = 0; i < values.length; i++) {
+			args[names[i + offset]] = values[i];
+		}
+		if (optSettings) {
+			$.each(optSettings, function(i, value) {
+				if (typeof args[value] == 'object') {
+					args.settings = args[value];
+					args[value] = null;
+				}
+			});
+		}
+		return args;
+	},
+
+	/* Add a title.
+	   @param  parent    (element or jQuery) the parent node for the new title (optional)
+	   @param  text      (string) the text of the title
+	   @param  settings  (object) additional settings for the title (optional)
+	   @return  (element) the new title node */
+        /*
+        //COMMENTED OUT BY Mike Solomon
+        //this creates unwanted tooltip behavior
+	title: function(parent, text, settings) {
+		var args = this._args(arguments, ['text']);
+		var node = this._makeNode(args.parent, 'title', args.settings || {});
+		node.appendChild(this._svg.ownerDocument.createTextNode(args.text));
+		return node;
+	},
+        */
+	/* Add a description.
+	   @param  parent    (element or jQuery) the parent node for the new description (optional)
+	   @param  text      (string) the text of the description
+	   @param  settings  (object) additional settings for the description (optional)
+	   @return  (element) the new description node */
+	describe: function(parent, text, settings) {
+		var args = this._args(arguments, ['text']);
+		var node = this._makeNode(args.parent, 'desc', args.settings || {});
+		node.appendChild(this._svg.ownerDocument.createTextNode(args.text));
+		return node;
+	},
+
+	/* Add a definitions node.
+	   @param  parent    (element or jQuery) the parent node for the new definitions (optional)
+	   @param  id        (string) the ID of this definitions (optional)
+	   @param  settings  (object) additional settings for the definitions (optional)
+	   @return  (element) the new definitions node */
+	defs: function(parent, id, settings) {
+		var args = this._args(arguments, ['id'], ['id']);
+		return this._makeNode(args.parent, 'defs', $.extend(
+			(args.id ? {id: args.id} : {}), args.settings || {}));
+	},
+
+	/* Add a symbol definition.
+	   @param  parent    (element or jQuery) the parent node for the new symbol (optional)
+	   @param  id        (string) the ID of this symbol
+	   @param  x1        (number) the left coordinate for this symbol
+	   @param  y1        (number) the top coordinate for this symbol
+	   @param  width     (number) the width of this symbol
+	   @param  height    (number) the height of this symbol
+	   @param  settings  (object) additional settings for the symbol (optional)
+	   @return  (element) the new symbol node */
+	symbol: function(parent, id, x1, y1, width, height, settings) {
+		var args = this._args(arguments, ['id', 'x1', 'y1', 'width', 'height']);
+		return this._makeNode(args.parent, 'symbol', $.extend({id: args.id,
+			viewBox: args.x1 + ' ' + args.y1 + ' ' + args.width + ' ' + args.height},
+			args.settings || {}));
+	},
+
+	/* Add a marker definition.
+	   @param  parent    (element or jQuery) the parent node for the new marker (optional)
+	   @param  id        (string) the ID of this marker
+	   @param  refX      (number) the x-coordinate for the reference point
+	   @param  refY      (number) the y-coordinate for the reference point
+	   @param  mWidth    (number) the marker viewport width
+	   @param  mHeight   (number) the marker viewport height
+	   @param  orient    (string or int) 'auto' or angle (degrees) (optional)
+	   @param  settings  (object) additional settings for the marker (optional)
+	   @return  (element) the new marker node */
+	marker: function(parent, id, refX, refY, mWidth, mHeight, orient, settings) {
+		var args = this._args(arguments, ['id', 'refX', 'refY',
+			'mWidth', 'mHeight', 'orient'], ['orient']);
+		return this._makeNode(args.parent, 'marker', $.extend(
+			{id: args.id, refX: args.refX, refY: args.refY, markerWidth: args.mWidth,
+			markerHeight: args.mHeight, orient: args.orient || 'auto'}, args.settings || {}));
+	},
+
+	/* Add a style node.
+	   @param  parent    (element or jQuery) the parent node for the new node (optional)
+	   @param  styles    (string) the CSS styles
+	   @param  settings  (object) additional settings for the node (optional)
+	   @return  (element) the new style node */
+	style: function(parent, styles, settings) {
+		var args = this._args(arguments, ['styles']);
+		var node = this._makeNode(args.parent, 'style', $.extend(
+			{type: 'text/css'}, args.settings || {}));
+		node.appendChild(this._svg.ownerDocument.createTextNode(args.styles));
+		if ($.browser.opera) {
+			$('head').append('<style type="text/css">' + args.styles + '</style>');
+		}
+		return node;
+	},
+
+	/* Add a script node.
+	   @param  parent    (element or jQuery) the parent node for the new node (optional)
+	   @param  script    (string) the JavaScript code
+	   @param  type      (string) the MIME type for the code (optional, default 'text/javascript')
+	   @param  settings  (object) additional settings for the node (optional)
+	   @return  (element) the new script node */
+	script: function(parent, script, type, settings) {
+		var args = this._args(arguments, ['script', 'type'], ['type']);
+		var node = this._makeNode(args.parent, 'script', $.extend(
+			{type: args.type || 'text/javascript'}, args.settings || {}));
+		node.appendChild(this._svg.ownerDocument.createTextNode(args.script));
+		if (!$.browser.mozilla) {
+			$.globalEval(args.script);
+		}
+		return node;
+	},
+
+	/* Add a linear gradient definition.
+	   Specify all of x1, y1, x2, y2 or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new gradient (optional)
+	   @param  id        (string) the ID for this gradient
+	   @param  stops     (string[][]) the gradient stops, each entry is
+	                     [0] is offset (0.0-1.0 or 0%-100%), [1] is colour,
+						 [2] is opacity (optional)
+	   @param  x1        (number) the x-coordinate of the gradient start (optional)
+	   @param  y1        (number) the y-coordinate of the gradient start (optional)
+	   @param  x2        (number) the x-coordinate of the gradient end (optional)
+	   @param  y2        (number) the y-coordinate of the gradient end (optional)
+	   @param  settings  (object) additional settings for the gradient (optional)
+	   @return  (element) the new gradient node */
+	linearGradient: function(parent, id, stops, x1, y1, x2, y2, settings) {
+		var args = this._args(arguments,
+			['id', 'stops', 'x1', 'y1', 'x2', 'y2'], ['x1']);
+		var sets = $.extend({id: args.id},
+			(args.x1 != null ? {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2} : {}));
+		return this._gradient(args.parent, 'linearGradient',
+			$.extend(sets, args.settings || {}), args.stops);
+	},
+
+	/* Add a radial gradient definition.
+	   Specify all of cx, cy, r, fx, fy or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new gradient (optional)
+	   @param  id        (string) the ID for this gradient
+	   @param  stops     (string[][]) the gradient stops, each entry
+	                     [0] is offset, [1] is colour, [2] is opacity (optional)
+	   @param  cx        (number) the x-coordinate of the largest circle centre (optional)
+	   @param  cy        (number) the y-coordinate of the largest circle centre (optional)
+	   @param  r         (number) the radius of the largest circle (optional)
+	   @param  fx        (number) the x-coordinate of the gradient focus (optional)
+	   @param  fy        (number) the y-coordinate of the gradient focus (optional)
+	   @param  settings  (object) additional settings for the gradient (optional)
+	   @return  (element) the new gradient node */
+	radialGradient: function(parent, id, stops, cx, cy, r, fx, fy, settings) {
+		var args = this._args(arguments,
+			['id', 'stops', 'cx', 'cy', 'r', 'fx', 'fy'], ['cx']);
+		var sets = $.extend({id: args.id}, (args.cx != null ?
+			{cx: args.cx, cy: args.cy, r: args.r, fx: args.fx, fy: args.fy} : {}));
+		return this._gradient(args.parent, 'radialGradient',
+			$.extend(sets, args.settings || {}), args.stops);
+	},
+
+	/* Add a gradient node. */
+	_gradient: function(parent, name, settings, stops) {
+		var node = this._makeNode(parent, name, settings);
+		for (var i = 0; i < stops.length; i++) {
+			var stop = stops[i];
+			this._makeNode(node, 'stop', $.extend(
+				{offset: stop[0], stopColor: stop[1]},
+				(stop[2] != null ? {stopOpacity: stop[2]} : {})));
+		}
+		return node;
+	},
+
+	/* Add a pattern definition.
+	   Specify all of vx, vy, xwidth, vheight or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new pattern (optional)
+	   @param  id        (string) the ID for this pattern
+	   @param  x         (number) the x-coordinate for the left edge of the pattern
+	   @param  y         (number) the y-coordinate for the top edge of the pattern
+	   @param  width     (number) the width of the pattern
+	   @param  height    (number) the height of the pattern
+	   @param  vx        (number) the minimum x-coordinate for view box (optional)
+	   @param  vy        (number) the minimum y-coordinate for the view box (optional)
+	   @param  vwidth    (number) the width of the view box (optional)
+	   @param  vheight   (number) the height of the view box (optional)
+	   @param  settings  (object) additional settings for the pattern (optional)
+	   @return  (element) the new pattern node */
+	pattern: function(parent, id, x, y, width, height, vx, vy, vwidth, vheight, settings) {
+		var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height',
+			'vx', 'vy', 'vwidth', 'vheight'], ['vx']);
+		var sets = $.extend({id: args.id, x: args.x, y: args.y,
+			width: args.width, height: args.height}, (args.vx != null ?
+			{viewBox: args.vx + ' ' + args.vy + ' ' + args.vwidth + ' ' + args.vheight} : {}));
+		return this._makeNode(args.parent, 'pattern', $.extend(sets, args.settings || {}));
+	},
+
+	/* Add a clip path definition.
+	   @param  parent  (element) the parent node for the new element (optional)
+	   @param  id      (string) the ID for this path
+	   @param  units   (string) either 'userSpaceOnUse' (default) or 'objectBoundingBox' (optional)
+	   @return  (element) the new clipPath node */
+	clipPath: function(parent, id, units, settings) {
+		var args = this._args(arguments, ['id', 'units']);
+		args.units = args.units || 'userSpaceOnUse';
+		return this._makeNode(args.parent, 'clipPath', $.extend(
+			{id: args.id, clipPathUnits: args.units}, args.settings || {}));
+	},
+
+	/* Add a mask definition.
+	   @param  parent    (element or jQuery) the parent node for the new mask (optional)
+	   @param  id        (string) the ID for this mask
+	   @param  x         (number) the x-coordinate for the left edge of the mask
+	   @param  y         (number) the y-coordinate for the top edge of the mask
+	   @param  width     (number) the width of the mask
+	   @param  height    (number) the height of the mask
+	   @param  settings  (object) additional settings for the mask (optional)
+	   @return  (element) the new mask node */
+	mask: function(parent, id, x, y, width, height, settings) {
+		var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
+		return this._makeNode(args.parent, 'mask', $.extend(
+			{id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
+			args.settings || {}));
+	},
+
+	/* Create a new path object.
+	   @return  (SVGPath) a new path object */
+	createPath: function() {
+		return new SVGPath();
+	},
+
+	/* Create a new text object.
+	   @return  (SVGText) a new text object */
+	createText: function() {
+		return new SVGText();
+	},
+
+	/* Add an embedded SVG element.
+	   Specify all of vx, vy, vwidth, vheight or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new node (optional)
+	   @param  x         (number) the x-coordinate for the left edge of the node
+	   @param  y         (number) the y-coordinate for the top edge of the node
+	   @param  width     (number) the width of the node
+	   @param  height    (number) the height of the node
+	   @param  vx        (number) the minimum x-coordinate for view box (optional)
+	   @param  vy        (number) the minimum y-coordinate for the view box (optional)
+	   @param  vwidth    (number) the width of the view box (optional)
+	   @param  vheight   (number) the height of the view box (optional)
+	   @param  settings  (object) additional settings for the node (optional)
+	   @return  (element) the new node */
+	svg: function(parent, x, y, width, height, vx, vy, vwidth, vheight, settings) {
+		var args = this._args(arguments, ['x', 'y', 'width', 'height',
+			'vx', 'vy', 'vwidth', 'vheight'], ['vx']);
+		var sets = $.extend({x: args.x, y: args.y, width: args.width, height: args.height},
+			(args.vx != null ? {viewBox: args.vx + ' ' + args.vy + ' ' +
+			args.vwidth + ' ' + args.vheight} : {}));
+		return this._makeNode(args.parent, 'svg', $.extend(sets, args.settings || {}));
+	},
+
+	/* Create a group.
+	   @param  parent    (element or jQuery) the parent node for the new group (optional)
+	   @param  id        (string) the ID of this group (optional)
+	   @param  settings  (object) additional settings for the group (optional)
+	   @return  (element) the new group node */
+	group: function(parent, id, settings) {
+		var args = this._args(arguments, ['id'], ['id']);
+		return this._makeNode(args.parent, 'g', $.extend({id: args.id}, args.settings || {}));
+	},
+
+	/* Add a usage reference.
+	   Specify all of x, y, width, height or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new node (optional)
+	   @param  x         (number) the x-coordinate for the left edge of the node (optional)
+	   @param  y         (number) the y-coordinate for the top edge of the node (optional)
+	   @param  width     (number) the width of the node (optional)
+	   @param  height    (number) the height of the node (optional)
+	   @param  ref       (string) the ID of the definition node
+	   @param  settings  (object) additional settings for the node (optional)
+	   @return  (element) the new node */
+	use: function(parent, x, y, width, height, ref, settings) {
+		var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']);
+		if (typeof args.x == 'string') {
+			args.ref = args.x;
+			args.settings = args.y;
+			args.x = args.y = args.width = args.height = null;
+		}
+		var node = this._makeNode(args.parent, 'use', $.extend(
+			{x: args.x, y: args.y, width: args.width, height: args.height},
+			args.settings || {}));
+		node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+		return node;
+	},
+
+	/* Add a link, which applies to all child elements.
+	   @param  parent    (element or jQuery) the parent node for the new link (optional)
+	   @param  ref       (string) the target URL
+	   @param  settings  (object) additional settings for the link (optional)
+	   @return  (element) the new link node */
+	link: function(parent, ref, settings) {
+		var args = this._args(arguments, ['ref']);
+		var node = this._makeNode(args.parent, 'a', args.settings);
+		node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+		return node;
+	},
+
+	/* Add an image.
+	   @param  parent    (element or jQuery) the parent node for the new image (optional)
+	   @param  x         (number) the x-coordinate for the left edge of the image
+	   @param  y         (number) the y-coordinate for the top edge of the image
+	   @param  width     (number) the width of the image
+	   @param  height    (number) the height of the image
+	   @param  ref       (string) the path to the image
+	   @param  settings  (object) additional settings for the image (optional)
+	   @return  (element) the new image node */
+	image: function(parent, x, y, width, height, ref, settings) {
+		var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']);
+		var node = this._makeNode(args.parent, 'image', $.extend(
+			{x: args.x, y: args.y, width: args.width, height: args.height},
+			args.settings || {}));
+		node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+		return node;
+	},
+
+	/* Draw a path.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  path      (string or SVGPath) the path to draw
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	path: function(parent, path, settings) {
+		var args = this._args(arguments, ['path']);
+		return this._makeNode(args.parent, 'path', $.extend(
+			{d: (args.path.path ? args.path.path() : args.path)}, args.settings || {}));
+	},
+
+	/* Draw a rectangle.
+	   Specify both of rx and ry or neither.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  x         (number) the x-coordinate for the left edge of the rectangle
+	   @param  y         (number) the y-coordinate for the top edge of the rectangle
+	   @param  width     (number) the width of the rectangle
+	   @param  height    (number) the height of the rectangle
+	   @param  rx        (number) the x-radius of the ellipse for the rounded corners (optional)
+	   @param  ry        (number) the y-radius of the ellipse for the rounded corners (optional)
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	rect: function(parent, x, y, width, height, rx, ry, settings) {
+		var args = this._args(arguments, ['x', 'y', 'width', 'height', 'rx', 'ry'], ['rx']);
+		return this._makeNode(args.parent, 'rect', $.extend(
+			{x: args.x, y: args.y, width: args.width, height: args.height},
+			(args.rx ? {rx: args.rx, ry: args.ry} : {}), args.settings || {}));
+	},
+
+	/* Draw a circle.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  cx        (number) the x-coordinate for the centre of the circle
+	   @param  cy        (number) the y-coordinate for the centre of the circle
+	   @param  r         (number) the radius of the circle
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	circle: function(parent, cx, cy, r, settings) {
+		var args = this._args(arguments, ['cx', 'cy', 'r']);
+		return this._makeNode(args.parent, 'circle', $.extend(
+			{cx: args.cx, cy: args.cy, r: args.r}, args.settings || {}));
+	},
+
+	/* Draw an ellipse.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  cx        (number) the x-coordinate for the centre of the ellipse
+	   @param  cy        (number) the y-coordinate for the centre of the ellipse
+	   @param  rx        (number) the x-radius of the ellipse
+	   @param  ry        (number) the y-radius of the ellipse
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	ellipse: function(parent, cx, cy, rx, ry, settings) {
+		var args = this._args(arguments, ['cx', 'cy', 'rx', 'ry']);
+		return this._makeNode(args.parent, 'ellipse', $.extend(
+			{cx: args.cx, cy: args.cy, rx: args.rx, ry: args.ry}, args.settings || {}));
+	},
+
+	/* Draw a line.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  x1        (number) the x-coordinate for the start of the line
+	   @param  y1        (number) the y-coordinate for the start of the line
+	   @param  x2        (number) the x-coordinate for the end of the line
+	   @param  y2        (number) the y-coordinate for the end of the line
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	line: function(parent, x1, y1, x2, y2, settings) {
+		var args = this._args(arguments, ['x1', 'y1', 'x2', 'y2']);
+		return this._makeNode(args.parent, 'line', $.extend(
+			{x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2}, args.settings || {}));
+	},
+
+	/* Draw a polygonal line.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  points    (number[][]) the x-/y-coordinates for the points on the line
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	polyline: function(parent, points, settings) {
+		var args = this._args(arguments, ['points']);
+		return this._poly(args.parent, 'polyline', args.points, args.settings);
+	},
+
+	/* Draw a polygonal shape.
+	   @param  parent    (element or jQuery) the parent node for the new shape (optional)
+	   @param  points    (number[][]) the x-/y-coordinates for the points on the shape
+	   @param  settings  (object) additional settings for the shape (optional)
+	   @return  (element) the new shape node */
+	polygon: function(parent, points, settings) {
+		var args = this._args(arguments, ['points']);
+		return this._poly(args.parent, 'polygon', args.points, args.settings);
+	},
+
+	/* Draw a polygonal line or shape. */
+	_poly: function(parent, name, points, settings) {
+		var ps = '';
+		for (var i = 0; i < points.length; i++) {
+			ps += points[i].join() + ' ';
+		}
+		return this._makeNode(parent, name, $.extend(
+			{points: $.trim(ps)}, settings || {}));
+	},
+
+	/* Draw text.
+	   Specify both of x and y or neither of them.
+	   @param  parent    (element or jQuery) the parent node for the text (optional)
+	   @param  x         (number or number[]) the x-coordinate(s) for the text (optional)
+	   @param  y         (number or number[]) the y-coordinate(s) for the text (optional)
+	   @param  value     (string) the text content or
+	                     (SVGText) text with spans and references
+	   @param  settings  (object) additional settings for the text (optional)
+	   @return  (element) the new text node */
+	text: function(parent, x, y, value, settings) {
+		var args = this._args(arguments, ['x', 'y', 'value']);
+		if (typeof args.x == 'string' && arguments.length < 4) {
+			args.value = args.x;
+			args.settings = args.y;
+			args.x = args.y = null;
+		}
+		return this._text(args.parent, 'text', args.value, $.extend(
+			{x: (args.x && isArray(args.x) ? args.x.join(' ') : args.x),
+			y: (args.y && isArray(args.y) ? args.y.join(' ') : args.y)},
+			args.settings || {}));
+	},
+
+	/* Draw text along a path.
+	   @param  parent    (element or jQuery) the parent node for the text (optional)
+	   @param  path      (string) the ID of the path
+	   @param  value     (string) the text content or
+	                     (SVGText) text with spans and references
+	   @param  settings  (object) additional settings for the text (optional)
+	   @return  (element) the new text node */
+	textpath: function(parent, path, value, settings) {
+		var args = this._args(arguments, ['path', 'value']);
+		var node = this._text(args.parent, 'textPath', args.value, args.settings || {});
+		node.setAttributeNS($.svg.xlinkNS, 'href', args.path);
+		return node;
+	},
+
+	/* Draw text. */
+	_text: function(parent, name, value, settings) {
+		var node = this._makeNode(parent, name, settings);
+		if (typeof value == 'string') {
+			node.appendChild(node.ownerDocument.createTextNode(value));
+		}
+		else {
+			for (var i = 0; i < value._parts.length; i++) {
+				var part = value._parts[i];
+				if (part[0] == 'tspan') {
+					var child = this._makeNode(node, part[0], part[2]);
+					child.appendChild(node.ownerDocument.createTextNode(part[1]));
+					node.appendChild(child);
+				}
+				else if (part[0] == 'tref') {
+					var child = this._makeNode(node, part[0], part[2]);
+					child.setAttributeNS($.svg.xlinkNS, 'href', part[1]);
+					node.appendChild(child);
+				}
+				else if (part[0] == 'textpath') {
+					var set = $.extend({}, part[2]);
+					set.href = null;
+					var child = this._makeNode(node, part[0], set);
+					child.setAttributeNS($.svg.xlinkNS, 'href', part[2].href);
+					child.appendChild(node.ownerDocument.createTextNode(part[1]));
+					node.appendChild(child);
+				}
+				else { // straight text
+					node.appendChild(node.ownerDocument.createTextNode(part[1]));
+				}
+			}
+		}
+		return node;
+	},
+
+	/* Add a custom SVG element.
+	   @param  parent    (element or jQuery) the parent node for the new element (optional)
+	   @param  name      (string) the name of the element
+	   @param  settings  (object) additional settings for the element (optional)
+	   @return  (element) the new custom node */
+	other: function(parent, name, settings) {
+		var args = this._args(arguments, ['name']);
+		return this._makeNode(args.parent, args.name, args.settings || {});
+	},
+
+	/* Create a shape node with the given settings. */
+	_makeNode: function(parent, name, settings) {
+		parent = parent || this._svg;
+		var node = this._svg.ownerDocument.createElementNS($.svg.svgNS, name);
+		for (var name in settings) {
+			var value = settings[name];
+			if (value != null && value != null &&
+					(typeof value != 'string' || value != '')) {
+				node.setAttribute($.svg._attrNames[name] || name, value);
+			}
+		}
+		parent.appendChild(node);
+		return node;
+	},
+
+	/* Add an existing SVG node to the diagram.
+	   @param  parent  (element or jQuery) the parent node for the new node (optional)
+	   @param  node    (element) the new node to add or
+	                   (string) the jQuery selector for the node or
+	                   (jQuery collection) set of nodes to add
+	   @return  (SVGWrapper) this wrapper */
+	add: function(parent, node) {
+		var args = this._args((arguments.length == 1 ? [null, parent] : arguments), ['node']);
+		var svg = this;
+		args.parent = args.parent || this._svg;
+		args.node = (args.node.jquery ? args.node : $(args.node));
+		try {
+			if ($.svg._renesis) {
+				throw 'Force traversal';
+			}
+			args.parent.appendChild(args.node.cloneNode(true));
+		}
+		catch (e) {
+			args.node.each(function() {
+				var child = svg._cloneAsSVG(this);
+				if (child) {
+					args.parent.appendChild(child);
+				}
+			});
+		}
+		return this;
+	},
+
+	/* Clone an existing SVG node and add it to the diagram.
+	   @param  parent  (element or jQuery) the parent node for the new node (optional)
+	   @param  node    (element) the new node to add or
+	                   (string) the jQuery selector for the node or
+	                   (jQuery collection) set of nodes to add
+	   @return  (element[]) collection of new nodes */
+	clone: function(parent, node) {
+		var svg = this;
+		var args = this._args((arguments.length == 1 ? [null, parent] : arguments), ['node']);
+		args.parent = args.parent || this._svg;
+		args.node = (args.node.jquery ? args.node : $(args.node));
+		var newNodes = [];
+		args.node.each(function() {
+			var child = svg._cloneAsSVG(this);
+			if (child) {
+				child.id = '';
+				args.parent.appendChild(child);
+				newNodes.push(child);
+			}
+		});
+		return newNodes;
+	},
+
+	/* SVG nodes must belong to the SVG namespace, so clone and ensure this is so.
+	   @param  node  (element) the SVG node to clone
+	   @return  (element) the cloned node */
+	_cloneAsSVG: function(node) {
+		var newNode = null;
+		if (node.nodeType == 1) { // element
+			newNode = this._svg.ownerDocument.createElementNS(
+				$.svg.svgNS, this._checkName(node.nodeName));
+			for (var i = 0; i < node.attributes.length; i++) {
+				var attr = node.attributes.item(i);
+				if (attr.nodeName != 'xmlns' && attr.nodeValue) {
+					if (attr.prefix == 'xlink') {
+						newNode.setAttributeNS($.svg.xlinkNS,
+							attr.localName || attr.baseName, attr.nodeValue);
+					}
+					else {
+						newNode.setAttribute(this._checkName(attr.nodeName), attr.nodeValue);
+					}
+				}
+			}
+			for (var i = 0; i < node.childNodes.length; i++) {
+				var child = this._cloneAsSVG(node.childNodes[i]);
+				if (child) {
+					newNode.appendChild(child);
+				}
+			}
+		}
+		else if (node.nodeType == 3) { // text
+			if ($.trim(node.nodeValue)) {
+				newNode = this._svg.ownerDocument.createTextNode(node.nodeValue);
+			}
+		}
+		else if (node.nodeType == 4) { // CDATA
+			if ($.trim(node.nodeValue)) {
+				try {
+					newNode = this._svg.ownerDocument.createCDATASection(node.nodeValue);
+				}
+				catch (e) {
+					newNode = this._svg.ownerDocument.createTextNode(
+						node.nodeValue.replace(/&/g, '&').
+						replace(/</g, '<').replace(/>/g, '>'));
+				}
+			}
+		}
+		return newNode;
+	},
+
+	/* Node names must be lower case and without SVG namespace prefix. */
+	_checkName: function(name) {
+		name = (name.substring(0, 1) >= 'A' && name.substring(0, 1) <= 'Z' ?
+			name.toLowerCase() : name);
+		return (name.substring(0, 4) == 'svg:' ? name.substring(4) : name);
+	},
+
+	/* Load an external SVG document.
+	   @param  url       (string) the location of the SVG document or
+	                     the actual SVG content
+	   @param  settings  (boolean) see addTo below or
+	                     (function) see onLoad below or
+	                     (object) additional settings for the load with attributes below:
+	                       addTo       (boolean) true to add to what's already there,
+	                                   or false to clear the canvas first
+						   changeSize  (boolean) true to allow the canvas size to change,
+	                                   or false to retain the original
+	                       onLoad      (function) callback after the document has loaded,
+	                                   'this' is the container, receives SVG object and
+	                                   optional error message as a parameter
+	                       parent      (string or element or jQuery) the parent to load
+	                                   into, defaults to top-level svg element
+	   @return  (SVGWrapper) this root */
+	load: function(url, settings) {
+		settings = (typeof settings == 'boolean' ? {addTo: settings} :
+			(typeof settings == 'function' ? {onLoad: settings} :
+			(typeof settings == 'string' ? {parent: settings} :
+			(typeof settings == 'object' && settings.nodeName ? {parent: settings} :
+			(typeof settings == 'object' && settings.jquery ? {parent: settings} :
+			settings || {})))));
+		if (!settings.parent && !settings.addTo) {
+			this.clear(false);
+		}
+		var size = [this._svg.getAttribute('width'), this._svg.getAttribute('height')];
+		var wrapper = this;
+		// Report a problem with the load
+		var reportError = function(message) {
+			message = $.svg.local.errorLoadingText + ': ' + message;
+			if (settings.onLoad) {
+				settings.onLoad.apply(wrapper._container || wrapper._svg, [wrapper, message]);
+			}
+			else {
+				wrapper.text(null, 10, 20, message);
+			}
+		};
+		// Create a DOM from SVG content
+		var loadXML4IE = function(data) {
+			var xml = new ActiveXObject('Microsoft.XMLDOM');
+			xml.validateOnParse = false;
+			xml.resolveExternals = false;
+			xml.async = false;
+			xml.loadXML(data);
+			if (xml.parseError.errorCode != 0) {
+				reportError(xml.parseError.reason);
+				return null;
+			}
+			return xml;
+		};
+		// Load the SVG DOM
+		var loadSVG = function(data) {
+			if (!data) {
+				return;
+			}
+			if (data.documentElement.nodeName != 'svg') {
+				var errors = data.getElementsByTagName('parsererror');
+				var messages = (errors.length ? errors[0].getElementsByTagName('div') : []); // Safari
+				reportError(!errors.length ? '???' :
+					(messages.length ? messages[0] : errors[0]).firstChild.nodeValue);
+				return;
+			}
+			var parent = (settings.parent ? $(settings.parent)[0] : wrapper._svg);
+			var attrs = {};
+			for (var i = 0; i < data.documentElement.attributes.length; i++) {
+				var attr = data.documentElement.attributes.item(i);
+				if (!(attr.nodeName == 'version' || attr.nodeName.substring(0, 5) == 'xmlns')) {
+					attrs[attr.nodeName] = attr.nodeValue;
+				}
+			}
+			wrapper.configure(parent, attrs, !settings.parent);
+			var nodes = data.documentElement.childNodes;
+			for (var i = 0; i < nodes.length; i++) {
+				try {
+					if ($.svg._renesis) {
+						throw 'Force traversal';
+					}
+					parent.appendChild(wrapper._svg.ownerDocument.importNode(nodes[i], true));
+					if (nodes[i].nodeName == 'script') {
+						$.globalEval(nodes[i].textContent);
+					}
+				}
+				catch (e) {
+					wrapper.add(parent, nodes[i]);
+				}
+			}
+			if (!settings.changeSize) {
+				wrapper.configure(parent, {width: size[0], height: size[1]});
+			}
+			if (settings.onLoad) {
+				settings.onLoad.apply(wrapper._container || wrapper._svg, [wrapper]);
+			}
+		};
+		if (url.match('<svg')) { // Inline SVG
+			loadSVG($.browser.msie ? loadXML4IE(url) :
+				new DOMParser().parseFromString(url, 'text/xml'));
+		}
+		else { // Remote SVG
+			$.ajax({url: url, dataType: ($.browser.msie ? 'text' : 'xml'),
+				success: function(xml) {
+					loadSVG($.browser.msie ? loadXML4IE(xml) : xml);
+				}, error: function(http, message, exc) {
+					reportError(message + (exc ? ' ' + exc.message : ''));
+				}});
+		}
+		return this;
+	},
+
+	/* Delete a specified node.
+	   @param  node  (element or jQuery) the drawing node to remove
+	   @return  (SVGWrapper) this root */
+	remove: function(node) {
+		node = (node.jquery ? node[0] : node);
+		node.parentNode.removeChild(node);
+		return this;
+	},
+
+	/* Delete everything in the current document.
+	   @param  attrsToo  (boolean) true to clear any root attributes as well,
+	                     false to leave them (optional)
+	   @return  (SVGWrapper) this root */
+	clear: function(attrsToo) {
+		if (attrsToo) {
+			this.configure({}, true);
+		}
+		while (this._svg.firstChild) {
+			this._svg.removeChild(this._svg.firstChild);
+		}
+		return this;
+	},
+
+	/* Serialise the current diagram into an SVG text document.
+	   @param  node  (SVG element) the starting node (optional)
+	   @return  (string) the SVG as text */
+	toSVG: function(node) {
+		node = node || this._svg;
+		return (typeof XMLSerializer == 'undefined' ? this._toSVG(node) :
+			new XMLSerializer().serializeToString(node));
+	},
+
+	/* Serialise one node in the SVG hierarchy. */
+	_toSVG: function(node) {
+		var svgDoc = '';
+		if (!node) {
+			return svgDoc;
+		}
+		if (node.nodeType == 3) { // Text
+			svgDoc = node.nodeValue;
+		}
+		else if (node.nodeType == 4) { // CDATA
+			svgDoc = '<![CDATA[' + node.nodeValue + ']]>';
+		}
+		else { // Element
+			svgDoc = '<' + node.nodeName;
+			if (node.attributes) {
+				for (var i = 0; i < node.attributes.length; i++) {
+					var attr = node.attributes.item(i);
+					if (!($.trim(attr.nodeValue) == '' || attr.nodeValue.match(/^\[object/) ||
+							attr.nodeValue.match(/^function/))) {
+						svgDoc += ' ' + (attr.namespaceURI == $.svg.xlinkNS ? 'xlink:' : '') +
+							attr.nodeName + '="' + attr.nodeValue + '"';
+					}
+				}
+			}
+			if (node.firstChild) {
+				svgDoc += '>';
+				var child = node.firstChild;
+				while (child) {
+					svgDoc += this._toSVG(child);
+					child = child.nextSibling;
+				}
+				svgDoc += '</' + node.nodeName + '>';
+			}
+				else {
+				svgDoc += '/>';
+			}
+		}
+		return svgDoc;
+	}
+});
+
+/* Helper to generate an SVG path.
+   Obtain an instance from the SVGWrapper object.
+   String calls together to generate the path and use its value:
+   var path = root.createPath();
+   root.path(null, path.move(100, 100).line(300, 100).line(200, 300).close(), {fill: 'red'});
+   or
+   root.path(null, path.move(100, 100).line([[300, 100], [200, 300]]).close(), {fill: 'red'}); */
+function SVGPath() {
+	this._path = '';
+}
+
+$.extend(SVGPath.prototype, {
+	/* Prepare to create a new path.
+	   @return  (SVGPath) this path */
+	reset: function() {
+		this._path = '';
+		return this;
+	},
+
+	/* Move the pointer to a position.
+	   @param  x         (number) x-coordinate to move to or
+	                     (number[][]) x-/y-coordinates to move to
+	   @param  y         (number) y-coordinate to move to (omitted if x is array)
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	move: function(x, y, relative) {
+		relative = (isArray(x) ? y : relative);
+		return this._coords((relative ? 'm' : 'M'), x, y);
+	},
+
+	/* Draw a line to a position.
+	   @param  x         (number) x-coordinate to move to or
+	                     (number[][]) x-/y-coordinates to move to
+	   @param  y         (number) y-coordinate to move to (omitted if x is array)
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	line: function(x, y, relative) {
+		relative = (isArray(x) ? y : relative);
+		return this._coords((relative ? 'l' : 'L'), x, y);
+	},
+
+	/* Draw a horizontal line to a position.
+	   @param  x         (number) x-coordinate to draw to or
+	                     (number[]) x-coordinates to draw to
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	horiz: function(x, relative) {
+		this._path += (relative ? 'h' : 'H') + (isArray(x) ? x.join(' ') : x);
+		return this;
+	},
+
+	/* Draw a vertical line to a position.
+	   @param  y         (number) y-coordinate to draw to or
+	                     (number[]) y-coordinates to draw to
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	vert: function(y, relative) {
+		this._path += (relative ? 'v' : 'V') + (isArray(y) ? y.join(' ') : y);
+		return this;
+	},
+
+	/* Draw a cubic Bézier curve.
+	   @param  x1        (number) x-coordinate of beginning control point or
+	                     (number[][]) x-/y-coordinates of control and end points to draw to
+	   @param  y1        (number) y-coordinate of beginning control point (omitted if x1 is array)
+	   @param  x2        (number) x-coordinate of ending control point (omitted if x1 is array)
+	   @param  y2        (number) y-coordinate of ending control point (omitted if x1 is array)
+	   @param  x         (number) x-coordinate of curve end (omitted if x1 is array)
+	   @param  y         (number) y-coordinate of curve end (omitted if x1 is array)
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	curveC: function(x1, y1, x2, y2, x, y, relative) {
+		relative = (isArray(x1) ? y1 : relative);
+		return this._coords((relative ? 'c' : 'C'), x1, y1, x2, y2, x, y);
+	},
+
+	/* Continue a cubic Bézier curve.
+	   Starting control point is the reflection of the previous end control point.
+	   @param  x2        (number) x-coordinate of ending control point or
+	                     (number[][]) x-/y-coordinates of control and end points to draw to
+	   @param  y2        (number) y-coordinate of ending control point (omitted if x2 is array)
+	   @param  x         (number) x-coordinate of curve end (omitted if x2 is array)
+	   @param  y         (number) y-coordinate of curve end (omitted if x2 is array)
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	smoothC: function(x2, y2, x, y, relative) {
+		relative = (isArray(x2) ? y2 : relative);
+		return this._coords((relative ? 's' : 'S'), x2, y2, x, y);
+	},
+
+	/* Draw a quadratic Bézier curve.
+	   @param  x1        (number) x-coordinate of control point or
+	                     (number[][]) x-/y-coordinates of control and end points to draw to
+	   @param  y1        (number) y-coordinate of control point (omitted if x1 is array)
+	   @param  x         (number) x-coordinate of curve end (omitted if x1 is array)
+	   @param  y         (number) y-coordinate of curve end (omitted if x1 is array)
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	curveQ: function(x1, y1, x, y, relative) {
+		relative = (isArray(x1) ? y1 : relative);
+		return this._coords((relative ? 'q' : 'Q'), x1, y1, x, y);
+	},
+
+	/* Continue a quadratic Bézier curve.
+	   Control point is the reflection of the previous control point.
+	   @param  x         (number) x-coordinate of curve end or
+	                     (number[][]) x-/y-coordinates of points to draw to
+	   @param  y         (number) y-coordinate of curve end (omitted if x is array)
+	   @param  relative  (boolean) true for coordinates relative to the current point,
+	                     false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	smoothQ: function(x, y, relative) {
+		relative = (isArray(x) ? y : relative);
+		return this._coords((relative ? 't' : 'T'), x, y);
+	},
+
+	/* Generate a path command with (a list of) coordinates. */
+	_coords: function(cmd, x1, y1, x2, y2, x3, y3) {
+		if (isArray(x1)) {
+			for (var i = 0; i < x1.length; i++) {
+				var cs = x1[i];
+				this._path += (i == 0 ? cmd : ' ') + cs[0] + ',' + cs[1] +
+					(cs.length < 4 ? '' : ' ' + cs[2] + ',' + cs[3] +
+					(cs.length < 6 ? '': ' ' + cs[4] + ',' + cs[5]));
+			}
+		}
+		else {
+			this._path += cmd + x1 + ',' + y1 +
+				(x2 == null ? '' : ' ' + x2 + ',' + y2 +
+				(x3 == null ? '' : ' ' + x3 + ',' + y3));
+		}
+		return this;
+	},
+
+	/* Draw an arc to a position.
+	   @param  rx         (number) x-radius of arc or
+	                      (number/boolean[][]) x-/y-coordinates and flags for points to draw to
+	   @param  ry         (number) y-radius of arc (omitted if rx is array)
+	   @param  xRotate    (number) x-axis rotation (degrees, clockwise) (omitted if rx is array)
+	   @param  large      (boolean) true to draw the large part of the arc,
+	                      false to draw the small part (omitted if rx is array)
+	   @param  clockwise  (boolean) true to draw the clockwise arc,
+	                      false to draw the anti-clockwise arc (omitted if rx is array)
+	   @param  x          (number) x-coordinate of arc end (omitted if rx is array)
+	   @param  y          (number) y-coordinate of arc end (omitted if rx is array)
+	   @param  relative   (boolean) true for coordinates relative to the current point,
+	                      false for coordinates being absolute
+	   @return  (SVGPath) this path */
+	arc: function(rx, ry, xRotate, large, clockwise, x, y, relative) {
+		relative = (isArray(rx) ? ry : relative);
+		this._path += (relative ? 'a' : 'A');
+		if (isArray(rx)) {
+			for (var i = 0; i < rx.length; i++) {
+				var cs = rx[i];
+				this._path += (i == 0 ? '' : ' ') + cs[0] + ',' + cs[1] + ' ' +
+					cs[2] + ' ' + (cs[3] ? '1' : '0') + ',' +
+					(cs[4] ? '1' : '0') + ' ' + cs[5] + ',' + cs[6];
+			}
+		}
+		else {
+			this._path += rx + ',' + ry + ' ' + xRotate + ' ' +
+				(large ? '1' : '0') + ',' + (clockwise ? '1' : '0') + ' ' + x + ',' + y;
+		}
+		return this;
+	},
+
+	/* Close the current path.
+	   @return  (SVGPath) this path */
+	close: function() {
+		this._path += 'z';
+		return this;
+	},
+
+	/* Return the string rendering of the specified path.
+	   @return  (string) stringified path */
+	path: function() {
+		return this._path;
+	}
+});
+
+SVGPath.prototype.moveTo = SVGPath.prototype.move;
+SVGPath.prototype.lineTo = SVGPath.prototype.line;
+SVGPath.prototype.horizTo = SVGPath.prototype.horiz;
+SVGPath.prototype.vertTo = SVGPath.prototype.vert;
+SVGPath.prototype.curveCTo = SVGPath.prototype.curveC;
+SVGPath.prototype.smoothCTo = SVGPath.prototype.smoothC;
+SVGPath.prototype.curveQTo = SVGPath.prototype.curveQ;
+SVGPath.prototype.smoothQTo = SVGPath.prototype.smoothQ;
+SVGPath.prototype.arcTo = SVGPath.prototype.arc;
+
+/* Helper to generate an SVG text object.
+   Obtain an instance from the SVGWrapper object.
+   String calls together to generate the text and use its value:
+   var text = root.createText();
+   root.text(null, x, y, text.string('This is ').
+     span('red', {fill: 'red'}).string('!'), {fill: 'blue'}); */
+function SVGText() {
+	this._parts = []; // The components of the text object
+}
+
+$.extend(SVGText.prototype, {
+	/* Prepare to create a new text object.
+	   @return  (SVGText) this text */
+	reset: function() {
+		this._parts = [];
+		return this;
+	},
+
+	/* Add a straight string value.
+	   @param  value  (string) the actual text
+	   @return  (SVGText) this text object */
+	string: function(value) {
+		this._parts[this._parts.length] = ['text', value];
+		return this;
+	},
+
+	/* Add a separate text span that has its own settings.
+	   @param  value     (string) the actual text
+	   @param  settings  (object) the settings for this text
+	   @return  (SVGText) this text object */
+	span: function(value, settings) {
+		this._parts[this._parts.length] = ['tspan', value, settings];
+		return this;
+	},
+
+	/* Add a reference to a previously defined text string.
+	   @param  id        (string) the ID of the actual text
+	   @param  settings  (object) the settings for this text
+	   @return  (SVGText) this text object */
+	ref: function(id, settings) {
+		this._parts[this._parts.length] = ['tref', id, settings];
+		return this;
+	},
+
+	/* Add text drawn along a path.
+	   @param  id        (string) the ID of the path
+	   @param  value     (string) the actual text
+	   @param  settings  (object) the settings for this text
+	   @return  (SVGText) this text object */
+	path: function(id, value, settings) {
+		this._parts[this._parts.length] = ['textpath', value,
+			$.extend({href: id}, settings || {})];
+		return this;
+	}
+});
+
+/* Attach the SVG functionality to a jQuery selection.
+   @param  command  (string) the command to run (optional, default 'attach')
+   @param  options  (object) the new settings to use for these SVG instances
+   @return jQuery (object) for chaining further calls */
+$.fn.svg = function(options) {
+	var otherArgs = Array.prototype.slice.call(arguments, 1);
+	if (typeof options == 'string' && options == 'get') {
+		return $.svg['_' + options + 'SVG'].apply($.svg, [this[0]].concat(otherArgs));
+	}
+	return this.each(function() {
+		if (typeof options == 'string') {
+			$.svg['_' + options + 'SVG'].apply($.svg, [this].concat(otherArgs));
+		}
+		else {
+			$.svg._attachSVG(this, options || {});
+		}
+	});
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+	return (a && a.constructor == Array);
+}
+
+// Singleton primary SVG interface
+$.svg = new SVGManager();
+
+})(jQuery);
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.min.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.min.js
new file mode 100644
index 0000000..537e7ee
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.min.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+(function($){function SVGManager(){this._settings=[];this._extensions=[];this.regional=[];this.regional['']={errorLoadingText:'Error loading',notSupportedText:'This browser does not support SVG'};this.local=this.regional[''];this._uuid=new Date().getTime();this._renesis=detectActiveX('RenesisX.RenesisCtrl')}function detectActiveX(a){try{return!!(window.ActiveXObject&&new ActiveXObject(a))}catch(e){return false}}var q='svgwrapper';$.extend(SVGManager.prototype,{markerClassName:'hasSVG',svgNS:'http://www.w3.org/2000/svg',xlinkNS:'http://www.w3.org/1999/xlink',_wrapperClass:SVGWrapper,_attrNames:{class_:'class',in_:'in',alignmentBaseline:'alignment-baseline',baselineShift:'baseline-shift',clipPath:'clip-path',clipRule:'clip-rule',colorInterpolation:'color-interpolation',colorInterpolationFilters:'color-interpolation-filters',colorRendering:'color-rendering',dominantBaseline:'dominant-baseline',enableBackground:'enable-background',fillOpacity:'fill-opacity',fillRule:'fill-rule',floodColor:'flood-color',floodOpacity:'flood-opacity',fontFamily:'font-family',fontSize:'font-size',fontSizeAdjust:'font-size-adjust',fontStretch:'font-stretch',fontStyle:'font-style',fontVariant:'font-variant',fontWeight:'font-weight',glyphOrientationHorizontal:'glyph-orientation-horizontal',glyphOrientationVertical:'glyph-orientation-vertical',horizAdvX:'horiz-adv-x',horizOriginX:'horiz-origin-x',imageRendering:'image-rendering',letterSpacing:'letter-spacing',lightingColor:'lighting-color',markerEnd:'marker-end',markerMid:'marker-mid',markerStart:'marker-start',stopColor:'stop-color',stopOpacity:'stop-opacity',strikethroughPosition:'strikethrough-position',strikethroughThickness:'strikethrough-thickness',strokeDashArray:'stroke-dasharray',strokeDashOffset:'stroke-dashoffset',strokeLineCap:'stroke-linecap',strokeLineJoin:'stroke-linejoin',strokeMiterLimit:'stroke-miterlimit',strokeOpacity:'stroke-opacity',strokeWidth:'stroke-width',textAnchor:'text-anchor',textDecoration:'text-decoration',textRendering:'text-rendering',underlinePosition:'underline-position',underlineThickness:'underline-thickness',vertAdvY:'vert-adv-y',vertOriginY:'vert-origin-y',wordSpacing:'word-spacing',writingMode:'writing-mode'},_attachSVG:function(a,b){var c=(a.namespaceURI==this.svgNS?a:null);var a=(c?null:a);if($(a||c).hasClass(this.markerClassName)){return}if(typeof b=='string'){b={loadURL:b}}else if(typeof b=='function'){b={onLoad:b}}$(a||c).addClass(this.markerClassName);try{if(!c){c=document.createElementNS(this.svgNS,'svg');c.setAttribute('version','1.1');if(a.clientWidth>0){c.setAttribute('width',a.clientWidth)}if(a.clientHeight>0){c.setAttribute('height',a.clientHeight)}a.appendChild(c)}this._afterLoad(a,c,b||{})}catch(e){if($.browser.msie){if(!a.id){a.id='svg'+(this._uuid++)}this._settings[a.id]=b;a.innerHTML='<embed type="image/svg+xml" width="100%" '+'height="100%" src="'+(b.initPath||'')+'blank.svg" '+'pluginspage="http://www.adobe.com/svg/viewer/install/main.html"/>'}else{a.innerHTML='<p class="svg_error">'+this.local.notSupportedText+'</p>'}}},_registerSVG:function(){for(var i=0;i<document.embeds.length;i++){var a=document.embeds[i].parentNode;if(!$(a).hasClass($.svg.markerClassName)||$.data(a,q)){continue}var b=null;try{b=document.embeds[i].getSVGDocument()}catch(e){setTimeout($.svg._registerSVG,250);return}b=(b?b.documentElement:null);if(b){$.svg._afterLoad(a,b)}}},_afterLoad:function(a,b,c){var c=c||this._settings[a.id];this._settings[a?a.id:'']=null;var d=new this._wrapperClass(b,a);$.data(a||b,q,d);try{if(c.loadURL){d.load(c.loadURL,c)}if(c.settings){d.configure(c.settings)}if(c.onLoad&&!c.loadURL){c.onLoad.apply(a||b,[d])}}catch(e){alert(e)}},_getSVG:function(a){a=(typeof a=='string'?$(a)[0]:(a.jquery?a[0]:a));return $.data(a,q)},_destroySVG:function(a){var b=$(a);if(!b.hasClass(this.markerClassName)){return}b.removeClass(this.markerClassName);if(a.namespaceURI!=this.svgNS){b.empty()}$.removeData(a,q)},addExtension:function(a,b){this._extensions.push([a,b])},isSVGElem:function(a){return(a.nodeType==1&&a.namespaceURI==$.svg.svgNS)}});function SVGWrapper(a,b){this._svg=a;this._container=b;for(var i=0;i<$.svg._extensions.length;i++){var c=$.svg._extensions[i];this[c[0]]=new c[1](this)}}$.extend(SVGWrapper.prototype,{_width:function(){return(this._container?this._container.clientWidth:this._svg.width)},_height:function(){return(this._container?this._container.clientHeight:this._svg.height)},root:function(){return this._svg},configure:function(a,b,c){if(!a.nodeName){c=b;b=a;a=this._svg}if(c){for(var i=a.attributes.length-1;i>=0;i--){var d=a.attributes.item(i);if(!(d.nodeName=='onload'||d.nodeName=='version'||d.nodeName.substring(0,5)=='xmlns')){a.attributes.removeNamedItem(d.nodeName)}}}for(var e in b){a.setAttribute($.svg._attrNames[e]||e,b[e])}return this},getElementById:function(a){return this._svg.ownerDocument.getElementById(a)},change:function(a,b){if(a){for(var c in b){if(b[c]==null){a.removeAttribute($.svg._attrNames[c]||c)}else{a.setAttribute($.svg._attrNames[c]||c,b[c])}}}return this},_args:function(b,c,d){c.splice(0,0,'parent');c.splice(c.length,0,'settings');var e={};var f=0;if(b[0]!=null&&b[0].jquery){b[0]=b[0][0]}if(b[0]!=null&&!(typeof b[0]=='object'&&b[0].nodeName)){e['parent']=null;f=1}for(var i=0;i<b.length;i++){e[c[i+f]]=b[i]}if(d){$.each(d,function(i,a){if(typeof e[a]=='object'){e.settings=e[a];e[a]=null}})}return e},/*title:function(a,b,c){var d=this._args(arguments,['text']);var e=this._makeNode(d.parent,'title',d.settings||{});e.appendChild(this._svg.ownerDocument.createTextNode(d.text));return e},*/describe:function(a,b,c){var d=this._args(arguments,['text']);var e=this._makeNode(d.parent,'desc',d.settings||{});e.appendChild(this._svg.ownerDocument.createTextNode(d.text));return e},defs:function(a,b,c){var d=this._args(arguments,['id'],['id']);return this._makeNode(d.parent,'defs',$.extend((d.id?{id:d.id}:{}),d.settings||{}))},symbol:function(a,b,c,d,e,f,g){var h=this._args(arguments,['id','x1','y1','width','height']);return this._makeNode(h.parent,'symbol',$.extend({id:h.id,viewBox:h.x1+' '+h.y1+' '+h.width+' '+h.height},h.settings||{}))},marker:function(a,b,c,d,e,f,g,h){var i=this._args(arguments,['id','refX','refY','mWidth','mHeight','orient'],['orient']);return this._makeNode(i.parent,'marker',$.extend({id:i.id,refX:i.refX,refY:i.refY,markerWidth:i.mWidth,markerHeight:i.mHeight,orient:i.orient||'auto'},i.settings||{}))},style:function(a,b,c){var d=this._args(arguments,['styles']);var e=this._makeNode(d.parent,'style',$.extend({type:'text/css'},d.settings||{}));e.appendChild(this._svg.ownerDocument.createTextNode(d.styles));if($.browser.opera){$('head').append('<style type="text/css">'+d.styles+'</style>')}return e},script:function(a,b,c,d){var e=this._args(arguments,['script','type'],['type']);var f=this._makeNode(e.parent,'script',$.extend({type:e.type||'text/javascript'},e.settings||{}));f.appendChild(this._svg.ownerDocument.createTextNode(e.script));if(!$.browser.mozilla){$.globalEval(e.script)}return f},linearGradient:function(a,b,c,d,e,f,g,h){var i=this._args(arguments,['id','stops','x1','y1','x2','y2'],['x1']);var j=$.extend({id:i.id},(i.x1!=null?{x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2}:{}));return this._gradient(i.parent,'linearGradient',$.extend(j,i.settings||{}),i.stops)},radialGradient:function(a,b,c,d,e,r,f,g,h){var i=this._args(arguments,['id','stops','cx','cy','r','fx','fy'],['cx']);var j=$.extend({id:i.id},(i.cx!=null?{cx:i.cx,cy:i.cy,r:i.r,fx:i.fx,fy:i.fy}:{}));return this._gradient(i.parent,'radialGradient',$.extend(j,i.settings||{}),i.stops)},_gradient:function(a,b,c,d){var e=this._makeNode(a,b,c);for(var i=0;i<d.length;i++){var f=d[i];this._makeNode(e,'stop',$.extend({offset:f[0],stopColor:f[1]},(f[2]!=null?{stopOpacity:f[2]}:{})))}return e},pattern:function(a,b,x,y,c,d,e,f,g,h,i){var j=this._args(arguments,['id','x','y','width','height','vx','vy','vwidth','vheight'],['vx']);var k=$.extend({id:j.id,x:j.x,y:j.y,width:j.width,height:j.height},(j.vx!=null?{viewBox:j.vx+' '+j.vy+' '+j.vwidth+' '+j.vheight}:{}));return this._makeNode(j.parent,'pattern',$.extend(k,j.settings||{}))},clipPath:function(a,b,c,d){var e=this._args(arguments,['id','units']);e.units=e.units||'userSpaceOnUse';return this._makeNode(e.parent,'clipPath',$.extend({id:e.id,clipPathUnits:e.units},e.settings||{}))},mask:function(a,b,x,y,c,d,e){var f=this._args(arguments,['id','x','y','width','height']);return this._makeNode(f.parent,'mask',$.extend({id:f.id,x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}))},createPath:function(){return new SVGPath()},createText:function(){return new SVGText()},svg:function(a,x,y,b,c,d,e,f,g,h){var i=this._args(arguments,['x','y','width','height','vx','vy','vwidth','vheight'],['vx']);var j=$.extend({x:i.x,y:i.y,width:i.width,height:i.height},(i.vx!=null?{viewBox:i.vx+' '+i.vy+' '+i.vwidth+' '+i.vheight}:{}));return this._makeNode(i.parent,'svg',$.extend(j,i.settings||{}))},group:function(a,b,c){var d=this._args(arguments,['id'],['id']);return this._makeNode(d.parent,'g',$.extend({id:d.id},d.settings||{}))},use:function(a,x,y,b,c,d,e){var f=this._args(arguments,['x','y','width','height','ref']);if(typeof f.x=='string'){f.ref=f.x;f.settings=f.y;f.x=f.y=f.width=f.height=null}var g=this._makeNode(f.parent,'use',$.extend({x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}));g.setAttributeNS($.svg.xlinkNS,'href',f.ref);return g},link:function(a,b,c){var d=this._args(arguments,['ref']);var e=this._makeNode(d.parent,'a',d.settings);e.setAttributeNS($.svg.xlinkNS,'href',d.ref);return e},image:function(a,x,y,b,c,d,e){var f=this._args(arguments,['x','y','width','height','ref']);var g=this._makeNode(f.parent,'image',$.extend({x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}));g.setAttributeNS($.svg.xlinkNS,'href',f.ref);return g},path:function(a,b,c){var d=this._args(arguments,['path']);return this._makeNode(d.parent,'path',$.extend({d:(d.path.path?d.path.path():d.path)},d.settings||{}))},rect:function(a,x,y,b,c,d,e,f){var g=this._args(arguments,['x','y','width','height','rx','ry'],['rx']);return this._makeNode(g.parent,'rect',$.extend({x:g.x,y:g.y,width:g.width,height:g.height},(g.rx?{rx:g.rx,ry:g.ry}:{}),g.settings||{}))},circle:function(a,b,c,r,d){var e=this._args(arguments,['cx','cy','r']);return this._makeNode(e.parent,'circle',$.extend({cx:e.cx,cy:e.cy,r:e.r},e.settings||{}))},ellipse:function(a,b,c,d,e,f){var g=this._args(arguments,['cx','cy','rx','ry']);return this._makeNode(g.parent,'ellipse',$.extend({cx:g.cx,cy:g.cy,rx:g.rx,ry:g.ry},g.settings||{}))},line:function(a,b,c,d,e,f){var g=this._args(arguments,['x1','y1','x2','y2']);return this._makeNode(g.parent,'line',$.extend({x1:g.x1,y1:g.y1,x2:g.x2,y2:g.y2},g.settings||{}))},polyline:function(a,b,c){var d=this._args(arguments,['points']);return this._poly(d.parent,'polyline',d.points,d.settings)},polygon:function(a,b,c){var d=this._args(arguments,['points']);return this._poly(d.parent,'polygon',d.points,d.settings)},_poly:function(a,b,c,d){var e='';for(var i=0;i<c.length;i++){e+=c[i].join()+' '}return this._makeNode(a,b,$.extend({points:$.trim(e)},d||{}))},text:function(a,x,y,b,c){var d=this._args(arguments,['x','y','value']);if(typeof d.x=='string'&&arguments.length<4){d.value=d.x;d.settings=d.y;d.x=d.y=null}return this._text(d.parent,'text',d.value,$.extend({x:(d.x&&isArray(d.x)?d.x.join(' '):d.x),y:(d.y&&isArray(d.y)?d.y.join(' '):d.y)},d.settings||{}))},textpath:function(a,b,c,d){var e=this._args(arguments,['path','value']);var f=this._text(e.parent,'textPath',e.value,e.settings||{});f.setAttributeNS($.svg.xlinkNS,'href',e.path);return f},_text:function(a,b,c,d){var e=this._makeNode(a,b,d);if(typeof c=='string'){e.appendChild(e.ownerDocument.createTextNode(c))}else{for(var i=0;i<c._parts.length;i++){var f=c._parts[i];if(f[0]=='tspan'){var g=this._makeNode(e,f[0],f[2]);g.appendChild(e.ownerDocument.createTextNode(f[1]));e.appendChild(g)}else if(f[0]=='tref'){var g=this._makeNode(e,f[0],f[2]);g.setAttributeNS($.svg.xlinkNS,'href',f[1]);e.appendChild(g)}else if(f[0]=='textpath'){var h=$.extend({},f[2]);h.href=null;var g=this._makeNode(e,f[0],h);g.setAttributeNS($.svg.xlinkNS,'href',f[2].href);g.appendChild(e.ownerDocument.createTextNode(f[1]));e.appendChild(g)}else{e.appendChild(e.ownerDocument.createTextNode(f[1]))}}}return e},other:function(a,b,c){var d=this._args(arguments,['name']);return this._makeNode(d.parent,d.name,d.settings||{})},_makeNode:function(a,b,c){a=a||this._svg;var d=this._svg.ownerDocument.createElementNS($.svg.svgNS,b);for(var b in c){var e=c[b];if(e!=null&&e!=null&&(typeof e!='string'||e!='')){d.setAttribute($.svg._attrNames[b]||b,e)}}a.appendChild(d);return d},add:function(b,c){var d=this._args((arguments.length==1?[null,b]:arguments),['node']);var f=this;d.parent=d.parent||this._svg;d.node=(d.node.jquery?d.node:$(d.node));try{if($.svg._renesis){throw'Force traversal';}d.parent.appendChild(d.node.cloneNode(true))}catch(e){d.node.each(function(){var a=f._cloneAsSVG(this);if(a){d.parent.appendChild(a)}})}return this},clone:function(b,c){var d=this;var e=this._args((arguments.length==1?[null,b]:arguments),['node']);e.parent=e.parent||this._svg;e.node=(e.node.jquery?e.node:$(e.node));var f=[];e.node.each(function(){var a=d._cloneAsSVG(this);if(a){a.id='';e.parent.appendChild(a);f.push(a)}});return f},_cloneAsSVG:function(a){var b=null;if(a.nodeType==1){b=this._svg.ownerDocument.createElementNS($.svg.svgNS,this._checkName(a.nodeName));for(var i=0;i<a.attributes.length;i++){var c=a.attributes.item(i);if(c.nodeName!='xmlns'&&c.nodeValue){if(c.prefix=='xlink'){b.setAttributeNS($.svg.xlinkNS,c.localName||c.baseName,c.nodeValue)}else{b.setAttribute(this._checkName(c.nodeName),c.nodeValue)}}}for(var i=0;i<a.childNodes.length;i++){var d=this._cloneAsSVG(a.childNodes[i]);if(d){b.appendChild(d)}}}else if(a.nodeType==3){if($.trim(a.nodeValue)){b=this._svg.ownerDocument.createTextNode(a.nodeValue)}}else if(a.nodeType==4){if($.trim(a.nodeValue)){try{b=this._svg.ownerDocument.createCDATASection(a.nodeValue)}catch(e){b=this._svg.ownerDocument.createTextNode(a.nodeValue.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'))}}}return b},_checkName:function(a){a=(a.substring(0,1)>='A'&&a.substring(0,1)<='Z'?a.toLowerCase():a);return(a.substring(0,4)=='svg:'?a.substring(4):a)},load:function(j,k){k=(typeof k=='boolean'?{addTo:k}:(typeof k=='function'?{onLoad:k}:(typeof k=='string'?{parent:k}:(typeof k=='object'&&k.nodeName?{parent:k}:(typeof k=='object'&&k.jquery?{parent:k}:k||{})))));if(!k.parent&&!k.addTo){this.clear(false)}var l=[this._svg.getAttribute('width'),this._svg.getAttribute('height')];var m=this;var n=function(a){a=$.svg.local.errorLoadingText+': '+a;if(k.onLoad){k.onLoad.apply(m._container||m._svg,[m,a])}else{m.text(null,10,20,a)}};var o=function(a){var b=new ActiveXObject('Microsoft.XMLDOM');b.validateOnParse=false;b.resolveExternals=false;b.async=false;b.loadXML(a);if(b.parseError.errorCode!=0){n(b.parseError.reason);return null}return b};var p=function(a){if(!a){return}if(a.documentElement.nodeName!='svg'){var b=a.getElementsByTagName('parsererror');var c=(b.length?b[0].getElementsByTagName('div'):[]);n(!b.length?'???':(c.length?c[0]:b[0]).firstChild.nodeValue);return}var d=(k.parent?$(k.parent)[0]:m._svg);var f={};for(var i=0;i<a.documentElement.attributes.length;i++){var g=a.documentElement.attributes.item(i);if(!(g.nodeName=='version'||g.nodeName.substring(0,5)=='xmlns')){f[g.nodeName]=g.nodeValue}}m.configure(d,f,!k.parent);var h=a.documentElement.childNodes;for(var i=0;i<h.length;i++){try{if($.svg._renesis){throw'Force traversal';}d.appendChild(m._svg.ownerDocument.importNode(h[i],true));if(h[i].nodeName=='script'){$.globalEval(h[i].textContent)}}catch(e){m.add(d,h[i])}}if(!k.changeSize){m.configure(d,{width:l[0],height:l[1]})}if(k.onLoad){k.onLoad.apply(m._container||m._svg,[m])}};if(j.match('<svg')){p($.browser.msie?o(j):new DOMParser().parseFromString(j,'text/xml'))}else{$.ajax({url:j,dataType:($.browser.msie?'text':'xml'),success:function(a){p($.browser.msie?o(a):a)},error:function(a,b,c){n(b+(c?' '+c.message:''))}})}return this},remove:function(a){a=(a.jquery?a[0]:a);a.parentNode.removeChild(a);return this},clear:function(a){if(a){this.configure({},true)}while(this._svg.firstChild){this._svg.removeChild(this._svg.firstChild)}return this},toSVG:function(a){a=a||this._svg;return(typeof XMLSerializer=='undefined'?this._toSVG(a):new XMLSerializer().serializeToString(a))},_toSVG:function(a){var b='';if(!a){return b}if(a.nodeType==3){b=a.nodeValue}else if(a.nodeType==4){b='<![CDATA['+a.nodeValue+']]>'}else{b='<'+a.nodeName;if(a.attributes){for(var i=0;i<a.attributes.length;i++){var c=a.attributes.item(i);if(!($.trim(c.nodeValue)==''||c.nodeValue.match(/^\[object/)||c.nodeValue.match(/^function/))){b+=' '+(c.namespaceURI==$.svg.xlinkNS?'xlink:':'')+c.nodeName+'="'+c.nodeValue+'"'}}}if(a.firstChild){b+='>';var d=a.firstChild;while(d){b+=this._toSVG(d);d=d.nextSibling}b+='</'+a.nodeName+'>'}else{b+='/>'}}return b}});function SVGPath(){this._path=''}$.extend(SVGPath.prototype,{reset:function(){this._path='';return this},move:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'m':'M'),x,y)},line:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'l':'L'),x,y)},horiz:function(x,a){this._path+=(a?'h':'H')+(isArray(x)?x.join(' '):x);return this},vert:function(y,a){this._path+=(a?'v':'V')+(isArray(y)?y.join(' '):y);return this},curveC:function(a,b,c,d,x,y,e){e=(isArray(a)?b:e);return this._coords((e?'c':'C'),a,b,c,d,x,y)},smoothC:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'s':'S'),a,b,x,y)},curveQ:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'q':'Q'),a,b,x,y)},smoothQ:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'t':'T'),x,y)},_coords:function(a,b,c,d,e,f,g){if(isArray(b)){for(var i=0;i<b.length;i++){var h=b[i];this._path+=(i==0?a:' ')+h[0]+','+h[1]+(h.length<4?'':' '+h[2]+','+h[3]+(h.length<6?'':' '+h[4]+','+h[5]))}}else{this._path+=a+b+','+c+(d==null?'':' '+d+','+e+(f==null?'':' '+f+','+g))}return this},arc:function(a,b,c,d,e,x,y,f){f=(isArray(a)?b:f);this._path+=(f?'a':'A');if(isArray(a)){for(var i=0;i<a.length;i++){var g=a[i];this._path+=(i==0?'':' ')+g[0]+','+g[1]+' '+g[2]+' '+(g[3]?'1':'0')+','+(g[4]?'1':'0')+' '+g[5]+','+g[6]}}else{this._path+=a+','+b+' '+c+' '+(d?'1':'0')+','+(e?'1':'0')+' '+x+','+y}return this},close:function(){this._path+='z';return this},path:function(){return this._path}});SVGPath.prototype.moveTo=SVGPath.prototype.move;SVGPath.prototype.lineTo=SVGPath.prototype.line;SVGPath.prototype.horizTo=SVGPath.prototype.horiz;SVGPath.prototype.vertTo=SVGPath.prototype.vert;SVGPath.prototype.curveCTo=SVGPath.prototype.curveC;SVGPath.prototype.smoothCTo=SVGPath.prototype.smoothC;SVGPath.prototype.curveQTo=SVGPath.prototype.curveQ;SVGPath.prototype.smoothQTo=SVGPath.prototype.smoothQ;SVGPath.prototype.arcTo=SVGPath.prototype.arc;function SVGText(){this._parts=[]}$.extend(SVGText.prototype,{reset:function(){this._parts=[];return this},string:function(a){this._parts[this._parts.length]=['text',a];return this},span:function(a,b){this._parts[this._parts.length]=['tspan',a,b];return this},ref:function(a,b){this._parts[this._parts.length]=['tref',a,b];return this},path:function(a,b,c){this._parts[this._parts.length]=['textpath',b,$.extend({href:a},c||{})];return this}});$.fn.svg=function(a){var b=Array.prototype.slice.call(arguments,1);if(typeof a=='string'&&a=='get'){return $.svg['_'+a+'SVG'].apply($.svg,[this[0]].concat(b))}return this.each(function(){if(typeof a=='string'){$.svg['_'+a+'SVG'].apply($.svg,[this].concat(b))}else{$.svg._attachSVG(this,a||{})}})};function isArray(a){return(a&&a.constructor==Array)}$.svg=new SVGManager()})(jQuery);
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.pack.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.pack.js
new file mode 100644
index 0000000..9567a3d
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svg.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){9 2k(){7.1X=[];7.1Y=[];7.2l=[];7.2l[\'\']={2Z:\'4d 4e\',30:\'4f 1r 4g 4h 4i 2m\'};7.2n=7.2l[\'\'];7.31=1e 4j().4k();7.2o=32(\'4l.4m\')}9 32(a){1s{u!!(4n.2p&&1e 2p(a))}1t(e){u 1L}}8 q=\'4o\';$.I(2k.W,{1C:\'4p\',1u:\'2q://2r.33.34/4q/D\',1j:\'2q://2r.33.34/4r/2s\',35:2t,1M:{4s:\'36\',4t:\'1Z\',4u:\'4v-2u\',4w:\'2u-4x\',2v:\'37-19\',4y:\'37-38\',4z:\'1D-39\',4A:\'1D-39-4B\',4C:\'1D-2w\',4D:\'4E-2u\',4F:\'4G-4H\',4I:\'3a-21\',4J:\'3a-38\',4K:\'3b-1D\',4L:\'3b-21\',4M:\'1v-4N\',4O:\'1v-3c\',4P:\'1v-3c-4Q\',4R:\'1v-4S\',4T:\'1v-1N\',4U:\'1v-4V\',4W:\'1v-4X\',4Y:\'3d-3e-4Z\',50:\'3d-3e-51\',52:\'22-3f-x\',53:\'22-3g-x\',54:\'23-2w\',55:\'56-3h\',57:\'58-1D\',59:\'1O-5a\',5b:\'1O-5c\',5d:\'1O-5e\',3i:\'2x-1D\',3j:\'2x-21\',5f:\'3k-3l\',5g:\'3k-3m\',5h:\'1w-5i\',5j:\'1w-5k\',5l:\'1w-5m\',5n:\'1w-5o\',5p:\'1w-5q\',5r:\'1w-21\',5s:\'1w-O\',5t:\'15-5u\',5v:\'15-5w\',5x:\'15-2w\',5y:\'3n-3l\',5z:\'3n-3m\',5A:\'24-3f-y\',5B:\'24-3g-y\',5C:\'5D-3h\',5E:\'5F-5G\'},3o:9(a,b){8 c=(a.25==7.1u?a:P);8 a=(c?P:a);w($(a||c).2y(7.1C)){u}w(13 b==\'1f\'){b={26:b}}Y w(13 b==\'9\'){b={1m:b}}$(a||c).5H(7.1C);1s{w(!c){c=27.2z(7.1u,\'D\');c.1x(\'2A\',\'1.1\');w(a.2B>0){c.1x(\'O\',a.2B)}w(a.2C>0){c.1x(\'U\',a.2C)}a.11(c)}7.2D(a,c,b||{})}1t(e){w($.1r.28){w(!a.E){a.E=\'D\'+(7.31++)}7.1X[a.E]=b;a.3p=\'<5I 1y="23/D+2E" O="3q%" \'+\'U="3q%" 5J="\'+(b.5K||\'\')+\'5L.D" \'+\'5M="2q://2r.5N.5O/D/5P/5Q/5R.5S"/>\'}Y{a.3p=\'<p 36="5T">\'+7.2n.30+\'</p>\'}}},3r:9(){14(8 i=0;i<27.2F.R;i++){8 a=27.2F[i].3s;w(!$(a).2y($.D.1C)||$.2G(a,q)){5U}8 b=P;1s{b=27.2F[i].5V()}1t(e){5W($.D.3r,5X);u}b=(b?b.1P:P);w(b){$.D.2D(a,b)}}},2D:9(a,b,c){8 c=c||7.1X[a.E];7.1X[a?a.E:\'\']=P;8 d=1e 7.35(b,a);$.2G(a||b,q,d);1s{w(c.26){d.3t(c.26,c)}w(c.F){d.1Q(c.F)}w(c.1m&&!c.26){c.1m.1R(a||b,[d])}}1t(e){5Y(e)}},5Z:9(a){a=(13 a==\'1f\'?$(a)[0]:(a.1E?a[0]:a));u $.2G(a,q)},60:9(a){8 b=$(a);w(!b.2y(7.1C)){u}b.61(7.1C);w(a.25!=7.1u){b.62()}$.63(a,q)},64:9(a,b){7.1Y.3u([a,b])},65:9(a){u(a.1F==1&&a.25==$.D.1u)}});9 2t(a,b){7.N=a;7.1z=b;14(8 i=0;i<$.D.1Y.R;i++){8 c=$.D.1Y[i];7[c[0]]=1e c[1](7)}}$.I(2t.W,{66:9(){u(7.1z?7.1z.2B:7.N.O)},67:9(){u(7.1z?7.1z.2C:7.N.U)},68:9(){u 7.N},1Q:9(a,b,c){w(!a.12){c=b;b=a;a=7.N}w(c){14(8 i=a.1g.R-1;i>=0;i--){8 d=a.1g.29(i);w(!(d.12==\'69\'||d.12==\'2A\'||d.12.1G(0,5)==\'2H\')){a.1g.6a(d.12)}}}14(8 e 1Z b){a.1x($.D.1M[e]||e,b[e])}u 7},3v:9(a){u 7.N.17.3v(a)},6b:9(a,b){w(a){14(8 c 1Z b){w(b[c]==P){a.6c($.D.1M[c]||c)}Y{a.1x($.D.1M[c]||c,b[c])}}}u 7},J:9(b,c,d){c.3w(0,0,\'B\');c.3w(c.R,0,\'F\');8 e={};8 f=0;w(b[0]!=P&&b[0].1E){b[0]=b[0][0]}w(b[0]!=P&&!(13 b[0]==\'1S\'&&b[0].12)){e[\'B\']=P;f=1}14(8 i=0;i<b.R;i++){e[c[i+f]]=b[i]}w(d){$.2a(d,9(i,a){w(13 e[a]==\'1S\'){e.F=e[a];e[a]=P}})}u e},3x:9(a,b,c){8 d=7.J(G,[\'15\']);8 e=7.K(d.B,\'3x\',d.F||{});e.11(7.N.17.1h(d.15));u e},6d:9(a,b,c){8 d=7.J(G,[\'15\']);8 e=7.K(d.B,\'6e\',d.F||{});e.11(7.N.17.1h(d.15));u e},3y:9(a,b,c){8 d=7.J(G,[\'E\'],[\'E\']);u 7.K(d.B,\'3y\',$.I((d.E?{E:d.E}:{}),d.F||{}))},3z:9(a,b,c,d,e,f,g){8 h=7.J(G,[\'E\',\'1i\',\'1n\',\'O\',\'U\']);u 7.K(h.B,\'3z\',$.I({E:h.E,2I:h.1i+\' \'+h.1n+\' \'+h.O+\' \'+h.U},h.F||{}))},1O:9(a,b,c,d,e,f,g,h){8 i=7.J(G,[\'E\',\'2J\',\'2K\',\'3A\',\'3B\',\'2b\'],[\'2b\']);u 7.K(i.B,\'1O\',$.I({E:i.E,2J:i.2J,2K:i.2K,6f:i.3A,6g:i.3B,2b:i.2b||\'6h\'},i.F||{}))},1N:9(a,b,c){8 d=7.J(G,[\'2L\']);8 e=7.K(d.B,\'1N\',$.I({1y:\'15/3C\'},d.F||{}));e.11(7.N.17.1h(d.2L));w($.1r.6i){$(\'6j\').6k(\'<1N 1y="15/3C">\'+d.2L+\'</1N>\')}u e},1H:9(a,b,c,d){8 e=7.J(G,[\'1H\',\'1y\'],[\'1y\']);8 f=7.K(e.B,\'1H\',$.I({1y:e.1y||\'15/6l\'},e.F||{}));f.11(7.N.17.1h(e.1H));w(!$.1r.6m){$.3D(e.1H)}u f},3E:9(a,b,c,d,e,f,g,h){8 i=7.J(G,[\'E\',\'2c\',\'1i\',\'1n\',\'1I\',\'1J\'],[\'1i\']);8 j=$.I({E:i.E},(i.1i!=P?{1i:i.1i,1n:i.1n,1I:i.1I,1J:i.1J}:{}));u 7.2M(i.B,\'3E\',$.I(j,i.F||{}),i.2c)},3F:9(a,b,c,d,e,r,f,g,h){8 i=7.J(G,[\'E\',\'2c\',\'1c\',\'1k\',\'r\',\'2N\',\'2O\'],[\'1c\']);8 j=$.I({E:i.E},(i.1c!=P?{1c:i.1c,1k:i.1k,r:i.r,2N:i.2N,2O:i.2O}:{}));u 7.2M(i.B,\'3F\',$.I(j,i.F||{}),i.2c)},2M:9(a,b,c,d){8 e=7.K(a,b,c);14(8 i=0;i<d.R;i++){8 f=d[i];7.K(e,\'2x\',$.I({6n:f[0],3i:f[1]},(f[2]!=P?{3j:f[2]}:{})))}u e},3G:9(a,b,x,y,c,d,e,f,g,h,i){8 j=7.J(G,[\'E\',\'x\',\'y\',\'O\',\'U\',\'1o\',\'2d\',\'2e\',\'2f\'],[\'1o\']);8 k=$.I({E:j.E,x:j.x,y:j.y,O:j.O,U:j.U},(j.1o!=P?{2I:j.1o+\' \'+j.2d+\' \'+j.2e+\' \'+j.2f}:{}));u 7.K(j.B,\'3G\',$.I(k,j.F||{}))},2v:9(a,b,c,d){8 e=7.J(G,[\'E\',\'2g\']);e.2g=e.2g||\'6o\';u 7.K(e.B,\'2v\',$.I({E:e.E,6p:e.2g},e.F||{}))},3H:9(a,b,x,y,c,d,e){8 f=7.J(G,[\'E\',\'x\',\'y\',\'O\',\'U\']);u 7.K(f.B,\'3H\',$.I({E:f.E,x:f.x,y:f.y,O:f.O,U:f.U},f.F||{}))},6q:9(){u 1e X()},6r:9(){u 1e 2P()},D:9(a,x,y,b,c,d,e,f,g,h){8 i=7.J(G,[\'x\',\'y\',\'O\',\'U\',\'1o\',\'2d\',\'2e\',\'2f\'],[\'1o\']);8 j=$.I({x:i.x,y:i.y,O:i.O,U:i.U},(i.1o!=P?{2I:i.1o+\' \'+i.2d+\' \'+i.2e+\' \'+i.2f}:{}));u 7.K(i.B,\'D\',$.I(j,i.F||{}))},6s:9(a,b,c){8 d=7.J(G,[\'E\'],[\'E\']);u 7.K(d.B,\'g\',$.I({E:d.E},d.F||{}))},3I:9(a,x,y,b,c,d,e){8 f=7.J(G,[\'x\',\'y\',\'O\',\'U\',\'1p\']);w(13 f.x==\'1f\'){f.1p=f.x;f.F=f.y;f.x=f.y=f.O=f.U=P}8 g=7.K(f.B,\'3I\',$.I({x:f.x,y:f.y,O:f.O,U:f.U},f.F||{}));g.1A($.D.1j,\'1l\',f.1p);u g},6t:9(a,b,c){8 d=7.J(G,[\'1p\']);8 e=7.K(d.B,\'a\',d.F);e.1A($.D.1j,\'1l\',d.1p);u e},23:9(a,x,y,b,c,d,e){8 f=7.J(G,[\'x\',\'y\',\'O\',\'U\',\'1p\']);8 g=7.K(f.B,\'23\',$.I({x:f.x,y:f.y,O:f.O,U:f.U},f.F||{}));g.1A($.D.1j,\'1l\',f.1p);u g},19:9(a,b,c){8 d=7.J(G,[\'19\']);u 7.K(d.B,\'19\',$.I({d:(d.19.19?d.19.19():d.19)},d.F||{}))},3J:9(a,x,y,b,c,d,e,f){8 g=7.J(G,[\'x\',\'y\',\'O\',\'U\',\'1q\',\'1K\'],[\'1q\']);u 7.K(g.B,\'3J\',$.I({x:g.x,y:g.y,O:g.O,U:g.U},(g.1q?{1q:g.1q,1K:g.1K}:{}),g.F||{}))},3K:9(a,b,c,r,d){8 e=7.J(G,[\'1c\',\'1k\',\'r\']);u 7.K(e.B,\'3K\',$.I({1c:e.1c,1k:e.1k,r:e.r},e.F||{}))},3L:9(a,b,c,d,e,f){8 g=7.J(G,[\'1c\',\'1k\',\'1q\',\'1K\']);u 7.K(g.B,\'3L\',$.I({1c:g.1c,1k:g.1k,1q:g.1q,1K:g.1K},g.F||{}))},2h:9(a,b,c,d,e,f){8 g=7.J(G,[\'1i\',\'1n\',\'1I\',\'1J\']);u 7.K(g.B,\'2h\',$.I({1i:g.1i,1n:g.1n,1I:g.1I,1J:g.1J},g.F||{}))},3M:9(a,b,c){8 d=7.J(G,[\'1T\']);u 7.2Q(d.B,\'3M\',d.1T,d.F)},3N:9(a,b,c){8 d=7.J(G,[\'1T\']);u 7.2Q(d.B,\'3N\',d.1T,d.F)},2Q:9(a,b,c,d){8 e=\'\';14(8 i=0;i<c.R;i++){e+=c[i].1U()+\' \'}u 7.K(a,b,$.I({1T:$.2i(e)},d||{}))},15:9(a,x,y,b,c){8 d=7.J(G,[\'x\',\'y\',\'1V\']);w(13 d.x==\'1f\'&&G.R<4){d.1V=d.x;d.F=d.y;d.x=d.y=P}u 7.2R(d.B,\'15\',d.1V,$.I({x:(d.x&&18(d.x)?d.x.1U(\' \'):d.x),y:(d.y&&18(d.y)?d.y.1U(\' \'):d.y)},d.F||{}))},2S:9(a,b,c,d){8 e=7.J(G,[\'19\',\'1V\']);8 f=7.2R(e.B,\'6u\',e.1V,e.F||{});f.1A($.D.1j,\'1l\',e.19);u f},2R:9(a,b,c,d){8 e=7.K(a,b,d);w(13 c==\'1f\'){e.11(e.17.1h(c))}Y{14(8 i=0;i<c.1b.R;i++){8 f=c.1b[i];w(f[0]==\'3O\'){8 g=7.K(e,f[0],f[2]);g.11(e.17.1h(f[1]));e.11(g)}Y w(f[0]==\'3P\'){8 g=7.K(e,f[0],f[2]);g.1A($.D.1j,\'1l\',f[1]);e.11(g)}Y w(f[0]==\'2S\'){8 h=$.I({},f[2]);h.1l=P;8 g=7.K(e,f[0],h);g.1A($.D.1j,\'1l\',f[2].1l);g.11(e.17.1h(f[1]));e.11(g)}Y{e.11(e.17.1h(f[1]))}}}u e},6v:9(a,b,c){8 d=7.J(G,[\'3Q\']);u 7.K(d.B,d.3Q,d.F||{})},K:9(a,b,c){a=a||7.N;8 d=7.N.17.2z($.D.1u,b);14(8 b 1Z c){8 e=c[b];w(e!=P&&e!=P&&(13 e!=\'1f\'||e!=\'\')){d.1x($.D.1M[b]||b,e)}}a.11(d);u d},3R:9(b,c){8 d=7.J((G.R==1?[P,b]:G),[\'1a\']);8 f=7;d.B=d.B||7.N;d.1a=(d.1a.1E?d.1a:$(d.1a));1s{w($.D.2o){3S\'3T 3U\';}d.B.11(d.1a.6w(2T))}1t(e){d.1a.2a(9(){8 a=f.2j(7);w(a){d.B.11(a)}})}u 7},6x:9(b,c){8 d=7;8 e=7.J((G.R==1?[P,b]:G),[\'1a\']);e.B=e.B||7.N;e.1a=(e.1a.1E?e.1a:$(e.1a));8 f=[];e.1a.2a(9(){8 a=d.2j(7);w(a){a.E=\'\';e.B.11(a);f.3u(a)}});u f},2j:9(a){8 b=P;w(a.1F==1){b=7.N.17.2z($.D.1u,7.2U(a.12));14(8 i=0;i<a.1g.R;i++){8 c=a.1g.29(i);w(c.12!=\'2H\'&&c.16){w(c.6y==\'2s\'){b.1A($.D.1j,c.6z||c.6A,c.16)}Y{b.1x(7.2U(c.12),c.16)}}}14(8 i=0;i<a.2V.R;i++){8 d=7.2j(a.2V[i]);w(d){b.11(d)}}}Y w(a.1F==3){w($.2i(a.16)){b=7.N.17.1h(a.16)}}Y w(a.1F==4){w($.2i(a.16)){1s{b=7.N.17.6B(a.16)}1t(e){b=7.N.17.1h(a.16.2W(/&/g,\'&6C;\').2W(/</g,\'&6D;\').2W(/>/g,\'&6E;\'))}}}u b},2U:9(a){a=(a.1G(0,1)>=\'A\'&&a.1G(0,1)<=\'Z\'?a.6F():a);u(a.1G(0,4)==\'D:\'?a.1G(4):a)},3t:9(j,k){k=(13 k==\'6G\'?{3V:k}:(13 k==\'9\'?{1m:k}:(13 k==\'1f\'?{B:k}:(13 k==\'1S\'&&k.12?{B:k}:(13 k==\'1S\'&&k.1E?{B:k}:k||{})))));w(!k.B&&!k.3V){7.3W(1L)}8 l=[7.N.3X(\'O\'),7.N.3X(\'U\')];8 m=7;8 n=9(a){a=$.D.2n.2Z+\': \'+a;w(k.1m){k.1m.1R(m.1z||m.N,[m,a])}Y{m.15(P,10,20,a)}};8 o=9(a){8 b=1e 2p(\'6H.6I\');b.6J=1L;b.6K=1L;b.6L=1L;b.6M(a);w(b.3Y.6N!=0){n(b.3Y.6O);u P}u b};8 p=9(a){w(!a){u}w(a.1P.12!=\'D\'){8 b=a.3Z(\'6P\');8 c=(b.R?b[0].3Z(\'6Q\'):[]);n(!b.R?\'???\':(c.R?c[0]:b[0]).1W.16);u}8 d=(k.B?$(k.B)[0]:m.N);8 f={};14(8 i=0;i<a.1P.1g.R;i++){8 g=a.1P.1g.29(i);w(!(g.12==\'2A\'||g.12.1G(0,5)==\'2H\')){f[g.12]=g.16}}m.1Q(d,f,!k.B);8 h=a.1P.2V;14(8 i=0;i<h.R;i++){1s{w($.D.2o){3S\'3T 3U\';}d.11(m.N.17.6R(h[i],2T));w(h[i].12==\'1H\'){$.3D(h[i].6S)}}1t(e){m.3R(d,h[i])}}w(!k.6T){m.1Q(d,{O:l[0],U:l[1]})}w(k.1m){k.1m.1R(m.1z||m.N,[m])}};w(j.2X(\'<D\')){p($.1r.28?o(j):1e 6U().6V(j,\'15/2E\'))}Y{$.6W({6X:j,6Y:($.1r.28?\'15\':\'2E\'),6Z:9(a){p($.1r.28?o(a):a)},70:9(a,b,c){n(b+(c?\' \'+c.71:\'\'))}})}u 7},72:9(a){a=(a.1E?a[0]:a);a.3s.40(a);u 7},3W:9(a){w(a){7.1Q({},2T)}41(7.N.1W){7.N.40(7.N.1W)}u 7},73:9(a){a=a||7.N;u(13 42==\'74\'?7.2Y(a):1e 42().75(a))},2Y:9(a){8 b=\'\';w(!a){u b}w(a.1F==3){b=a.16}Y w(a.1F==4){b=\'<![76[\'+a.16+\']]>\'}Y{b=\'<\'+a.12;w(a.1g){14(8 i=0;i<a.1g.R;i++){8 c=a.1g.29(i);w(!($.2i(c.16)==\'\'||c.16.2X(/^\\[1S/)||c.16.2X(/^9/))){b+=\' \'+(c.25==$.D.1j?\'2s:\':\'\')+c.12+\'="\'+c.16+\'"\'}}}w(a.1W){b+=\'>\';8 d=a.1W;41(d){b+=7.2Y(d);d=d.77}b+=\'</\'+a.12+\'>\'}Y{b+=\'/>\'}}u b}});9 X(){7.1d=\'\'}$.I(X.W,{43:9(){7.1d=\'\';u 7},44:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'m\':\'M\'),x,y)},2h:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'l\':\'L\'),x,y)},22:9(x,a){7.1d+=(a?\'h\':\'H\')+(18(x)?x.1U(\' \'):x);u 7},24:9(y,a){7.1d+=(a?\'v\':\'V\')+(18(y)?y.1U(\' \'):y);u 7},45:9(a,b,c,d,x,y,e){e=(18(a)?b:e);u 7.1B((e?\'c\':\'C\'),a,b,c,d,x,y)},46:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'s\':\'S\'),a,b,x,y)},47:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'q\':\'Q\'),a,b,x,y)},48:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'t\':\'T\'),x,y)},1B:9(a,b,c,d,e,f,g){w(18(b)){14(8 i=0;i<b.R;i++){8 h=b[i];7.1d+=(i==0?a:\' \')+h[0]+\',\'+h[1]+(h.R<4?\'\':\' \'+h[2]+\',\'+h[3]+(h.R<6?\'\':\' \'+h[4]+\',\'+h[5]))}}Y{7.1d+=a+b+\',\'+c+(d==P?\'\':\' \'+d+\',\'+e+(f==P?\'\':\' \'+f+\',\'+g))}u 7},49:9(a,b,c,d,e,x,y,f){f=(18(a)?b:f);7.1d+=(f?\'a\':\'A\');w(18(a)){14(8 i=0;i<a.R;i++){8 g=a[i];7.1d+=(i==0?\'\':\' \')+g[0]+\',\'+g[1]+\' \'+g[2]+\' \'+(g[3]?\'1\':\'0\')+\',\'+(g[4]?\'1\':\'0\')+\' \'+g[5]+\',\'+g[6]}}Y{7.1d+=a+\',\'+b+\' \'+c+\' \'+(d?\'1\':\'0\')+\',\'+(e?\'1\':\'0\')+\' \'+x+\',\'+y}u 7},78:9(){7.1d+=\'z\';u 7},19:9(){u 7.1d}});X.W.79=X.W.44;X.W.7a=X.W.2h;X.W.7b=X.W.22;X.W.7c=X.W.24;X.W.7d=X.W.45;X.W.7e=X.W.46;X.W.7f=X.W.47;X.W.7g=X.W.48;X.W.7h=X.W.49;9 2P(){7.1b=[]}$.I(2P.W,{43:9(){7.1b=[];u 7},1f:9(a){7.1b[7.1b.R]=[\'15\',a];u 7},7i:9(a,b){7.1b[7.1b.R]=[\'3O\',a,b];u 7},1p:9(a,b){7.1b[7.1b.R]=[\'3P\',a,b];u 7},19:9(a,b,c){7.1b[7.1b.R]=[\'2S\',b,$.I({1l:a},c||{})];u 7}});$.7j.D=9(a){8 b=4a.W.7k.7l(G,1);w(13 a==\'1f\'&&a==\'7m\'){u $.D[\'4b\'+a+\'2m\'].1R($.D,[7[0]].4c(b))}u 7.2a(9(){w(13 a==\'1f\'){$.D[\'4b\'+a+\'2m\'].1R($.D,[7].4c(b))}Y{$.D.3o(7,a||{})}})};9 18(a){u(a&&a.7n==4a)}$.D=1e 2k()})(7o);',62,459,'|||||||this|var|function|||||||||||||||||||||return||if|||||parent||svg|id|settings|arguments||extend|_args|_makeNode|||_svg|width|null||length|||height||prototype|SVGPath|else|||appendChild|nodeName|typeof|for|text|nodeValue|ownerDocument|isArray|path|node|_parts|cx|_path|new|string|attributes|createTextNode|x1|xlinkNS|cy|href|onLoad|y1|vx|ref|rx|browser|try|catch|svgNS|font|stroke|setAttribute|type|_container|setAttributeNS|_coords|markerClassName|color|jquery|nodeType|substring|script|x2|y2|ry|false|_attrNames|style|marker|documentElement|configure|apply|object|points|join|value|firstChild|_settings|_extensions|in||opacity|horiz|image|vert|namespaceURI|loadURL|document|msie|item|each|orient|stops|vy|vwidth|vheight|units|line|trim|_cloneAsSVG|SVGManager|regional|SVG|local|_renesis|ActiveXObject|http|www|xlink|SVGWrapper|baseline|clipPath|rendering|stop|hasClass|createElementNS|version|clientWidth|clientHeight|_afterLoad|xml|embeds|data|xmlns|viewBox|refX|refY|styles|_gradient|fx|fy|SVGText|_poly|_text|textpath|true|_checkName|childNodes|replace|match|_toSVG|errorLoadingText|notSupportedText|_uuid|detectActiveX|w3|org|_wrapperClass|class|clip|rule|interpolation|fill|flood|size|glyph|orientation|adv|origin|spacing|stopColor|stopOpacity|strikethrough|position|thickness|underline|_attachSVG|innerHTML|100|_registerSVG|parentNode|load|push|getElementById|splice|title|defs|symbol|mWidth|mHeight|css|globalEval|linearGradient|radialGradient|pattern|mask|use|rect|circle|ellipse|polyline|polygon|tspan|tref|name|add|throw|Force|traversal|addTo|clear|getAttribute|parseError|getElementsByTagName|removeChild|while|XMLSerializer|reset|move|curveC|smoothC|curveQ|smoothQ|arc|Array|_|concat|Error|loading|This|does|not|support|Date|getTime|RenesisX|RenesisCtrl|window|svgwrapper|hasSVG|2000|1999|class_|in_|alignmentBaseline|alignment|baselineShift|shift|clipRule|colorInterpolation|colorInterpolationFilters|filters|colorRendering|dominantBaseline|dominant|enableBackground|enable|background|fillOpacity|fillRule|floodColor|floodOpacity|fontFamily|family|fontSize|fontSizeAdjust|adjust|fontStretch|stretch|fontStyle|fontVariant|variant|fontWeight|weight|glyphOrientationHorizontal|horizontal|glyphOrientationVertical|vertical|horizAdvX|horizOriginX|imageRendering|letterSpacing|letter|lightingColor|lighting|markerEnd|end|markerMid|mid|markerStart|start|strikethroughPosition|strikethroughThickness|strokeDashArray|dasharray|strokeDashOffset|dashoffset|strokeLineCap|linecap|strokeLineJoin|linejoin|strokeMiterLimit|miterlimit|strokeOpacity|strokeWidth|textAnchor|anchor|textDecoration|decoration|textRendering|underlinePosition|underlineThickness|vertAdvY|vertOriginY|wordSpacing|word|writingMode|writing|mode|addClass|embed|src|initPath|blank|pluginspage|adobe|com|viewer|install|main|html|svg_error|continue|getSVGDocument|setTimeout|250|alert|_getSVG|_destroySVG|removeClass|empty|removeData|addExtension|isSVGElem|_width|_height|root|onload|removeNamedItem|change|removeAttribute|describe|desc|markerWidth|markerHeight|auto|opera|head|append|javascript|mozilla|offset|userSpaceOnUse|clipPathUnits|createPath|createText|group|link|textPath|other|cloneNode|clone|prefix|localName|baseName|createCDATASection|amp|lt|gt|toLowerCase|boolean|Microsoft|XMLDOM|validateOnParse|resolveExternals|async|loadXML|errorCode|reason|parsererror|div|importNode|textContent|changeSize|DOMParser|parseFromString|ajax|url|dataType|success|error|message|remove|toSVG|undefined|serializeToString|CDATA|nextSibling|close|moveTo|lineTo|horizTo|vertTo|curveCTo|smoothCTo|curveQTo|smoothQTo|arcTo|span|fn|slice|call|get|constructor|jQuery'.split('|'),0,{}))
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.js
new file mode 100644
index 0000000..890fa54
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.js
@@ -0,0 +1,473 @@
+/* http://keith-wood.name/svg.html
+   SVG attribute animations for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) June 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+// Enable animation for all of these SVG numeric attributes -
+// named as svg-* or svg* (with first character upper case)
+$.each(['x', 'y', 'width', 'height', 'rx', 'ry', 'cx', 'cy', 'r', 'x1', 'y1', 'x2', 'y2',
+		'stroke-width', 'strokeWidth', 'opacity', 'fill-opacity', 'fillOpacity',
+		'stroke-opacity', 'strokeOpacity', 'stroke-dashoffset', 'strokeDashOffset',
+		'font-size', 'fontSize', 'font-weight', 'fontWeight',
+		'letter-spacing', 'letterSpacing', 'word-spacing', 'wordSpacing'],
+	function(i, attrName) {
+		var ccName = attrName.charAt(0).toUpperCase() + attrName.substr(1);
+		if ($.cssProps) {
+			$.cssProps['svg' + ccName] = $.cssProps['svg-' + attrName] = attrName;
+		}
+		$.fx.step['svg' + ccName] = $.fx.step['svg-' + attrName] = function(fx) {
+			var realAttrName = $.svg._attrNames[attrName] || attrName;
+			var attr = fx.elem.attributes.getNamedItem(realAttrName);
+			if (!fx.set) {
+				fx.start = (attr ? parseFloat(attr.nodeValue) : 0);
+				var offset = ($.fn.jquery >= '1.6' ? '' :
+					fx.options.curAnim['svg' + ccName] || fx.options.curAnim['svg-' + attrName]);
+				if (/^[+-]=/.exec(offset)) {
+					fx.end = fx.start + parseFloat(offset.replace(/=/, ''));
+				}
+				$(fx.elem).css(realAttrName, '');
+				fx.set = true;
+			}
+			var value = (fx.pos * (fx.end - fx.start) + fx.start) + (fx.unit == '%' ? '%' : '');
+			(attr ? attr.nodeValue = value : fx.elem.setAttribute(realAttrName, value));
+		};
+	}
+);
+
+// Enable animation for the SVG strokeDashArray attribute
+$.fx.step['svgStrokeDashArray'] = $.fx.step['svg-strokeDashArray'] =
+$.fx.step['svgStroke-dasharray'] = $.fx.step['svg-stroke-dasharray'] = function(fx) {
+	var attr = fx.elem.attributes.getNamedItem('stroke-dasharray');
+	if (!fx.set) {
+		fx.start = parseDashArray(attr ? attr.nodeValue : '');
+		var offset = ($.fn.jquery >= '1.6' ? fx.end :
+			fx.options.curAnim['svgStrokeDashArray'] || fx.options.curAnim['svg-strokeDashArray'] ||
+			fx.options.curAnim['svgStroke-dasharray'] || fx.options.curAnim['svg-stroke-dasharray']);
+		fx.end = parseDashArray(offset);
+		if (/^[+-]=/.exec(offset)) {
+			offset = offset.split(/[, ]+/);
+			if (offset.length % 2 == 1) { // Must have an even number
+				var len = offset.length;
+				for (var i = 0; i < len; i++) { // So repeat
+					offset.push(offset[i]);
+				}
+			}
+			for (var i = 0; i < offset.length; i++) {
+				if (/^[+-]=/.exec(offset[i])) {
+					fx.end[i] = fx.start[i] + parseFloat(offset[i].replace(/=/, ''));
+				}
+			}
+		}
+		fx.set = true;
+	}
+	var value = $.map(fx.start, function(n, i) {
+		return (fx.pos * (fx.end[i] - n) + n);
+	}).join(',');
+	(attr ? attr.nodeValue = value : fx.elem.setAttribute('stroke-dasharray', value));
+};
+
+/* Parse a strokeDashArray definition: dash, gap, ...
+   @param  value  (string) the definition
+   @return  (number[2n]) the extracted values */
+function parseDashArray(value) {
+	var dashArray = value.split(/[, ]+/);
+	for (var i = 0; i < dashArray.length; i++) {
+		dashArray[i] = parseFloat(dashArray[i]);
+		if (isNaN(dashArray[i])) {
+			dashArray[i] = 0;
+		}
+	}
+	if (dashArray.length % 2 == 1) { // Must have an even number
+		var len = dashArray.length;
+		for (var i = 0; i < len; i++) { // So repeat
+			dashArray.push(dashArray[i]);
+		}
+	}
+	return dashArray;
+}
+
+// Enable animation for the SVG viewBox attribute
+$.fx.step['svgViewBox'] = $.fx.step['svg-viewBox'] = function(fx) {
+	var attr = fx.elem.attributes.getNamedItem('viewBox');
+	if (!fx.set) {
+		fx.start = parseViewBox(attr ? attr.nodeValue : '');
+		var offset = ($.fn.jquery >= '1.6' ? fx.end :
+			fx.options.curAnim['svgViewBox'] || fx.options.curAnim['svg-viewBox']);
+		fx.end = parseViewBox(offset);
+		if (/^[+-]=/.exec(offset)) {
+			offset = offset.split(/[, ]+/);
+			while (offset.length < 4) {
+				offset.push('0');
+			}
+			for (var i = 0; i < 4; i++) {
+				if (/^[+-]=/.exec(offset[i])) {
+					fx.end[i] = fx.start[i] + parseFloat(offset[i].replace(/=/, ''));
+				}
+			}
+		}
+		fx.set = true;
+	}
+	var value = $.map(fx.start, function(n, i) {
+		return (fx.pos * (fx.end[i] - n) + n);
+	}).join(' ');
+	(attr ? attr.nodeValue = value : fx.elem.setAttribute('viewBox', value));
+};
+
+/* Parse a viewBox definition: x, y, width, height.
+   @param  value  (string) the definition
+   @return  (number[4]) the extracted values */
+function parseViewBox(value) {
+	var viewBox = value.split(/[, ]+/);
+	for (var i = 0; i < viewBox.length; i++) {
+		viewBox[i] = parseFloat(viewBox[i]);
+		if (isNaN(viewBox[i])) {
+			viewBox[i] = 0;
+		}
+	}
+	while (viewBox.length < 4) {
+		viewBox.push(0);
+	}
+	return viewBox;
+}
+
+// Enable animation for the SVG transform attribute
+$.fx.step['svgTransform'] = $.fx.step['svg-transform'] = function(fx) {
+	var attr = fx.elem.attributes.getNamedItem('transform');
+	if (!fx.set) {
+		fx.start = parseTransform(attr ? attr.nodeValue : '');
+		fx.end = parseTransform(fx.end, fx.start);
+		fx.set = true;
+	}
+	var transform = '';
+	for (var i = 0; i < fx.end.order.length; i++) {
+		switch (fx.end.order.charAt(i)) {
+			case 't':
+				transform += ' translate(' +
+					(fx.pos * (fx.end.translateX - fx.start.translateX) + fx.start.translateX) + ',' +
+					(fx.pos * (fx.end.translateY - fx.start.translateY) + fx.start.translateY) + ')';
+				break;
+			case 's':
+				transform += ' scale(' +
+					(fx.pos * (fx.end.scaleX - fx.start.scaleX) + fx.start.scaleX) + ',' +
+					(fx.pos * (fx.end.scaleY - fx.start.scaleY) + fx.start.scaleY) + ')';
+				break;
+			case 'r':
+				transform += ' rotate(' +
+					(fx.pos * (fx.end.rotateA - fx.start.rotateA) + fx.start.rotateA) + ',' +
+					(fx.pos * (fx.end.rotateX - fx.start.rotateX) + fx.start.rotateX) + ',' +
+					(fx.pos * (fx.end.rotateY - fx.start.rotateY) + fx.start.rotateY) + ')';
+				break;
+			case 'x':
+				transform += ' skewX(' +
+					(fx.pos * (fx.end.skewX - fx.start.skewX) + fx.start.skewX) + ')';
+			case 'y':
+				transform += ' skewY(' +
+					(fx.pos * (fx.end.skewY - fx.start.skewY) + fx.start.skewY) + ')';
+				break;
+			case 'm':
+				var matrix = '';
+				for (var j = 0; j < 6; j++) {
+					matrix += ',' + (fx.pos * (fx.end.matrix[j] - fx.start.matrix[j]) + fx.start.matrix[j]);
+				}
+				transform += ' matrix(' + matrix.substr(1) + ')';
+				break;
+		}
+	}
+	(attr ? attr.nodeValue = transform : fx.elem.setAttribute('transform', transform));
+};
+
+/* Decode a transform string and extract component values.
+   @param  value     (string) the transform string to parse
+   @param  original  (object) the settings from the original node
+   @return  (object) the combined transformation attributes */
+function parseTransform(value, original) {
+	value = value || '';
+	if (typeof value == 'object') {
+		value = value.nodeValue;
+	}
+	var transform = $.extend({translateX: 0, translateY: 0, scaleX: 0, scaleY: 0,
+		rotateA: 0, rotateX: 0, rotateY: 0, skewX: 0, skewY: 0,
+		matrix: [0, 0, 0, 0, 0, 0]}, original || {});
+	transform.order = '';
+	var pattern = /([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g;
+	var result = pattern.exec(value);
+	while (result) {
+		switch (result[1]) {
+			case 'translate':
+				transform.order += 't';
+				transform.translateX = parseFloat(result[2]);
+				transform.translateY = (result[3] ? parseFloat(result[3]) : 0);
+				break;
+			case 'scale':
+				transform.order += 's';
+				transform.scaleX = parseFloat(result[2]);
+				transform.scaleY = (result[3] ? parseFloat(result[3]) : transform.scaleX);
+				break;
+			case 'rotate':
+				transform.order += 'r';
+				transform.rotateA = parseFloat(result[2]);
+				transform.rotateX = (result[3] ? parseFloat(result[3]) : 0);
+				transform.rotateY = (result[4] ? parseFloat(result[4]) : 0);
+				break;
+			case 'skewX':
+				transform.order += 'x';
+				transform.skewX = parseFloat(result[2]);
+				break;
+			case 'skewY':
+				transform.order += 'y';
+				transform.skewY = parseFloat(result[2]);
+				break;
+			case 'matrix':
+				transform.order += 'm';
+				transform.matrix = [parseFloat(result[2]), parseFloat(result[3]),
+					parseFloat(result[4]), parseFloat(result[5]),
+					parseFloat(result[6]), parseFloat(result[7])];
+				break;
+		}
+		result = pattern.exec(value);
+	}
+	if (transform.order == 'm' && Math.abs(transform.matrix[0]) == Math.abs(transform.matrix[3]) &&
+			transform.matrix[1] != 0 && Math.abs(transform.matrix[1]) == Math.abs(transform.matrix[2])) {
+		// Simple rotate about origin and translate
+		var angle = Math.acos(transform.matrix[0]) * 180 / Math.PI;
+		angle = (transform.matrix[1] < 0 ? 360 - angle : angle);
+		transform.order = 'rt';
+		transform.rotateA = angle;
+		transform.rotateX = transform.rotateY = 0;
+		transform.translateX = transform.matrix[4];
+		transform.translateY = transform.matrix[5];
+	}
+	return transform;
+}
+
+// Enable animation for all of these SVG colour properties - based on jquery.color.js
+$.each(['fill', 'stroke'],
+	function(i, attrName) {
+		var ccName = attrName.charAt(0).toUpperCase() + attrName.substr(1);
+		$.fx.step['svg' + ccName] = $.fx.step['svg-' + attrName] = function(fx) {
+			if (!fx.set) {
+				fx.start = $.svg._getColour(fx.elem, attrName);
+				var toNone = (fx.end == 'none');
+				fx.end = (toNone ? $.svg._getColour(fx.elem.parentNode, attrName) : $.svg._getRGB(fx.end));
+				fx.end[3] = toNone;
+				$(fx.elem).css(attrName, '');
+				fx.set = true;
+			}
+			var attr = fx.elem.attributes.getNamedItem(attrName);
+			var colour = 'rgb(' + [
+				Math.min(Math.max(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 0), 255),
+				Math.min(Math.max(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 0), 255),
+				Math.min(Math.max(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 0), 255)
+			].join(',') + ')';
+			colour = (fx.end[3] && fx.state == 1 ? 'none' : colour);
+			(attr ? attr.nodeValue = colour : fx.elem.setAttribute(attrName, colour));
+		}
+	}
+);
+
+/* Find this attribute value somewhere up the node hierarchy.
+   @param  elem  (element) the starting element to find the attribute
+   @param  attr  (string) the attribute name
+   @return  (number[3]) RGB components for the attribute colour */
+$.svg._getColour = function(elem, attr) {
+	elem = $(elem);
+	var colour;
+	do {
+		colour = elem.attr(attr) || elem.css(attr);
+		// Keep going until we find an element that has colour, or exit SVG
+		if ((colour != '' && colour != 'none') || elem.hasClass($.svg.markerClassName)) {
+			break;
+		}
+	} while (elem = elem.parent());
+	return $.svg._getRGB(colour);
+};
+
+/* Parse strings looking for common colour formats.
+   @param  colour  (string) colour description to parse
+   @return  (number[3]) RGB components of this colour */
+$.svg._getRGB = function(colour) {
+	var result;
+	// Check if we're already dealing with an array of colors
+	if (colour && colour.constructor == Array) {
+		return (colour.length == 3 || colour.length == 4 ? colour : colours['none']);
+	}
+	// Look for rgb(num,num,num)
+	if (result = /^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/.exec(colour)) {
+		return [parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10)];
+	}
+	// Look for rgb(num%,num%,num%)
+	if (result = /^rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)$/.exec(colour)) {
+		return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55,
+			parseFloat(result[3]) * 2.55];
+	}
+	// Look for #a0b1c2
+	if (result = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(colour)) {
+		return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
+	}
+	// Look for #abc
+	if (result = /^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(colour)) {
+		return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16),
+			parseInt(result[3] + result[3], 16)];
+	}
+	// Otherwise, we're most likely dealing with a named color
+	return colours[$.trim(colour).toLowerCase()] || colours['none'];
+};
+
+// The SVG named colours
+var colours = {
+	'':						[255, 255, 255, 1],
+	none:					[255, 255, 255, 1],
+	aliceblue:				[240, 248, 255],
+	antiquewhite:			[250, 235, 215],
+	aqua:					[0, 255, 255],
+	aquamarine:				[127, 255, 212],
+	azure:					[240, 255, 255],
+	beige:					[245, 245, 220],
+	bisque:					[255, 228, 196],
+	black:					[0, 0, 0],
+	blanchedalmond:			[255, 235, 205],
+	blue:					[0, 0, 255],
+	blueviolet:				[138, 43, 226],
+	brown:					[165, 42, 42],
+	burlywood:				[222, 184, 135],
+	cadetblue:				[95, 158, 160],
+	chartreuse:				[127, 255, 0],
+	chocolate:				[210, 105, 30],
+	coral:					[255, 127, 80],
+	cornflowerblue:			[100, 149, 237],
+	cornsilk:				[255, 248, 220],
+	crimson:				[220, 20, 60],
+	cyan:					[0, 255, 255],
+	darkblue:				[0, 0, 139],
+	darkcyan:				[0, 139, 139],
+	darkgoldenrod:			[184, 134, 11],
+	darkgray:				[169, 169, 169],
+	darkgreen:				[0, 100, 0],
+	darkgrey:				[169, 169, 169],
+	darkkhaki:				[189, 183, 107],
+	darkmagenta:			[139, 0, 139],
+	darkolivegreen:			[85, 107, 47],
+	darkorange:				[255, 140, 0],
+	darkorchid:				[153, 50, 204],
+	darkred:				[139, 0, 0],
+	darksalmon:				[233, 150, 122],
+	darkseagreen:			[143, 188, 143],
+	darkslateblue:			[72, 61, 139],
+	darkslategray:			[47, 79, 79],
+	darkslategrey:			[47, 79, 79],
+	darkturquoise:			[0, 206, 209],
+	darkviolet:				[148, 0, 211],
+	deeppink:				[255, 20, 147],
+	deepskyblue:			[0, 191, 255],
+	dimgray:				[105, 105, 105],
+	dimgrey:				[105, 105, 105],
+	dodgerblue:				[30, 144, 255],
+	firebrick:				[178, 34, 34],
+	floralwhite:			[255, 250, 240],
+	forestgreen:			[34, 139, 34],
+	fuchsia:				[255, 0, 255],
+	gainsboro:				[220, 220, 220],
+	ghostwhite:				[248, 248, 255],
+	gold:					[255, 215, 0],
+	goldenrod:				[218, 165, 32],
+	gray:					[128, 128, 128],
+	grey:					[128, 128, 128],
+	green:					[0, 128, 0],
+	greenyellow:			[173, 255, 47],
+	honeydew:				[240, 255, 240],
+	hotpink:				[255, 105, 180],
+	indianred:				[205, 92, 92],
+	indigo:					[75, 0, 130],
+	ivory:					[255, 255, 240],
+	khaki:					[240, 230, 140],
+	lavender:				[230, 230, 250],
+	lavenderblush:			[255, 240, 245],
+	lawngreen:				[124, 252, 0],
+	lemonchiffon:			[255, 250, 205],
+	lightblue:				[173, 216, 230],
+	lightcoral:				[240, 128, 128],
+	lightcyan:				[224, 255, 255],
+	lightgoldenrodyellow:	[250, 250, 210],
+	lightgray:				[211, 211, 211],
+	lightgreen:				[144, 238, 144],
+	lightgrey:				[211, 211, 211],
+	lightpink:				[255, 182, 193],
+	lightsalmon:			[255, 160, 122],
+	lightseagreen:			[32, 178, 170],
+	lightskyblue:			[135, 206, 250],
+	lightslategray:			[119, 136, 153],
+	lightslategrey:			[119, 136, 153],
+	lightsteelblue:			[176, 196, 222],
+	lightyellow:			[255, 255, 224],
+	lime:					[0, 255, 0],
+	limegreen:				[50, 205, 50],
+	linen:					[250, 240, 230],
+	magenta:				[255, 0, 255],
+	maroon:					[128, 0, 0],
+	mediumaquamarine:		[102, 205, 170],
+	mediumblue:				[0, 0, 205],
+	mediumorchid:			[186, 85, 211],
+	mediumpurple:			[147, 112, 219],
+	mediumseagreen:			[60, 179, 113],
+	mediumslateblue:		[123, 104, 238],
+	mediumspringgreen:		[0, 250, 154],
+	mediumturquoise:		[72, 209, 204],
+	mediumvioletred:		[199, 21, 133],
+	midnightblue:			[25, 25, 112],
+	mintcream:				[245, 255, 250],
+	mistyrose:				[255, 228, 225],
+	moccasin:				[255, 228, 181],
+	navajowhite:			[255, 222, 173],
+	navy:					[0, 0, 128],
+	oldlace:				[253, 245, 230],
+	olive:					[128, 128, 0],
+	olivedrab:				[107, 142, 35],
+	orange:					[255, 165, 0],
+	orangered:				[255, 69, 0],
+	orchid:					[218, 112, 214],
+	palegoldenrod:			[238, 232, 170],
+	palegreen:				[152, 251, 152],
+	paleturquoise:			[175, 238, 238],
+	palevioletred:			[219, 112, 147],
+	papayawhip:				[255, 239, 213],
+	peachpuff:				[255, 218, 185],
+	peru:					[205, 133, 63],
+	pink:					[255, 192, 203],
+	plum:					[221, 160, 221],
+	powderblue:				[176, 224, 230],
+	purple:					[128, 0, 128],
+	red:					[255, 0, 0],
+	rosybrown:				[188, 143, 143],
+	royalblue:				[65, 105, 225],
+	saddlebrown:			[139, 69, 19],
+	salmon:					[250, 128, 114],
+	sandybrown:				[244, 164, 96],
+	seagreen:				[46, 139, 87],
+	seashell:				[255, 245, 238],
+	sienna:					[160, 82, 45],
+	silver:					[192, 192, 192],
+	skyblue:				[135, 206, 235],
+	slateblue:				[106, 90, 205],
+	slategray:				[112, 128, 144],
+	slategrey:				[112, 128, 144],
+	snow:					[255, 250, 250],
+	springgreen:			[0, 255, 127],
+	steelblue:				[70, 130, 180],
+	tan:					[210, 180, 140],
+	teal:					[0, 128, 128],
+	thistle:				[216, 191, 216],
+	tomato:					[255, 99, 71],
+	turquoise:				[64, 224, 208],
+	violet:					[238, 130, 238],
+	wheat:					[245, 222, 179],
+	white:					[255, 255, 255],
+	whitesmoke:				[245, 245, 245],
+	yellow:					[255, 255, 0],
+	yellowgreen:			[154, 205, 50]
+};
+
+})(jQuery);
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.min.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.min.js
new file mode 100644
index 0000000..de372bb
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.min.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG attribute animations for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) June 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+(function($){$.each(['x','y','width','height','rx','ry','cx','cy','r','x1','y1','x2','y2','stroke-width','strokeWidth','opacity','fill-opacity','fillOpacity','stroke-opacity','strokeOpacity','stroke-dashoffset','strokeDashOffset','font-size','fontSize','font-weight','fontWeight','letter-spacing','letterSpacing','word-spacing','wordSpacing'],function(i,f){var g=f.charAt(0).toUpperCase()+f.substr(1);if($.cssProps){$.cssProps['svg'+g]=$.cssProps['svg-'+f]=f}$.fx.step['svg'+g]=$.fx.step['svg-'+f]=function(a){var b=$.svg._attrNames[f]||f;var c=a.elem.attributes.getNamedItem(b);if(!a.set){a.start=(c?parseFloat(c.nodeValue):0);var d=($.fn.jquery>='1.6'?'':a.options.curAnim['svg'+g]||a.options.curAnim['svg-'+f]);if(/^[+-]=/.exec(d)){a.end=a.start+parseFloat(d.replace(/=/,''))}$(a.elem).css(b,'');a.set=true}var e=(a.pos*(a.end-a.start)+a.start)+(a.unit=='%'?'%':'');(c?c.nodeValue=e:a.elem.setAttribute(b,e))}});$.fx.step['svgStrokeDashArray']=$.fx.step['svg-strokeDashArray']=$.fx.step['svgStroke-dasharray']=$.fx.step['svg-stroke-dasharray']=function(a){var b=a.elem.attributes.getNamedItem('stroke-dasharray');if(!a.set){a.start=parseDashArray(b?b.nodeValue:'');var c=($.fn.jquery>='1.6'?a.end:a.options.curAnim['svgStrokeDashArray']||a.options.curAnim['svg-strokeDashArray']||a.options.curAnim['svgStroke-dasharray']||a.options.curAnim['svg-stroke-dasharray']);a.end=parseDashArray(c);if(/^[+-]=/.exec(c)){c=c.split(/[, ]+/);if(c.length%2==1){var d=c.length;for(var i=0;i<d;i++){c.push(c[i])}}for(var i=0;i<c.length;i++){if(/^[+-]=/.exec(c[i])){a.end[i]=a.start[i]+parseFloat(c[i].replace(/=/,''))}}}a.set=true}var e=$.map(a.start,function(n,i){return(a.pos*(a.end[i]-n)+n)}).join(',');(b?b.nodeValue=e:a.elem.setAttribute('stroke-dasharray',e))};function parseDashArray(a){var b=a.split(/[, ]+/);for(var i=0;i<b.length;i++){b[i]=parseFloat(b[i]);if(isNaN(b[i])){b[i]=0}}if(b.length%2==1){var c=b.length;for(var i=0;i<c;i++){b.push(b[i])}}return b}$.fx.step['svgViewBox']=$.fx.step['svg-viewBox']=function(a){var b=a.elem.attributes.getNamedItem('viewBox');if(!a.set){a.start=parseViewBox(b?b.nodeValue:'');var c=($.fn.jquery>='1.6'?a.end:a.options.curAnim['svgViewBox']||a.options.curAnim['svg-viewBox']);a.end=parseViewBox(c);if(/^[+-]=/.exec(c)){c=c.split(/[, ]+/);while(c.length<4){c.push('0')}for(var i=0;i<4;i++){if(/^[+-]=/.exec(c[i])){a.end[i]=a.start[i]+parseFloat(c[i].replace(/=/,''))}}}a.set=true}var d=$.map(a.start,function(n,i){return(a.pos*(a.end[i]-n)+n)}).join(' ');(b?b.nodeValue=d:a.elem.setAttribute('viewBox',d))};function parseViewBox(a){var b=a.split(/[, ]+/);for(var i=0;i<b.length;i++){b[i]=parseFloat(b[i]);if(isNaN(b[i])){b[i]=0}}while(b.length<4){b.push(0)}return b}$.fx.step['svgTransform']=$.fx.step['svg-transform']=function(a){var b=a.elem.attributes.getNamedItem('transform');if(!a.set){a.start=parseTransform(b?b.nodeValue:'');a.end=parseTransform(a.end,a.start);a.set=true}var c='';for(var i=0;i<a.end.order.length;i++){switch(a.end.order.charAt(i)){case't':c+=' translate('+(a.pos*(a.end.translateX-a.start.translateX)+a.start.translateX)+','+(a.pos*(a.end.translateY-a.start.translateY)+a.start.translateY)+')';break;case's':c+=' scale('+(a.pos*(a.end.scaleX-a.start.scaleX)+a.start.scaleX)+','+(a.pos*(a.end.scaleY-a.start.scaleY)+a.start.scaleY)+')';break;case'r':c+=' rotate('+(a.pos*(a.end.rotateA-a.start.rotateA)+a.start.rotateA)+','+(a.pos*(a.end.rotateX-a.start.rotateX)+a.start.rotateX)+','+(a.pos*(a.end.rotateY-a.start.rotateY)+a.start.rotateY)+')';break;case'x':c+=' skewX('+(a.pos*(a.end.skewX-a.start.skewX)+a.start.skewX)+')';case'y':c+=' skewY('+(a.pos*(a.end.skewY-a.start.skewY)+a.start.skewY)+')';break;case'm':var d='';for(var j=0;j<6;j++){d+=','+(a.pos*(a.end.matrix[j]-a.start.matrix[j])+a.start.matrix[j])}c+=' matrix('+d.substr(1)+')';break}}(b?b.nodeValue=c:a.elem.setAttribute('transform',c))};function parseTransform(a,b){a=a||'';if(typeof a=='object'){a=a.nodeValue}var c=$.extend({translateX:0,translateY:0,scaleX:0,scaleY:0,rotateA:0,rotateX:0,rotateY:0,skewX:0,skewY:0,matrix:[0,0,0,0,0,0]},b||{});c.order='';var d=/([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g;var e=d.exec(a);while(e){switch(e[1]){case'translate':c.order+='t';c.translateX=parseFloat(e[2]);c.translateY=(e[3]?parseFloat(e[3]):0);break;case'scale':c.order+='s';c.scaleX=parseFloat(e[2]);c.scaleY=(e[3]?parseFloat(e[3]):c.scaleX);break;case'rotate':c.order+='r';c.rotateA=parseFloat(e[2]);c.rotateX=(e[3]?parseFloat(e[3]):0);c.rotateY=(e[4]?parseFloat(e[4]):0);break;case'skewX':c.order+='x';c.skewX=parseFloat(e[2]);break;case'skewY':c.order+='y';c.skewY=parseFloat(e[2]);break;case'matrix':c.order+='m';c.matrix=[parseFloat(e[2]),parseFloat(e[3]),parseFloat(e[4]),parseFloat(e[5]),parseFloat(e[6]),parseFloat(e[7])];break}e=d.exec(a)}if(c.order=='m'&&Math.abs(c.matrix[0])==Math.abs(c.matrix[3])&&c.matrix[1]!=0&&Math.abs(c.matrix[1])==Math.abs(c.matrix[2])){var f=Math.acos(c.matrix[0])*180/Math.PI;f=(c.matrix[1]<0?360-f:f);c.order='rt';c.rotateA=f;c.rotateX=c.rotateY=0;c.translateX=c.matrix[4];c.translateY=c.matrix[5]}return c}$.each(['fill','stroke'],function(i,e){var f=e.charAt(0).toUpperCase()+e.substr(1);$.fx.step['svg'+f]=$.fx.step['svg-'+e]=function(a){if(!a.set){a.start=$.svg._getColour(a.elem,e);var b=(a.end=='none');a.end=(b?$.svg._getColour(a.elem.parentNode,e):$.svg._getRGB(a.end));a.end[3]=b;$(a.elem).css(e,'');a.set=true}var c=a.elem.attributes.getNamedItem(e);var d='rgb('+[Math.min(Math.max(parseInt((a.pos*(a.end[0]-a.start[0]))+a.start[0],10),0),255),Math.min(Math.max(parseInt((a.pos*(a.end[1]-a.start[1]))+a.start[1],10),0),255),Math.min(Math.max(parseInt((a.pos*(a.end[2]-a.start[2]))+a.start[2],10),0),255)].join(',')+')';d=(a.end[3]&&a.state==1?'none':d);(c?c.nodeValue=d:a.elem.setAttribute(e,d))}});$.svg._getColour=function(a,b){a=$(a);var c;do{c=a.attr(b)||a.css(b);if((c!=''&&c!='none')||a.hasClass($.svg.markerClassName)){break}}while(a=a.parent());return $.svg._getRGB(c)};$.svg._getRGB=function(a){var b;if(a&&a.constructor==Array){return(a.length==3||a.length==4?a:h['none'])}if(b=/^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/.exec(a)){return[parseInt(b[1],10),parseInt(b[2],10),parseInt(b[3],10)]}if(b=/^rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)$/.exec(a)){return[parseFloat(b[1])*2.55,parseFloat(b[2])*2.55,parseFloat(b[3])*2.55]}if(b=/^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(a)){return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]}if(b=/^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(a)){return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)]}return h[$.trim(a).toLowerCase()]||h['none']};var h={'':[255,255,255,1],none:[255,255,255,1],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}})(jQuery);
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.pack.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.pack.js
new file mode 100644
index 0000000..0c563aa
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svganim.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG attribute animations for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) June 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(A($){$.2f([\'x\',\'y\',\'2g\',\'2S\',\'2T\',\'2U\',\'2V\',\'2W\',\'r\',\'2X\',\'2Y\',\'2Z\',\'31\',\'U-2g\',\'33\',\'1F\',\'2h-1F\',\'36\',\'U-1F\',\'37\',\'U-38\',\'39\',\'2i-3a\',\'3b\',\'2i-3c\',\'3d\',\'3e-2j\',\'3f\',\'3g-2j\',\'3h\'],A(i,f){l g=f.1G(0).2k()+f.1H(1);q($.1I){$.1I[\'u\'+g]=$.1I[\'u-\'+f]=f}$.D.E[\'u\'+g]=$.D.E[\'u-\'+f]=A(a){l b=$.u.3i[f]||f;l c=a.B.1l.1m(b);q(!a.N){a.k=(c?p(c.O):0);l d=($.1J.1K>=\'1.6\'?\'\':a.V.W[\'u\'+g]||a.V.W[\'u-\'+f]);q(/^[+-]=/.L(d)){a.o=a.k+p(d.1L(/=/,\'\'))}$(a.B).1M(b,\'\');a.N=1n}l e=(a.w*(a.o-a.k)+a.k)+(a.3j==\'%\'?\'%\':\'\');(c?c.O=e:a.B.1o(b,e))}});$.D.E[\'2l\']=$.D.E[\'u-2m\']=$.D.E[\'2n-17\']=$.D.E[\'u-U-17\']=A(a){l b=a.B.1l.1m(\'U-17\');q(!a.N){a.k=1N(b?b.O:\'\');l c=($.1J.1K>=\'1.6\'?a.o:a.V.W[\'2l\']||a.V.W[\'u-2m\']||a.V.W[\'2n-17\']||a.V.W[\'u-U-17\']);a.o=1N(c);q(/^[+-]=/.L(c)){c=c.1r(/[, ]+/);q(c.F%2==1){l d=c.F;X(l i=0;i<d;i++){c.1s(c[i])}}X(l i=0;i<c.F;i++){q(/^[+-]=/.L(c[i])){a.o[i]=a.k[i]+p(c[i].1L(/=/,\'\'))}}}a.N=1n}l e=$.2o(a.k,A(n,i){G(a.w*(a.o[i]-n)+n)}).1O(\',\');(b?b.O=e:a.B.1o(\'U-17\',e))};A 1N(a){l b=a.1r(/[, ]+/);X(l i=0;i<b.F;i++){b[i]=p(b[i]);q(2p(b[i])){b[i]=0}}q(b.F%2==1){l c=b.F;X(l i=0;i<c;i++){b.1s(b[i])}}G b}$.D.E[\'2q\']=$.D.E[\'u-1t\']=A(a){l b=a.B.1l.1m(\'1t\');q(!a.N){a.k=1P(b?b.O:\'\');l c=($.1J.1K>=\'1.6\'?a.o:a.V.W[\'2q\']||a.V.W[\'u-1t\']);a.o=1P(c);q(/^[+-]=/.L(c)){c=c.1r(/[, ]+/);1u(c.F<4){c.1s(\'0\')}X(l i=0;i<4;i++){q(/^[+-]=/.L(c[i])){a.o[i]=a.k[i]+p(c[i].1L(/=/,\'\'))}}}a.N=1n}l d=$.2o(a.k,A(n,i){G(a.w*(a.o[i]-n)+n)}).1O(\' \');(b?b.O=d:a.B.1o(\'1t\',d))};A 1P(a){l b=a.1r(/[, ]+/);X(l i=0;i<b.F;i++){b[i]=p(b[i]);q(2p(b[i])){b[i]=0}}1u(b.F<4){b.1s(0)}G b}$.D.E[\'3k\']=$.D.E[\'u-1Q\']=A(a){l b=a.B.1l.1m(\'1Q\');q(!a.N){a.k=1R(b?b.O:\'\');a.o=1R(a.o,a.k);a.N=1n}l c=\'\';X(l i=0;i<a.o.M.F;i++){2r(a.o.M.1G(i)){H\'t\':c+=\' 2s(\'+(a.w*(a.o.18-a.k.18)+a.k.18)+\',\'+(a.w*(a.o.1a-a.k.1a)+a.k.1a)+\')\';I;H\'s\':c+=\' 2t(\'+(a.w*(a.o.1b-a.k.1b)+a.k.1b)+\',\'+(a.w*(a.o.1p-a.k.1p)+a.k.1p)+\')\';I;H\'r\':c+=\' 2u(\'+(a.w*(a.o.1c-a.k.1c)+a.k.1c)+\',\'+(a.w*(a.o.1d-a.k.1d)+a.k.1d)+\',\'+(a.w*(a.o.1e-a.k.1e)+a.k.1e)+\')\';I;H\'x\':c+=\' 13(\'+(a.w*(a.o.13-a.k.13)+a.k.13)+\')\';H\'y\':c+=\' 14(\'+(a.w*(a.o.14-a.k.14)+a.k.14)+\')\';I;H\'m\':l d=\'\';X(l j=0;j<6;j++){d+=\',\'+(a.w*(a.o.z[j]-a.k.z[j])+a.k.z[j])}c+=\' z(\'+d.1H(1)+\')\';I}}(b?b.O=c:a.B.1o(\'1Q\',c))};A 1R(a,b){a=a||\'\';q(3l a==\'3m\'){a=a.O}l c=$.3n({18:0,1a:0,1b:0,1p:0,1c:0,1d:0,1e:0,13:0,14:0,z:[0,0,0,0,0,0]},b||{});c.M=\'\';l d=/([a-3o-Z]+)\\(\\s*([+-]?[\\d\\.]+)\\s*(?:[\\s,]\\s*([+-]?[\\d\\.]+)\\s*(?:[\\s,]\\s*([+-]?[\\d\\.]+)\\s*(?:[\\s,]\\s*([+-]?[\\d\\.]+)\\s*[\\s,]\\s*([+-]?[\\d\\.]+)\\s*[\\s,]\\s*([+-]?[\\d\\.]+)\\s*)?)?)?\\)/g;l e=d.L(a);1u(e){2r(e[1]){H\'2s\':c.M+=\'t\';c.18=p(e[2]);c.1a=(e[3]?p(e[3]):0);I;H\'2t\':c.M+=\'s\';c.1b=p(e[2]);c.1p=(e[3]?p(e[3]):c.1b);I;H\'2u\':c.M+=\'r\';c.1c=p(e[2]);c.1d=(e[3]?p(e[3]):0);c.1e=(e[4]?p(e[4]):0);I;H\'13\':c.M+=\'x\';c.13=p(e[2]);I;H\'14\':c.M+=\'y\';c.14=p(e[2]);I;H\'z\':c.M+=\'m\';c.z=[p(e[2]),p(e[3]),p(e[4]),p(e[5]),p(e[6]),p(e[7])];I}e=d.L(a)}q(c.M==\'m\'&&J.1v(c.z[0])==J.1v(c.z[3])&&c.z[1]!=0&&J.1v(c.z[1])==J.1v(c.z[2])){l f=J.3p(c.z[0])*1w/J.3q;f=(c.z[1]<0?3r-f:f);c.M=\'3s\';c.1c=f;c.1d=c.1e=0;c.18=c.z[4];c.1a=c.z[5]}G c}$.2f([\'2h\',\'U\'],A(i,e){l f=e.1G(0).2k()+e.1H(1);$.D.E[\'u\'+f]=$.D.E[\'u-\'+e]=A(a){q(!a.N){a.k=$.u.1S(a.B,e);l b=(a.o==\'1f\');a.o=(b?$.u.1S(a.B.3t,e):$.u.1T(a.o));a.o[3]=b;$(a.B).1M(e,\'\');a.N=1n}l c=a.B.1l.1m(e);l d=\'1U(\'+[J.1V(J.1W(K((a.w*(a.o[0]-a.k[0]))+a.k[0],10),0),8),J.1V(J.1W(K((a.w*(a.o[1]-a.k[1]))+a.k[1],10),0),8),J.1V(J.1W(K((a.w*(a.o[2]-a.k[2]))+a.k[2],10),0),8)].1O(\',\')+\')\';d=(a.o[3]&&a.3u==1?\'1f\':d);(c?c.O=d:a.B.1o(e,d))}});$.u.1S=A(a,b){a=$(a);l c;3v{c=a.3w(b)||a.1M(b);q((c!=\'\'&&c!=\'1f\')||a.3x($.u.3y)){I}}1u(a=a.3z());G $.u.1T(c)};$.u.1T=A(a){l b;q(a&&a.3A==3B){G(a.F==3||a.F==4?a:h[\'1f\'])}q(b=/^1U\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)$/.L(a)){G[K(b[1],10),K(b[2],10),K(b[3],10)]}q(b=/^1U\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)$/.L(a)){G[p(b[1])*2.55,p(b[2])*2.55,p(b[3])*2.55]}q(b=/^#([a-1g-1h-9]{2})([a-1g-1h-9]{2})([a-1g-1h-9]{2})$/.L(a)){G[K(b[1],16),K(b[2],16),K(b[3],16)]}q(b=/^#([a-1g-1h-9])([a-1g-1h-9])([a-1g-1h-9])$/.L(a)){G[K(b[1]+b[1],16),K(b[2]+b[2],16),K(b[3]+b[3],16)]}G h[$.3C(a).3D()]||h[\'1f\']};l h={\'\':[8,8,8,1],1f:[8,8,8,1],3E:[P,1x,8],3F:[C,1X,2v],3G:[0,8,8],3H:[1y,8,3I],3J:[P,8,8],3K:[Q,Q,1i],3L:[8,1Y,2w],3M:[0,0,0],3N:[8,1X,S],3O:[0,0,8],3P:[3Q,43,3R],3S:[1Z,42,42],3T:[1z,2x,22],3U:[3V,3W,1A],3X:[1y,8,0],3Y:[23,T,30],3Z:[8,1y,40],41:[2y,44,48],49:[8,1x,1i],4a:[1i,20,60],4b:[0,8,8],4c:[0,0,R],4d:[0,R,R],4e:[2x,4f,11],4g:[1j,1j,1j],4h:[0,2y,0],4i:[1j,1j,1j],4j:[4k,4l,24],4m:[R,0,R],4n:[2z,24,47],4o:[8,26,0],4p:[27,50,2A],4q:[R,0,0],4r:[4s,4t,2B],4u:[1B,2C,1B],4v:[2D,61,R],4w:[47,1C,1C],4x:[47,1C,1C],4y:[0,28,2E],4z:[4A,0,Y],4B:[8,20,29],4C:[0,2F,8],4D:[T,T,T],4E:[T,T,T],4F:[30,1q,8],4G:[2G,34,34],4H:[8,C,P],4I:[34,R,34],4J:[8,0,8],4K:[1i,1i,1i],4L:[1x,1x,8],4M:[8,2v,0],4N:[2a,1Z,32],4O:[v,v,v],4P:[v,v,v],4Q:[0,v,0],4R:[2b,8,47],4S:[P,8,P],4T:[8,T,1w],4U:[S,2H,2H],4V:[4W,0,2c],4X:[8,8,P],4Y:[P,15,26],4Z:[15,15,C],51:[8,P,Q],52:[53,54,0],56:[8,C,S],57:[2b,2d,15],58:[P,v,v],59:[1D,8,8],5a:[C,C,23],5b:[Y,Y,Y],5c:[1q,12,1q],5d:[Y,Y,Y],5e:[8,5f,5g],5h:[8,1A,2B],5i:[32,2G,2e],5j:[22,28,C],5k:[2I,2J,27],5l:[2I,2J,27],5m:[2K,2w,1z],5n:[8,8,1D],5o:[0,8,0],5p:[50,S,50],5q:[C,P,15],5r:[8,0,8],5s:[v,0,0],5t:[5u,S,2e],5v:[0,0,S],5w:[5x,2z,Y],5y:[29,1k,2L],5z:[60,2M,5A],5B:[5C,5D,12],5E:[0,C,2N],5F:[2D,2E,2A],5G:[5H,21,2O],5I:[25,25,1k],5J:[Q,8,C],5K:[8,1Y,2P],5L:[8,1Y,5M],5N:[8,1z,2b],5O:[0,0,v],5P:[5Q,Q,15],5R:[v,v,0],5S:[24,5T,35],5U:[8,1Z,0],5V:[8,69,0],5W:[2a,1k,5X],5Y:[12,5Z,2e],62:[2Q,66,2Q],67:[68,12,12],6a:[2L,1k,29],6b:[8,6c,6d],6e:[8,2a,6f],6g:[S,2O,63],6h:[8,1E,6i],6j:[2R,1A,2R],6k:[2K,1D,15],6l:[v,0,v],6m:[8,0,0],6n:[2C,1B,1B],6o:[65,T,2P],6p:[R,69,19],6q:[C,v,6r],6s:[6t,6u,6v],6w:[46,R,6x],6y:[8,Q,12],6z:[1A,6A,45],6B:[1E,1E,1E],6C:[22,28,1X],6D:[6E,6F,S],6G:[1k,v,1q],6H:[1k,v,1q],6I:[8,C,C],6J:[0,8,1y],6K:[70,2c,1w],6L:[23,1w,26],6M:[0,v,v],6N:[2d,2F,2d],6O:[8,6P,6Q],6R:[64,1D,6S],6T:[12,2c,12],6U:[Q,1z,2M],6V:[8,8,8],6W:[Q,Q,Q],6X:[8,8,0],6Y:[2N,S,50]}})(6Z);',62,435,'||||||||255||||||||||||start|var|||end|parseFloat|if||||svg|128|pos|||matrix|function|elem|250|fx|step|length|return|case|break|Math|parseInt|exec|order|set|nodeValue|240|245|139|205|105|stroke|options|curAnim|for|211||||238|skewX|skewY|230||dasharray|translateX||translateY|scaleX|rotateA|rotateX|rotateY|none|fA|F0|220|169|112|attributes|getNamedItem|true|setAttribute|scaleY|144|split|push|viewBox|while|abs|180|248|127|222|160|143|79|224|192|opacity|charAt|substr|cssProps|fn|jquery|replace|css|parseDashArray|join|parseViewBox|transform|parseTransform|_getColour|_getRGB|rgb|min|max|235|228|165|||135|210|107||140|153|206|147|218|173|130|216|170|each|width|fill|font|spacing|toUpperCase|svgStrokeDashArray|strokeDashArray|svgStroke|map|isNaN|svgViewBox|switch|translate|scale|rotate|215|196|184|100|85|204|122|188|72|209|191|178|92|119|136|176|219|179|154|133|225|152|221|height|rx|ry|cx|cy|x1|y1|x2||y2||strokeWidth|||fillOpacity|strokeOpacity|dashoffset|strokeDashOffset|size|fontSize|weight|fontWeight|letter|letterSpacing|word|wordSpacing|_attrNames|unit|svgTransform|typeof|object|extend|zA|acos|PI|360|rt|parentNode|state|do|attr|hasClass|markerClassName|parent|constructor|Array|trim|toLowerCase|aliceblue|antiquewhite|aqua|aquamarine|212|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|138|226|brown|burlywood|cadetblue|95|158|chartreuse|chocolate|coral|80|cornflowerblue|||149||||237|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|134|darkgray|darkgreen|darkgrey|darkkhaki|189|183|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|233|150|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|148|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|75|ivory|khaki|lavender||lavenderblush|lawngreen|124|252||lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|182|193|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|102|mediumblue|mediumorchid|186|mediumpurple|mediumseagreen|113|mediumslateblue|123|104|mediumspringgreen|mediumturquoise|mediumvioletred|199|midnightblue|mintcream|mistyrose|moccasin|181|navajowhite|navy|oldlace|253|olive|olivedrab|142|orange|orangered|orchid|214|palegoldenrod|232|||palegreen||||251|paleturquoise|175||palevioletred|papayawhip|239|213|peachpuff|185|peru|pink|203|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|114|sandybrown|244|164|96|seagreen|87|seashell|sienna|82|silver|skyblue|slateblue|106|90|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|99|71|turquoise|208|violet|wheat|white|whitesmoke|yellow|yellowgreen|jQuery|'.split('|'),0,{}))
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.js
new file mode 100644
index 0000000..f96d1ea
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.js
@@ -0,0 +1,406 @@
+/* http://keith-wood.name/svg.html
+   jQuery DOM compatibility for jQuery SVG v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+/* Support adding class names to SVG nodes. */
+$.fn.addClass = function(origAddClass) {
+	return function(classNames) {
+		classNames = classNames || '';
+		return this.each(function() {
+			if ($.svg.isSVGElem(this)) {
+				var node = this;
+				$.each(classNames.split(/\s+/), function(i, className) {
+					var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
+					if ($.inArray(className, classes.split(/\s+/)) == -1) {
+						classes += (classes ? ' ' : '') + className;
+						(node.className ? node.className.baseVal = classes :
+							node.setAttribute('class',  classes));
+					}
+				});
+			}
+			else {
+				origAddClass.apply($(this), [classNames]);
+			}
+		});
+	};
+}($.fn.addClass);
+
+/* Support removing class names from SVG nodes. */
+$.fn.removeClass = function(origRemoveClass) {
+	return function(classNames) {
+		classNames = classNames || '';
+		return this.each(function() {
+			if ($.svg.isSVGElem(this)) {
+				var node = this;
+				$.each(classNames.split(/\s+/), function(i, className) {
+					var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
+					classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).
+						join(' ');
+					(node.className ? node.className.baseVal = classes :
+						node.setAttribute('class', classes));
+				});
+			}
+			else {
+				origRemoveClass.apply($(this), [classNames]);
+			}
+		});
+	};
+}($.fn.removeClass);
+
+/* Support toggling class names on SVG nodes. */
+$.fn.toggleClass = function(origToggleClass) {
+	return function(className, state) {
+		return this.each(function() {
+			if ($.svg.isSVGElem(this)) {
+				if (typeof state !== 'boolean') {
+					state = !$(this).hasClass(className);
+				}
+				$(this)[(state ? 'add' : 'remove') + 'Class'](className);
+			}
+			else {
+				origToggleClass.apply($(this), [className, state]);
+			}
+		});
+	};
+}($.fn.toggleClass);
+
+/* Support checking class names on SVG nodes. */
+$.fn.hasClass = function(origHasClass) {
+	return function(className) {
+		className = className || '';
+		var found = false;
+		this.each(function() {
+			if ($.svg.isSVGElem(this)) {
+				var classes = (this.className ? this.className.baseVal :
+					this.getAttribute('class')).split(/\s+/);
+				found = ($.inArray(className, classes) > -1);
+			}
+			else {
+				found = (origHasClass.apply($(this), [className]));
+			}
+			return !found;
+		});
+		return found;
+	};
+}($.fn.hasClass);
+
+/* Support attributes on SVG nodes. */
+$.fn.attr = function(origAttr) {
+	return function(name, value, type) {
+		if (typeof name === 'string' && value === undefined) {
+			var val = origAttr.apply(this, [name]);
+			if (val && val.baseVal && val.baseVal.numberOfItems != null) { // Multiple values
+				value = '';
+				val = val.baseVal;
+				if (name == 'transform') {
+					for (var i = 0; i < val.numberOfItems; i++) {
+						var item = val.getItem(i);
+						switch (item.type) {
+							case 1: value += ' matrix(' + item.matrix.a + ',' + item.matrix.b + ',' +
+										item.matrix.c + ',' + item.matrix.d + ',' +
+										item.matrix.e + ',' + item.matrix.f + ')';
+									break;
+							case 2: value += ' translate(' + item.matrix.e + ',' + item.matrix.f + ')'; break;
+							case 3: value += ' scale(' + item.matrix.a + ',' + item.matrix.d + ')'; break;
+							case 4: value += ' rotate(' + item.angle + ')'; break; // Doesn't handle new origin
+							case 5: value += ' skewX(' + item.angle + ')'; break;
+							case 6: value += ' skewY(' + item.angle + ')'; break;
+						}
+					}
+					val = value.substring(1);
+				}
+				else {
+					val = val.getItem(0).valueAsString;
+				}
+			}
+			return (val && val.baseVal ? val.baseVal.valueAsString : val);
+		}
+
+		var options = name;
+		if (typeof name === 'string') {
+			options = {};
+			options[name] = value;
+		}
+		return this.each(function() {
+			if ($.svg.isSVGElem(this)) {
+				for (var n in options) {
+					var val = ($.isFunction(options[n]) ? options[n]() : options[n]);
+					(type ? this.style[n] = val : this.setAttribute(n, val));
+				}
+			}
+			else {
+				origAttr.apply($(this), [name, value, type]);
+			}
+		});
+	};
+}($.fn.attr);
+
+/* Support removing attributes on SVG nodes. */
+$.fn.removeAttr = function(origRemoveAttr) {
+	return function(name) {
+		return this.each(function() {
+			if ($.svg.isSVGElem(this)) {
+				(this[name] && this[name].baseVal ? this[name].baseVal.value = '' :
+					this.setAttribute(name, ''));
+			}
+			else {
+				origRemoveAttr.apply($(this), [name]);
+			}
+		});
+	};
+}($.fn.removeAttr);
+
+/* Add numeric only properties. */
+$.extend($.cssNumber, {
+	'stopOpacity': true,
+	'strokeMitrelimit': true,
+	'strokeOpacity': true
+});
+
+/* Support retrieving CSS/attribute values on SVG nodes. */
+if ($.cssProps) {
+	$.css = function(origCSS) {
+		return function(elem, name, extra) {
+			var value = (name.match(/^svg.*/) ? $(elem).attr($.cssProps[name] || name) : '');
+			return value || origCSS(elem, name, extra);
+		};
+	}($.css);
+}
+
+/* Determine if any nodes are SVG nodes. */
+function anySVG(checkSet) {
+	for (var i = 0; i < checkSet.length; i++) {
+		if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/* Update Sizzle selectors. */
+
+$.expr.relative['+'] = function(origRelativeNext) {
+	return function(checkSet, part, isXML) {
+		origRelativeNext(checkSet, part, isXML || anySVG(checkSet));
+	};
+}($.expr.relative['+']);
+
+$.expr.relative['>'] = function(origRelativeChild) {
+	return function(checkSet, part, isXML) {
+		origRelativeChild(checkSet, part, isXML || anySVG(checkSet));
+	};
+}($.expr.relative['>']);
+
+$.expr.relative[''] = function(origRelativeDescendant) {
+	return function(checkSet, part, isXML) {
+		origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));
+	};
+}($.expr.relative['']);
+
+$.expr.relative['~'] = function(origRelativeSiblings) {
+	return function(checkSet, part, isXML) {
+		origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));
+	};
+}($.expr.relative['~']);
+
+$.expr.find.ID = function(origFindId) {
+	return function(match, context, isXML) {
+		return ($.svg.isSVGElem(context) ?
+			[context.ownerDocument.getElementById(match[1])] :
+			origFindId(match, context, isXML));
+	};
+}($.expr.find.ID);
+
+var div = document.createElement('div');
+div.appendChild(document.createComment(''));
+if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found
+	$.expr.find.TAG = function(match, context) {
+		var results = context.getElementsByTagName(match[1]);
+		if (match[1] === '*') { // Filter out possible comments
+			var tmp = [];
+			for (var i = 0; results[i] || results.item(i); i++) {
+				if ((results[i] || results.item(i)).nodeType === 1) {
+					tmp.push(results[i] || results.item(i));
+				}
+			}
+			results = tmp;
+		}
+		return results;
+	};
+}
+
+$.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {
+	match = ' ' + match[1].replace(/\\/g, '') + ' ';
+	if (isXML) {
+		return match;
+	}
+	for (var i = 0, elem = {}; elem != null; i++) {
+		elem = curLoop[i];
+		if (!elem) {
+			try {
+				elem = curLoop.item(i);
+			}
+			catch (e) {
+				// Ignore
+			}
+		}
+		if (elem) {
+			var className = (!$.svg.isSVGElem(elem) ? elem.className :
+				(elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));
+			if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {
+				if (!inplace)
+					result.push(elem);
+			}
+			else if (inplace) {
+				curLoop[i] = false;
+			}
+		}
+	}
+	return false;
+};
+
+$.expr.filter.CLASS = function(elem, match) {
+	var className = (!$.svg.isSVGElem(elem) ? elem.className :
+		(elem.className ? elem.className.baseVal : elem.getAttribute('class')));
+	return (' ' + className + ' ').indexOf(match) > -1;
+};
+
+$.expr.filter.ATTR = function(origFilterAttr) {
+	return function(elem, match) {
+		var handler = null;
+		if ($.svg.isSVGElem(elem)) {
+			handler = match[1];
+			$.expr.attrHandle[handler] = function(elem){
+				var attr = elem.getAttribute(handler);
+				return attr && attr.baseVal || attr;
+			};
+		}
+		var filter = origFilterAttr(elem, match);
+		if (handler) {
+			$.expr.attrHandle[handler] = null;
+		}
+		return filter;
+	};
+}($.expr.filter.ATTR);
+
+/*
+	In the removeData function (line 1881, v1.7.2):
+
+				if ( jQuery.support.deleteExpando ) {
+					delete elem[ internalKey ];
+				} else {
+					try { // SVG
+						elem.removeAttribute( internalKey );
+					} catch (e) {
+						elem[ internalKey ] = null;
+					}
+				}
+
+	In the event.add function (line 2985, v1.7.2):
+
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					try { // SVG
+						elem.addEventListener( type, eventHandle, false );
+					} catch(e) {
+						if ( elem.attachEvent ) {
+							elem.attachEvent( "on" + type, eventHandle );
+						}
+					}
+				}
+
+	In the event.remove function (line 3074, v1.7.2):
+
+			if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+				try { // SVG
+					elem.removeEventListener(type, elemData.handle, false);
+				}
+				catch (e) {
+					if (elem.detachEvent) {
+						elem.detachEvent("on" + type, elemData.handle);
+					}
+				}
+			}
+
+	In the event.fix function (line 3394, v1.7.2):
+
+		if (event.target.namespaceURI == 'http://www.w3.org/2000/svg') { // SVG
+			event.button = [1, 4, 2][event.button];
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && button !== undefined ) {
+			event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+		}
+
+	In the Sizzle function (line 4083, v1.7.2):
+
+	if ( toString.call(checkSet) === "[object Array]" ) {
+		if ( !prune ) {
+			results.push.apply( results, checkSet );
+
+		} else if ( context && context.nodeType === 1 ) {
+			for ( i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+				results.push( set[i] || set.item(i) ); // SVG
+				}
+			}
+
+		} else {
+			for ( i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+					results.push( set[i] || set.item(i) ); // SVG
+				}
+			}
+		}
+	} else {...
+
+	In the fallback for the Sizzle makeArray function (line 4877, v1.7.2):
+
+	if ( toString.call(array) === "[object Array]" ) {
+		Array.prototype.push.apply( ret, array );
+
+	} else {
+		if ( typeof array.length === "number" ) {
+			for ( var l = array.length; i < l; i++ ) {
+				ret.push( array[i] || array.item(i) ); // SVG
+			}
+
+		} else {
+			for ( ; array[i]; i++ ) {
+				ret.push( array[i] );
+			}
+		}
+	}
+
+	In the jQuery.cleandata function (line 6538, v1.7.2):
+
+				if ( deleteExpando ) {
+					delete elem[ jQuery.expando ];
+
+				} else {
+					try { // SVG
+						elem.removeAttribute( jQuery.expando );
+					} catch (e) {
+						// Ignore
+					}
+				}
+
+	In the fallback getComputedStyle function (line 6727, v1.7.2):
+
+		defaultView = (elem.ownerDocument ? elem.ownerDocument.defaultView : elem.defaultView); // SVG
+		if ( defaultView &&
+		(computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+
+			ret = computedStyle.getPropertyValue( name );
+			...
+
+*/
+
+})(jQuery);
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.min.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.min.js
new file mode 100644
index 0000000..e75453f
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.min.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   jQuery DOM compatibility for jQuery SVG v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+(function($){$.fn.addClass=function(e){return function(d){d=d||'';return this.each(function(){if($.svg.isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=(c.className?c.className.baseVal:c.getAttribute('class'));if($.inArray(a,b.split(/\s+/))==-1){b+=(b?' ':'')+a;(c.className?c.className.baseVal=b:c.setAttribute('class',b))}})}else{e.apply($(this),[d])}})}}($.fn.addClass);$.fn.removeClass=function(e){return function(d){d=d||'';return this.each(function(){if($.svg.isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=(c.className?c.className.baseVal:c.getAttribute('class'));b=$.grep(b.split(/\s+/),function(n,i){return n!=a}).join(' ');(c.className?c.className.baseVal=b:c.setAttribute('class',b))})}else{e.apply($(this),[d])}})}}($.fn.removeClass);$.fn.toggleClass=function(c){return function(a,b){return this.each(function(){if($.svg.isSVGElem(this)){if(typeof b!=='boolean'){b=!$(this).hasClass(a)}$(this)[(b?'add':'remove')+'Class'](a)}else{c.apply($(this),[a,b])}})}}($.fn.toggleClass);$.fn.hasClass=function(d){return function(b){b=b||'';var c=false;this.each(function(){if($.svg.isSVGElem(this)){var a=(this.className?this.className.baseVal:this.getAttribute('class')).split(/\s+/);c=($.inArray(b,a)>-1)}else{c=(d.apply($(this),[b]))}return!c});return c}}($.fn.hasClass);$.fn.attr=function(h){return function(b,c,d){if(typeof b==='string'&&c===undefined){var e=h.apply(this,[b]);if(e&&e.baseVal&&e.baseVal.numberOfItems!=null){c='';e=e.baseVal;if(b=='transform'){for(var i=0;i<e.numberOfItems;i++){var f=e.getItem(i);switch(f.type){case 1:c+=' matrix('+f.matrix.a+','+f.matrix.b+','+f.matrix.c+','+f.matrix.d+','+f.matrix.e+','+f.matrix.f+')';break;case 2:c+=' translate('+f.matrix.e+','+f.matrix.f+')';break;case 3:c+=' scale('+f.matrix.a+','+f.matrix.d+')';break;case 4:c+=' rotate('+f.angle+')';break;case 5:c+=' skewX('+f.angle+')';break;case 6:c+=' skewY('+f.angle+')';break}}e=c.substring(1)}else{e=e.getItem(0).valueAsString}}return(e&&e.baseVal?e.baseVal.valueAsString:e)}var g=b;if(typeof b==='string'){g={};g[b]=c}return this.each(function(){if($.svg.isSVGElem(this)){for(var n in g){var a=($.isFunction(g[n])?g[n]():g[n]);(d?this.style[n]=a:this.setAttribute(n,a))}}else{h.apply($(this),[b,c,d])}})}}($.fn.attr);$.fn.removeAttr=function(b){return function(a){return this.each(function(){if($.svg.isSVGElem(this)){(this[a]&&this[a].baseVal?this[a].baseVal.value='':this.setAttribute(a,''))}else{b.apply($(this),[a])}})}}($.fn.removeAttr);$.extend($.cssNumber,{'stopOpacity':true,'strokeMitrelimit':true,'strokeOpacity':true});if($.cssProps){$.css=function(e){return function(a,b,c){var d=(b.match(/^svg.*/)?$(a).attr($.cssProps[b]||b):'');return d||e(a,b,c)}}($.css)}function anySVG(a){for(var i=0;i<a.length;i++){if(a[i].nodeType==1&&a[i].namespaceURI==$.svg.svgNS){return true}}return false}$.expr.relative['+']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['+']);$.expr.relative['>']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['>']);$.expr.relative['']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['']);$.expr.relative['~']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['~']);$.expr.find.ID=function(d){return function(a,b,c){return($.svg.isSVGElem(b)?[b.ownerDocument.getElementById(a[1])]:d(a,b,c))}}($.expr.find.ID);var j=document.createElement('div');j.appendChild(document.createComment(''));if(j.getElementsByTagName('*').length>0){$.expr.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==='*'){var d=[];for(var i=0;c[i]||c.item(i);i++){if((c[i]||c.item(i)).nodeType===1){d.push(c[i]||c.item(i))}}c=d}return c}}$.expr.preFilter.CLASS=function(a,b,c,d,f,g){a=' '+a[1].replace(/\\/g,'')+' ';if(g){return a}for(var i=0,elem={};elem!=null;i++){elem=b[i];if(!elem){try{elem=b.item(i)}catch(e){}}if(elem){var h=(!$.svg.isSVGElem(elem)?elem.className:(elem.className?elem.className.baseVal:'')||elem.getAttribute('class'));if(f^(h&&(' '+h+' ').indexOf(a)>-1)){if(!c)d.push(elem)}else if(c){b[i]=false}}}return false};$.expr.filter.CLASS=function(a,b){var c=(!$.svg.isSVGElem(a)?a.className:(a.className?a.className.baseVal:a.getAttribute('class')));return(' '+c+' ').indexOf(b)>-1};$.expr.filter.ATTR=function(g){return function(c,d){var e=null;if($.svg.isSVGElem(c)){e=d[1];$.expr.attrHandle[e]=function(a){var b=a.getAttribute(e);return b&&b.baseVal||b}}var f=g(c,d);if(e){$.expr.attrHandle[e]=null}return f}}($.expr.filter.ATTR)})(jQuery);
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.pack.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.pack.js
new file mode 100644
index 0000000..2cf6b7c
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgdom.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   jQuery DOM compatibility for jQuery SVG v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.q.S=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));k($.T(a,b.E(/\\s+/))==-1){b+=(b?\' \':\'\')+a;(c.o?c.o.p=b:c.H(\'z\',b))}})}x{e.A($(9),[d])}})}}($.q.S);$.q.U=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));b=$.1d(b.E(/\\s+/),7(n,i){8 n!=a}).1e(\' \');(c.o?c.o.p=b:c.H(\'z\',b))})}x{e.A($(9),[d])}})}}($.q.U);$.q.V=7(c){8 7(a,b){8 9.w(7(){k($.r.v(9)){k(M b!==\'1f\'){b=!$(9).N(a)}$(9)[(b?\'1g\':\'1h\')+\'1i\'](a)}x{c.A($(9),[a,b])}})}}($.q.V);$.q.N=7(d){8 7(b){b=b||\'\';l c=I;9.w(7(){k($.r.v(9)){l a=(9.o?9.o.p:9.B(\'z\')).E(/\\s+/);c=($.T(b,a)>-1)}x{c=(d.A($(9),[b]))}8!c});8 c}}($.q.N);$.q.O=7(h){8 7(b,c,d){k(M b===\'W\'&&c===1j){l e=h.A(9,[b]);k(e&&e.p&&e.p.X!=J){c=\'\';e=e.p;k(b==\'1k\'){F(l i=0;i<e.X;i++){l f=e.Y(i);1l(f.1m){C 1:c+=\' u(\'+f.u.a+\',\'+f.u.b+\',\'+f.u.c+\',\'+f.u.d+\',\'+f.u.e+\',\'+f.u.f+\')\';D;C 2:c+=\' 1n(\'+f.u.e+\',\'+f.u.f+\')\';D;C 3:c+=\' 1o(\'+f.u.a+\',\'+f.u.d+\')\';D;C 4:c+=\' 1p(\'+f.P+\')\';D;C 5:c+=\' 1q(\'+f.P+\')\';D;C 6:c+=\' 1r(\'+f.P+\')\';D}}e=c.1s(1)}x{e=e.Y(0).Z}}8(e&&e.p?e.p.Z:e)}l g=b;k(M b===\'W\'){g={};g[b]=c}8 9.w(7(){k($.r.v(9)){F(l n 1t g){l a=($.1u(g[n])?g[n]():g[n]);(d?9.1v[n]=a:9.H(n,a))}}x{h.A($(9),[b,c,d])}})}}($.q.O);$.q.10=7(b){8 7(a){8 9.w(7(){k($.r.v(9)){(9[a]&&9[a].p?9[a].p.1w=\'\':9.H(a,\'\'))}x{b.A($(9),[a])}})}}($.q.10);$.1x($.1y,{\'1z\':K,\'1A\':K,\'1B\':K});k($.11){$.12=7(e){8 7(a,b,c){l d=(b.1C(/^r.*/)?$(a).O($.11[b]||b):\'\');8 d||e(a,b,c)}}($.12)}7 G(a){F(l i=0;i<a.13;i++){k(a[i].14==1&&a[i].1D==$.r.1E){8 K}}8 I}$.m.y[\'+\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'+\']);$.m.y[\'>\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'>\']);$.m.y[\'\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'\']);$.m.y[\'~\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'~\']);$.m.Q.15=7(d){8 7(a,b,c){8($.r.v(b)?[b.1F.1G(a[1])]:d(a,b,c))}}($.m.Q.15);l j=16.1H(\'1I\');j.1J(16.1K(\'\'));k(j.17(\'*\').13>0){$.m.Q.1L=7(a,b){l c=b.17(a[1]);k(a[1]===\'*\'){l d=[];F(l i=0;c[i]||c.L(i);i++){k((c[i]||c.L(i)).14===1){d.18(c[i]||c.L(i))}}c=d}8 c}}$.m.1M.19=7(a,b,c,d,f,g){a=\' \'+a[1].1N(/\\\\/g,\'\')+\' \';k(g){8 a}F(l i=0,t={};t!=J;i++){t=b[i];k(!t){1O{t=b.L(i)}1P(e){}}k(t){l h=(!$.r.v(t)?t.o:(t.o?t.o.p:\'\')||t.B(\'z\'));k(f^(h&&(\' \'+h+\' \').1a(a)>-1)){k(!c)d.18(t)}x k(c){b[i]=I}}}8 I};$.m.R.19=7(a,b){l c=(!$.r.v(a)?a.o:(a.o?a.o.p:a.B(\'z\')));8(\' \'+c+\' \').1a(b)>-1};$.m.R.1b=7(g){8 7(c,d){l e=J;k($.r.v(c)){e=d[1];$.m.1c[e]=7(a){l b=a.B(e);8 b&&b.p||b}}l f=g(c,d);k(e){$.m.1c[e]=J}8 f}}($.m.R.1b)})(1Q);',62,115,'|||||||function|return|this|||||||||||if|var|expr||className|baseVal|fn|svg||elem|matrix|isSVGElem|each|else|relative|class|apply|getAttribute|case|break|split|for|anySVG|setAttribute|false|null|true|item|typeof|hasClass|attr|angle|find|filter|addClass|inArray|removeClass|toggleClass|string|numberOfItems|getItem|valueAsString|removeAttr|cssProps|css|length|nodeType|ID|document|getElementsByTagName|push|CLASS|indexOf|ATTR|attrHandle|grep|join|boolean|add|remove|Class|undefined|transform|switch|type|translate|scale|rotate|skewX|skewY|substring|in|isFunction|style|value|extend|cssNumber|stopOpacity|strokeMitrelimit|strokeOpacity|match|namespaceURI|svgNS|ownerDocument|getElementById|createElement|div|appendChild|createComment|TAG|preFilter|replace|try|catch|jQuery'.split('|'),0,{}))
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.js
new file mode 100644
index 0000000..7e5466e
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.js
@@ -0,0 +1,402 @@
+/* http://keith-wood.name/svg.html
+   SVG filters for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+$.svg.addExtension('filters', SVGFilter);
+
+$.extend($.svg._wrapperClass.prototype, {
+
+	/* Add a filter definition.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  id        (string) the ID for this filter
+	   @param  x         (number) the x-coordinate for the left edge of the filter
+	   @param  y         (number) the y-coordinate for the top edge of the filter
+	   @param  width     (number) the width of the filter
+	   @param  height    (number) the height of the filter
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	filter: function(parent, id, x, y, width, height, settings) {
+		var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
+		return this._makeNode(args.parent, 'filter', $.extend(
+			{id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
+			args.settings || {}));
+	}
+});
+
+/* Extension point for SVG filters.
+   Access through svg.filters. */
+function SVGFilter(wrapper) {
+	this._wrapper = wrapper; // The attached SVG wrapper object
+}
+
+$.extend(SVGFilter.prototype, {
+
+	/* Add a distant light filter.
+	   @param  parent     (element or jQuery) the parent node for the new filter (optional)
+	   @param  result     (string) the ID of this filter
+	   @param  azimuth    (number) the angle (degrees) in the XY plane for the light source
+	   @param  elevation  (number) the angle (degrees) in the YZ plane for the light source
+	   @param  settings   (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	distantLight: function(parent, result, azimuth, elevation, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'azimuth', 'elevation']);
+		return this._wrapper._makeNode(args.parent, 'feDistantLight', $.extend(
+			{result: args.result, azimuth: args.azimuth, elevation: args.elevation},
+			args.settings || {}));
+	},
+
+	/* Add a point light filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  x         (number) the x-coordinate for the light source
+	   @param  y         (number) the y-coordinate for the light source
+	   @param  z         (number) the z-coordinate for the light source
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	pointLight: function(parent, result, x, y, z, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'z']);
+		return this._wrapper._makeNode(args.parent, 'fePointLight', $.extend(
+			{result: args.result, x: args.x, y: args.y, z: args.z}, args.settings || {}));
+	},
+
+	/* Add a spot light filter.
+	   Specify all of toX, toY, toZ or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  x         (number) the x-coordinate for the light source
+	   @param  y         (number) the y-coordinate for the light source
+	   @param  z         (number) the z-coordinate for the light source
+	   @param  toX       (number) the x-coordinate for where the light is pointing (optional)
+	   @param  toY       (number) the y-coordinate for where the light is pointing (optional)
+	   @param  toZ       (number) the z-coordinate for where the light is pointing (optional)
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	spotLight: function(parent, result, x, y, z, toX, toY, toZ, settings) {
+		var args = this._wrapper._args(arguments,
+			['result', 'x', 'y', 'z', 'toX', 'toY', 'toZ'], ['toX']);
+		var sets = $.extend({result: args.result, x: args.x, y: args.y, z: args.z},
+			(args.toX != null ? {pointsAtX: args.toX, pointsAtY: args.toY,
+			pointsAtZ: args.toZ} : {}));
+		return this._wrapper._makeNode(args.parent, 'feSpotLight',
+			$.extend(sets, args.settings || {}));
+	},
+
+	/* Add a blend filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  mode      (string) normal | multiply | screen | darken | lighten
+	   @param  in1       (string) the first image to blend
+	   @param  in2       (string) the second image to blend
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	blend: function(parent, result, mode, in1, in2, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'mode', 'in1', 'in2']);
+		return this._wrapper._makeNode(args.parent, 'feBlend', $.extend(
+			{result: args.result, mode: args.mode, in_: args.in1, in2: args.in2},
+			args.settings || {}));
+	},
+
+	/* Add a colour matrix filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  in1       (string) the source to colour
+	   @param  type      (string) matrix | saturate | hueRotate | luminanceToAlpha
+	   @param  values    (number[][]) for 'matrix' the matrix (5x4) values to apply
+	                     (number) for 'saturate' 0.0 to 1.0
+	                     (number) for 'hueRotate' degrees
+	                     (void) for 'luminanceToAlpha'
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	colorMatrix: function(parent, result, in1, type, values, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'in1', 'type', 'values']);
+		if (isArray(args.values)) {
+			var vs = '';
+			for (var i = 0; i < args.values.length; i++) {
+				vs += (i == 0 ? '' : ' ') + args.values[i].join(' ');
+			}
+			args.values = vs;
+		}
+		else if (typeof args.values == 'object') {
+			args.settings = args.values;
+			args.values = null;
+		}
+		var sets = $.extend({result: args.result, in_: args.in1, type: args.type},
+			(args.values != null ? {values: args.values} : {}));
+		return this._wrapper._makeNode(args.parent, 'feColorMatrix',
+			$.extend(sets, args.settings || {}));
+	},
+
+	/* Add a component transfer filter.
+	   @param  parent     (element or jQuery) the parent node for the new filter (optional)
+	   @param  result     (string) the ID of this filter
+	   @param  functions  (object[]) one for each of RGB and A (alpha, optional)
+	                      for each entry:
+	                      [0] is (string) identity | table | discrete | linear | gamma
+	                      [1] is (number[]) for 'table' or 'discrete' the list of
+	                      interpolation or step values OR
+	                      (number) for 'linear' the slope, for 'gamma' the amplitude,
+	                      [2] is (number) for 'linear' the intercept, for 'gamma' the exponent,
+	                      [3] is (number) for 'gamma' the offset
+	   @param  settings   (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	componentTransfer: function(parent, result, functions, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'functions']);
+		var node = this._wrapper._makeNode(args.parent, 'feComponentTransfer',
+			$.extend({result: args.result}, args.settings || {}));
+		var rgba = ['R', 'G', 'B', 'A'];
+		for (var i = 0; i < Math.min(4, args.functions.length); i++) {
+			var props = args.functions[i];
+			var sets = $.extend({type: props[0]},
+				(props[0] == 'table' || props[0] == 'discrete' ? {tableValues: props[1].join(' ')} :
+				(props[0] == 'linear' ? {slope: props[1], intercept: props[2]} :
+				(props[0] == 'gamma' ? {amplitude: props[1],
+				exponent: props[2], offset: props[3]} : {}))));
+			this._wrapper._makeNode(node, 'feFunc' + rgba[i], sets);
+		}
+		return node;
+	},
+
+	/* Add a composite filter.
+	   Specify all of k1, k2, k3, k4 or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  operator  (string) over | in | out | atop | xor | arithmetic
+	   @param  in1       (string) the first filter to compose
+	   @param  in2       (string) the second filter to compose
+	   @param  k1        (number) for 'arithmetic' (optional)
+	   @param  k2        (number) for 'arithmetic' (optional)
+	   @param  k3        (number) for 'arithmetic' (optional)
+	   @param  k4        (number) for 'arithmetic' (optional)
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	composite: function(parent, result, operator, in1, in2, k1, k2, k3, k4, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'operator',
+			'in1', 'in2', 'k1', 'k2', 'k3', 'k4'], ['k1']);
+		var sets = $.extend({result: args.result, operator: args.operator,
+			'in': args.in1, in2: args.in2},
+			(args.k1 != null ? {k1: args.k1, k2: args.k2, k3: args.k3, k4: args.k4} : {}));
+		return this._wrapper._makeNode(args.parent, 'feComposite',
+			$.extend(sets, args.settings || {}));
+	},
+
+	/* Add a convolve matrix filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  order     (int or 'int int') the size(s) of the matrix
+	   @param  matrix    (number[][]) the kernel matrix for the convolution
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	convolveMatrix: function(parent, result, order, matrix, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'order', 'matrix']);
+		var mx = '';
+		for (var i = 0; i < args.matrix.length; i++) {
+			mx += (i == 0 ? '' : ' ') + args.matrix[i].join(' ');
+		}
+		args.matrix = mx;
+		return this._wrapper._makeNode(args.parent, 'feConvolveMatrix', $.extend(
+			{result: args.result, order: args.order, kernelMatrix: args.matrix},
+			args.settings || {}));
+	},
+
+	/* Add a diffuse lighting filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  colour    (string) the lighting colour (optional)
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	diffuseLighting: function(parent, result, colour, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'colour'], ['colour']);
+		return this._wrapper._makeNode(args.parent, 'feDiffuseLighting',
+			$.extend($.extend({result: args.result},
+			(args.colour ? {lightingColor: args.colour} : {})), args.settings || {}));
+	},
+
+	/* Add a displacement map filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  in1       (string) the source image
+	   @param  in2       (string) the displacement image
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	displacementMap: function(parent, result, in1, in2, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'in1', 'in2']);
+		return this._wrapper._makeNode(args.parent, 'feDisplacementMap',
+			$.extend({result: args.result, in_: args.in1, in2: args.in2},
+			args.settings || {}));
+	},
+
+	/* Add a flood filter.
+	   Specify all of x, y, width, height or none of them.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  x         (number) the left coordinate of the rectangle (optional)
+	   @param  y         (number) the top coordinate of the rectangle (optional)
+	   @param  width     (number) the width of the rectangle (optional)
+	   @param  height    (number) the height of the rectangle (optional)
+	   @param  colour    (string) the colour to fill with
+	   @param  opacity   (number) the opacity 0.0-1.0
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	flood: function(parent, result, x, y, width, height, colour, opacity, settings) {
+		var args = this._wrapper._args(arguments,
+			['result', 'x', 'y', 'width', 'height', 'colour', 'opacity']);
+		if (arguments.length < 6) {
+			args.colour = args.x;
+			args.opacity = args.y;
+			args.settings = args.width;
+			args.x = null;
+		}
+		var sets = $.extend({result: args.result, floodColor: args.colour,
+			floodOpacity: args.opacity}, (args.x != null ?
+			{x: args.x, y: args.y, width: args.width, height: args.height} : {}));
+		return this._wrapper._makeNode(args.parent, 'feFlood',
+			$.extend(sets, args.settings || {}));
+	},
+
+	/* Add a Gaussian blur filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  in1       (string) the source filter
+	   @param  stdDevX   (number) the standard deviation along the x-axis
+	   @param  stdDevY   (number) the standard deviation along the y-axis (optional)
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	gaussianBlur: function(parent, result, in1, stdDevX, stdDevY, settings) {
+		var args = this._wrapper._args(arguments,
+			['result', 'in1', 'stdDevX', 'stdDevY'], ['stdDevY']);
+		return this._wrapper._makeNode(args.parent, 'feGaussianBlur', $.extend(
+			{result: args.result, in_: args.in1, stdDeviation: args.stdDevX +
+			(args.stdDevY ? ' ' + args.stdDevY : '')}, args.settings || {}));
+	},
+
+	/* Add an image filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  href      (string) the URL of the image
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	image: function(parent, result, href, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'href']);
+		var node = this._wrapper._makeNode(args.parent, 'feImage', $.extend(
+			{result: args.result}, args.settings || {}));
+		node.setAttributeNS($.svg.xlinkNS, 'href', args.href);
+		return node;
+	},
+
+	/* Add a merge filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  refs      (string[]) the IDs of the filters to merge
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	merge: function(parent, result, refs, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'refs']);
+		var node = this._wrapper._makeNode(args.parent, 'feMerge', $.extend(
+			{result: args.result}, args.settings || {}));
+		for (var i = 0; i < args.refs.length; i++) {
+			this._wrapper._makeNode(node, 'feMergeNode', {in_: args.refs[i]});
+		}
+		return node;
+	},
+
+	/* Add a morphology filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  in1       (string) the source filter
+	   @param  operator  (string) erode | dilate
+	   @param  radiusX   (number) the size of the operation in the x-axis
+	   @param  radiusY   (number) the size of the operation in the y-axis (optional)
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	morphology: function(parent, result, in1, operator, radiusX, radiusY, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'in1',
+			'operator', 'radiusX', 'radiusY'], ['radiusY']);
+		return this._wrapper._makeNode(args.parent, 'feMorphology', $.extend(
+			{result: args.result, in_: args.in1, operator: args.operator,
+			radius: args.radiusX + (args.radiusY ? ' ' + args.radiusY : '')},
+			args.settings || {}));
+	},
+
+	/* Add an offset filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  in1       (string) the source filter
+	   @param  dX        (number) the offset in the x-axis
+	   @param  dY        (number) the offset in the y-axis
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	offset: function(parent, result, in1, dx, dy, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'in1', 'dx', 'dy']);
+		return this._wrapper._makeNode(args.parent, 'feOffset', $.extend(
+			{result: args.result, in_: args.in1, dx: args.dx, dy: args.dy},
+			args.settings || {}));
+	},
+
+	/* Add a specular lighting filter.
+	   Numeric params are only optional if following numeric params are also omitted.
+	   @param  parent            (element or jQuery) the parent node for the new filter (optional)
+	   @param  result            (string) the ID of this filter
+	   @param  in1               (string) the source filter
+	   @param  surfaceScale      (number) the surface height when Ain = 1 (optional)
+	   @param  specularConstant  (number) the ks in Phong lighting model (optional)
+	   @param  specularExponent  (number) the shininess 1.0-128.0 (optional)
+	   @param  settings          (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	specularLighting: function(parent, result, in1, surfaceScale,
+			specularConstant, specularExponent, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'in1',
+			'surfaceScale', 'specularConstant', 'specularExponent'],
+			['surfaceScale', 'specularConstant', 'specularExponent']);
+		return this._wrapper._makeNode(args.parent, 'feSpecularLighting', $.extend(
+			{result: args.result, in_: args.in1, surfaceScale: args.surfaceScale,
+			specularConstant: args.specularConstant, specularExponent: args.specularExponent},
+			args.settings || {}));
+	},
+
+	/* Add a tile filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  in1       (string) the source filter
+	   @param  x         (number) the left coordinate of the rectangle
+	   @param  y         (number) the top coordinate of the rectangle
+	   @param  width     (number) the width of the rectangle
+	   @param  height    (number) the height of the rectangle
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	tile: function(parent, result, in1, x, y, width, height, settings) {
+		var args = this._wrapper._args(arguments,
+			['result', 'in1', 'x', 'y', 'width', 'height']);
+		return this._wrapper._makeNode(args.parent, 'feTile', $.extend(
+			{result: args.result, in_: args.in1, x: args.x, y: args.y,
+			width: args.width, height: args.height}, args.settings || {}));
+	},
+
+	/* Add a turbulence filter.
+	   @param  parent    (element or jQuery) the parent node for the new filter (optional)
+	   @param  result    (string) the ID of this filter
+	   @param  type      (string) fractalNoise | turbulence
+	   @param  baseFreq  (number or 'number number') the base frequency,
+	                     optionally separated into x- and y-components
+	   @param  octaves   (number) the amount of turbulence (optional)
+	   @param  settings  (object) additional settings for the filter (optional)
+	   @return  (element) the new filter node */
+	turbulence: function(parent, result, type, baseFreq, octaves, settings) {
+		var args = this._wrapper._args(arguments, ['result', 'type',
+			'baseFreq', 'octaves'], ['octaves']);
+		return this._wrapper._makeNode(args.parent, 'feTurbulence', $.extend(
+			{result: args.result, type: args.type, baseFrequency: args.baseFreq,
+			numOctaves: args.octaves}, args.settings || {}));
+	}
+});
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+	return (a && a.constructor == Array);
+}
+
+})(jQuery)
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.min.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.min.js
new file mode 100644
index 0000000..65cfae2
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.min.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG filters for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+(function($){$.svg.addExtension('filters',SVGFilter);$.extend($.svg._wrapperClass.prototype,{filter:function(a,b,x,y,c,d,e){var f=this._args(arguments,['id','x','y','width','height']);return this._makeNode(f.parent,'filter',$.extend({id:f.id,x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}))}});function SVGFilter(a){this._wrapper=a}$.extend(SVGFilter.prototype,{distantLight:function(a,b,c,d,e){var f=this._wrapper._args(arguments,['result','azimuth','elevation']);return this._wrapper._makeNode(f.parent,'feDistantLight',$.extend({result:f.result,azimuth:f.azimuth,elevation:f.elevation},f.settings||{}))},pointLight:function(a,b,x,y,z,c){var d=this._wrapper._args(arguments,['result','x','y','z']);return this._wrapper._makeNode(d.parent,'fePointLight',$.extend({result:d.result,x:d.x,y:d.y,z:d.z},d.settings||{}))},spotLight:function(a,b,x,y,z,c,d,e,f){var g=this._wrapper._args(arguments,['result','x','y','z','toX','toY','toZ'],['toX']);var h=$.extend({result:g.result,x:g.x,y:g.y,z:g.z},(g.toX!=null?{pointsAtX:g.toX,pointsAtY:g.toY,pointsAtZ:g.toZ}:{}));return this._wrapper._makeNode(g.parent,'feSpotLight',$.extend(h,g.settings||{}))},blend:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','mode','in1','in2']);return this._wrapper._makeNode(g.parent,'feBlend',$.extend({result:g.result,mode:g.mode,in_:g.in1,in2:g.in2},g.settings||{}))},colorMatrix:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','in1','type','values']);if(isArray(g.values)){var h='';for(var i=0;i<g.values.length;i++){h+=(i==0?'':' ')+g.values[i].join(' ')}g.values=h}else if(typeof g.values=='object'){g.settings=g.values;g.values=null}var j=$.extend({result:g.result,in_:g.in1,type:g.type},(g.values!=null?{values:g.values}:{}));return this._wrapper._makeNode(g.parent,'feColorMatrix',$.extend(j,g.settings||{}))},componentTransfer:function(a,b,c,d){var e=this._wrapper._args(arguments,['result','functions']);var f=this._wrapper._makeNode(e.parent,'feComponentTransfer',$.extend({result:e.result},e.settings||{}));var g=['R','G','B','A'];for(var i=0;i<Math.min(4,e.functions.length);i++){var h=e.functions[i];var j=$.extend({type:h[0]},(h[0]=='table'||h[0]=='discrete'?{tableValues:h[1].join(' ')}:(h[0]=='linear'?{slope:h[1],intercept:h[2]}:(h[0]=='gamma'?{amplitude:h[1],exponent:h[2],offset:h[3]}:{}))));this._wrapper._makeNode(f,'feFunc'+g[i],j)}return f},composite:function(a,b,c,d,e,f,g,h,i,j){var k=this._wrapper._args(arguments,['result','operator','in1','in2','k1','k2','k3','k4'],['k1']);var l=$.extend({result:k.result,operator:k.operator,'in':k.in1,in2:k.in2},(k.k1!=null?{k1:k.k1,k2:k.k2,k3:k.k3,k4:k.k4}:{}));return this._wrapper._makeNode(k.parent,'feComposite',$.extend(l,k.settings||{}))},convolveMatrix:function(a,b,c,d,e){var f=this._wrapper._args(arguments,['result','order','matrix']);var g='';for(var i=0;i<f.matrix.length;i++){g+=(i==0?'':' ')+f.matrix[i].join(' ')}f.matrix=g;return this._wrapper._makeNode(f.parent,'feConvolveMatrix',$.extend({result:f.result,order:f.order,kernelMatrix:f.matrix},f.settings||{}))},diffuseLighting:function(a,b,c,d){var e=this._wrapper._args(arguments,['result','colour'],['colour']);return this._wrapper._makeNode(e.parent,'feDiffuseLighting',$.extend($.extend({result:e.result},(e.colour?{lightingColor:e.colour}:{})),e.settings||{}))},displacementMap:function(a,b,c,d,e){var f=this._wrapper._args(arguments,['result','in1','in2']);return this._wrapper._makeNode(f.parent,'feDisplacementMap',$.extend({result:f.result,in_:f.in1,in2:f.in2},f.settings||{}))},flood:function(a,b,x,y,c,d,e,f,g){var h=this._wrapper._args(arguments,['result','x','y','width','height','colour','opacity']);if(arguments.length<6){h.colour=h.x;h.opacity=h.y;h.settings=h.width;h.x=null}var i=$.extend({result:h.result,floodColor:h.colour,floodOpacity:h.opacity},(h.x!=null?{x:h.x,y:h.y,width:h.width,height:h.height}:{}));return this._wrapper._makeNode(h.parent,'feFlood',$.extend(i,h.settings||{}))},gaussianBlur:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','in1','stdDevX','stdDevY'],['stdDevY']);return this._wrapper._makeNode(g.parent,'feGaussianBlur',$.extend({result:g.result,in_:g.in1,stdDeviation:g.stdDevX+(g.stdDevY?' '+g.stdDevY:'')},g.settings||{}))},image:function(a,b,c,d){var e=this._wrapper._args(arguments,['result','href']);var f=this._wrapper._makeNode(e.parent,'feImage',$.extend({result:e.result},e.settings||{}));f.setAttributeNS($.svg.xlinkNS,'href',e.href);return f},merge:function(a,b,c,d){var e=this._wrapper._args(arguments,['result','refs']);var f=this._wrapper._makeNode(e.parent,'feMerge',$.extend({result:e.result},e.settings||{}));for(var i=0;i<e.refs.length;i++){this._wrapper._makeNode(f,'feMergeNode',{in_:e.refs[i]})}return f},morphology:function(a,b,c,d,e,f,g){var h=this._wrapper._args(arguments,['result','in1','operator','radiusX','radiusY'],['radiusY']);return this._wrapper._makeNode(h.parent,'feMorphology',$.extend({result:h.result,in_:h.in1,operator:h.operator,radius:h.radiusX+(h.radiusY?' '+h.radiusY:'')},h.settings||{}))},offset:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','in1','dx','dy']);return this._wrapper._makeNode(g.parent,'feOffset',$.extend({result:g.result,in_:g.in1,dx:g.dx,dy:g.dy},g.settings||{}))},specularLighting:function(a,b,c,d,e,f,g){var h=this._wrapper._args(arguments,['result','in1','surfaceScale','specularConstant','specularExponent'],['surfaceScale','specularConstant','specularExponent']);return this._wrapper._makeNode(h.parent,'feSpecularLighting',$.extend({result:h.result,in_:h.in1,surfaceScale:h.surfaceScale,specularConstant:h.specularConstant,specularExponent:h.specularExponent},h.settings||{}))},tile:function(a,b,c,x,y,d,e,f){var g=this._wrapper._args(arguments,['result','in1','x','y','width','height']);return this._wrapper._makeNode(g.parent,'feTile',$.extend({result:g.result,in_:g.in1,x:g.x,y:g.y,width:g.width,height:g.height},g.settings||{}))},turbulence:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','type','baseFreq','octaves'],['octaves']);return this._wrapper._makeNode(g.parent,'feTurbulence',$.extend({result:g.result,type:g.type,baseFrequency:g.baseFreq,numOctaves:g.octaves},g.settings||{}))}});function isArray(a){return(a&&a.constructor==Array)}})(jQuery)
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.pack.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.pack.js
new file mode 100644
index 0000000..86ca895
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgfilter.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG filters for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(n($){$.V.1n(\'1o\',W);$.m($.V.1p.1e,{1f:n(a,b,x,y,c,d,e){9 f=7.s(q,[\'X\',\'x\',\'y\',\'w\',\'C\']);r 7.o(f.t,\'1f\',$.m({X:f.X,x:f.x,y:f.y,w:f.w,C:f.C},f.p||{}))}});n W(a){7.8=a}$.m(W.1e,{1q:n(a,b,c,d,e){9 f=7.8.s(q,[\'5\',\'Y\',\'Z\']);r 7.8.o(f.t,\'1r\',$.m({5:f.5,Y:f.Y,Z:f.Z},f.p||{}))},1s:n(a,b,x,y,z,c){9 d=7.8.s(q,[\'5\',\'x\',\'y\',\'z\']);r 7.8.o(d.t,\'1t\',$.m({5:d.5,x:d.x,y:d.y,z:d.z},d.p||{}))},1u:n(a,b,x,y,z,c,d,e,f){9 g=7.8.s(q,[\'5\',\'x\',\'y\',\'z\',\'N\',\'1g\',\'1h\'],[\'N\']);9 h=$.m({5:g.5,x:g.x,y:g.y,z:g.z},(g.N!=I?{1v:g.N,1w:g.1g,1x:g.1h}:{}));r 7.8.o(g.t,\'1y\',$.m(h,g.p||{}))},1z:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'10\',\'u\',\'D\']);r 7.8.o(g.t,\'1A\',$.m({5:g.5,10:g.10,E:g.u,D:g.D},g.p||{}))},1B:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'u\',\'F\',\'v\']);11(1i(g.v)){9 h=\'\';O(9 i=0;i<g.v.K;i++){h+=(i==0?\'\':\' \')+g.v[i].12(\' \')}g.v=h}1C 11(1D g.v==\'1E\'){g.p=g.v;g.v=I}9 j=$.m({5:g.5,E:g.u,F:g.F},(g.v!=I?{v:g.v}:{}));r 7.8.o(g.t,\'1F\',$.m(j,g.p||{}))},1G:n(a,b,c,d){9 e=7.8.s(q,[\'5\',\'13\']);9 f=7.8.o(e.t,\'1H\',$.m({5:e.5},e.p||{}));9 g=[\'R\',\'G\',\'B\',\'A\'];O(9 i=0;i<1I.1J(4,e.13.K);i++){9 h=e.13[i];9 j=$.m({F:h[0]},(h[0]==\'1K\'||h[0]==\'1L\'?{1M:h[1].12(\' \')}:(h[0]==\'1N\'?{1O:h[1],1P:h[2]}:(h[0]==\'1Q\'?{1R:h[1],1S:h[2],1j:h[3]}:{}))));7.8.o(f,\'1T\'+g[i],j)}r f},1U:n(a,b,c,d,e,f,g,h,i,j){9 k=7.8.s(q,[\'5\',\'J\',\'u\',\'D\',\'L\',\'14\',\'15\',\'16\'],[\'L\']);9 l=$.m({5:k.5,J:k.J,\'1V\':k.u,D:k.D},(k.L!=I?{L:k.L,14:k.14,15:k.15,16:k.16}:{}));r 7.8.o(k.t,\'1W\',$.m(l,k.p||{}))},1X:n(a,b,c,d,e){9 f=7.8.s(q,[\'5\',\'17\',\'M\']);9 g=\'\';O(9 i=0;i<f.M.K;i++){g+=(i==0?\'\':\' \')+f.M[i].12(\' \')}f.M=g;r 7.8.o(f.t,\'1Y\',$.m({5:f.5,17:f.17,1Z:f.M},f.p||{}))},20:n(a,b,c,d){9 e=7.8.s(q,[\'5\',\'H\'],[\'H\']);r 7.8.o(e.t,\'21\',$.m($.m({5:e.5},(e.H?{22:e.H}:{})),e.p||{}))},23:n(a,b,c,d,e){9 f=7.8.s(q,[\'5\',\'u\',\'D\']);r 7.8.o(f.t,\'24\',$.m({5:f.5,E:f.u,D:f.D},f.p||{}))},25:n(a,b,x,y,c,d,e,f,g){9 h=7.8.s(q,[\'5\',\'x\',\'y\',\'w\',\'C\',\'H\',\'18\']);11(q.K<6){h.H=h.x;h.18=h.y;h.p=h.w;h.x=I}9 i=$.m({5:h.5,26:h.H,27:h.18},(h.x!=I?{x:h.x,y:h.y,w:h.w,C:h.C}:{}));r 7.8.o(h.t,\'28\',$.m(i,h.p||{}))},29:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'u\',\'1k\',\'P\'],[\'P\']);r 7.8.o(g.t,\'2a\',$.m({5:g.5,E:g.u,2b:g.1k+(g.P?\' \'+g.P:\'\')},g.p||{}))},2c:n(a,b,c,d){9 e=7.8.s(q,[\'5\',\'19\']);9 f=7.8.o(e.t,\'2d\',$.m({5:e.5},e.p||{}));f.2e($.V.2f,\'19\',e.19);r f},2g:n(a,b,c,d){9 e=7.8.s(q,[\'5\',\'1a\']);9 f=7.8.o(e.t,\'2h\',$.m({5:e.5},e.p||{}));O(9 i=0;i<e.1a.K;i++){7.8.o(f,\'2i\',{E:e.1a[i]})}r f},2j:n(a,b,c,d,e,f,g){9 h=7.8.s(q,[\'5\',\'u\',\'J\',\'1l\',\'Q\'],[\'Q\']);r 7.8.o(h.t,\'2k\',$.m({5:h.5,E:h.u,J:h.J,2l:h.1l+(h.Q?\' \'+h.Q:\'\')},h.p||{}))},1j:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'u\',\'1b\',\'1c\']);r 7.8.o(g.t,\'2m\',$.m({5:g.5,E:g.u,1b:g.1b,1c:g.1c},g.p||{}))},2n:n(a,b,c,d,e,f,g){9 h=7.8.s(q,[\'5\',\'u\',\'S\',\'T\',\'U\'],[\'S\',\'T\',\'U\']);r 7.8.o(h.t,\'2o\',$.m({5:h.5,E:h.u,S:h.S,T:h.T,U:h.U},h.p||{}))},2p:n(a,b,c,x,y,d,e,f){9 g=7.8.s(q,[\'5\',\'u\',\'x\',\'y\',\'w\',\'C\']);r 7.8.o(g.t,\'2q\',$.m({5:g.5,E:g.u,x:g.x,y:g.y,w:g.w,C:g.C},g.p||{}))},2r:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'F\',\'1m\',\'1d\'],[\'1d\']);r 7.8.o(g.t,\'2s\',$.m({5:g.5,F:g.F,2t:g.1m,2u:g.1d},g.p||{}))}});n 1i(a){r(a&&a.2v==2w)}})(2x)',62,158,'|||||result||this|_wrapper|var|||||||||||||extend|function|_makeNode|settings|arguments|return|_args|parent|in1|values|width||||||height|in2|in_|type||colour|null|operator|length|k1|matrix|toX|for|stdDevY|radiusY||surfaceScale|specularConstant|specularExponent|svg|SVGFilter|id|azimuth|elevation|mode|if|join|functions|k2|k3|k4|order|opacity|href|refs|dx|dy|octaves|prototype|filter|toY|toZ|isArray|offset|stdDevX|radiusX|baseFreq|addExtension|filters|_wrapperClass|distantLight|feDistantLight|pointLight|fePointLight|spotLight|pointsAtX|pointsAtY|pointsAtZ|feSpotLight|blend|feBlend|colorMatrix|else|typeof|object|feColorMatrix|componentTransfer|feComponentTransfer|Math|min|table|discrete|tableValues|linear|slope|intercept|gamma|amplitude|exponent|feFunc|composite|in|feComposite|convolveMatrix|feConvolveMatrix|kernelMatrix|diffuseLighting|feDiffuseLighting|lightingColor|displacementMap|feDisplacementMap|flood|floodColor|floodOpacity|feFlood|gaussianBlur|feGaussianBlur|stdDeviation|image|feImage|setAttributeNS|xlinkNS|merge|feMerge|feMergeNode|morphology|feMorphology|radius|feOffset|specularLighting|feSpecularLighting|tile|feTile|turbulence|feTurbulence|baseFrequency|numOctaves|constructor|Array|jQuery'.split('|'),0,{}))
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.js
new file mode 100644
index 0000000..5318d7b
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.js
@@ -0,0 +1,1482 @@
+/* http://keith-wood.name/svg.html
+   SVG graphing extension for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+$.svg.addExtension('graph', SVGGraph);
+
+// Singleton primary SVG graphing interface
+$.svg.graphing = new SVGGraphing();
+
+function SVGGraphing() {
+	this.regional = [];
+	this.regional[''] = {percentageText: 'Percentage'};
+	this.region = this.regional[''];
+}
+
+$.extend(SVGGraphing.prototype, {
+	_chartTypes: [],
+
+	/* Add a new chart rendering type to the package.
+	   The rendering object must implement the following functions:
+	   getTitle(), getDescription(), getOptions(), drawChart(graph).
+	   @param  id         (string) the ID of this graph renderer
+	   @param  chartType  (object) the object implementing this chart type */
+	addChartType: function(id, chartType) {
+		this._chartTypes[id] = chartType;
+	},
+
+	/* Retrieve the list of chart types.
+	   @return  (object[string]) the array of chart types indexed by ID */
+	chartTypes: function() {
+		return this._chartTypes;
+	}
+});
+
+/* Extension point for SVG graphing.
+   Access through svg.graph. */
+function SVGGraph(wrapper) {
+	this._wrapper = wrapper; // The attached SVG wrapper object
+	this._drawNow = false; // True for immediate update, false to wait for redraw call
+	for (var id in $.svg.graphing._chartTypes) {
+		this._chartType = $.svg.graphing._chartTypes[id]; // Use first graph renderer
+		break;
+	}
+	this._chartOptions = {}; // Extra options for the graph type
+	// The graph title and settings
+	this._title = {value: '', offset: 25, settings: {textAnchor: 'middle'}};
+	this._area = [0.1, 0.1, 0.8, 0.9]; // The chart area: left, top, right, bottom,
+		// > 1 in pixels, <= 1 as proportion
+	this._chartFormat = {fill: 'none', stroke: 'black'}; // The formatting for the chart area
+	this._gridlines = []; // The formatting of the x- and y-gridlines
+	this._series = []; // The series to be plotted, each is an object
+	this._onstatus = null; // The callback function for status updates
+	this._chartCont = this._wrapper.svg(0, 0, 0, 0, {class_: 'svg-graph'}); // The main container for the graph
+
+	this.xAxis = new SVGGraphAxis(this); // The main x-axis
+	this.xAxis.title('', 40);
+	this.yAxis = new SVGGraphAxis(this); // The main y-axis
+	this.yAxis.title('', 40);
+	this.x2Axis = null; // The secondary x-axis
+	this.y2Axis = null; // The secondary y-axis
+	this.legend = new SVGGraphLegend(this); // The chart legend
+	this._drawNow = true;
+}
+
+$.extend(SVGGraph.prototype, {
+
+	/* Useful indexes. */
+	X: 0,
+	Y: 1,
+	W: 2,
+	H: 3,
+	L: 0,
+	T: 1,
+	R: 2,
+	B: 3,
+
+	/* Standard percentage axis. */
+	_percentageAxis: new SVGGraphAxis(this, $.svg.graphing.region.percentageText, 0, 100, 10, 0),
+
+	/* Set or retrieve the container for the graph.
+	   @param  cont  (SVG element) the container for the graph
+	   @return  (SVGGraph) this graph object or
+	            (SVG element) the current container (if no parameters) */
+	container: function(cont) {
+		if (arguments.length == 0) {
+			return this._chartCont;
+		}
+		this._chartCont = cont;
+		return this;
+	},
+
+	/* Set or retrieve the type of chart to be rendered.
+	   See $.svg.graphing.getChartTypes() for the list of available types.
+	   @param  id       (string) the ID of the chart type
+	   @param  options  (object) additional settings for this chart type (optional)
+	   @return  (SVGGraph) this graph object or
+	            (string) the chart type (if no parameters)
+	   @deprecated  use type() */
+	chartType: function(id, options) {
+		return (arguments.length == 0 ? this.type() : this.type(id, options));
+	},
+
+	/* Set or retrieve the type of chart to be rendered.
+	   See $.svg.graphing.getChartTypes() for the list of available types.
+	   @param  id       (string) the ID of the chart type
+	   @param  options  (object) additional settings for this chart type (optional)
+	   @return  (SVGGraph) this graph object or
+	            (string) the chart type (if no parameters) */
+	type: function(id, options) {
+		if (arguments.length == 0) {
+			return this._chartType;
+		}
+		var chartType = $.svg.graphing._chartTypes[id];
+		if (chartType) {
+			this._chartType = chartType;
+			this._chartOptions = $.extend({}, options || {});
+		}
+		this._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve additional options for the particular chart type.
+	   @param  options  (object) the extra options
+	   @return  (SVGGraph) this graph object or
+	            (object) the chart options (if no parameters)
+	   @deprecated  use options() */
+	chartOptions: function(options) {
+		return(arguments.length == 0 ? this.options() : this.options(options));
+	},
+
+	/* Set or retrieve additional options for the particular chart type.
+	   @param  options  (object) the extra options
+	   @return  (SVGGraph) this graph object or
+	            (object) the chart options (if no parameters) */
+	options: function(options) {
+		if (arguments.length == 0) {
+			return this._chartOptions;
+		}
+		this._chartOptions = $.extend({}, options);
+		this._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the background of the graph chart.
+	   @param  fill      (string) how to fill the chart background
+	   @param  stroke    (string) the colour of the outline (optional)
+	   @param  settings  (object) additional formatting for the chart background (optional)
+	   @return  (SVGGraph) this graph object or
+	            (object) the chart format (if no parameters)
+	   @deprecated  use format() */
+	chartFormat: function(fill, stroke, settings) {
+		return (arguments.length == 0 ? this.format() : this.format(fill, stroke, settings));
+	},
+
+	/* Set or retrieve the background of the graph chart.
+	   @param  fill      (string) how to fill the chart background
+	   @param  stroke    (string) the colour of the outline (optional)
+	   @param  settings  (object) additional formatting for the chart background (optional)
+	   @return  (SVGGraph) this graph object or
+	            (object) the chart format (if no parameters) */
+	format: function(fill, stroke, settings) {
+		if (arguments.length == 0) {
+			return this._chartFormat;
+		}
+		if (typeof stroke == 'object') {
+			settings = stroke;
+			stroke = null;
+		}
+		this._chartFormat = $.extend({fill: fill},
+			(stroke ? {stroke: stroke} : {}), settings || {});
+		this._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the main chart area.
+	   @param  left    (number) > 1 is pixels, <= 1 is proportion of width or
+	                   (number[4]) for left, top, right, bottom
+	   @param  top     (number) > 1 is pixels, <= 1 is proportion of height
+	   @param  right   (number) > 1 is pixels, <= 1 is proportion of width
+	   @param  bottom  (number) > 1 is pixels, <= 1 is proportion of height
+	   @return  (SVGGraph) this graph object or
+	            (number[4]) the chart area: left, top, right, bottom (if no parameters)
+	   @deprecated use area() */
+	chartArea: function(left, top, right, bottom) {
+		return (arguments.length == 0 ? this.area() : this.area(left, top, right, bottom));
+	},
+
+	/* Set or retrieve the main chart area.
+	   @param  left    (number) > 1 is pixels, <= 1 is proportion of width or
+	                   (number[4]) for left, top, right, bottom
+	   @param  top     (number) > 1 is pixels, <= 1 is proportion of height
+	   @param  right   (number) > 1 is pixels, <= 1 is proportion of width
+	   @param  bottom  (number) > 1 is pixels, <= 1 is proportion of height
+	   @return  (SVGGraph) this graph object or
+	            (number[4]) the chart area: left, top, right, bottom (if no parameters) */
+	area: function(left, top, right, bottom) {
+		if (arguments.length == 0) {
+			return this._area;
+		}
+		this._area = (isArray(left) ? left : [left, top, right, bottom]);
+		this._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the gridlines formatting for the graph chart.
+	   @param  xSettings  (string) the colour of the gridlines along the x-axis, or
+	                      (object) formatting for the gridlines along the x-axis, or
+	                      null for none
+	   @param  ySettings  (string) the colour of the gridlines along the y-axis, or
+	                      (object) formatting for the gridlines along the y-axis, or
+	                      null for none
+	   @return  (SVGGraph) this graph object or
+	            (object[2]) the gridlines formatting (if no parameters) */
+	gridlines: function(xSettings, ySettings) {
+		if (arguments.length == 0) {
+			return this._gridlines;
+		}
+		this._gridlines = [(typeof xSettings == 'string' ? {stroke: xSettings} : xSettings),
+			(typeof ySettings == 'string' ? {stroke: ySettings} : ySettings)];
+		if (this._gridlines[0] == null && this._gridlines[1] == null) {
+			this._gridlines = [];
+		}
+		this._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the title of the graph and its formatting.
+	   @param  value     (string) the title
+	   @param  offset    (number) the vertical positioning of the title
+                          > 1 is pixels, <= 1 is proportion of width (optional)
+	   @param  colour    (string) the colour of the title (optional)
+	   @param  settings  (object) formatting for the title (optional)
+	   @return  (SVGGraph) this graph object or
+	            (object) value, offset, and settings for the title (if no parameters) */
+	title: function(value, offset, colour, settings) {
+		if (arguments.length == 0) {
+			return this._title;
+		}
+		if (typeof offset != 'number') {
+			settings = colour;
+			colour = offset;
+			offset = null;
+		}
+		if (typeof colour != 'string') {
+			settings = colour;
+			colour = null;
+		}
+		this._title = {value: value, offset: offset || this._title.offset,
+			settings: $.extend({textAnchor: 'middle'},
+			(colour ? {fill: colour} : {}), settings || {})};
+		this._drawGraph();
+		return this;
+	},
+
+	/* Add a series of values to be plotted on the graph.
+	   @param  name         (string) the name of this series (optional)
+	   @param  values       (number[]) the values to be plotted
+	   @param  fill         (string) how the plotted values are filled
+	   @param  stroke       (string) the colour of the plotted lines (optional)
+	   @param  strokeWidth  (number) the width of the plotted lines (optional)
+	   @param  settings     (object) additional settings for the plotted values (optional)
+	   @return  (SVGGraph) this graph object */
+	addSeries: function(name, values, fill, stroke, strokeWidth, settings) {
+		this._series.push(new SVGGraphSeries(
+			this, name, values, fill, stroke, strokeWidth, settings));
+		this._drawGraph();
+		return this;
+	},
+
+	/* Retrieve the series wrappers.
+	   @param  i  (number) the series index (optional)
+	   @return  (SVGGraphSeries) the specified series or
+	            (SVGGraphSeries[]) the list of series */
+	series: function(i) {
+		return (arguments.length > 0 ? this._series[i] : null) || this._series;
+	},
+
+	/* Suppress drawing of the graph until redraw() is called.
+	   @return  (SVGGraph) this graph object */
+	noDraw: function() {
+		this._drawNow = false;
+		return this;
+	},
+
+	/* Redraw the entire graph with the current settings and values.
+	   @return  (SVGGraph) this graph object */
+	redraw: function() {
+		this._drawNow = true;
+		this._drawGraph();
+		return this;
+	},
+
+	/* Set the callback function for status updates.
+	   @param  onstatus  (function) the callback function
+	   @return  (SVGGraph) this graph object */
+	status: function(onstatus) {
+		this._onstatus = onstatus;
+		return this;
+	},
+
+	/* Actually draw the graph (if allowed) based on the graph type set. */
+	_drawGraph: function() {
+		if (!this._drawNow) {
+			return;
+		}
+		while (this._chartCont.firstChild) {
+			this._chartCont.removeChild(this._chartCont.firstChild);
+		}
+		if (!this._chartCont.parent) {
+			this._wrapper._svg.appendChild(this._chartCont);
+		}
+		// Set sizes if not already there
+		if (!this._chartCont.width) {
+			this._chartCont.setAttribute('width',
+				parseInt(this._chartCont.getAttribute('width'), 10) || this._wrapper._width());
+		}
+		else if (this._chartCont.width.baseVal) {
+			this._chartCont.width.baseVal.value =
+				this._chartCont.width.baseVal.value || this._wrapper._width();
+		}
+		else {
+			this._chartCont.width = this._chartCont.width || this._wrapper._width();
+		}
+		if (!this._chartCont.height) {
+			this._chartCont.setAttribute('height',
+				parseInt(this._chartCont.getAttribute('height'), 10) || this._wrapper._height());
+		}
+		else if (this._chartCont.height.baseVal) {
+			this._chartCont.height.baseVal.value =
+				this._chartCont.height.baseVal.value || this._wrapper._height();
+		}
+		else {
+			this._chartCont.height = this._chartCont.height || this._wrapper._height();
+		}
+		this._chartType.drawGraph(this);
+	},
+
+	/* Decode an attribute value.
+	   @param  node  the node to examine
+	   @param  name  the attribute name
+	   @return  the actual value */
+	_getValue: function(node, name) {
+		return (!node[name] ? parseInt(node.getAttribute(name), 10) :
+			(node[name].baseVal ? node[name].baseVal.value : node[name]));
+	},
+
+	/* Draw the graph title - centred. */
+	_drawTitle: function() {
+		this._wrapper.text(this._chartCont, this._getValue(this._chartCont, 'width') / 2,
+			this._title.offset, this._title.value, this._title.settings);
+	},
+
+	/* Calculate the actual dimensions of the chart area.
+	   @param  area  (number[4]) the area values to evaluate (optional)
+	   @return  (number[4]) an array of dimension values: left, top, width, height */
+	_getDims: function(area) {
+		area = area || this._area;
+		var availWidth = this._getValue(this._chartCont, 'width');
+		var availHeight = this._getValue(this._chartCont, 'height');
+		var left = (area[this.L] > 1 ? area[this.L] : availWidth * area[this.L]);
+		var top = (area[this.T] > 1 ? area[this.T] : availHeight * area[this.T]);
+		var width = (area[this.R] > 1 ? area[this.R] : availWidth * area[this.R]) - left;
+		var height = (area[this.B] > 1 ? area[this.B] : availHeight * area[this.B]) - top;
+		return [left, top, width, height];
+	},
+
+	/* Draw the chart background, including gridlines.
+	   @param  noXGrid  (boolean) true to suppress the x-gridlines, false to draw them (optional)
+	   @param  noYGrid  (boolean) true to suppress the y-gridlines, false to draw them (optional)
+	   @return  (element) the background group element */
+	_drawChartBackground: function(noXGrid, noYGrid) {
+		var bg = this._wrapper.group(this._chartCont, {class_: 'background'});
+		var dims = this._getDims();
+		this._wrapper.rect(bg, dims[this.X], dims[this.Y], dims[this.W], dims[this.H], this._chartFormat);
+		if (this._gridlines[0] && this.yAxis._ticks.major && !noYGrid) {
+			this._drawGridlines(bg, this.yAxis, true, dims, this._gridlines[0]);
+		}
+		if (this._gridlines[1] && this.xAxis._ticks.major && !noXGrid) {
+			this._drawGridlines(bg, this.xAxis, false, dims, this._gridlines[1]);
+		}
+		return bg;
+	},
+
+	/* Draw one set of gridlines.
+	   @param  bg      (element) the background group element
+	   @param  axis    (SVGGraphAxis) the axis definition
+	   @param  horiz   (boolean) true if horizontal, false if vertical
+	   @param  dims    (number[]) the left, top, width, height of the chart area
+	   @param  format  (object) additional settings for the gridlines */
+	_drawGridlines: function(bg, axis, horiz, dims, format) {
+		var g = this._wrapper.group(bg, format);
+		var scale = (horiz ? dims[this.H] : dims[this.W]) / (axis._scale.max - axis._scale.min);
+		var major = Math.floor(axis._scale.min / axis._ticks.major) * axis._ticks.major;
+		major = (major < axis._scale.min ? major + axis._ticks.major : major);
+		while (major <= axis._scale.max) {
+			var v = (horiz ? axis._scale.max - major : major - axis._scale.min) * scale +
+				(horiz ? dims[this.Y] : dims[this.X]);
+			this._wrapper.line(g, (horiz ? dims[this.X] : v), (horiz ? v : dims[this.Y]),
+				(horiz ? dims[this.X] + dims[this.W] : v), (horiz ? v : dims[this.Y] + dims[this.H]));
+			major += axis._ticks.major;
+		}
+	},
+
+	/* Draw the axes in their standard configuration.
+	   @param  noX  (boolean) true to suppress the x-axes, false to draw it (optional) */
+	_drawAxes: function(noX) {
+		var dims = this._getDims();
+		if (this.xAxis && !noX) {
+			if (this.xAxis._title) {
+				this._wrapper.text(this._chartCont, dims[this.X] + dims[this.W] / 2,
+					dims[this.Y] + dims[this.H] + this.xAxis._titleOffset,
+					this.xAxis._title, this.xAxis._titleFormat);
+			}
+			this._drawAxis(this.xAxis, 'xAxis', dims[this.X], dims[this.Y] + dims[this.H],
+				dims[this.X] + dims[this.W], dims[this.Y] + dims[this.H]);
+		}
+		if (this.yAxis) {
+			if (this.yAxis._title) {
+				this._wrapper.text(this._chartCont, 0, 0, this.yAxis._title, $.extend({textAnchor: 'middle',
+					transform: 'translate(' + (dims[this.X] - this.yAxis._titleOffset) + ',' +
+					(dims[this.Y] + dims[this.H] / 2) + ') rotate(-90)'}, this.yAxis._titleFormat || {}));
+			}
+			this._drawAxis(this.yAxis, 'yAxis', dims[this.X], dims[this.Y],
+				dims[this.X], dims[this.Y] + dims[this.H]);
+		}
+		if (this.x2Axis && !noX) {
+			if (this.x2Axis._title) {
+				this._wrapper.text(this._chartCont, dims[this.X] + dims[this.W] / 2,
+					dims[this.X] - this.x2Axis._titleOffset, this.x2Axis._title, this.x2Axis._titleFormat);
+			}
+			this._drawAxis(this.x2Axis, 'x2Axis', dims[this.X], dims[this.Y],
+				dims[this.X] + dims[this.W], dims[this.Y]);
+		}
+		if (this.y2Axis) {
+			if (this.y2Axis._title) {
+				this._wrapper.text(this._chartCont, 0, 0, this.y2Axis._title, $.extend({textAnchor: 'middle',
+					transform: 'translate(' + (dims[this.X] + dims[this.W] + this.y2Axis._titleOffset) +
+					',' + (dims[this.Y] + dims[this.H] / 2) + ') rotate(-90)'}, this.y2Axis._titleFormat || {}));
+			}
+			this._drawAxis(this.y2Axis, 'y2Axis', dims[this.X] + dims[this.W], dims[this.Y],
+				dims[this.X] + dims[this.W], dims[this.Y] + dims[this.H]);
+		}
+	},
+
+	/* Draw an axis and its tick marks.
+	   @param  axis  (SVGGraphAxis) the axis definition
+	   @param  id    (string) the identifier for the axis group element
+	   @param  x1    (number) starting x-coodinate for the axis
+	   @param  y1    (number) starting y-coodinate for the axis
+	   @param  x2    (number) ending x-coodinate for the axis
+	   @param  y2    (number) ending y-coodinate for the axis */
+	_drawAxis: function(axis, id, x1, y1, x2, y2) {
+		var horiz = (y1 == y2);
+		var gl = this._wrapper.group(this._chartCont, $.extend({class_: id}, axis._lineFormat));
+		var gt = this._wrapper.group(this._chartCont, $.extend({class_: id + 'Labels',
+			textAnchor: (horiz ? 'middle' : 'end')}, axis._labelFormat));
+		this._wrapper.line(gl, x1, y1, x2, y2);
+		if (axis._ticks.major) {
+			var bottomRight = (x2 > (this._getValue(this._chartCont, 'width') / 2) &&
+				y2 > (this._getValue(this._chartCont, 'height') / 2));
+			var scale = (horiz ? x2 - x1 : y2 - y1) / (axis._scale.max - axis._scale.min);
+			var size = axis._ticks.size;
+			var major = Math.floor(axis._scale.min / axis._ticks.major) * axis._ticks.major;
+			major = (major < axis._scale.min ? major + axis._ticks.major : major);
+			var minor = (!axis._ticks.minor ? axis._scale.max + 1 :
+				Math.floor(axis._scale.min / axis._ticks.minor) * axis._ticks.minor);
+			minor = (minor < axis._scale.min ? minor + axis._ticks.minor : minor);
+			var offsets = this._getTickOffsets(axis, bottomRight);
+			var count = 0;
+			while (major <= axis._scale.max || minor <= axis._scale.max) {
+				var cur = Math.min(major, minor);
+				var len = (cur == major ? size : size / 2);
+				var v = (horiz ? x1 : y1) +
+					(horiz ? cur - axis._scale.min : axis._scale.max - cur) * scale;
+				this._wrapper.line(gl, (horiz ? v : x1 + len * offsets[0]),
+					(horiz ? y1 + len * offsets[0] : v),
+					(horiz ? v : x1 + len * offsets[1]),
+					(horiz ? y1 + len * offsets[1] : v));
+				if (cur == major) {
+					this._wrapper.text(gt, (horiz ? v : x1 - size), (horiz ? y1 + 2 * size : v),
+						(axis._labels ? axis._labels[count++] : '' + cur));
+				}
+				major += (cur == major ? axis._ticks.major : 0);
+				minor += (cur == minor ? axis._ticks.minor : 0);
+			}
+		}
+	},
+
+	/* Calculate offsets based on axis and tick positions.
+	   @param  axis         (SVGGraphAxis) the axis definition
+	   @param  bottomRight  (boolean) true if this axis is appearing on the bottom or
+	                        right of the chart area, false if to the top or left
+	   @return  (number[2]) the array of offset multipliers (-1..+1) */
+	_getTickOffsets: function(axis, bottomRight) {
+		return [(axis._ticks.position == (bottomRight ? 'in' : 'out') ||
+			axis._ticks.position == 'both' ? -1 : 0),
+			(axis._ticks.position == (bottomRight ? 'out' : 'in') ||
+			axis._ticks.position == 'both' ? +1 : 0), ];
+	},
+
+	/* Retrieve the standard percentage axis.
+	   @return  (SVGGraphAxis) percentage axis */
+	_getPercentageAxis: function() {
+		this._percentageAxis._title = $.svg.graphing.region.percentageText;
+		return this._percentageAxis;
+	},
+
+	/* Calculate the column totals across all the series. */
+	_getTotals: function() {
+		var totals = [];
+		var numVal = (this._series.length ? this._series[0]._values.length : 0);
+		for (var i = 0; i < numVal; i++) {
+			totals[i] = 0;
+			for (var j = 0; j < this._series.length; j++) {
+				totals[i] += this._series[j]._values[i];
+			}
+		}
+		return totals;
+	},
+
+	/* Draw the chart legend. */
+	_drawLegend: function() {
+		if (!this.legend._show) {
+			return;
+		}
+		var g = this._wrapper.group(this._chartCont, {class_: 'legend'});
+		var dims = this._getDims(this.legend._area);
+		this._wrapper.rect(g, dims[this.X], dims[this.Y], dims[this.W], dims[this.H],
+			this.legend._bgSettings);
+		var horiz =  dims[this.W] > dims[this.H];
+		var numSer = this._series.length;
+		var offset = (horiz ? dims[this.W] : dims[this.H]) / numSer;
+		var xBase = dims[this.X] + 5;
+		var yBase = dims[this.Y] + ((horiz ? dims[this.H] : offset) + this.legend._sampleSize) / 2;
+		for (var i = 0; i < numSer; i++) {
+			var series = this._series[i];
+			this._wrapper.rect(g, xBase + (horiz ? i * offset : 0),
+				yBase + (horiz ? 0 : i * offset) - this.legend._sampleSize,
+				this.legend._sampleSize, this.legend._sampleSize,
+				{fill: series._fill, stroke: series._stroke, strokeWidth: 1});
+			this._wrapper.text(g, xBase + (horiz ? i * offset : 0) + this.legend._sampleSize + 5,
+				yBase + (horiz ? 0 : i * offset), series._name, this.legend._textSettings);
+		}
+	},
+
+	/* Show the current value status on hover. */
+	_showStatus: function(elem, label, value) {
+		var status = this._onstatus;
+		if (this._onstatus) {
+			$(elem).hover(function() { status.apply(this, [label, value]); },
+				function() { status.apply(this, ['', 0]); });
+		}
+	}
+});
+
+/* Details about each graph series.
+   @param  graph        (SVGGraph) the owning graph
+   @param  name         (string) the name of this series (optional)
+   @param  values       (number[]) the list of values to be plotted
+   @param  fill         (string) how the series should be displayed
+   @param  stroke       (string) the colour of the (out)line for the series (optional)
+   @param  strokeWidth  (number) the width of the (out)line for the series (optional)
+   @param  settings     (object) additional formatting settings (optional)
+   @return  (SVGGraphSeries) the new series object */
+function SVGGraphSeries(graph, name, values, fill, stroke, strokeWidth, settings) {
+	if (typeof name != 'string') {
+		settings = strokeWidth;
+		strokeWidth = stroke;
+		stroke = fill;
+		fill = values;
+		values = name;
+		name = null;
+	}
+	if (typeof stroke != 'string') {
+		settings = strokeWidth;
+		strokeWidth = stroke;
+		stroke = null;
+	}
+	if (typeof strokeWidth != 'number') {
+		settings = strokeWidth;
+		strokeWidth = null;
+	}
+	this._graph = graph; // The owning graph
+	this._name = name || ''; // The name of this series
+	this._values = values || []; // The list of values for this series
+	this._axis = 1; // Which axis this series applies to: 1 = primary, 2 = secondary
+	this._fill = fill || 'green'; // How the series is plotted
+	this._stroke = stroke || 'black'; // The colour for the (out)line
+	this._strokeWidth = strokeWidth || 1; // The (out)line width
+	this._settings = settings || {}; // Additional formatting settings for the series
+}
+
+$.extend(SVGGraphSeries.prototype, {
+
+	/* Set or retrieve the name for this series.
+	   @param  name    (string) the series' name
+	   @return  (SVGGraphSeries) this series object or
+	            (string) the series name (if no parameters) */
+	name: function(name) {
+		if (arguments.length == 0) {
+			return this._name;
+		}
+		this._name = name;
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the values for this series.
+	   @param  name    (string) the series' name (optional)
+	   @param  values  (number[]) the values to be graphed
+	   @return  (SVGGraphSeries) this series object or
+	            (number[]) the series values (if no parameters) */
+	values: function(name, values) {
+		if (arguments.length == 0) {
+			return this._values;
+		}
+		if (isArray(name)) {
+			values = name;
+			name = null;
+		}
+		this._name = name || this._name;
+		this._values = values;
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the formatting for this series.
+	   @param  fill         (string) how the values are filled when plotted
+	   @param  stroke       (string) the (out)line colour (optional)
+	   @param  strokeWidth  (number) the line's width (optional)
+	   @param  settings     (object) additional formatting settings for the series (optional)
+	   @return  (SVGGraphSeries) this series object or
+	            (object) formatting settings (if no parameters) */
+	format: function(fill, stroke, strokeWidth, settings) {
+		if (arguments.length == 0) {
+			return $.extend({fill: this._fill, stroke: this._stroke,
+				strokeWidth: this._strokeWidth}, this._settings);
+		}
+		if (typeof stroke != 'string') {
+			settings = strokeWidth;
+			strokeWidth = stroke;
+			stroke = null;
+		}
+		if (typeof strokeWidth != 'number') {
+			settings = strokeWidth;
+			strokeWidth = null;
+		}
+		this._fill = fill || this._fill;
+		this._stroke = stroke || this._stroke;
+		this._strokeWidth = strokeWidth || this._strokeWidth;
+		$.extend(this._settings, settings || {});
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Return to the parent graph. */
+	end: function() {
+		return this._graph;
+	}
+});
+
+/* Details about each graph axis.
+   @param  graph  (SVGGraph) the owning graph
+   @param  title  (string) the title of the axis
+   @param  min    (number) the minimum value displayed on this axis
+   @param  max    (number) the maximum value displayed on this axis
+   @param  major  (number) the distance between major ticks
+   @param  minor  (number) the distance between minor ticks (optional)
+   @return  (SVGGraphAxis) the new axis object */
+function SVGGraphAxis(graph, title, min, max, major, minor) {
+	this._graph = graph; // The owning graph
+	this._title = title || ''; // Title of this axis
+	this._titleFormat = {}; // Formatting settings for the title
+	this._titleOffset = 0; // The offset for positioning the title
+	this._labels = null; // List of labels for this axis - one per possible value across all series
+	this._labelFormat = {}; // Formatting settings for the labels
+	this._lineFormat = {stroke: 'black', strokeWidth: 1}; // Formatting settings for the axis lines
+	this._ticks = {major: major || 10, minor: minor || 0, size: 10, position: 'out'}; // Tick mark options
+	this._scale = {min: min || 0, max: max || 100}; // Axis scale settings
+	this._crossAt = 0; // Where this axis crosses the other one
+}
+
+$.extend(SVGGraphAxis.prototype, {
+
+	/* Set or retrieve the scale for this axis.
+	   @param  min  (number) the minimum value shown
+	   @param  max  (number) the maximum value shown
+	   @return  (SVGGraphAxis) this axis object or
+	            (object) min and max values (if no parameters) */
+	scale: function(min, max) {
+		if (arguments.length == 0) {
+			return this._scale;
+		}
+		this._scale.min = min;
+		this._scale.max = max;
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the ticks for this axis.
+	   @param  major     (number) the distance between major ticks
+	   @param  minor     (number) the distance between minor ticks
+	   @param  size      (number) the length of the major ticks (minor are half) (optional)
+	   @param  position  (string) the location of the ticks:
+	                     'in', 'out', 'both' (optional)
+	   @return  (SVGGraphAxis) this axis object or
+	            (object) major, minor, size, and position values (if no parameters) */
+	ticks: function(major, minor, size, position) {
+		if (arguments.length == 0) {
+			return this._ticks;
+		}
+		if (typeof size == 'string') {
+			position = size;
+			size = null;
+		}
+		this._ticks.major = major;
+		this._ticks.minor = minor;
+		this._ticks.size = size || this._ticks.size;
+		this._ticks.position = position || this._ticks.position;
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the title for this axis.
+	   @param  title   (string) the title text
+	   @param  offset  (number) the distance to offset the title position (optional)
+	   @param  colour  (string) how to colour the title (optional)
+	   @param  format  (object) formatting settings for the title (optional)
+	   @return  (SVGGraphAxis) this axis object or
+	            (object) title, offset, and format values (if no parameters) */
+	title: function(title, offset, colour, format) {
+		if (arguments.length == 0) {
+			return {title: this._title, offset: this._titleOffset, format: this._titleFormat};
+		}
+		if (typeof offset != 'number') {
+			format = colour;
+			colour = offset;
+			offset = null;
+		}
+		if (typeof colour != 'string') {
+			format = colour;
+			colour = null;
+		}
+		this._title = title;
+		this._titleOffset = (offset != null ? offset : this._titleOffset);
+		if (colour || format) {
+			this._titleFormat = $.extend(format || {}, (colour ? {fill: colour} : {}));
+		}
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the labels for this axis.
+	   @param  labels  (string[]) the text for each entry
+	   @param  colour  (string) how to colour the labels (optional)
+	   @param  format  (object) formatting settings for the labels (optional)
+	   @return  (SVGGraphAxis) this axis object or
+	            (object) labels and format values (if no parameters) */
+	labels: function(labels, colour, format) {
+		if (arguments.length == 0) {
+			return {labels: this._labels, format: this._labelFormat};
+		}
+		if (typeof colour != 'string') {
+			format = colour;
+			colour = null;
+		}
+		this._labels = labels;
+		if (colour || format) {
+			this._labelFormat = $.extend(format || {}, (colour ? {fill: colour} : {}));
+		}
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the line formatting for this axis.
+	   @param  colour    (string) the line's colour
+	   @param  width     (number) the line's width (optional)
+	   @param  settings  (object) additional formatting settings for the line (optional)
+	   @return  (SVGGraphAxis) this axis object or
+	            (object) line formatting values (if no parameters) */
+	line: function(colour, width, settings) {
+		if (arguments.length == 0) {
+			return this._lineFormat;
+		}
+		if (typeof width == 'object') {
+			settings = width;
+			width = null;
+		}
+		$.extend(this._lineFormat, {stroke: colour},
+			(width ? {strokeWidth: width} : {}), settings || {});
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Return to the parent graph. */
+	end: function() {
+		return this._graph;
+	}
+});
+
+/* Details about the graph legend.
+   @param  graph         (SVGGraph) the owning graph
+   @param  bgSettings    (object) additional formatting settings for the legend background (optional)
+   @param  textSettings  (object) additional formatting settings for the legend text (optional)
+   @return  (SVGGraphLegend) the new legend object */
+function SVGGraphLegend(graph, bgSettings, textSettings) {
+	this._graph = graph; // The owning graph
+	this._show = true; // Show the legend?
+	this._area = [0.9, 0.1, 1.0, 0.9]; // The legend area: left, top, right, bottom,
+		// > 1 in pixels, <= 1 as proportion
+	this._sampleSize = 15; // Size of sample box
+	this._bgSettings = bgSettings || {stroke: 'gray'}; // Additional formatting settings for the legend background
+	this._textSettings = textSettings || {}; // Additional formatting settings for the text
+}
+
+$.extend(SVGGraphLegend.prototype, {
+
+	/* Set or retrieve whether the legend should be shown.
+	   @param  show  (boolean) true to display it, false to hide it
+	   @return  (SVGGraphLegend) this legend object or
+	            (boolean) show the legend? (if no parameters) */
+	show: function(show) {
+		if (arguments.length == 0) {
+			return this._show;
+		}
+		this._show = show;
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve the legend area.
+	   @param  left    (number) > 1 is pixels, <= 1 is proportion of width or
+	                   (number[4]) for left, top, right, bottom
+	   @param  top     (number) > 1 is pixels, <= 1 is proportion of height
+	   @param  right   (number) > 1 is pixels, <= 1 is proportion of width
+	   @param  bottom  (number) > 1 is pixels, <= 1 is proportion of height
+	   @return  (SVGGraphLegend) this legend object or
+	            (number[4]) the legend area: left, top, right, bottom (if no parameters) */
+	area: function(left, top, right, bottom) {
+		if (arguments.length == 0) {
+			return this._area;
+		}
+		this._area = (isArray(left) ? left : [left, top, right, bottom]);
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Set or retrieve additional settings for the legend area.
+	   @param  sampleSize    (number) the size of the sample box to display (optional)
+	   @param  bgSettings    (object) additional formatting settings for the legend background
+	   @param  textSettings  (object) additional formatting settings for the legend text (optional)
+	   @return  (SVGGraphLegend) this legend object or
+	            (object) bgSettings and textSettings for the legend (if no parameters) */
+	settings: function(sampleSize, bgSettings, textSettings) {
+		if (arguments.length == 0) {
+			return {sampleSize: this._sampleSize, bgSettings: this._bgSettings,
+				textSettings: this._textSettings};
+		}
+		if (typeof sampleSize != 'number') {
+			textSettings = bgSettings;
+			bgSettings = sampleSize;
+			sampleSize = null;
+		}
+		this._sampleSize = sampleSize || this._sampleSize;
+		this._bgSettings = bgSettings;
+		this._textSettings = textSettings || this._textSettings;
+		this._graph._drawGraph();
+		return this;
+	},
+
+	/* Return to the parent graph. */
+	end: function() {
+		return this._graph;
+	}
+});
+
+//==============================================================================
+
+/* Round a number to a given number of decimal points. */
+function roundNumber(num, dec) {
+	return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
+}
+
+var barOptions = ['barWidth (number) - the width of each bar',
+	'barGap (number) - the gap between sets of bars'];
+
+//------------------------------------------------------------------------------
+
+/* Draw a standard grouped column bar chart. */
+function SVGColumnChart() {
+}
+
+$.extend(SVGColumnChart.prototype, {
+
+	/* Retrieve the display title for this chart type.
+	   @return  the title */
+	title: function() {
+		return 'Basic column chart';
+	},
+
+	/* Retrieve a description of this chart type.
+	   @return  its description */
+	description: function() {
+		return 'Compare sets of values as vertical bars with grouped categories.';
+	},
+
+	/* Retrieve a list of the options that may be set for this chart type.
+	   @return  options list */
+	options: function() {
+		return barOptions;
+	},
+
+	/* Actually draw the graph in this type's style.
+	   @param  graph  (object) the SVGGraph object */
+	drawGraph: function(graph) {
+		graph._drawChartBackground(true);
+		var barWidth = graph._chartOptions.barWidth || 10;
+		var barGap = graph._chartOptions.barGap || 10;
+		var numSer = graph._series.length;
+		var numVal = (numSer ? (graph._series[0])._values.length : 0);
+		var dims = graph._getDims();
+		var xScale = dims[graph.W] / ((numSer * barWidth + barGap) * numVal + barGap);
+		var yScale = dims[graph.H] / (graph.yAxis._scale.max - graph.yAxis._scale.min);
+		this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'});
+		for (var i = 0; i < numSer; i++) {
+			this._drawSeries(graph, i, numSer, barWidth, barGap, dims, xScale, yScale);
+		}
+		graph._drawTitle();
+		graph._drawAxes(true);
+		this._drawXAxis(graph, numSer, numVal, barWidth, barGap, dims, xScale);
+		graph._drawLegend();
+	},
+
+	/* Plot an individual series. */
+	_drawSeries: function(graph, cur, numSer, barWidth, barGap, dims, xScale, yScale) {
+		var series = graph._series[cur];
+		var g = graph._wrapper.group(this._chart,
+			$.extend({class_: 'series' + cur, fill: series._fill, stroke: series._stroke,
+			strokeWidth: series._strokeWidth}, series._settings || {}));
+		for (var i = 0; i < series._values.length; i++) {
+			var r = graph._wrapper.rect(g,
+				dims[graph.X] + xScale * (barGap + i * (numSer * barWidth + barGap) + (cur * barWidth)),
+				dims[graph.Y] + yScale * (graph.yAxis._scale.max - series._values[i]),
+				xScale * barWidth, yScale * series._values[i]);
+			graph._showStatus(r, series._name, series._values[i]);
+		}
+	},
+
+	/* Draw the x-axis and its ticks. */
+	_drawXAxis: function(graph, numSer, numVal, barWidth, barGap, dims, xScale) {
+		var axis = graph.xAxis;
+		if (axis._title) {
+			graph._wrapper.text(graph._chartCont, dims[graph.X] + dims[graph.W] / 2,
+				dims[graph.Y] + dims[graph.H] + axis._titleOffset,
+				axis._title, $.extend({textAnchor: 'middle'}, axis._titleFormat || {}));
+		}
+		var gl = graph._wrapper.group(graph._chartCont, $.extend({class_: 'xAxis'}, axis._lineFormat));
+		var gt = graph._wrapper.group(graph._chartCont, $.extend({class_: 'xAxisLabels',
+			textAnchor: 'middle'}, axis._labelFormat));
+		graph._wrapper.line(gl, dims[graph.X], dims[graph.Y] + dims[graph.H],
+			dims[graph.X] + dims[graph.W], dims[graph.Y] + dims[graph.H]);
+		if (axis._ticks.major) {
+			var offsets = graph._getTickOffsets(axis, true);
+			for (var i = 1; i < numVal; i++) {
+				var x = dims[graph.X] + xScale * (barGap / 2 + i * (numSer * barWidth + barGap));
+				graph._wrapper.line(gl, x, dims[graph.Y] + dims[graph.H] + offsets[0] * axis._ticks.size,
+					x, dims[graph.Y] + dims[graph.H] + offsets[1] * axis._ticks.size);
+			}
+			for (var i = 0; i < numVal; i++) {
+				var x = dims[graph.X] + xScale * (barGap / 2 + (i + 0.5) * (numSer * barWidth + barGap));
+				graph._wrapper.text(gt, x, dims[graph.Y] + dims[graph.H] + 2 * axis._ticks.size,
+					(axis._labels ? axis._labels[i] : '' + i));
+			}
+		}
+	}
+});
+
+//------------------------------------------------------------------------------
+
+/* Draw a stacked column bar chart. */
+function SVGStackedColumnChart() {
+}
+
+$.extend(SVGStackedColumnChart.prototype, {
+
+	/* Retrieve the display title for this chart type.
+	   @return  the title */
+	title: function() {
+		return 'Stacked column chart';
+	},
+
+	/* Retrieve a description of this chart type.
+	   @return  its description */
+	description: function() {
+		return 'Compare sets of values as vertical bars showing ' +
+			'relative contributions to the whole for each category.';
+	},
+
+	/* Retrieve a list of the options that may be set for this chart type.
+	   @return  options list */
+	options: function() {
+		return barOptions;
+	},
+
+	/* Actually draw the graph in this type's style.
+	   @param  graph  (object) the SVGGraph object */
+	drawGraph: function(graph) {
+		var bg = graph._drawChartBackground(true, true);
+		var dims = graph._getDims();
+		if (graph._gridlines[0] && graph.xAxis._ticks.major) {
+			graph._drawGridlines(bg, graph._getPercentageAxis(), true, dims, graph._gridlines[0]);
+		}
+		var barWidth = graph._chartOptions.barWidth || 10;
+		var barGap = graph._chartOptions.barGap || 10;
+		var numSer = graph._series.length;
+		var numVal = (numSer ? (graph._series[0])._values.length : 0);
+		var xScale = dims[graph.W] / ((barWidth + barGap) * numVal + barGap);
+		var yScale = dims[graph.H];
+		this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'});
+		this._drawColumns(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale);
+		graph._drawTitle();
+		graph._wrapper.text(graph._chartCont, 0, 0, $.svg.graphing.region.percentageText,
+			$.extend({textAnchor: 'middle', transform: 'translate(' +
+			(dims[graph.X] - graph.yAxis._titleOffset) + ',' +
+			(dims[graph.Y] + dims[graph.H] / 2) + ') rotate(-90)'}, graph.yAxis._titleFormat || {}));
+		var pAxis = $.extend({}, graph._getPercentageAxis());
+		$.extend(pAxis._labelFormat, graph.yAxis._labelFormat || {});
+		graph._drawAxis(pAxis, 'yAxis', dims[graph.X], dims[graph.Y],
+			dims[graph.X], dims[graph.Y] + dims[graph.H]);
+		this._drawXAxis(graph, numVal, barWidth, barGap, dims, xScale);
+		graph._drawLegend();
+	},
+
+	/* Plot all of the columns. */
+	_drawColumns: function(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale) {
+		var totals = graph._getTotals();
+		var accum = [];
+		for (var i = 0; i < numVal; i++) {
+			accum[i] = 0;
+		}
+		for (var s = 0; s < numSer; s++) {
+			var series = graph._series[s];
+			var g = graph._wrapper.group(this._chart,
+				$.extend({class_: 'series' + s, fill: series._fill,
+				stroke: series._stroke, strokeWidth: series._strokeWidth},
+				series._settings || {}));
+			for (var i = 0; i < series._values.length; i++) {
+				accum[i] += series._values[i];
+				var r = graph._wrapper.rect(g,
+					dims[graph.X] + xScale * (barGap + i * (barWidth + barGap)),
+					dims[graph.Y] + yScale * (totals[i] - accum[i]) / totals[i],
+					xScale * barWidth, yScale * series._values[i] / totals[i]);
+				graph._showStatus(r, series._name,
+					roundNumber(series._values[i] / totals[i] * 100, 2));
+			}
+		}
+	},
+
+	/* Draw the x-axis and its ticks. */
+	_drawXAxis: function(graph, numVal, barWidth, barGap, dims, xScale) {
+		var axis = graph.xAxis;
+		if (axis._title) {
+			graph._wrapper.text(graph._chartCont, dims[graph.X] + dims[graph.W] / 2,
+				dims[graph.Y] + dims[graph.H] + axis._titleOffset,
+				axis._title, $.extend({textAnchor: 'middle'}, axis._titleFormat || {}));
+		}
+		var gl = graph._wrapper.group(graph._chartCont, $.extend({class_: 'xAxis'}, axis._lineFormat));
+		var gt = graph._wrapper.group(graph._chartCont, $.extend({class_: 'xAxisLabels',
+			textAnchor: 'middle'}, axis._labelFormat));
+		graph._wrapper.line(gl, dims[graph.X], dims[graph.Y] + dims[graph.H],
+		dims[graph.X] + dims[graph.W], dims[graph.Y] + dims[graph.H]);
+		if (axis._ticks.major) {
+			var offsets = graph._getTickOffsets(axis, true);
+			for (var i = 1; i < numVal; i++) {
+				var x = dims[graph.X] + xScale * (barGap / 2 + i * (barWidth + barGap));
+				graph._wrapper.line(gl, x, dims[graph.Y] + dims[graph.H] + offsets[0] * axis._ticks.size,
+					x, dims[graph.Y] + dims[graph.H] + offsets[1] * axis._ticks.size);
+			}
+			for (var i = 0; i < numVal; i++) {
+				var x = dims[graph.X] + xScale * (barGap / 2 + (i + 0.5) * (barWidth + barGap));
+				graph._wrapper.text(gt, x, dims[graph.Y] + dims[graph.H] + 2 * axis._ticks.size,
+					(axis._labels ? axis._labels[i] : '' + i));
+			}
+		}
+	}
+});
+
+//------------------------------------------------------------------------------
+
+/* Draw a standard grouped row bar chart. */
+function SVGRowChart() {
+}
+
+$.extend(SVGRowChart.prototype, {
+
+	/* Retrieve the display title for this chart type.
+	   @return  the title */
+	title: function() {
+		return 'Basic row chart';
+	},
+
+	/* Retrieve a description of this chart type.
+	   @return  its description */
+	description: function() {
+		return 'Compare sets of values as horizontal rows with grouped categories.';
+	},
+
+	/* Retrieve a list of the options that may be set for this chart type.
+	   @return  options list */
+	options: function() {
+		return barOptions;
+	},
+
+	/* Actually draw the graph in this type's style.
+	   @param  graph  (object) the SVGGraph object */
+	drawGraph: function(graph) {
+		var bg = graph._drawChartBackground(true, true);
+		var dims = graph._getDims();
+		graph._drawGridlines(bg, graph.yAxis, false, dims, graph._gridlines[0]);
+		var barWidth = graph._chartOptions.barWidth || 10;
+		var barGap = graph._chartOptions.barGap || 10;
+		var numSer = graph._series.length;
+		var numVal = (numSer ? (graph._series[0])._values.length : 0);
+		var xScale = dims[graph.W] / (graph.yAxis._scale.max - graph.yAxis._scale.min);
+		var yScale = dims[graph.H] / ((numSer * barWidth + barGap) * numVal + barGap);
+		this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'});
+		for (var i = 0; i < numSer; i++) {
+			this._drawSeries(graph, i, numSer, barWidth, barGap, dims, xScale, yScale);
+		}
+		graph._drawTitle();
+		this._drawAxes(graph, numSer, numVal, barWidth, barGap, dims, yScale);
+		graph._drawLegend();
+	},
+
+	/* Plot an individual series. */
+	_drawSeries: function(graph, cur, numSer, barWidth, barGap, dims, xScale, yScale) {
+		var series = graph._series[cur];
+		var g = graph._wrapper.group(this._chart,
+			$.extend({class_: 'series' + cur, fill: series._fill,
+			stroke: series._stroke, strokeWidth: series._strokeWidth},
+			series._settings || {}));
+		for (var i = 0; i < series._values.length; i++) {
+			var r = graph._wrapper.rect(g,
+				dims[graph.X] + xScale * (0 - graph.yAxis._scale.min),
+				dims[graph.Y] + yScale * (barGap + i * (numSer * barWidth + barGap) + (cur * barWidth)),
+				xScale * series._values[i], yScale * barWidth);
+			graph._showStatus(r, series._name, series._values[i]);
+		}
+	},
+
+	/* Draw the axes for this graph. */
+	_drawAxes: function(graph, numSer, numVal, barWidth, barGap, dims, yScale) {
+		// X-axis
+		var axis = graph.yAxis;
+		if (axis) {
+			if (axis._title) {
+				graph._wrapper.text(graph._chartCont, dims[graph.X] + dims[graph.W] / 2,
+					dims[graph.Y] + dims[graph.H] + axis._titleOffset, axis._title, axis._titleFormat);
+			}
+			graph._drawAxis(axis, 'xAxis', dims[graph.X], dims[graph.Y] + dims[graph.H],
+				dims[graph.X] + dims[graph.W], dims[graph.Y] + dims[graph.H]);
+		}
+		// Y-axis
+		var axis = graph.xAxis;
+		if (axis._title) {
+			graph._wrapper.text(graph._chartCont, 0, 0, axis._title, $.extend({textAnchor: 'middle',
+				transform: 'translate(' + (dims[graph.X] - axis._titleOffset) + ',' +
+				(dims[graph.Y] + dims[graph.H] / 2) + ') rotate(-90)'}, axis._titleFormat || {}));
+		}
+		var gl = graph._wrapper.group(graph._chartCont, $.extend({class_: 'yAxis'}, axis._lineFormat));
+		var gt = graph._wrapper.group(graph._chartCont, $.extend(
+			{class_: 'yAxisLabels', textAnchor: 'end'}, axis._labelFormat));
+		graph._wrapper.line(gl, dims[graph.X], dims[graph.Y], dims[graph.X], dims[graph.Y] + dims[graph.H]);
+		if (axis._ticks.major) {
+			var offsets = graph._getTickOffsets(axis, false);
+			for (var i = 1; i < numVal; i++) {
+				var y = dims[graph.Y] + yScale * (barGap / 2 + i * (numSer * barWidth + barGap));
+				graph._wrapper.line(gl, dims[graph.X] + offsets[0] * axis._ticks.size, y,
+					dims[graph.X] + offsets[1] * axis._ticks.size, y);
+			}
+			for (var i = 0; i < numVal; i++) {
+				var y = dims[graph.Y] + yScale * (barGap / 2 + (i + 0.5) * (numSer * barWidth + barGap));
+				graph._wrapper.text(gt, dims[graph.X] - axis._ticks.size, y,
+					(axis._labels ? axis._labels[i] : '' + i));
+			}
+		}
+	}
+});
+
+//------------------------------------------------------------------------------
+
+/* Draw a stacked row bar chart. */
+function SVGStackedRowChart() {
+}
+
+$.extend(SVGStackedRowChart.prototype, {
+
+	/* Retrieve the display title for this chart type.
+	   @return  the title */
+	title: function() {
+		return 'Stacked row chart';
+	},
+
+	/* Retrieve a description of this chart type.
+	   @return  its description */
+	description: function() {
+		return 'Compare sets of values as horizontal bars showing ' +
+			'relative contributions to the whole for each category.';
+	},
+
+	/* Retrieve a list of the options that may be set for this chart type.
+	   @return  options list */
+	options: function() {
+		return barOptions;
+	},
+
+	/* Actually draw the graph in this type's style.
+	   @param  graph  (object) the SVGGraph object */
+	drawGraph: function(graph) {
+		var bg = graph._drawChartBackground(true, true);
+		var dims = graph._getDims();
+		if (graph._gridlines[0] && graph.xAxis._ticks.major) {
+			graph._drawGridlines(bg, graph._getPercentageAxis(), false, dims, graph._gridlines[0]);
+		}
+		var barWidth = graph._chartOptions.barWidth || 10;
+		var barGap = graph._chartOptions.barGap || 10;
+		var numSer = graph._series.length;
+		var numVal = (numSer ? (graph._series[0])._values.length : 0);
+		var xScale = dims[graph.W];
+		var yScale = dims[graph.H] / ((barWidth + barGap) * numVal + barGap);
+		this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'});
+		this._drawRows(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale);
+		graph._drawTitle();
+		graph._wrapper.text(graph._chartCont, dims[graph.X] + dims[graph.W] / 2,
+			dims[graph.Y] + dims[graph.H] + graph.xAxis._titleOffset,
+			$.svg.graphing.region.percentageText,
+			$.extend({textAnchor: 'middle'}, graph.yAxis._titleFormat || {}));
+		var pAxis = $.extend({}, graph._getPercentageAxis());
+		$.extend(pAxis._labelFormat, graph.yAxis._labelFormat || {});
+		graph._drawAxis(pAxis, 'xAxis', dims[graph.X], dims[graph.Y] + dims[graph.H],
+			dims[graph.X] + dims[graph.W], dims[graph.Y] + dims[graph.H]);
+		this._drawYAxis(graph, numVal, barWidth, barGap, dims, yScale);
+		graph._drawLegend();
+	},
+
+	/* Plot all of the rows. */
+	_drawRows: function(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale) {
+		var totals = graph._getTotals();
+		var accum = [];
+		for (var i = 0; i < numVal; i++) {
+			accum[i] = 0;
+		}
+		for (var s = 0; s < numSer; s++) {
+			var series = graph._series[s];
+			var g = graph._wrapper.group(this._chart,
+				$.extend({class_: 'series' + s, fill: series._fill,
+				stroke: series._stroke, strokeWidth: series._strokeWidth},
+				series._settings || {}));
+			for (var i = 0; i < series._values.length; i++) {
+				var r = graph._wrapper.rect(g,
+					dims[graph.X] + xScale * accum[i] / totals[i],
+					dims[graph.Y] + yScale * (barGap + i * (barWidth + barGap)),
+					xScale * series._values[i] / totals[i], yScale * barWidth);
+				graph._showStatus(r, series._name,
+					roundNumber(series._values[i] / totals[i] * 100, 2));
+				accum[i] += series._values[i];
+			}
+		}
+	},
+
+	/* Draw the y-axis and its ticks. */
+	_drawYAxis: function(graph, numVal, barWidth, barGap, dims, yScale) {
+		var axis = graph.xAxis;
+		if (axis._title) {
+			graph._wrapper.text(graph._chartCont, 0, 0, axis._title, $.extend({textAnchor: 'middle',
+				transform: 'translate(' + (dims[graph.X] - axis._titleOffset) + ',' +
+				(dims[graph.Y] + dims[graph.H] / 2) + ') rotate(-90)'}, axis._titleFormat || {}));
+		}
+		var gl = graph._wrapper.group(graph._chartCont,
+			$.extend({class_: 'yAxis'}, axis._lineFormat));
+		var gt = graph._wrapper.group(graph._chartCont,
+			$.extend({class_: 'yAxisLabels', textAnchor: 'end'}, axis._labelFormat));
+		graph._wrapper.line(gl, dims[graph.X], dims[graph.Y],
+			dims[graph.X], dims[graph.Y] + dims[graph.H]);
+		if (axis._ticks.major) {
+			var offsets = graph._getTickOffsets(axis, false);
+			for (var i = 1; i < numVal; i++) {
+				var y = dims[graph.Y] + yScale * (barGap / 2 + i * (barWidth + barGap));
+				graph._wrapper.line(gl, dims[graph.X] + offsets[0] * axis._ticks.size, y,
+					dims[graph.X] + offsets[1] * axis._ticks.size, y);
+			}
+			for (var i = 0; i < numVal; i++) {
+				var y = dims[graph.Y] + yScale * (barGap / 2 + (i + 0.5) * (barWidth + barGap));
+				graph._wrapper.text(gt, dims[graph.X] - axis._ticks.size, y,
+					(axis._labels ? axis._labels[i] : '' + i));
+			}
+		}
+	}
+});
+
+//------------------------------------------------------------------------------
+
+/* Draw a standard line chart. */
+function SVGLineChart() {
+}
+
+$.extend(SVGLineChart.prototype, {
+
+	/* Retrieve the display title for this chart type.
+	   @return  the title */
+	title: function() {
+		return 'Basic line chart';
+	},
+
+	/* Retrieve a description of this chart type.
+	   @return  its description */
+	description: function() {
+		return 'Compare sets of values as continuous lines.';
+	},
+
+	/* Retrieve a list of the options that may be set for this chart type.
+	   @return  options list */
+	options: function() {
+		return [];
+	},
+
+	/* Actually draw the graph in this type's style.
+	   @param  graph  (object) the SVGGraph object */
+	drawGraph: function(graph) {
+		graph._drawChartBackground();
+		var dims = graph._getDims();
+		var xScale = dims[graph.W] / (graph.xAxis._scale.max - graph.xAxis._scale.min);
+		var yScale = dims[graph.H] / (graph.yAxis._scale.max - graph.yAxis._scale.min);
+		this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'});
+		for (var i = 0; i < graph._series.length; i++) {
+			this._drawSeries(graph, i, dims, xScale, yScale);
+		}
+		graph._drawTitle();
+		graph._drawAxes();
+		graph._drawLegend();
+	},
+
+	/* Plot an individual series. */
+	_drawSeries: function(graph, cur, dims, xScale, yScale) {
+		var series = graph._series[cur];
+		var path = graph._wrapper.createPath();
+		for (var i = 0; i < series._values.length; i++) {
+			var x = dims[graph.X] + i * xScale;
+			var y = dims[graph.Y] + (graph.yAxis._scale.max - series._values[i]) * yScale;
+			if (i == 0) {
+				path.move(x, y);
+			}
+			else {
+				path.line(x, y);
+			}
+		}
+		var p = graph._wrapper.path(this._chart, path,
+			$.extend({id: 'series' + cur, fill: 'none', stroke: series._stroke,
+			strokeWidth: series._strokeWidth}, series._settings || {}));
+		graph._showStatus(p, series._name, 0);
+	}
+});
+
+//------------------------------------------------------------------------------
+
+/* Draw a standard pie chart. */
+function SVGPieChart() {
+}
+
+$.extend(SVGPieChart.prototype, {
+
+	_options: ['explode (number or number[]) - indexes of sections to explode out of the pie',
+		'explodeDist (number) - the distance to move an exploded section',
+		'pieGap (number) - the distance between pies for multiple values'],
+
+	/* Retrieve the display title for this chart type.
+	   @return  the title */
+	title: function() {
+		return 'Pie chart';
+	},
+
+	/* Retrieve a description of this chart type.
+	   @return  its description */
+	description: function() {
+		return 'Compare relative sizes of values as contributions to the whole.';
+	},
+
+	/* Retrieve a list of the options that may be set for this chart type.
+	   @return  options list */
+	options: function() {
+		return this._options;
+	},
+
+	/* Actually draw the graph in this type's style.
+	   @param  graph  (object) the SVGGraph object */
+	drawGraph: function(graph) {
+		graph._drawChartBackground(true, true);
+		this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'});
+		var dims = graph._getDims();
+		this._drawSeries(graph, dims);
+		graph._drawTitle();
+		graph._drawLegend();
+	},
+
+	/* Plot all the series. */
+	_drawSeries: function(graph, dims) {
+		var totals = graph._getTotals();
+		var numSer = graph._series.length;
+		var numVal = (numSer ? (graph._series[0])._values.length : 0);
+		var path = graph._wrapper.createPath();
+		var explode = graph._chartOptions.explode || [];
+		explode = (isArray(explode) ? explode : [explode]);
+		var explodeDist = graph._chartOptions.explodeDist || 10;
+		var pieGap = (numVal <= 1 ? 0 : graph._chartOptions.pieGap || 10);
+		var xBase = (dims[graph.W] - (numVal * pieGap) - pieGap) / numVal / 2;
+		var yBase = dims[graph.H] / 2;
+		var radius = Math.min(xBase, yBase) - (explode.length > 0 ? explodeDist : 0);
+		var gt = graph._wrapper.group(graph._chartCont, $.extend(
+			{class_: 'xAxisLabels', textAnchor: 'middle'}, graph.xAxis._labelFormat));
+		var gl = [];
+		for (var i = 0; i < numVal; i++) {
+			var cx = dims[graph.X] + xBase + (i * (2 * Math.min(xBase, yBase) + pieGap)) + pieGap;
+			var cy = dims[graph.Y] + yBase;
+			var curTotal = 0;
+			for (var j = 0; j < numSer; j++) {
+				var series = graph._series[j];
+				if (i == 0) {
+					gl[j] = graph._wrapper.group(this._chart, $.extend({class_: 'series' + j,
+						fill: series._fill, stroke: series._stroke,
+						strokeWidth: series._strokeWidth}, series._settings || {}));
+				}
+				if (series._values[i] == 0) {
+					continue;
+				}
+				var start = (curTotal / totals[i]) * 2 * Math.PI;
+				curTotal += series._values[i];
+				var end = (curTotal / totals[i]) * 2 * Math.PI;
+				var exploding = false;
+				for (var k = 0; k < explode.length; k++) {
+					if (explode[k] == j) {
+						exploding = true;
+						break;
+					}
+				}
+				var x = cx + (exploding ? explodeDist * Math.cos((start + end) / 2) : 0);
+				var y = cy + (exploding ? explodeDist * Math.sin((start + end) / 2) : 0);
+				var p = graph._wrapper.path(gl[j], path.reset().move(x, y).
+					line(x + radius * Math.cos(start), y + radius * Math.sin(start)).
+					arc(radius, radius, 0, (end - start < Math.PI ? 0 : 1), 1,
+					x + radius * Math.cos(end), y + radius * Math.sin(end)).close());
+				graph._showStatus(p, series._name,
+					roundNumber((end - start) / 2 / Math.PI * 100, 2));
+			}
+			if (graph.xAxis) {
+				graph._wrapper.text(gt, cx, dims[graph.Y] + dims[graph.H] + graph.xAxis._titleOffset,
+					graph.xAxis._labels[i])
+			}
+		}
+	}
+});
+
+//------------------------------------------------------------------------------
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+	return (a && a.constructor == Array);
+}
+
+// Basic chart types
+$.svg.graphing.addChartType('column', new SVGColumnChart());
+$.svg.graphing.addChartType('stackedColumn', new SVGStackedColumnChart());
+$.svg.graphing.addChartType('row', new SVGRowChart());
+$.svg.graphing.addChartType('stackedRow', new SVGStackedRowChart());
+$.svg.graphing.addChartType('line', new SVGLineChart());
+$.svg.graphing.addChartType('pie', new SVGPieChart());
+
+})(jQuery)
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.min.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.min.js
new file mode 100644
index 0000000..f693148
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.min.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG graphing extension for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+(function($){$.svg.addExtension('graph',SVGGraph);$.svg.graphing=new SVGGraphing();function SVGGraphing(){this.regional=[];this.regional['']={percentageText:'Percentage'};this.region=this.regional['']}$.extend(SVGGraphing.prototype,{_chartTypes:[],addChartType:function(a,b){this._chartTypes[a]=b},chartTypes:function(){return this._chartTypes}});function SVGGraph(a){this._wrapper=a;this._drawNow=false;for(var b in $.svg.graphing._chartTypes){this._chartType=$.svg.graphing._chartTypes[b];break}this._chartOptions={};this._title={value:'',offset:25,settings:{textAnchor:'middle'}};this._area=[0.1,0.1,0.8,0.9];this._chartFormat={fill:'none',stroke:'black'};this._gridlines=[];this._series=[];this._onstatus=null;this._chartCont=this._wrapper.svg(0,0,0,0,{class_:'svg-graph'});this.xAxis=new SVGGraphAxis(this);this.xAxis.title('',40);this.yAxis=new SVGGraphAxis(this);this.yAxis.title('',40);this.x2Axis=null;this.y2Axis=null;this.legend=new SVGGraphLegend(this);this._drawNow=true}$.extend(SVGGraph.prototype,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,_percentageAxis:new SVGGraphAxis(this,$.svg.graphing.region.percentageText,0,100,10,0),container:function(a){if(arguments.length==0){return this._chartCont}this._chartCont=a;return this},chartType:function(a,b){return(arguments.length==0?this.type():this.type(a,b))},type:function(a,b){if(arguments.length==0){return this._chartType}var c=$.svg.graphing._chartTypes[a];if(c){this._chartType=c;this._chartOptions=$.extend({},b||{})}this._drawGraph();return this},chartOptions:function(a){return(arguments.length==0?this.options():this.options(a))},options:function(a){if(arguments.length==0){return this._chartOptions}this._chartOptions=$.extend({},a);this._drawGraph();return this},chartFormat:function(a,b,c){return(arguments.length==0?this.format():this.format(a,b,c))},format:function(a,b,c){if(arguments.length==0){return this._chartFormat}if(typeof b=='object'){c=b;b=null}this._chartFormat=$.extend({fill:a},(b?{stroke:b}:{}),c||{});this._drawGraph();return this},chartArea:function(a,b,c,d){return(arguments.length==0?this.area():this.area(a,b,c,d))},area:function(a,b,c,d){if(arguments.length==0){return this._area}this._area=(isArray(a)?a:[a,b,c,d]);this._drawGraph();return this},gridlines:function(a,b){if(arguments.length==0){return this._gridlines}this._gridlines=[(typeof a=='string'?{stroke:a}:a),(typeof b=='string'?{stroke:b}:b)];if(this._gridlines[0]==null&&this._gridlines[1]==null){this._gridlines=[]}this._drawGraph();return this},title:function(a,b,c,d){if(arguments.length==0){return this._title}if(typeof b!='number'){d=c;c=b;b=null}if(typeof c!='string'){d=c;c=null}this._title={value:a,offset:b||this._title.offset,settings:$.extend({textAnchor:'middle'},(c?{fill:c}:{}),d||{})};this._drawGraph();return this},addSeries:function(a,b,c,d,e,f){this._series.push(new SVGGraphSeries(this,a,b,c,d,e,f));this._drawGraph();return this},series:function(i){return(arguments.length>0?this._series[i]:null)||this._series},noDraw:function(){this._drawNow=false;return this},redraw:function(){this._drawNow=true;this._drawGraph();return this},status:function(a){this._onstatus=a;return this},_drawGraph:function(){if(!this._drawNow){return}while(this._chartCont.firstChild){this._chartCont.removeChild(this._chartCont.firstChild)}if(!this._chartCont.parent){this._wrapper._svg.appendChild(this._chartCont)}if(!this._chartCont.width){this._chartCont.setAttribute('width',parseInt(this._chartCont.getAttribute('width'),10)||this._wrapper._width())}else if(this._chartCont.width.baseVal){this._chartCont.width.baseVal.value=this._chartCont.width.baseVal.value||this._wrapper._width()}else{this._chartCont.width=this._chartCont.width||this._wrapper._width()}if(!this._chartCont.height){this._chartCont.setAttribute('height',parseInt(this._chartCont.getAttribute('height'),10)||this._wrapper._height())}else if(this._chartCont.height.baseVal){this._chartCont.height.baseVal.value=this._chartCont.height.baseVal.value||this._wrapper._height()}else{this._chartCont.height=this._chartCont.height||this._wrapper._height()}this._chartType.drawGraph(this)},_getValue:function(a,b){return(!a[b]?parseInt(a.getAttribute(b),10):(a[b].baseVal?a[b].baseVal.value:a[b]))},_drawTitle:function(){this._wrapper.text(this._chartCont,this._getValue(this._chartCont,'width')/2,this._title.offset,this._title.value,this._title.settings)},_getDims:function(a){a=a||this._area;var b=this._getValue(this._chartCont,'width');var c=this._getValue(this._chartCont,'height');var d=(a[this.L]>1?a[this.L]:b*a[this.L]);var e=(a[this.T]>1?a[this.T]:c*a[this.T]);var f=(a[this.R]>1?a[this.R]:b*a[this.R])-d;var g=(a[this.B]>1?a[this.B]:c*a[this.B])-e;return[d,e,f,g]},_drawChartBackground:function(a,b){var c=this._wrapper.group(this._chartCont,{class_:'background'});var d=this._getDims();this._wrapper.rect(c,d[this.X],d[this.Y],d[this.W],d[this.H],this._chartFormat);if(this._gridlines[0]&&this.yAxis._ticks.major&&!b){this._drawGridlines(c,this.yAxis,true,d,this._gridlines[0])}if(this._gridlines[1]&&this.xAxis._ticks.major&&!a){this._drawGridlines(c,this.xAxis,false,d,this._gridlines[1])}return c},_drawGridlines:function(a,b,c,d,e){var g=this._wrapper.group(a,e);var f=(c?d[this.H]:d[this.W])/(b._scale.max-b._scale.min);var h=Math.floor(b._scale.min/b._ticks.major)*b._ticks.major;h=(h<b._scale.min?h+b._ticks.major:h);while(h<=b._scale.max){var v=(c?b._scale.max-h:h-b._scale.min)*f+(c?d[this.Y]:d[this.X]);this._wrapper.line(g,(c?d[this.X]:v),(c?v:d[this.Y]),(c?d[this.X]+d[this.W]:v),(c?v:d[this.Y]+d[this.H]));h+=b._ticks.major}},_drawAxes:function(a){var b=this._getDims();if(this.xAxis&&!a){if(this.xAxis._title){this._wrapper.text(this._chartCont,b[this.X]+b[this.W]/2,b[this.Y]+b[this.H]+this.xAxis._titleOffset,this.xAxis._title,this.xAxis._titleFormat)}this._drawAxis(this.xAxis,'xAxis',b[this.X],b[this.Y]+b[this.H],b[this.X]+b[this.W],b[this.Y]+b[this.H])}if(this.yAxis){if(this.yAxis._title){this._wrapper.text(this._chartCont,0,0,this.yAxis._title,$.extend({textAnchor:'middle',transform:'translate('+(b[this.X]-this.yAxis._titleOffset)+','+(b[this.Y]+b[this.H]/2)+') rotate(-90)'},this.yAxis._titleFormat||{}))}this._drawAxis(this.yAxis,'yAxis',b[this.X],b[this.Y],b[this.X],b[this.Y]+b[this.H])}if(this.x2Axis&&!a){if(this.x2Axis._title){this._wrapper.text(this._chartCont,b[this.X]+b[this.W]/2,b[this.X]-this.x2Axis._titleOffset,this.x2Axis._title,this.x2Axis._titleFormat)}this._drawAxis(this.x2Axis,'x2Axis',b[this.X],b[this.Y],b[this.X]+b[this.W],b[this.Y])}if(this.y2Axis){if(this.y2Axis._title){this._wrapper.text(this._chartCont,0,0,this.y2Axis._title,$.extend({textAnchor:'middle',transform:'translate('+(b[this.X]+b[this.W]+this.y2Axis._titleOffset)+','+(b[this.Y]+b[this.H]/2)+') rotate(-90)'},this.y2Axis._titleFormat||{}))}this._drawAxis(this.y2Axis,'y2Axis',b[this.X]+b[this.W],b[this.Y],b[this.X]+b[this.W],b[this.Y]+b[this.H])}},_drawAxis:function(a,b,c,d,e,f){var g=(d==f);var h=this._wrapper.group(this._chartCont,$.extend({class_:b},a._lineFormat));var i=this._wrapper.group(this._chartCont,$.extend({class_:b+'Labels',textAnchor:(g?'middle':'end')},a._labelFormat));this._wrapper.line(h,c,d,e,f);if(a._ticks.major){var j=(e>(this._getValue(this._chartCont,'width')/2)&&f>(this._getValue(this._chartCont,'height')/2));var k=(g?e-c:f-d)/(a._scale.max-a._scale.min);var l=a._ticks.size;var m=Math.floor(a._scale.min/a._ticks.major)*a._ticks.major;m=(m<a._scale.min?m+a._ticks.major:m);var n=(!a._ticks.minor?a._scale.max+1:Math.floor(a._scale.min/a._ticks.minor)*a._ticks.minor);n=(n<a._scale.min?n+a._ticks.minor:n);var o=this._getTickOffsets(a,j);var p=0;while(m<=a._scale.max||n<=a._scale.max){var q=Math.min(m,n);var r=(q==m?l:l/2);var v=(g?c:d)+(g?q-a._scale.min:a._scale.max-q)*k;this._wrapper.line(h,(g?v:c+r*o[0]),(g?d+r*o[0]:v),(g?v:c+r*o[1]),(g?d+r*o[1]:v));if(q==m){this._wrapper.text(i,(g?v:c-l),(g?d+2*l:v),(a._labels?a._labels[p++]:''+q))}m+=(q==m?a._ticks.major:0);n+=(q==n?a._ticks.minor:0)}}},_getTickOffsets:function(a,b){return[(a._ticks.position==(b?'in':'out')||a._ticks.position=='both'?-1:0),(a._ticks.position==(b?'out':'in')||a._ticks.position=='both'?+1:0),]},_getPercentageAxis:function(){this._percentageAxis._title=$.svg.graphing.region.percentageText;return this._percentageAxis},_getTotals:function(){var a=[];var b=(this._series.length?this._series[0]._values.length:0);for(var i=0;i<b;i++){a[i]=0;for(var j=0;j<this._series.length;j++){a[i]+=this._series[j]._values[i]}}return a},_drawLegend:function(){if(!this.legend._show){return}var g=this._wrapper.group(this._chartCont,{class_:'legend'});var a=this._getDims(this.legend._area);this._wrapper.rect(g,a[this.X],a[this.Y],a[this.W],a[this.H],this.legend._bgSettings);var b=a[this.W]>a[this.H];var c=this._series.length;var d=(b?a[this.W]:a[this.H])/c;var e=a[this.X]+5;var f=a[this.Y]+((b?a[this.H]:d)+this.legend._sampleSize)/2;for(var i=0;i<c;i++){var h=this._series[i];this._wrapper.rect(g,e+(b?i*d:0),f+(b?0:i*d)-this.legend._sampleSize,this.legend._sampleSize,this.legend._sampleSize,{fill:h._fill,stroke:h._stroke,strokeWidth:1});this._wrapper.text(g,e+(b?i*d:0)+this.legend._sampleSize+5,f+(b?0:i*d),h._name,this.legend._textSettings)}},_showStatus:function(a,b,c){var d=this._onstatus;if(this._onstatus){$(a).hover(function(){d.apply(this,[b,c])},function(){d.apply(this,['',0])})}}});function SVGGraphSeries(a,b,c,d,e,f,g){if(typeof b!='string'){g=f;f=e;e=d;d=c;c=b;b=null}if(typeof e!='string'){g=f;f=e;e=null}if(typeof f!='number'){g=f;f=null}this._graph=a;this._name=b||'';this._values=c||[];this._axis=1;this._fill=d||'green';this._stroke=e||'black';this._strokeWidth=f||1;this._settings=g||{}}$.extend(SVGGraphSeries.prototype,{name:function(a){if(arguments.length==0){return this._name}this._name=a;this._graph._drawGraph();return this},values:function(a,b){if(arguments.length==0){return this._values}if(isArray(a)){b=a;a=null}this._name=a||this._name;this._values=b;this._graph._drawGraph();return this},format:function(a,b,c,d){if(arguments.length==0){return $.extend({fill:this._fill,stroke:this._stroke,strokeWidth:this._strokeWidth},this._settings)}if(typeof b!='string'){d=c;c=b;b=null}if(typeof c!='number'){d=c;c=null}this._fill=a||this._fill;this._stroke=b||this._stroke;this._strokeWidth=c||this._strokeWidth;$.extend(this._settings,d||{});this._graph._drawGraph();return this},end:function(){return this._graph}});function SVGGraphAxis(a,b,c,d,e,f){this._graph=a;this._title=b||'';this._titleFormat={};this._titleOffset=0;this._labels=null;this._labelFormat={};this._lineFormat={stroke:'black',strokeWidth:1};this._ticks={major:e||10,minor:f||0,size:10,position:'out'};this._scale={min:c||0,max:d||100};this._crossAt=0}$.extend(SVGGraphAxis.prototype,{scale:function(a,b){if(arguments.length==0){return this._scale}this._scale.min=a;this._scale.max=b;this._graph._drawGraph();return this},ticks:function(a,b,c,d){if(arguments.length==0){return this._ticks}if(typeof c=='string'){d=c;c=null}this._ticks.major=a;this._ticks.minor=b;this._ticks.size=c||this._ticks.size;this._ticks.position=d||this._ticks.position;this._graph._drawGraph();return this},title:function(a,b,c,d){if(arguments.length==0){return{title:this._title,offset:this._titleOffset,format:this._titleFormat}}if(typeof b!='number'){d=c;c=b;b=null}if(typeof c!='string'){d=c;c=null}this._title=a;this._titleOffset=(b!=null?b:this._titleOffset);if(c||d){this._titleFormat=$.extend(d||{},(c?{fill:c}:{}))}this._graph._drawGraph();return this},labels:function(a,b,c){if(arguments.length==0){return{labels:this._labels,format:this._labelFormat}}if(typeof b!='string'){c=b;b=null}this._labels=a;if(b||c){this._labelFormat=$.extend(c||{},(b?{fill:b}:{}))}this._graph._drawGraph();return this},line:function(a,b,c){if(arguments.length==0){return this._lineFormat}if(typeof b=='object'){c=b;b=null}$.extend(this._lineFormat,{stroke:a},(b?{strokeWidth:b}:{}),c||{});this._graph._drawGraph();return this},end:function(){return this._graph}});function SVGGraphLegend(a,b,c){this._graph=a;this._show=true;this._area=[0.9,0.1,1.0,0.9];this._sampleSize=15;this._bgSettings=b||{stroke:'gray'};this._textSettings=c||{}}$.extend(SVGGraphLegend.prototype,{show:function(a){if(arguments.length==0){return this._show}this._show=a;this._graph._drawGraph();return this},area:function(a,b,c,d){if(arguments.length==0){return this._area}this._area=(isArray(a)?a:[a,b,c,d]);this._graph._drawGraph();return this},settings:function(a,b,c){if(arguments.length==0){return{sampleSize:this._sampleSize,bgSettings:this._bgSettings,textSettings:this._textSettings}}if(typeof a!='number'){c=b;b=a;a=null}this._sampleSize=a||this._sampleSize;this._bgSettings=b;this._textSettings=c||this._textSettings;this._graph._drawGraph();return this},end:function(){return this._graph}});function roundNumber(a,b){return Math.round(a*Math.pow(10,b))/Math.pow(10,b)}var B=['barWidth (number) - the width of each bar','barGap (number) - the gap between sets of bars'];function SVGColumnChart(){}$.extend(SVGColumnChart.prototype,{title:function(){return'Basic column chart'},description:function(){return'Compare sets of values as vertical bars with grouped categories.'},options:function(){return B},drawGraph:function(a){a._drawChartBackground(true);var b=a._chartOptions.barWidth||10;var c=a._chartOptions.barGap||10;var d=a._series.length;var e=(d?(a._series[0])._values.length:0);var f=a._getDims();var g=f[a.W]/((d*b+c)*e+c);var h=f[a.H]/(a.yAxis._scale.max-a.yAxis._scale.min);this._chart=a._wrapper.group(a._chartCont,{class_:'chart'});for(var i=0;i<d;i++){this._drawSeries(a,i,d,b,c,f,g,h)}a._drawTitle();a._drawAxes(true);this._drawXAxis(a,d,e,b,c,f,g);a._drawLegend()},_drawSeries:function(a,b,c,d,e,f,h,j){var k=a._series[b];var g=a._wrapper.group(this._chart,$.extend({class_:'series'+b,fill:k._fill,stroke:k._stroke,strokeWidth:k._strokeWidth},k._settings||{}));for(var i=0;i<k._values.length;i++){var r=a._wrapper.rect(g,f[a.X]+h*(e+i*(c*d+e)+(b*d)),f[a.Y]+j*(a.yAxis._scale.max-k._values[i]),h*d,j*k._values[i]);a._showStatus(r,k._name,k._values[i])}},_drawXAxis:function(a,b,c,d,e,f,g){var h=a.xAxis;if(h._title){a._wrapper.text(a._chartCont,f[a.X]+f[a.W]/2,f[a.Y]+f[a.H]+h._titleOffset,h._title,$.extend({textAnchor:'middle'},h._titleFormat||{}))}var j=a._wrapper.group(a._chartCont,$.extend({class_:'xAxis'},h._lineFormat));var k=a._wrapper.group(a._chartCont,$.extend({class_:'xAxisLabels',textAnchor:'middle'},h._labelFormat));a._wrapper.line(j,f[a.X],f[a.Y]+f[a.H],f[a.X]+f[a.W],f[a.Y]+f[a.H]);if(h._ticks.major){var l=a._getTickOffsets(h,true);for(var i=1;i<c;i++){var x=f[a.X]+g*(e/2+i*(b*d+e));a._wrapper.line(j,x,f[a.Y]+f[a.H]+l[0]*h._ticks.size,x,f[a.Y]+f[a.H]+l[1]*h._ticks.size)}for(var i=0;i<c;i++){var x=f[a.X]+g*(e/2+(i+0.5)*(b*d+e));a._wrapper.text(k,x,f[a.Y]+f[a.H]+2*h._ticks.size,(h._labels?h._labels[i]:''+i))}}}});function SVGStackedColumnChart(){}$.extend(SVGStackedColumnChart.prototype,{title:function(){return'Stacked column chart'},description:function(){return'Compare sets of values as vertical bars showing '+'relative contributions to the whole for each category.'},options:function(){return B},drawGraph:function(a){var b=a._drawChartBackground(true,true);var c=a._getDims();if(a._gridlines[0]&&a.xAxis._ticks.major){a._drawGridlines(b,a._getPercentageAxis(),true,c,a._gridlines[0])}var d=a._chartOptions.barWidth||10;var e=a._chartOptions.barGap||10;var f=a._series.length;var g=(f?(a._series[0])._values.length:0);var h=c[a.W]/((d+e)*g+e);var i=c[a.H];this._chart=a._wrapper.group(a._chartCont,{class_:'chart'});this._drawColumns(a,f,g,d,e,c,h,i);a._drawTitle();a._wrapper.text(a._chartCont,0,0,$.svg.graphing.region.percentageText,$.extend({textAnchor:'middle',transform:'translate('+(c[a.X]-a.yAxis._titleOffset)+','+(c[a.Y]+c[a.H]/2)+') rotate(-90)'},a.yAxis._titleFormat||{}));var j=$.extend({},a._getPercentageAxis());$.extend(j._labelFormat,a.yAxis._labelFormat||{});a._drawAxis(j,'yAxis',c[a.X],c[a.Y],c[a.X],c[a.Y]+c[a.H]);this._drawXAxis(a,g,d,e,c,h);a._drawLegend()},_drawColumns:function(a,b,c,d,e,f,h,j){var k=a._getTotals();var l=[];for(var i=0;i<c;i++){l[i]=0}for(var s=0;s<b;s++){var m=a._series[s];var g=a._wrapper.group(this._chart,$.extend({class_:'series'+s,fill:m._fill,stroke:m._stroke,strokeWidth:m._strokeWidth},m._settings||{}));for(var i=0;i<m._values.length;i++){l[i]+=m._values[i];var r=a._wrapper.rect(g,f[a.X]+h*(e+i*(d+e)),f[a.Y]+j*(k[i]-l[i])/k[i],h*d,j*m._values[i]/k[i]);a._showStatus(r,m._name,roundNumber(m._values[i]/k[i]*100,2))}}},_drawXAxis:function(a,b,c,d,e,f){var g=a.xAxis;if(g._title){a._wrapper.text(a._chartCont,e[a.X]+e[a.W]/2,e[a.Y]+e[a.H]+g._titleOffset,g._title,$.extend({textAnchor:'middle'},g._titleFormat||{}))}var h=a._wrapper.group(a._chartCont,$.extend({class_:'xAxis'},g._lineFormat));var j=a._wrapper.group(a._chartCont,$.extend({class_:'xAxisLabels',textAnchor:'middle'},g._labelFormat));a._wrapper.line(h,e[a.X],e[a.Y]+e[a.H],e[a.X]+e[a.W],e[a.Y]+e[a.H]);if(g._ticks.major){var k=a._getTickOffsets(g,true);for(var i=1;i<b;i++){var x=e[a.X]+f*(d/2+i*(c+d));a._wrapper.line(h,x,e[a.Y]+e[a.H]+k[0]*g._ticks.size,x,e[a.Y]+e[a.H]+k[1]*g._ticks.size)}for(var i=0;i<b;i++){var x=e[a.X]+f*(d/2+(i+0.5)*(c+d));a._wrapper.text(j,x,e[a.Y]+e[a.H]+2*g._ticks.size,(g._labels?g._labels[i]:''+i))}}}});function SVGRowChart(){}$.extend(SVGRowChart.prototype,{title:function(){return'Basic row chart'},description:function(){return'Compare sets of values as horizontal rows with grouped categories.'},options:function(){return B},drawGraph:function(a){var b=a._drawChartBackground(true,true);var c=a._getDims();a._drawGridlines(b,a.yAxis,false,c,a._gridlines[0]);var d=a._chartOptions.barWidth||10;var e=a._chartOptions.barGap||10;var f=a._series.length;var g=(f?(a._series[0])._values.length:0);var h=c[a.W]/(a.yAxis._scale.max-a.yAxis._scale.min);var j=c[a.H]/((f*d+e)*g+e);this._chart=a._wrapper.group(a._chartCont,{class_:'chart'});for(var i=0;i<f;i++){this._drawSeries(a,i,f,d,e,c,h,j)}a._drawTitle();this._drawAxes(a,f,g,d,e,c,j);a._drawLegend()},_drawSeries:function(a,b,c,d,e,f,h,j){var k=a._series[b];var g=a._wrapper.group(this._chart,$.extend({class_:'series'+b,fill:k._fill,stroke:k._stroke,strokeWidth:k._strokeWidth},k._settings||{}));for(var i=0;i<k._values.length;i++){var r=a._wrapper.rect(g,f[a.X]+h*(0-a.yAxis._scale.min),f[a.Y]+j*(e+i*(c*d+e)+(b*d)),h*k._values[i],j*d);a._showStatus(r,k._name,k._values[i])}},_drawAxes:function(a,b,c,d,e,f,g){var h=a.yAxis;if(h){if(h._title){a._wrapper.text(a._chartCont,f[a.X]+f[a.W]/2,f[a.Y]+f[a.H]+h._titleOffset,h._title,h._titleFormat)}a._drawAxis(h,'xAxis',f[a.X],f[a.Y]+f[a.H],f[a.X]+f[a.W],f[a.Y]+f[a.H])}var h=a.xAxis;if(h._title){a._wrapper.text(a._chartCont,0,0,h._title,$.extend({textAnchor:'middle',transform:'translate('+(f[a.X]-h._titleOffset)+','+(f[a.Y]+f[a.H]/2)+') rotate(-90)'},h._titleFormat||{}))}var j=a._wrapper.group(a._chartCont,$.extend({class_:'yAxis'},h._lineFormat));var k=a._wrapper.group(a._chartCont,$.extend({class_:'yAxisLabels',textAnchor:'end'},h._labelFormat));a._wrapper.line(j,f[a.X],f[a.Y],f[a.X],f[a.Y]+f[a.H]);if(h._ticks.major){var l=a._getTickOffsets(h,false);for(var i=1;i<c;i++){var y=f[a.Y]+g*(e/2+i*(b*d+e));a._wrapper.line(j,f[a.X]+l[0]*h._ticks.size,y,f[a.X]+l[1]*h._ticks.size,y)}for(var i=0;i<c;i++){var y=f[a.Y]+g*(e/2+(i+0.5)*(b*d+e));a._wrapper.text(k,f[a.X]-h._ticks.size,y,(h._labels?h._labels[i]:''+i))}}}});function SVGStackedRowChart(){}$.extend(SVGStackedRowChart.prototype,{title:function(){return'Stacked row chart'},description:function(){return'Compare sets of values as horizontal bars showing '+'relative contributions to the whole for each category.'},options:function(){return B},drawGraph:function(a){var b=a._drawChartBackground(true,true);var c=a._getDims();if(a._gridlines[0]&&a.xAxis._ticks.major){a._drawGridlines(b,a._getPercentageAxis(),false,c,a._gridlines[0])}var d=a._chartOptions.barWidth||10;var e=a._chartOptions.barGap||10;var f=a._series.length;var g=(f?(a._series[0])._values.length:0);var h=c[a.W];var i=c[a.H]/((d+e)*g+e);this._chart=a._wrapper.group(a._chartCont,{class_:'chart'});this._drawRows(a,f,g,d,e,c,h,i);a._drawTitle();a._wrapper.text(a._chartCont,c[a.X]+c[a.W]/2,c[a.Y]+c[a.H]+a.xAxis._titleOffset,$.svg.graphing.region.percentageText,$.extend({textAnchor:'middle'},a.yAxis._titleFormat||{}));var j=$.extend({},a._getPercentageAxis());$.extend(j._labelFormat,a.yAxis._labelFormat||{});a._drawAxis(j,'xAxis',c[a.X],c[a.Y]+c[a.H],c[a.X]+c[a.W],c[a.Y]+c[a.H]);this._drawYAxis(a,g,d,e,c,i);a._drawLegend()},_drawRows:function(a,b,c,d,e,f,h,j){var k=a._getTotals();var l=[];for(var i=0;i<c;i++){l[i]=0}for(var s=0;s<b;s++){var m=a._series[s];var g=a._wrapper.group(this._chart,$.extend({class_:'series'+s,fill:m._fill,stroke:m._stroke,strokeWidth:m._strokeWidth},m._settings||{}));for(var i=0;i<m._values.length;i++){var r=a._wrapper.rect(g,f[a.X]+h*l[i]/k[i],f[a.Y]+j*(e+i*(d+e)),h*m._values[i]/k[i],j*d);a._showStatus(r,m._name,roundNumber(m._values[i]/k[i]*100,2));l[i]+=m._values[i]}}},_drawYAxis:function(a,b,c,d,e,f){var g=a.xAxis;if(g._title){a._wrapper.text(a._chartCont,0,0,g._title,$.extend({textAnchor:'middle',transform:'translate('+(e[a.X]-g._titleOffset)+','+(e[a.Y]+e[a.H]/2)+') rotate(-90)'},g._titleFormat||{}))}var h=a._wrapper.group(a._chartCont,$.extend({class_:'yAxis'},g._lineFormat));var j=a._wrapper.group(a._chartCont,$.extend({class_:'yAxisLabels',textAnchor:'end'},g._labelFormat));a._wrapper.line(h,e[a.X],e[a.Y],e[a.X],e[a.Y]+e[a.H]);if(g._ticks.major){var k=a._getTickOffsets(g,false);for(var i=1;i<b;i++){var y=e[a.Y]+f*(d/2+i*(c+d));a._wrapper.line(h,e[a.X]+k[0]*g._ticks.size,y,e[a.X]+k[1]*g._ticks.size,y)}for(var i=0;i<b;i++){var y=e[a.Y]+f*(d/2+(i+0.5)*(c+d));a._wrapper.text(j,e[a.X]-g._ticks.size,y,(g._labels?g._labels[i]:''+i))}}}});function SVGLineChart(){}$.extend(SVGLineChart.prototype,{title:function(){return'Basic line chart'},description:function(){return'Compare sets of values as continuous lines.'},options:function(){return[]},drawGraph:function(a){a._drawChartBackground();var b=a._getDims();var c=b[a.W]/(a.xAxis._scale.max-a.xAxis._scale.min);var d=b[a.H]/(a.yAxis._scale.max-a.yAxis._scale.min);this._chart=a._wrapper.group(a._chartCont,{class_:'chart'});for(var i=0;i<a._series.length;i++){this._drawSeries(a,i,b,c,d)}a._drawTitle();a._drawAxes();a._drawLegend()},_drawSeries:function(a,b,c,d,e){var f=a._series[b];var g=a._wrapper.createPath();for(var i=0;i<f._values.length;i++){var x=c[a.X]+i*d;var y=c[a.Y]+(a.yAxis._scale.max-f._values[i])*e;if(i==0){g.move(x,y)}else{g.line(x,y)}}var p=a._wrapper.path(this._chart,g,$.extend({id:'series'+b,fill:'none',stroke:f._stroke,strokeWidth:f._strokeWidth},f._settings||{}));a._showStatus(p,f._name,0)}});function SVGPieChart(){}$.extend(SVGPieChart.prototype,{_options:['explode (number or number[]) - indexes of sections to explode out of the pie','explodeDist (number) - the distance to move an exploded section','pieGap (number) - the distance between pies for multiple values'],title:function(){return'Pie chart'},description:function(){return'Compare relative sizes of values as contributions to the whole.'},options:function(){return this._options},drawGraph:function(a){a._drawChartBackground(true,true);this._chart=a._wrapper.group(a._chartCont,{class_:'chart'});var b=a._getDims();this._drawSeries(a,b);a._drawTitle();a._drawLegend()},_drawSeries:function(a,b){var c=a._getTotals();var d=a._series.length;var e=(d?(a._series[0])._values.length:0);var f=a._wrapper.createPath();var g=a._chartOptions.explode||[];g=(isArray(g)?g:[g]);var h=a._chartOptions.explodeDist||10;var l=(e<=1?0:a._chartOptions.pieGap||10);var m=(b[a.W]-(e*l)-l)/e/2;var n=b[a.H]/2;var o=Math.min(m,n)-(g.length>0?h:0);var q=a._wrapper.group(a._chartCont,$.extend({class_:'xAxisLabels',textAnchor:'middle'},a.xAxis._labelFormat));var r=[];for(var i=0;i<e;i++){var s=b[a.X]+m+(i*(2*Math.min(m,n)+l))+l;var t=b[a.Y]+n;var u=0;for(var j=0;j<d;j++){var v=a._series[j];if(i==0){r[j]=a._wrapper.group(this._chart,$.extend({class_:'series'+j,fill:v._fill,stroke:v._stroke,strokeWidth:v._strokeWidth},v._settings||{}))}if(v._values[i]==0){continue}var w=(u/c[i])*2*Math.PI;u+=v._values[i];var z=(u/c[i])*2*Math.PI;var A=false;for(var k=0;k<g.length;k++){if(g[k]==j){A=true;break}}var x=s+(A?h*Math.cos((w+z)/2):0);var y=t+(A?h*Math.sin((w+z)/2):0);var p=a._wrapper.path(r[j],f.reset().move(x,y).line(x+o*Math.cos(w),y+o*Math.sin(w)).arc(o,o,0,(z-w<Math.PI?0:1),1,x+o*Math.cos(z),y+o*Math.sin(z)).close());a._showStatus(p,v._name,roundNumber((z-w)/2/Math.PI*100,2))}if(a.xAxis){a._wrapper.text(q,s,b[a.Y]+b[a.H]+a.xAxis._titleOffset,a.xAxis._labels[i])}}}});function isArray(a){return(a&&a.constructor==Array)}$.svg.graphing.addChartType('column',new SVGColumnChart());$.svg.graphing.addChartType('stackedColumn',new SVGStackedColumnChart());$.svg.graphing.addChartType('row',new SVGRowChart());$.svg.graphing.addChartType('stackedRow',new SVGStackedRowChart());$.svg.graphing.addChartType('line',new SVGLineChart());$.svg.graphing.addChartType('pie',new SVGPieChart())})(jQuery)
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.pack.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.pack.js
new file mode 100644
index 0000000..bb604f4
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svggraph.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG graphing extension for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.19.3M(\'3i\',2L);$.19.1k=1q 2M();7 2M(){4.2N=[];4.2N[\'\']={2g:\'3N\'};4.2h=4.2N[\'\']}$.G(2M.1v,{26:[],1V:7(a,b){4.26[a]=b},3O:7(){C 4.26}});7 2L(a){4.D=a;4.2i=1K;M(6 b 2O $.19.1k.26){4.2y=$.19.1k.26[b];3j}4.1h={};4.O={1L:\'\',2j:25,2z:{1b:\'1l\'}};4.1M=[0.1,0.1,0.8,0.9];4.2A={1o:\'3k\',1i:\'2P\'};4.1j=[];4.S=[];4.2B=Z;4.F=4.D.19(0,0,0,0,{U:\'19-3i\'});4.Q=1q 2k(4);4.Q.1w(\'\',40);4.N=1q 2k(4);4.N.1w(\'\',40);4.1N=Z;4.1O=Z;4.1x=1q 2Q(4);4.2i=18}$.G(2L.1v,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,2R:1q 2k(4,$.19.1k.2h.2g,0,2l,10,0),3P:7(a){E(11.J==0){C 4.F}4.F=a;C 4},3Q:7(a,b){C(11.J==0?4.2S():4.2S(a,b))},2S:7(a,b){E(11.J==0){C 4.2y}6 c=$.19.1k.26[a];E(c){4.2y=c;4.1h=$.G({},b||{})}4.12();C 4},3R:7(a){C(11.J==0?4.1G():4.1G(a))},1G:7(a){E(11.J==0){C 4.1h}4.1h=$.G({},a);4.12();C 4},3S:7(a,b,c){C(11.J==0?4.27():4.27(a,b,c))},27:7(a,b,c){E(11.J==0){C 4.2A}E(1c b==\'3l\'){c=b;b=Z}4.2A=$.G({1o:a},(b?{1i:b}:{}),c||{});4.12();C 4},3T:7(a,b,c,d){C(11.J==0?4.2C():4.2C(a,b,c,d))},2C:7(a,b,c,d){E(11.J==0){C 4.1M}4.1M=(2m(a)?a:[a,b,c,d]);4.12();C 4},3U:7(a,b){E(11.J==0){C 4.1j}4.1j=[(1c a==\'1H\'?{1i:a}:a),(1c b==\'1H\'?{1i:b}:b)];E(4.1j[0]==Z&&4.1j[1]==Z){4.1j=[]}4.12();C 4},1w:7(a,b,c,d){E(11.J==0){C 4.O}E(1c b!=\'1y\'){d=c;c=b;b=Z}E(1c c!=\'1H\'){d=c;c=Z}4.O={1L:a,2j:b||4.O.2j,2z:$.G({1b:\'1l\'},(c?{1o:c}:{}),d||{})};4.12();C 4},3V:7(a,b,c,d,e,f){4.S.3W(1q 2T(4,a,b,c,d,e,f));4.12();C 4},1W:7(i){C(11.J>0?4.S[i]:Z)||4.S},3X:7(){4.2i=1K;C 4},3Y:7(){4.2i=18;4.12();C 4},3Z:7(a){4.2B=a;C 4},12:7(){E(!4.2i){C}2U(4.F.3m){4.F.41(4.F.3m)}E(!4.F.42){4.D.43.44(4.F)}E(!4.F.1r){4.F.3n(\'1r\',2V(4.F.2W(\'1r\'),10)||4.D.2X())}2n E(4.F.1r.1P){4.F.1r.1P.1L=4.F.1r.1P.1L||4.D.2X()}2n{4.F.1r=4.F.1r||4.D.2X()}E(!4.F.1A){4.F.3n(\'1A\',2V(4.F.2W(\'1A\'),10)||4.D.2Y())}2n E(4.F.1A.1P){4.F.1A.1P.1L=4.F.1A.1P.1L||4.D.2Y()}2n{4.F.1A=4.F.1A||4.D.2Y()}4.2y.1X(4)},28:7(a,b){C(!a[b]?2V(a.2W(b),10):(a[b].1P?a[b].1P.1L:a[b]))},1Y:7(){4.D.14(4.F,4.28(4.F,\'1r\')/2,4.O.2j,4.O.1L,4.O.2z)},1B:7(a){a=a||4.1M;6 b=4.28(4.F,\'1r\');6 c=4.28(4.F,\'1A\');6 d=(a[4.L]>1?a[4.L]:b*a[4.L]);6 e=(a[4.T]>1?a[4.T]:c*a[4.T]);6 f=(a[4.R]>1?a[4.R]:b*a[4.R])-d;6 g=(a[4.B]>1?a[4.B]:c*a[4.B])-e;C[d,e,f,g]},1Z:7(a,b){6 c=4.D.V(4.F,{U:\'45\'});6 d=4.1B();4.D.20(c,d[4.X],d[4.Y],d[4.W],d[4.H],4.2A);E(4.1j[0]&&4.N.I.16&&!b){4.29(c,4.N,18,d,4.1j[0])}E(4.1j[1]&&4.Q.I.16&&!a){4.29(c,4.Q,1K,d,4.1j[1])}C c},29:7(a,b,c,d,e){6 g=4.D.V(a,e);6 f=(c?d[4.H]:d[4.W])/(b.K.1d-b.K.13);6 h=17.2Z(b.K.13/b.I.16)*b.I.16;h=(h<b.K.13?h+b.I.16:h);2U(h<=b.K.1d){6 v=(c?b.K.1d-h:h-b.K.13)*f+(c?d[4.Y]:d[4.X]);4.D.1e(g,(c?d[4.X]:v),(c?v:d[4.Y]),(c?d[4.X]+d[4.W]:v),(c?v:d[4.Y]+d[4.H]));h+=b.I.16}},2o:7(a){6 b=4.1B();E(4.Q&&!a){E(4.Q.O){4.D.14(4.F,b[4.X]+b[4.W]/2,b[4.Y]+b[4.H]+4.Q.1f,4.Q.O,4.Q.1m)}4.1Q(4.Q,\'Q\',b[4.X],b[4.Y]+b[4.H],b[4.X]+b[4.W],b[4.Y]+b[4.H])}E(4.N){E(4.N.O){4.D.14(4.F,0,0,4.N.O,$.G({1b:\'1l\',2p:\'2q(\'+(b[4.X]-4.N.1f)+\',\'+(b[4.Y]+b[4.H]/2)+\') 2r(-2s)\'},4.N.1m||{}))}4.1Q(4.N,\'N\',b[4.X],b[4.Y],b[4.X],b[4.Y]+b[4.H])}E(4.1N&&!a){E(4.1N.O){4.D.14(4.F,b[4.X]+b[4.W]/2,b[4.X]-4.1N.1f,4.1N.O,4.1N.1m)}4.1Q(4.1N,\'1N\',b[4.X],b[4.Y],b[4.X]+b[4.W],b[4.Y])}E(4.1O){E(4.1O.O){4.D.14(4.F,0,0,4.1O.O,$.G({1b:\'1l\',2p:\'2q(\'+(b[4.X]+b[4.W]+4.1O.1f)+\',\'+(b[4.Y]+b[4.H]/2)+\') 2r(-2s)\'},4.1O.1m||{}))}4.1Q(4.1O,\'1O\',b[4.X]+b[4.W],b[4.Y],b[4.X]+b[4.W],b[4.Y]+b[4.H])}},1Q:7(a,b,c,d,e,f){6 g=(d==f);6 h=4.D.V(4.F,$.G({U:b},a.1R));6 i=4.D.V(4.F,$.G({U:b+\'46\',1b:(g?\'1l\':\'2a\')},a.1p));4.D.1e(h,c,d,e,f);E(a.I.16){6 j=(e>(4.28(4.F,\'1r\')/2)&&f>(4.28(4.F,\'1A\')/2));6 k=(g?e-c:f-d)/(a.K.1d-a.K.13);6 l=a.I.1g;6 m=17.2Z(a.K.13/a.I.16)*a.I.16;m=(m<a.K.13?m+a.I.16:m);6 n=(!a.I.21?a.K.1d+1:17.2Z(a.K.13/a.I.21)*a.I.21);n=(n<a.K.13?n+a.I.21:n);6 o=4.2b(a,j);6 p=0;2U(m<=a.K.1d||n<=a.K.1d){6 q=17.13(m,n);6 r=(q==m?l:l/2);6 v=(g?c:d)+(g?q-a.K.13:a.K.1d-q)*k;4.D.1e(h,(g?v:c+r*o[0]),(g?d+r*o[0]:v),(g?v:c+r*o[1]),(g?d+r*o[1]:v));E(q==m){4.D.14(i,(g?v:c-l),(g?d+2*l:v),(a.1n?a.1n[p++]:\'\'+q))}m+=(q==m?a.I.16:0);n+=(q==n?a.I.21:0)}}},2b:7(a,b){C[(a.I.22==(b?\'2O\':\'2D\')||a.I.22==\'3o\'?-1:0),(a.I.22==(b?\'2D\':\'2O\')||a.I.22==\'3o\'?+1:0),]},2t:7(){4.2R.O=$.19.1k.2h.2g;C 4.2R},2E:7(){6 a=[];6 b=(4.S.J?4.S[0].P.J:0);M(6 i=0;i<b;i++){a[i]=0;M(6 j=0;j<4.S.J;j++){a[i]+=4.S[j].P[i]}}C a},23:7(){E(!4.1x.2F){C}6 g=4.D.V(4.F,{U:\'1x\'});6 a=4.1B(4.1x.1M);4.D.20(g,a[4.X],a[4.Y],a[4.W],a[4.H],4.1x.2G);6 b=a[4.W]>a[4.H];6 c=4.S.J;6 d=(b?a[4.W]:a[4.H])/c;6 e=a[4.X]+5;6 f=a[4.Y]+((b?a[4.H]:d)+4.1x.1I)/2;M(6 i=0;i<c;i++){6 h=4.S[i];4.D.20(g,e+(b?i*d:0),f+(b?0:i*d)-4.1x.1I,4.1x.1I,4.1x.1I,{1o:h.1C,1i:h.1z,1D:1});4.D.14(g,e+(b?i*d:0)+4.1x.1I+5,f+(b?0:i*d),h.1s,4.1x.2u)}},24:7(a,b,c){6 d=4.2B;E(4.2B){$(a).47(7(){d.3p(4,[b,c])},7(){d.3p(4,[\'\',0])})}}});7 2T(a,b,c,d,e,f,g){E(1c b!=\'1H\'){g=f;f=e;e=d;d=c;c=b;b=Z}E(1c e!=\'1H\'){g=f;f=e;e=Z}E(1c f!=\'1y\'){g=f;f=Z}4.1a=a;4.1s=b||\'\';4.P=c||[];4.48=1;4.1C=d||\'49\';4.1z=e||\'2P\';4.1E=f||1;4.1J=g||{}}$.G(2T.1v,{4a:7(a){E(11.J==0){C 4.1s}4.1s=a;4.1a.12();C 4},1S:7(a,b){E(11.J==0){C 4.P}E(2m(a)){b=a;a=Z}4.1s=a||4.1s;4.P=b;4.1a.12();C 4},27:7(a,b,c,d){E(11.J==0){C $.G({1o:4.1C,1i:4.1z,1D:4.1E},4.1J)}E(1c b!=\'1H\'){d=c;c=b;b=Z}E(1c c!=\'1y\'){d=c;c=Z}4.1C=a||4.1C;4.1z=b||4.1z;4.1E=c||4.1E;$.G(4.1J,d||{});4.1a.12();C 4},2a:7(){C 4.1a}});7 2k(a,b,c,d,e,f){4.1a=a;4.O=b||\'\';4.1m={};4.1f=0;4.1n=Z;4.1p={};4.1R={1i:\'2P\',1D:1};4.I={16:e||10,21:f||0,1g:10,22:\'2D\'};4.K={13:c||0,1d:d||2l};4.4b=0}$.G(2k.1v,{4c:7(a,b){E(11.J==0){C 4.K}4.K.13=a;4.K.1d=b;4.1a.12();C 4},4d:7(a,b,c,d){E(11.J==0){C 4.I}E(1c c==\'1H\'){d=c;c=Z}4.I.16=a;4.I.21=b;4.I.1g=c||4.I.1g;4.I.22=d||4.I.22;4.1a.12();C 4},1w:7(a,b,c,d){E(11.J==0){C{1w:4.O,2j:4.1f,27:4.1m}}E(1c b!=\'1y\'){d=c;c=b;b=Z}E(1c c!=\'1H\'){d=c;c=Z}4.O=a;4.1f=(b!=Z?b:4.1f);E(c||d){4.1m=$.G(d||{},(c?{1o:c}:{}))}4.1a.12();C 4},3q:7(a,b,c){E(11.J==0){C{3q:4.1n,27:4.1p}}E(1c b!=\'1H\'){c=b;b=Z}4.1n=a;E(b||c){4.1p=$.G(c||{},(b?{1o:b}:{}))}4.1a.12();C 4},1e:7(a,b,c){E(11.J==0){C 4.1R}E(1c b==\'3l\'){c=b;b=Z}$.G(4.1R,{1i:a},(b?{1D:b}:{}),c||{});4.1a.12();C 4},2a:7(){C 4.1a}});7 2Q(a,b,c){4.1a=a;4.2F=18;4.1M=[0.9,0.1,1.0,0.9];4.1I=15;4.2G=b||{1i:\'4e\'};4.2u=c||{}}$.G(2Q.1v,{4f:7(a){E(11.J==0){C 4.2F}4.2F=a;4.1a.12();C 4},2C:7(a,b,c,d){E(11.J==0){C 4.1M}4.1M=(2m(a)?a:[a,b,c,d]);4.1a.12();C 4},2z:7(a,b,c){E(11.J==0){C{4g:4.1I,4h:4.2G,4i:4.2u}}E(1c a!=\'1y\'){c=b;b=a;a=Z}4.1I=a||4.1I;4.2G=b;4.2u=c||4.2u;4.1a.12();C 4},2a:7(){C 4.1a}});7 2H(a,b){C 17.4j(a*17.3r(10,b))/17.3r(10,b)}6 B=[\'2v (1y) - 1T 1r 1F 30 4k\',\'2w (1y) - 1T 4l 3s 2c 1F 2I\'];7 31(){}$.G(31.1v,{1w:7(){C\'32 33 1t\'},2d:7(){C\'2e 2c 1F 1S 2f 3t 2I 3u 3v 3w.\'},1G:7(){C B},1X:7(a){a.1Z(18);6 b=a.1h.2v||10;6 c=a.1h.2w||10;6 d=a.S.J;6 e=(d?(a.S[0]).P.J:0);6 f=a.1B();6 g=f[a.W]/((d*b+c)*e+c);6 h=f[a.H]/(a.N.K.1d-a.N.K.13);4.1u=a.D.V(a.F,{U:\'1t\'});M(6 i=0;i<d;i++){4.1U(a,i,d,b,c,f,g,h)}a.1Y();a.2o(18);4.2J(a,d,e,b,c,f,g);a.23()},1U:7(a,b,c,d,e,f,h,j){6 k=a.S[b];6 g=a.D.V(4.1u,$.G({U:\'1W\'+b,1o:k.1C,1i:k.1z,1D:k.1E},k.1J||{}));M(6 i=0;i<k.P.J;i++){6 r=a.D.20(g,f[a.X]+h*(e+i*(c*d+e)+(b*d)),f[a.Y]+j*(a.N.K.1d-k.P[i]),h*d,j*k.P[i]);a.24(r,k.1s,k.P[i])}},2J:7(a,b,c,d,e,f,g){6 h=a.Q;E(h.O){a.D.14(a.F,f[a.X]+f[a.W]/2,f[a.Y]+f[a.H]+h.1f,h.O,$.G({1b:\'1l\'},h.1m||{}))}6 j=a.D.V(a.F,$.G({U:\'Q\'},h.1R));6 k=a.D.V(a.F,$.G({U:\'34\',1b:\'1l\'},h.1p));a.D.1e(j,f[a.X],f[a.Y]+f[a.H],f[a.X]+f[a.W],f[a.Y]+f[a.H]);E(h.I.16){6 l=a.2b(h,18);M(6 i=1;i<c;i++){6 x=f[a.X]+g*(e/2+i*(b*d+e));a.D.1e(j,x,f[a.Y]+f[a.H]+l[0]*h.I.1g,x,f[a.Y]+f[a.H]+l[1]*h.I.1g)}M(6 i=0;i<c;i++){6 x=f[a.X]+g*(e/2+(i+0.5)*(b*d+e));a.D.14(k,x,f[a.Y]+f[a.H]+2*h.I.1g,(h.1n?h.1n[i]:\'\'+i))}}}});7 35(){}$.G(35.1v,{1w:7(){C\'3x 33 1t\'},2d:7(){C\'2e 2c 1F 1S 2f 3t 2I 3y \'+\'36 37 2x 1T 38 M 30 3z.\'},1G:7(){C B},1X:7(a){6 b=a.1Z(18,18);6 c=a.1B();E(a.1j[0]&&a.Q.I.16){a.29(b,a.2t(),18,c,a.1j[0])}6 d=a.1h.2v||10;6 e=a.1h.2w||10;6 f=a.S.J;6 g=(f?(a.S[0]).P.J:0);6 h=c[a.W]/((d+e)*g+e);6 i=c[a.H];4.1u=a.D.V(a.F,{U:\'1t\'});4.3A(a,f,g,d,e,c,h,i);a.1Y();a.D.14(a.F,0,0,$.19.1k.2h.2g,$.G({1b:\'1l\',2p:\'2q(\'+(c[a.X]-a.N.1f)+\',\'+(c[a.Y]+c[a.H]/2)+\') 2r(-2s)\'},a.N.1m||{}));6 j=$.G({},a.2t());$.G(j.1p,a.N.1p||{});a.1Q(j,\'N\',c[a.X],c[a.Y],c[a.X],c[a.Y]+c[a.H]);4.2J(a,g,d,e,c,h);a.23()},3A:7(a,b,c,d,e,f,h,j){6 k=a.2E();6 l=[];M(6 i=0;i<c;i++){l[i]=0}M(6 s=0;s<b;s++){6 m=a.S[s];6 g=a.D.V(4.1u,$.G({U:\'1W\'+s,1o:m.1C,1i:m.1z,1D:m.1E},m.1J||{}));M(6 i=0;i<m.P.J;i++){l[i]+=m.P[i];6 r=a.D.20(g,f[a.X]+h*(e+i*(d+e)),f[a.Y]+j*(k[i]-l[i])/k[i],h*d,j*m.P[i]/k[i]);a.24(r,m.1s,2H(m.P[i]/k[i]*2l,2))}}},2J:7(a,b,c,d,e,f){6 g=a.Q;E(g.O){a.D.14(a.F,e[a.X]+e[a.W]/2,e[a.Y]+e[a.H]+g.1f,g.O,$.G({1b:\'1l\'},g.1m||{}))}6 h=a.D.V(a.F,$.G({U:\'Q\'},g.1R));6 j=a.D.V(a.F,$.G({U:\'34\',1b:\'1l\'},g.1p));a.D.1e(h,e[a.X],e[a.Y]+e[a.H],e[a.X]+e[a.W],e[a.Y]+e[a.H]);E(g.I.16){6 k=a.2b(g,18);M(6 i=1;i<b;i++){6 x=e[a.X]+f*(d/2+i*(c+d));a.D.1e(h,x,e[a.Y]+e[a.H]+k[0]*g.I.1g,x,e[a.Y]+e[a.H]+k[1]*g.I.1g)}M(6 i=0;i<b;i++){6 x=e[a.X]+f*(d/2+(i+0.5)*(c+d));a.D.14(j,x,e[a.Y]+e[a.H]+2*g.I.1g,(g.1n?g.1n[i]:\'\'+i))}}}});7 39(){}$.G(39.1v,{1w:7(){C\'32 3a 1t\'},2d:7(){C\'2e 2c 1F 1S 2f 3B 4m 3u 3v 3w.\'},1G:7(){C B},1X:7(a){6 b=a.1Z(18,18);6 c=a.1B();a.29(b,a.N,1K,c,a.1j[0]);6 d=a.1h.2v||10;6 e=a.1h.2w||10;6 f=a.S.J;6 g=(f?(a.S[0]).P.J:0);6 h=c[a.W]/(a.N.K.1d-a.N.K.13);6 j=c[a.H]/((f*d+e)*g+e);4.1u=a.D.V(a.F,{U:\'1t\'});M(6 i=0;i<f;i++){4.1U(a,i,f,d,e,c,h,j)}a.1Y();4.2o(a,f,g,d,e,c,j);a.23()},1U:7(a,b,c,d,e,f,h,j){6 k=a.S[b];6 g=a.D.V(4.1u,$.G({U:\'1W\'+b,1o:k.1C,1i:k.1z,1D:k.1E},k.1J||{}));M(6 i=0;i<k.P.J;i++){6 r=a.D.20(g,f[a.X]+h*(0-a.N.K.13),f[a.Y]+j*(e+i*(c*d+e)+(b*d)),h*k.P[i],j*d);a.24(r,k.1s,k.P[i])}},2o:7(a,b,c,d,e,f,g){6 h=a.N;E(h){E(h.O){a.D.14(a.F,f[a.X]+f[a.W]/2,f[a.Y]+f[a.H]+h.1f,h.O,h.1m)}a.1Q(h,\'Q\',f[a.X],f[a.Y]+f[a.H],f[a.X]+f[a.W],f[a.Y]+f[a.H])}6 h=a.Q;E(h.O){a.D.14(a.F,0,0,h.O,$.G({1b:\'1l\',2p:\'2q(\'+(f[a.X]-h.1f)+\',\'+(f[a.Y]+f[a.H]/2)+\') 2r(-2s)\'},h.1m||{}))}6 j=a.D.V(a.F,$.G({U:\'N\'},h.1R));6 k=a.D.V(a.F,$.G({U:\'3C\',1b:\'2a\'},h.1p));a.D.1e(j,f[a.X],f[a.Y],f[a.X],f[a.Y]+f[a.H]);E(h.I.16){6 l=a.2b(h,1K);M(6 i=1;i<c;i++){6 y=f[a.Y]+g*(e/2+i*(b*d+e));a.D.1e(j,f[a.X]+l[0]*h.I.1g,y,f[a.X]+l[1]*h.I.1g,y)}M(6 i=0;i<c;i++){6 y=f[a.Y]+g*(e/2+(i+0.5)*(b*d+e));a.D.14(k,f[a.X]-h.I.1g,y,(h.1n?h.1n[i]:\'\'+i))}}}});7 3b(){}$.G(3b.1v,{1w:7(){C\'3x 3a 1t\'},2d:7(){C\'2e 2c 1F 1S 2f 3B 2I 3y \'+\'36 37 2x 1T 38 M 30 3z.\'},1G:7(){C B},1X:7(a){6 b=a.1Z(18,18);6 c=a.1B();E(a.1j[0]&&a.Q.I.16){a.29(b,a.2t(),1K,c,a.1j[0])}6 d=a.1h.2v||10;6 e=a.1h.2w||10;6 f=a.S.J;6 g=(f?(a.S[0]).P.J:0);6 h=c[a.W];6 i=c[a.H]/((d+e)*g+e);4.1u=a.D.V(a.F,{U:\'1t\'});4.3D(a,f,g,d,e,c,h,i);a.1Y();a.D.14(a.F,c[a.X]+c[a.W]/2,c[a.Y]+c[a.H]+a.Q.1f,$.19.1k.2h.2g,$.G({1b:\'1l\'},a.N.1m||{}));6 j=$.G({},a.2t());$.G(j.1p,a.N.1p||{});a.1Q(j,\'Q\',c[a.X],c[a.Y]+c[a.H],c[a.X]+c[a.W],c[a.Y]+c[a.H]);4.3E(a,g,d,e,c,i);a.23()},3D:7(a,b,c,d,e,f,h,j){6 k=a.2E();6 l=[];M(6 i=0;i<c;i++){l[i]=0}M(6 s=0;s<b;s++){6 m=a.S[s];6 g=a.D.V(4.1u,$.G({U:\'1W\'+s,1o:m.1C,1i:m.1z,1D:m.1E},m.1J||{}));M(6 i=0;i<m.P.J;i++){6 r=a.D.20(g,f[a.X]+h*l[i]/k[i],f[a.Y]+j*(e+i*(d+e)),h*m.P[i]/k[i],j*d);a.24(r,m.1s,2H(m.P[i]/k[i]*2l,2));l[i]+=m.P[i]}}},3E:7(a,b,c,d,e,f){6 g=a.Q;E(g.O){a.D.14(a.F,0,0,g.O,$.G({1b:\'1l\',2p:\'2q(\'+(e[a.X]-g.1f)+\',\'+(e[a.Y]+e[a.H]/2)+\') 2r(-2s)\'},g.1m||{}))}6 h=a.D.V(a.F,$.G({U:\'N\'},g.1R));6 j=a.D.V(a.F,$.G({U:\'3C\',1b:\'2a\'},g.1p));a.D.1e(h,e[a.X],e[a.Y],e[a.X],e[a.Y]+e[a.H]);E(g.I.16){6 k=a.2b(g,1K);M(6 i=1;i<b;i++){6 y=e[a.Y]+f*(d/2+i*(c+d));a.D.1e(h,e[a.X]+k[0]*g.I.1g,y,e[a.X]+k[1]*g.I.1g,y)}M(6 i=0;i<b;i++){6 y=e[a.Y]+f*(d/2+(i+0.5)*(c+d));a.D.14(j,e[a.X]-g.I.1g,y,(g.1n?g.1n[i]:\'\'+i))}}}});7 3c(){}$.G(3c.1v,{1w:7(){C\'32 1e 1t\'},2d:7(){C\'2e 2c 1F 1S 2f 4n 4o.\'},1G:7(){C[]},1X:7(a){a.1Z();6 b=a.1B();6 c=b[a.W]/(a.Q.K.1d-a.Q.K.13);6 d=b[a.H]/(a.N.K.1d-a.N.K.13);4.1u=a.D.V(a.F,{U:\'1t\'});M(6 i=0;i<a.S.J;i++){4.1U(a,i,b,c,d)}a.1Y();a.2o();a.23()},1U:7(a,b,c,d,e){6 f=a.S[b];6 g=a.D.3F();M(6 i=0;i<f.P.J;i++){6 x=c[a.X]+i*d;6 y=c[a.Y]+(a.N.K.1d-f.P[i])*e;E(i==0){g.3d(x,y)}2n{g.1e(x,y)}}6 p=a.D.3G(4.1u,g,$.G({4p:\'1W\'+b,1o:\'3k\',1i:f.1z,1D:f.1E},f.1J||{}));a.24(p,f.1s,0)}});7 3e(){}$.G(3e.1v,{3H:[\'3f (1y 4q 1y[]) - 4r 1F 4s 2x 3f 2D 1F 1T 3I\',\'3J (1y) - 1T 3K 2x 3d 4t 4u 4v\',\'3L (1y) - 1T 3K 3s 4w M 4x 1S\'],1w:7(){C\'4y 1t\'},2d:7(){C\'2e 36 4z 1F 1S 2f 37 2x 1T 38.\'},1G:7(){C 4.3H},1X:7(a){a.1Z(18,18);4.1u=a.D.V(a.F,{U:\'1t\'});6 b=a.1B();4.1U(a,b);a.1Y();a.23()},1U:7(a,b){6 c=a.2E();6 d=a.S.J;6 e=(d?(a.S[0]).P.J:0);6 f=a.D.3F();6 g=a.1h.3f||[];g=(2m(g)?g:[g]);6 h=a.1h.3J||10;6 l=(e<=1?0:a.1h.3L||10);6 m=(b[a.W]-(e*l)-l)/e/2;6 n=b[a.H]/2;6 o=17.13(m,n)-(g.J>0?h:0);6 q=a.D.V(a.F,$.G({U:\'34\',1b:\'1l\'},a.Q.1p));6 r=[];M(6 i=0;i<e;i++){6 s=b[a.X]+m+(i*(2*17.13(m,n)+l))+l;6 t=b[a.Y]+n;6 u=0;M(6 j=0;j<d;j++){6 v=a.S[j];E(i==0){r[j]=a.D.V(4.1u,$.G({U:\'1W\'+j,1o:v.1C,1i:v.1z,1D:v.1E},v.1J||{}))}E(v.P[i]==0){4A}6 w=(u/c[i])*2*17.2K;u+=v.P[i];6 z=(u/c[i])*2*17.2K;6 A=1K;M(6 k=0;k<g.J;k++){E(g[k]==j){A=18;3j}}6 x=s+(A?h*17.3g((w+z)/2):0);6 y=t+(A?h*17.3h((w+z)/2):0);6 p=a.D.3G(r[j],f.4B().3d(x,y).1e(x+o*17.3g(w),y+o*17.3h(w)).4C(o,o,0,(z-w<17.2K?0:1),1,x+o*17.3g(z),y+o*17.3h(z)).4D());a.24(p,v.1s,2H((z-w)/2/17.2K*2l,2))}E(a.Q){a.D.14(q,s,b[a.Y]+b[a.H]+a.Q.1f,a.Q.1n[i])}}}});7 2m(a){C(a&&a.4E==4F)}$.19.1k.1V(\'33\',1q 31());$.19.1k.1V(\'4G\',1q 35());$.19.1k.1V(\'3a\',1q 39());$.19.1k.1V(\'4H\',1q 3b());$.19.1k.1V(\'1e\',1q 3c());$.19.1k.1V(\'3I\',1q 3e())})(4I)',62,293,'||||this||var|function|||||||||||||||||||||||||||||||return|_wrapper|if|_chartCont|extend||_ticks|length|_scale||for|yAxis|_title|_values|xAxis||_series||class_|group||||null||arguments|_drawGraph|min|text||major|Math|true|svg|_graph|textAnchor|typeof|max|line|_titleOffset|size|_chartOptions|stroke|_gridlines|graphing|middle|_titleFormat|_labels|fill|_labelFormat|new|width|_name|chart|_chart|prototype|title|legend|number|_stroke|height|_getDims|_fill|strokeWidth|_strokeWidth|of|options|string|_sampleSize|_settings|false|value|_area|x2Axis|y2Axis|baseVal|_drawAxis|_lineFormat|values|the|_drawSeries|addChartType|series|drawGraph|_drawTitle|_drawChartBackground|rect|minor|position|_drawLegend|_showStatus||_chartTypes|format|_getValue|_drawGridlines|end|_getTickOffsets|sets|description|Compare|as|percentageText|region|_drawNow|offset|SVGGraphAxis|100|isArray|else|_drawAxes|transform|translate|rotate|90|_getPercentageAxis|_textSettings|barWidth|barGap|to|_chartType|settings|_chartFormat|_onstatus|area|out|_getTotals|_show|_bgSettings|roundNumber|bars|_drawXAxis|PI|SVGGraph|SVGGraphing|regional|in|black|SVGGraphLegend|_percentageAxis|type|SVGGraphSeries|while|parseInt|getAttribute|_width|_height|floor|each|SVGColumnChart|Basic|column|xAxisLabels|SVGStackedColumnChart|relative|contributions|whole|SVGRowChart|row|SVGStackedRowChart|SVGLineChart|move|SVGPieChart|explode|cos|sin|graph|break|none|object|firstChild|setAttribute|both|apply|labels|pow|between|vertical|with|grouped|categories|Stacked|showing|category|_drawColumns|horizontal|yAxisLabels|_drawRows|_drawYAxis|createPath|path|_options|pie|explodeDist|distance|pieGap|addExtension|Percentage|chartTypes|container|chartType|chartOptions|chartFormat|chartArea|gridlines|addSeries|push|noDraw|redraw|status||removeChild|parent|_svg|appendChild|background|Labels|hover|_axis|green|name|_crossAt|scale|ticks|gray|show|sampleSize|bgSettings|textSettings|round|bar|gap|rows|continuous|lines|id|or|indexes|sections|an|exploded|section|pies|multiple|Pie|sizes|continue|reset|arc|close|constructor|Array|stackedColumn|stackedRow|jQuery'.split('|'),0,{}))
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.js
new file mode 100644
index 0000000..b399f1c
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.js
@@ -0,0 +1,817 @@
+/* http://keith-wood.name/svg.html
+   SVG plotting extension for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) December 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+$.svg.addExtension('plot', SVGPlot);
+
+/* Extension point for SVG plotting.
+   Access through svg.plot. */
+function SVGPlot(wrapper) {
+	this._wrapper = wrapper; // The attached SVG wrapper object
+	this._drawNow = false; // True for immediate update, false to wait for redraw call
+	// The plot title and settings
+	this._title = {value: '', offset: 25, settings: {textAnchor: 'middle'}};
+	this._area = [0.1, 0.1, 0.8, 0.9]; // The chart area: left, top, right, bottom,
+		// > 1 in pixels, <= 1 as proportion
+	this._areaFormat = {fill: 'none', stroke: 'black'}; // The formatting for the plot area
+	this._gridlines = []; // The formatting of the x- and y-gridlines
+	this._equalXY = true; // True for equal-sized x- and y-units, false to fill available space
+	this._functions = []; // The functions to be plotted, each is an object
+	this._onstatus = null; // The callback function for status updates
+	this._uuid = new Date().getTime();
+	this._plotCont = this._wrapper.svg(0, 0, 0, 0, {class_: 'svg-plot'}); // The main container for the plot
+
+	this.xAxis = new SVGPlotAxis(this); // The main x-axis
+	this.xAxis.title('X', 20);
+	this.yAxis = new SVGPlotAxis(this); // The main y-axis
+	this.yAxis.title('Y', 20);
+	this.legend = new SVGPlotLegend(this); // The plot legend
+	this._drawNow = true;
+}
+
+$.extend(SVGPlot.prototype, {
+
+	/* Useful indexes. */
+	X: 0,
+	Y: 1,
+	W: 2,
+	H: 3,
+	L: 0,
+	T: 1,
+	R: 2,
+	B: 3,
+
+	/* Set or retrieve the container for the plot.
+	   @param  cont  (SVG element) the container for the plot
+	   @return  (SVGPlot) this plot object or
+	            (SVG element) the current container (if no parameters) */
+	container: function(cont) {
+		if (arguments.length == 0) {
+			return this._plotCont;
+		}
+		this._plotCont = cont;
+		return this;
+	},
+
+	/* Set or retrieve the main plotting area.
+	   @param  left    (number) > 1 is pixels, <= 1 is proportion of width or
+	                   (number[4]) for left, top, right, bottom
+	   @param  top     (number) > 1 is pixels, <= 1 is proportion of height
+	   @param  right   (number) > 1 is pixels, <= 1 is proportion of width
+	   @param  bottom  (number) > 1 is pixels, <= 1 is proportion of height
+	   @return  (SVGPlot) this plot object or
+	            (number[4]) the plotting area: left, top, right, bottom (if no parameters) */
+	area: function(left, top, right, bottom) {
+		if (arguments.length == 0) {
+			return this._area;
+		}
+		this._area = (isArray(left) ? left : [left, top, right, bottom]);
+		this._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the background of the plot area.
+	   @param  fill      (string) how to fill the area background
+	   @param  stroke    (string) the colour of the outline (optional)
+	   @param  settings  (object) additional formatting for the area background (optional)
+	   @return  (SVGPlot) this plot object or
+	            (object) the area format (if no parameters) */
+	format: function(fill, stroke, settings) {
+		if (arguments.length == 0) {
+			return this._areaFormat;
+		}
+		if (typeof stroke == 'object') {
+			settings = stroke;
+			stroke = null;
+		}
+		this._areaFormat = $.extend({fill: fill},
+			(stroke ? {stroke: stroke} : {}), settings || {});
+		this._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the gridlines formatting for the plot area.
+	   @param  xSettings  (string) the colour of the gridlines along the x-axis, or
+	                      (object) formatting for the gridlines along the x-axis, or
+						  null for none
+	   @param  ySettings  (string) the colour of the gridlines along the y-axis, or
+	                      (object) formatting for the gridlines along the y-axis, or
+						  null for none
+	   @return  (SVGPlot) this plot object or
+	            (object[2]) the gridlines formatting (if no parameters) */
+	gridlines: function(xSettings, ySettings) {
+		if (arguments.length == 0) {
+			return this._gridlines;
+		}
+		this._gridlines = [(typeof xSettings == 'string' ? {stroke: xSettings} : xSettings),
+			(typeof ySettings == 'string' ? {stroke: ySettings} : ySettings)];
+		if (this._gridlines[0] == null && this._gridlines[1] == null) {
+			this._gridlines = [];
+		}
+		this._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the equality of the x- and y-axes.
+	   @param  value  (boolean) true for equal x- and y-units, false to fill the available space
+	   @return  (SVGPlot) this plot object or
+	            (boolean) the current setting (if no parameters) */
+	equalXY: function(value) {
+		if (arguments.length == 0) {
+			return this._equalXY;
+		}
+		this._equalXY = value;
+		return this;
+	},
+
+	/* Set or retrieve the title of the plot and its formatting.
+	   @param  value     (string) the title
+	   @param  offset    (number) the vertical positioning of the title
+                          > 1 is pixels, <= 1 is proportion of width (optional)
+	   @param  colour    (string) the colour of the title (optional)
+	   @param  settings  (object) formatting for the title (optional)
+	   @return  (SVGPlot) this plot object or
+	            (object) value, offset, and settings for the title (if no parameters) */
+	title: function(value, offset, colour, settings) {
+		if (arguments.length == 0) {
+			return this._title;
+		}
+		if (typeof offset != 'number') {
+			settings = colour;
+			colour = offset;
+			offset = null;
+		}
+		if (typeof colour != 'string') {
+			settings = colour;
+			colour = null;
+		}
+		this._title = {value: value, offset: offset || this._title.offset,
+			settings: $.extend({textAnchor: 'middle'},
+			(colour ? {fill: colour} : {}), settings || {})};
+		this._drawPlot();
+		return this;
+	},
+
+	/* Add a function to be plotted on the plot.
+	   @param  name         (string) the name of this series (optional)
+	   @param  fn           (function) the function to be plotted
+	   @param  range        (number[2]) the range of values to plot (optional)
+	   @param  points       (number) the number of points to plot within this range (optional)
+	   @param  stroke       (string) the colour of the plotted lines (optional)
+	   @param  strokeWidth  (number) the width of the plotted lines (optional)
+	   @param  settings     (object) additional settings for the plotted values (optional)
+	   @return  (SVGPlot) this plot object */
+	addFunction: function(name, fn, range, points, stroke, strokeWidth, settings) {
+		this._functions.push(new SVGPlotFunction(
+			this, name, fn, range, points, stroke, strokeWidth, settings));
+		this._drawPlot();
+		return this;
+	},
+
+	/* Retrieve the function wrappers.
+	   @param  i  (number) the function index (optional)
+	   @return  (SVGPlotFunction) the specified function or
+	            (SVGPlotFunction[]) the list of functions */
+	functions: function(i) {
+		return (arguments.length > 0 ? this._functions[i] : null) || this._functions;
+	},
+
+	/* Suppress drawing of the plot until redraw() is called.
+	   @return  (SVGPlot) this plot object */
+	noDraw: function() {
+		this._drawNow = false;
+		return this;
+	},
+
+	/* Redraw the entire plot with the current settings and values.
+	   @return  (SVGPlot) this plot object */
+	redraw: function() {
+		this._drawNow = true;
+		this._drawPlot();
+		return this;
+	},
+
+	/* Set the callback function for status updates.
+	   @param  onstatus  (function) the callback function
+	   @return  (SVGPlot) this plot object */
+	status: function(onstatus) {
+		this._onstatus = onstatus;
+		return this;
+	},
+
+	/* Actually draw the plot (if allowed). */
+	_drawPlot: function() {
+		if (!this._drawNow) {
+			return;
+		}
+		while (this._plotCont.firstChild) {
+			this._plotCont.removeChild(this._plotCont.firstChild);
+		}
+		if (!this._plotCont.parent) {
+			this._wrapper._svg.appendChild(this._plotCont);
+		}
+		// Set sizes if not already there
+		if (!this._plotCont.width) {
+			this._plotCont.setAttribute('width',
+				parseInt(this._plotCont.getAttribute('width'), 10) || this._wrapper._width());
+		}
+		else if (this._plotCont.width.baseVal) {
+			this._plotCont.width.baseVal.value =
+				this._plotCont.width.baseVal.value || this._wrapper._width();
+		}
+		else {
+			this._plotCont.width = this._plotCont.width || this._wrapper._width();
+		}
+		if (!this._plotCont.height) {
+			this._plotCont.setAttribute('height',
+				parseInt(this._plotCont.getAttribute('height'), 10) || this._wrapper._height());
+		}
+		else if (this._plotCont.height.baseVal) {
+			this._plotCont.height.baseVal.value =
+				this._plotCont.height.baseVal.value || this._wrapper._height();
+		}
+		else {
+			this._plotCont.height = this._plotCont.height || this._wrapper._height();
+		}
+		this._drawChartBackground();
+		var dims = this._getDims();
+		var clip = this._wrapper.other(this._plotCont, 'clipPath', {id: 'clip' + this._uuid});
+		this._wrapper.rect(clip, dims[this.X], dims[this.Y], dims[this.W], dims[this.H]);
+		this._plot = this._wrapper.group(this._plotCont,
+			{class_: 'foreground', clipPath: 'url(#clip' + this._uuid + ')'});
+		this._drawAxis(true);
+		this._drawAxis(false);
+		for (var i = 0; i < this._functions.length; i++) {
+			this._plotFunction(this._functions[i], i);
+		}
+		this._drawTitle();
+		this._drawLegend();
+	},
+
+	/* Decode an attribute value.
+	   @param  node  the node to examine
+	   @param  name  the attribute name
+	   @return  the actual value */
+	_getValue: function(node, name) {
+		return (!node[name] ? parseInt(node.getAttribute(name), 10) :
+			(node[name].baseVal ? node[name].baseVal.value : node[name]));
+	},
+
+	/* Calculate the actual dimensions of the plot area.
+	    @param  area  (number[4]) the area values to evaluate (optional)
+		@return  (number[4]) an array of dimension values: left, top, width, height */
+	_getDims: function(area) {
+		var otherArea = (area != null);
+		area = area || this._area;
+		var availWidth = this._getValue(this._plotCont, 'width');
+		var availHeight = this._getValue(this._plotCont, 'height');
+		var left = (area[this.L] > 1 ? area[this.L] : availWidth * area[this.L]);
+		var top = (area[this.T] > 1 ? area[this.T] : availHeight * area[this.T]);
+		var width = (area[this.R] > 1 ? area[this.R] : availWidth * area[this.R]) - left;
+		var height = (area[this.B] > 1 ? area[this.B] : availHeight * area[this.B]) - top;
+		if (this._equalXY && !otherArea) {
+			var scale = Math.min(width / (this.xAxis._scale.max - this.xAxis._scale.min),
+				height / (this.yAxis._scale.max - this.yAxis._scale.min));
+			width = scale * (this.xAxis._scale.max - this.xAxis._scale.min);
+			height = scale * (this.yAxis._scale.max - this.yAxis._scale.min);
+		}
+		return [left, top, width, height];
+	},
+
+	/* Calculate the scaling factors for the plot area.
+	   @return  (number[2]) the x- and y-scaling factors */
+	_getScales: function() {
+		var dims = this._getDims();
+		return [dims[this.W] / (this.xAxis._scale.max - this.xAxis._scale.min),
+			dims[this.H] / (this.yAxis._scale.max - this.yAxis._scale.min)];
+	},
+
+	/* Draw the chart background, including gridlines.
+	   @param  noXGrid  (boolean) true to suppress the x-gridlines, false to draw them (optional)
+	   @param  noYGrid  (boolean) true to suppress the y-gridlines, false to draw them (optional)
+	   @return  (element) the background group element */
+	_drawChartBackground: function(noXGrid, noYGrid) {
+		var bg = this._wrapper.group(this._plotCont, {class_: 'background'});
+		var dims = this._getDims();
+		this._wrapper.rect(bg, dims[this.X], dims[this.Y], dims[this.W], dims[this.H], this._areaFormat);
+		if (this._gridlines[0] && this.yAxis._ticks.major && !noYGrid) {
+			this._drawGridlines(bg, true, this._gridlines[0], dims);
+		}
+		if (this._gridlines[1] && this.xAxis._ticks.major && !noXGrid) {
+			this._drawGridlines(bg, false, this._gridlines[1], dims);
+		}
+		return bg;
+	},
+
+	/* Draw one set of gridlines.
+	   @param  bg      (element) the background group element
+	   @param  horiz   (boolean) true if horizontal, false if vertical
+	   @param  format  (object) additional settings for the gridlines */
+	_drawGridlines: function(bg, horiz, format, dims) {
+		var g = this._wrapper.group(bg, format);
+		var axis = (horiz ? this.yAxis : this.xAxis);
+		var scales = this._getScales();
+		var major = Math.floor(axis._scale.min / axis._ticks.major) * axis._ticks.major;
+		major += (major <= axis._scale.min ? axis._ticks.major : 0);
+		while (major < axis._scale.max) {
+			var v = (horiz ? axis._scale.max - major : major - axis._scale.min) *
+				scales[horiz ? 1 : 0] + (horiz ? dims[this.Y] : dims[this.X]);
+			this._wrapper.line(g, (horiz ? dims[this.X] : v), (horiz ? v : dims[this.Y]),
+				(horiz ? dims[this.X] + dims[this.W] : v), (horiz ? v : dims[this.Y] + dims[this.H]));
+			major += axis._ticks.major;
+		}
+	},
+
+	/* Draw an axis, its tick marks, and title.
+	   @param  horiz  (boolean) true for x-axis, false for y-axis */
+	_drawAxis: function(horiz) {
+		var id = (horiz ? 'x' : 'y') + 'Axis';
+		var axis = (horiz ? this.xAxis : this.yAxis);
+		var axis2 = (horiz ? this.yAxis : this.xAxis);
+		var dims = this._getDims();
+		var scales = this._getScales();
+		var gl = this._wrapper.group(this._plot, $.extend({class_: id}, axis._lineFormat));
+		var gt = this._wrapper.group(this._plot, $.extend({class_: id + 'Labels',
+			textAnchor: (horiz ? 'middle' : 'end')}, axis._labelFormat));
+		var zero = (horiz ? axis2._scale.max : -axis2._scale.min) *
+			scales[horiz ? 1 : 0] + (horiz ? dims[this.Y] : dims[this.X]);
+		this._wrapper.line(gl, (horiz ? dims[this.X] : zero), (horiz ? zero : dims[this.Y]),
+			(horiz ? dims[this.X] + dims[this.W] : zero),
+			(horiz ? zero : dims[this.Y] + dims[this.H]));
+		if (axis._ticks.major) {
+			var size = axis._ticks.size;
+			var major = Math.floor(axis._scale.min / axis._ticks.major) * axis._ticks.major;
+			major = (major < axis._scale.min ? major + axis._ticks.major : major);
+			var minor = (!axis._ticks.minor ? axis._scale.max + 1 :
+				Math.floor(axis._scale.min / axis._ticks.minor) * axis._ticks.minor);
+			minor = (minor < axis._scale.min ? minor + axis._ticks.minor : minor);
+			var offsets = [(axis._ticks.position == 'nw' || axis._ticks.position == 'both' ? -1 : 0),
+				(axis._ticks.position == 'se' || axis._ticks.position == 'both' ? +1 : 0)];
+			while (major <= axis._scale.max || minor <= axis._scale.max) {
+				var cur = Math.min(major, minor);
+				var len = (cur == major ? size : size / 2);
+				var xy = (horiz ? cur - axis._scale.min : axis._scale.max - cur) *
+					scales[horiz ? 0 : 1] + (horiz ? dims[this.X] : dims[this.Y]);
+				this._wrapper.line(gl, (horiz ? xy : zero + len * offsets[0]),
+					(horiz ? zero + len * offsets[0] : xy),
+					(horiz ? xy : zero + len * offsets[1]),
+					(horiz ? zero + len * offsets[1] : xy));
+				if (cur == major && cur != 0) {
+					this._wrapper.text(gt, (horiz ? xy : zero - size),
+						(horiz ? zero - size : xy), '' + cur);
+				}
+				major += (cur == major ? axis._ticks.major : 0);
+				minor += (cur == minor ? axis._ticks.minor : 0);
+			}
+		}
+		if (axis._title) {
+			if (horiz) {
+				this._wrapper.text(this._plotCont, dims[this.X] - axis._titleOffset,
+					zero, axis._title, $.extend({textAnchor: 'end'}, axis._titleFormat || {}));
+			}
+			else {
+				this._wrapper.text(this._plotCont, zero,
+					dims[this.Y] + dims[this.H] + axis._titleOffset,
+					axis._title, $.extend({textAnchor : 'middle'}, axis._titleFormat || {}));
+			}
+		}
+	},
+
+	/* Plot an individual function. */
+	_plotFunction: function(fn, cur) {
+		var dims = this._getDims();
+		var scales = this._getScales();
+		var path = this._wrapper.createPath();
+		var range = fn._range || [this.xAxis._scale.min, this.xAxis._scale.max];
+		var xScale = (range[1] - range[0]) / fn._points;
+		var first = true;
+		for (var i = 0; i <= fn._points; i++) {
+			var x = range[0] + i * xScale;
+			if (x > this.xAxis._scale.max + xScale) {
+				break;
+			}
+			if (x < this.xAxis._scale.min - xScale) {
+				continue;
+			}
+			var px = (x - this.xAxis._scale.min) * scales[0] + dims[this.X];
+			var py = dims[this.H] - ((fn._fn(x) - this.yAxis._scale.min) * scales[1]) + dims[this.Y];
+			path[(first ? 'move' : 'line') + 'To'](px, py);
+			first = false;
+		}
+		var p = this._wrapper.path(this._plot, path,
+			$.extend({class_: 'fn' + cur, fill: 'none', stroke: fn._stroke,
+			strokeWidth: fn._strokeWidth}, fn._settings || {}));
+		this._showStatus(p, fn._name);
+	},
+
+	/* Draw the plot title - centred. */
+	_drawTitle: function() {
+		this._wrapper.text(this._plotCont, this._getValue(this._plotCont, 'width') / 2,
+			this._title.offset, this._title.value, this._title.settings);
+	},
+
+	/* Draw the chart legend. */
+	_drawLegend: function() {
+		if (!this.legend._show) {
+			return;
+		}
+		var g = this._wrapper.group(this._plotCont, {class_: 'legend'});
+		var dims = this._getDims(this.legend._area);
+		this._wrapper.rect(g, dims[this.X], dims[this.Y], dims[this.W], dims[this.H],
+			this.legend._bgSettings);
+		var horiz =  dims[this.W] > dims[this.H];
+		var numFn = this._functions.length;
+		var offset = (horiz ? dims[this.W] : dims[this.H]) / numFn;
+		var xBase = dims[this.X] + 5;
+		var yBase = dims[this.Y] + ((horiz ? dims[this.H] : offset) + this.legend._sampleSize) / 2;
+		for (var i = 0; i < numFn; i++) {
+			var fn = this._functions[i];
+			this._wrapper.rect(g, xBase + (horiz ? i * offset : 0),
+				yBase + (horiz ? 0 : i * offset) - this.legend._sampleSize,
+				this.legend._sampleSize, this.legend._sampleSize, {fill: fn._stroke});
+			this._wrapper.text(g, xBase + (horiz ? i * offset : 0) + this.legend._sampleSize + 5,
+				yBase + (horiz ? 0 : i * offset), fn._name, this.legend._textSettings);
+		}
+	},
+
+	/* Show the current value status on hover. */
+	_showStatus: function(elem, label) {
+		var status = this._onstatus;
+		if (this._onstatus) {
+			$(elem).hover(function(evt) { status.apply(this, [label]); },
+				function() { status.apply(this, ['']); });
+		}
+	}
+});
+
+/* Details about each plot function.
+   @param  plot         (SVGPlot) the owning plot
+   @param  name         (string) the name of this function (optional)
+   @param  fn           (function) the function to be plotted
+   @param  range        (number[2]) the range of values to be plotted (optional)
+   @param  points       (number) the number of points to plot within this range (optional)
+   @param  stroke       (string) the colour of the (out)line for the plot (optional)
+   @param  strokeWidth  (number) the width of the (out)line for the plot (optional)
+   @param  settings     (object) additional formatting settings (optional)
+   @return  (SVGPlotFunction) the new plot function object */
+function SVGPlotFunction(plot, name, fn, range, points, stroke, strokeWidth, settings) {
+	if (typeof name != 'string') {
+		settings = strokeWidth;
+		strokeWidth = stroke;
+		stroke = points;
+		points = range;
+		range = fn;
+		fn = name;
+		name = null;
+	}
+	if (!isArray(range)) {
+		settings = strokeWidth;
+		strokeWidth = stroke;
+		stroke = points;
+		points = range;
+		range = null;
+	}
+	if (typeof points != 'number') {
+		settings = strokeWidth;
+		strokeWidth = stroke;
+		stroke = points;
+		points = null;
+	}
+	if (typeof stroke != 'string') {
+		settings = strokeWidth;
+		strokeWidth = stroke;
+		stroke = null;
+	}
+	if (typeof strokeWidth != 'number') {
+		settings = strokeWidth;
+		strokeWidth = null;
+	}
+	this._plot = plot; // The owning plot
+	this._name = name || ''; // Display name
+	this._fn = fn || identity; // The actual function: y = fn(x)
+	this._range = range; // The range of values plotted
+	this._points = points || 100; // The number of points plotted
+	this._stroke = stroke || 'black'; // The line colour
+	this._strokeWidth = strokeWidth || 1; // The line width
+	this._settings = settings || {}; // Any other settings
+}
+
+$.extend(SVGPlotFunction.prototype, {
+
+	/* Set or retrieve the name for this function.
+	   @param  name    (string) the function's name
+	   @return  (SVGPlotFunction) this plot function object or
+	            (string) the function name (if no parameters) */
+	name: function(name) {
+		if (arguments.length == 0) {
+			return this._name;
+		}
+		this._name = name;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the function to be plotted.
+	   @param  name  (string) the function's name (optional)
+	   @param  fn    (function) the function to be ploted
+	   @return  (SVGPlotFunction) this plot function object or
+	            (function) the actual function (if no parameters) */
+	fn: function(name, fn) {
+		if (arguments.length == 0) {
+			return this._fn;
+		}
+		if (typeof name == 'function') {
+			fn = name;
+			name = null;
+		}
+		this._name = name || this._name;
+		this._fn = fn;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the range of values to be plotted.
+	   @param  min  (number) the minimum value to be plotted
+	   @param  max  (number) the maximum value to be plotted
+	   @return  (SVGPlotFunction) this plot function object or
+	            (number[2]) the value range (if no parameters) */
+	range: function(min, max) {
+		if (arguments.length == 0) {
+			return this._range;
+		}
+		this._range = (min == null ? null : [min, max]);
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the number of points to be plotted.
+	   @param  value  (number) the number of points to plot
+	   @return  (SVGPlotFunction) this plot function object or
+	            (number) the number of points (if no parameters) */
+	points: function(value) {
+		if (arguments.length == 0) {
+			return this._points;
+		}
+		this._points = value;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the formatting for this function.
+	   @param  stroke       (string) the (out)line colour
+	   @param  strokeWidth  (number) the line's width (optional)
+	   @param  settings     (object) additional formatting settings for the function (optional)
+	   @return  (SVGPlotFunction) this plot function object or
+	            (object) formatting settings (if no parameters) */
+	format: function(stroke, strokeWidth, settings) {
+		if (arguments.length == 0) {
+			return $.extend({stroke: this._stroke,
+				strokeWidth: this._strokeWidth}, this._settings);
+		}
+		if (typeof strokeWidth != 'number') {
+			settings = strokeWidth;
+			strokeWidth = null;
+		}
+		this._stroke = stroke || this._stroke;
+		this._strokeWidth = strokeWidth || this._strokeWidth;
+		$.extend(this._settings, settings || {});
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Return to the parent plot. */
+	end: function() {
+		return this._plot;
+	}
+});
+
+/* Default function to plot.
+   @param  x  (number) the input value
+   @return  (number) the same value */
+function identity(x) {
+	return x;
+}
+
+/* Details about each plot axis.
+   @param  plot   (SVGPlot) the owning plot
+   @param  title  (string) the title of the axis
+   @param  min    (number) the minimum value displayed on this axis
+   @param  max    (number) the maximum value displayed on this axis
+   @param  major  (number) the distance between major ticks
+   @param  minor  (number) the distance between minor ticks (optional)
+   @return  (SVGPlotAxis) the new axis object */
+function SVGPlotAxis(plot, title, min, max, major, minor) {
+	this._plot = plot; // The owning plot
+	this._title = title || ''; // The plot's title
+	this._titleFormat = {}; // Formatting settings for the title
+	this._titleOffset = 0; // The offset for positioning the title
+	this._labelFormat = {}; // Formatting settings for the labels
+	this._lineFormat = {stroke: 'black', strokeWidth: 1}; // Formatting settings for the axis lines
+	this._ticks = {major: major || 10, minor: minor || 0, size: 10, position: 'both'}; // Tick mark options
+	this._scale = {min: min || 0, max: max || 100}; // Axis scale settings
+	this._crossAt = 0; // Where this axis crosses the other one. */
+}
+
+$.extend(SVGPlotAxis.prototype, {
+
+	/* Set or retrieve the scale for this axis.
+	   @param  min  (number) the minimum value shown
+	   @param  max  (number) the maximum value shown
+	   @return  (SVGPlotAxis) this axis object or
+	            (object) min and max values (if no parameters) */
+	scale: function(min, max) {
+		if (arguments.length == 0) {
+			return this._scale;
+		}
+		this._scale.min = min;
+		this._scale.max = max;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the ticks for this axis.
+	   @param  major     (number) the distance between major ticks
+	   @param  minor     (number) the distance between minor ticks
+	   @param  size      (number) the length of the major ticks (minor are half) (optional)
+	   @param  position  (string) the location of the ticks:
+	                     'nw', 'se', 'both' (optional)
+	   @return  (SVGPlotAxis) this axis object or
+	            (object) major, minor, size, and position values (if no parameters) */
+	ticks: function(major, minor, size, position) {
+		if (arguments.length == 0) {
+			return this._ticks;
+		}
+		if (typeof size == 'string') {
+			position = size;
+			size = null;
+		}
+		this._ticks.major = major;
+		this._ticks.minor = minor;
+		this._ticks.size = size || this._ticks.size;
+		this._ticks.position = position || this._ticks.position;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the title for this axis.
+	   @param  title   (string) the title text
+	   @param  offset  (number) the distance to offset the title position (optional)
+	   @param  colour  (string) how to colour the title (optional)
+	   @param  format  (object) formatting settings for the title (optional)
+	   @return  (SVGPlotAxis) this axis object or
+	            (object) title, offset, and format values (if no parameters) */
+	title: function(title, offset, colour, format) {
+		if (arguments.length == 0) {
+			return {title: this._title, offset: this._titleOffset, format: this._titleFormat};
+		}
+		if (typeof offset != 'number') {
+			format = colour;
+			colour = offset;
+			offset = null;
+		}
+		if (typeof colour != 'string') {
+			format = colour;
+			colour = null;
+		}
+		this._title = title;
+		this._titleOffset = (offset != null ? offset : this._titleOffset);
+		if (colour || format) {
+			this._titleFormat = $.extend(format || {}, (colour ? {fill: colour} : {}));
+		}
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the label format for this axis.
+	   @param  colour  (string) how to colour the labels (optional)
+	   @param  format  (object) formatting settings for the labels (optional)
+	   @return  (SVGPlotAxis) this axis object or
+	            (object) format values (if no parameters) */
+	format: function(colour, format) {
+		if (arguments.length == 0) {
+			return this._labelFormat;
+		}
+		if (typeof colour != 'string') {
+			format = colour;
+			colour = null;
+		}
+		this._labelFormat = $.extend(format || {}, (colour ? {fill: colour} : {}));
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the line formatting for this axis.
+	   @param  colour    (string) the line's colour
+	   @param  width     (number) the line's width (optional)
+	   @param  settings  (object) additional formatting settings for the line (optional)
+	   @return  (SVGPlotAxis) this axis object or
+	            (object) line formatting values (if no parameters) */
+	line: function(colour, width, settings) {
+		if (arguments.length == 0) {
+			return this._lineFormat;
+		}
+		if (typeof width != 'number') {
+			settings = width;
+			width = null;
+		}
+		$.extend(this._lineFormat, {stroke: colour, strokeWidth:
+			width || this._lineFormat.strokeWidth}, settings || {});
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Return to the parent plot. */
+	end: function() {
+		return this._plot;
+	}
+});
+
+/* Details about the plot legend.
+   @param  plot          (SVGPlot) the owning plot
+   @param  bgSettings    (object) additional formatting settings for the legend background (optional)
+   @param  textSettings  (object) additional formatting settings for the legend text (optional)
+   @return  (SVGPlotLegend) the new legend object */
+function SVGPlotLegend(plot, bgSettings, textSettings) {
+	this._plot = plot; // The owning plot
+	this._show = true; // Show the legend?
+	this._area = [0.9, 0.1, 1.0, 0.9]; // The legend area: left, top, right, bottom,
+		// > 1 in pixels, <= 1 as proportion
+	this._sampleSize = 15; // Size of sample box
+	this._bgSettings = bgSettings || {stroke: 'gray'}; // Additional formatting settings for the legend background
+	this._textSettings = textSettings || {}; // Additional formatting settings for the text
+}
+
+$.extend(SVGPlotLegend.prototype, {
+
+	/* Set or retrieve whether the legend should be shown.
+	   @param  show  (boolean) true to display it, false to hide it
+	   @return  (SVGPlotLegend) this legend object or
+	            (boolean) show the legend? (if no parameters) */
+	show: function(show) {
+		if (arguments.length == 0) {
+			return this._show;
+		}
+		this._show = show;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve the legend area.
+	   @param  left    (number) > 1 is pixels, <= 1 is proportion of width or
+	                   (number[4]) for left, top, right, bottom
+	   @param  top     (number) > 1 is pixels, <= 1 is proportion of height
+	   @param  right   (number) > 1 is pixels, <= 1 is proportion of width
+	   @param  bottom  (number) > 1 is pixels, <= 1 is proportion of height
+	   @return  (SVGPlotLegend) this legend object or
+	            (number[4]) the legend area: left, top, right, bottom (if no parameters) */
+	area: function(left, top, right, bottom) {
+		if (arguments.length == 0) {
+			return this._area;
+		}
+		this._area = (isArray(left) ? left : [left, top, right, bottom]);
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Set or retrieve additional settings for the legend area.
+	   @param  sampleSize    (number) the size of the sample box to display (optional)
+	   @param  bgSettings    (object) additional formatting settings for the legend background
+	   @param  textSettings  (object) additional formatting settings for the legend text (optional)
+	   @return  (SVGPlotLegend) this legend object or
+	            (object) bgSettings and textSettings for the legend (if no parameters) */
+	settings: function(sampleSize, bgSettings, textSettings) {
+		if (arguments.length == 0) {
+			return {sampleSize: this._sampleSize, bgSettings: this._bgSettings,
+				textSettings: this._textSettings};
+		}
+		if (typeof sampleSize == 'object') {
+			textSettings = bgSettings;
+			bgSettings = sampleSize;
+			sampleSize = null;
+		}
+		this._sampleSize = sampleSize || this._sampleSize;
+		this._bgSettings = bgSettings;
+		this._textSettings = textSettings || this._textSettings;
+		this._plot._drawPlot();
+		return this;
+	},
+
+	/* Return to the parent plot. */
+	end: function() {
+		return this._plot;
+	}
+});
+
+//==============================================================================
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+	return (a && a.constructor == Array);
+}
+
+})(jQuery)
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.min.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.min.js
new file mode 100644
index 0000000..78d9f39
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.min.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG plotting extension for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) December 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+(function($){$.svg.addExtension('plot',SVGPlot);function SVGPlot(a){this._wrapper=a;this._drawNow=false;this._title={value:'',offset:25,settings:{textAnchor:'middle'}};this._area=[0.1,0.1,0.8,0.9];this._areaFormat={fill:'none',stroke:'black'};this._gridlines=[];this._equalXY=true;this._functions=[];this._onstatus=null;this._uuid=new Date().getTime();this._plotCont=this._wrapper.svg(0,0,0,0,{class_:'svg-plot'});this.xAxis=new SVGPlotAxis(this);this.xAxis.title('X',20);this.yAxis=new SVGPlotAxis(this);this.yAxis.title('Y',20);this.legend=new SVGPlotLegend(this);this._drawNow=true}$.extend(SVGPlot.prototype,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,container:function(a){if(arguments.length==0){return this._plotCont}this._plotCont=a;return this},area:function(a,b,c,d){if(arguments.length==0){return this._area}this._area=(isArray(a)?a:[a,b,c,d]);this._drawPlot();return this},format:function(a,b,c){if(arguments.length==0){return this._areaFormat}if(typeof b=='object'){c=b;b=null}this._areaFormat=$.extend({fill:a},(b?{stroke:b}:{}),c||{});this._drawPlot();return this},gridlines:function(a,b){if(arguments.length==0){return this._gridlines}this._gridlines=[(typeof a=='string'?{stroke:a}:a),(typeof b=='string'?{stroke:b}:b)];if(this._gridlines[0]==null&&this._gridlines[1]==null){this._gridlines=[]}this._drawPlot();return this},equalXY:function(a){if(arguments.length==0){return this._equalXY}this._equalXY=a;return this},title:function(a,b,c,d){if(arguments.length==0){return this._title}if(typeof b!='number'){d=c;c=b;b=null}if(typeof c!='string'){d=c;c=null}this._title={value:a,offset:b||this._title.offset,settings:$.extend({textAnchor:'middle'},(c?{fill:c}:{}),d||{})};this._drawPlot();return this},addFunction:function(a,b,c,d,e,f,g){this._functions.push(new SVGPlotFunction(this,a,b,c,d,e,f,g));this._drawPlot();return this},functions:function(i){return(arguments.length>0?this._functions[i]:null)||this._functions},noDraw:function(){this._drawNow=false;return this},redraw:function(){this._drawNow=true;this._drawPlot();return this},status:function(a){this._onstatus=a;return this},_drawPlot:function(){if(!this._drawNow){return}while(this._plotCont.firstChild){this._plotCont.removeChild(this._plotCont.firstChild)}if(!this._plotCont.parent){this._wrapper._svg.appendChild(this._plotCont)}if(!this._plotCont.width){this._plotCont.setAttribute('width',parseInt(this._plotCont.getAttribute('width'),10)||this._wrapper._width())}else if(this._plotCont.width.baseVal){this._plotCont.width.baseVal.value=this._plotCont.width.baseVal.value||this._wrapper._width()}else{this._plotCont.width=this._plotCont.width||this._wrapper._width()}if(!this._plotCont.height){this._plotCont.setAttribute('height',parseInt(this._plotCont.getAttribute('height'),10)||this._wrapper._height())}else if(this._plotCont.height.baseVal){this._plotCont.height.baseVal.value=this._plotCont.height.baseVal.value||this._wrapper._height()}else{this._plotCont.height=this._plotCont.height||this._wrapper._height()}this._drawChartBackground();var a=this._getDims();var b=this._wrapper.other(this._plotCont,'clipPath',{id:'clip'+this._uuid});this._wrapper.rect(b,a[this.X],a[this.Y],a[this.W],a[this.H]);this._plot=this._wrapper.group(this._plotCont,{class_:'foreground',clipPath:'url(#clip'+this._uuid+')'});this._drawAxis(true);this._drawAxis(false);for(var i=0;i<this._functions.length;i++){this._plotFunction(this._functions[i],i)}this._drawTitle();this._drawLegend()},_getValue:function(a,b){return(!a[b]?parseInt(a.getAttribute(b),10):(a[b].baseVal?a[b].baseVal.value:a[b]))},_getDims:function(a){var b=(a!=null);a=a||this._area;var c=this._getValue(this._plotCont,'width');var d=this._getValue(this._plotCont,'height');var e=(a[this.L]>1?a[this.L]:c*a[this.L]);var f=(a[this.T]>1?a[this.T]:d*a[this.T]);var g=(a[this.R]>1?a[this.R]:c*a[this.R])-e;var h=(a[this.B]>1?a[this.B]:d*a[this.B])-f;if(this._equalXY&&!b){var i=Math.min(g/(this.xAxis._scale.max-this.xAxis._scale.min),h/(this.yAxis._scale.max-this.yAxis._scale.min));g=i*(this.xAxis._scale.max-this.xAxis._scale.min);h=i*(this.yAxis._scale.max-this.yAxis._scale.min)}return[e,f,g,h]},_getScales:function(){var a=this._getDims();return[a[this.W]/(this.xAxis._scale.max-this.xAxis._scale.min),a[this.H]/(this.yAxis._scale.max-this.yAxis._scale.min)]},_drawChartBackground:function(a,b){var c=this._wrapper.group(this._plotCont,{class_:'background'});var d=this._getDims();this._wrapper.rect(c,d[this.X],d[this.Y],d[this.W],d[this.H],this._areaFormat);if(this._gridlines[0]&&this.yAxis._ticks.major&&!b){this._drawGridlines(c,true,this._gridlines[0],d)}if(this._gridlines[1]&&this.xAxis._ticks.major&&!a){this._drawGridlines(c,false,this._gridlines[1],d)}return c},_drawGridlines:function(a,b,c,d){var g=this._wrapper.group(a,c);var e=(b?this.yAxis:this.xAxis);var f=this._getScales();var h=Math.floor(e._scale.min/e._ticks.major)*e._ticks.major;h+=(h<=e._scale.min?e._ticks.major:0);while(h<e._scale.max){var v=(b?e._scale.max-h:h-e._scale.min)*f[b?1:0]+(b?d[this.Y]:d[this.X]);this._wrapper.line(g,(b?d[this.X]:v),(b?v:d[this.Y]),(b?d[this.X]+d[this.W]:v),(b?v:d[this.Y]+d[this.H]));h+=e._ticks.major}},_drawAxis:function(a){var b=(a?'x':'y')+'Axis';var c=(a?this.xAxis:this.yAxis);var d=(a?this.yAxis:this.xAxis);var e=this._getDims();var f=this._getScales();var g=this._wrapper.group(this._plot,$.extend({class_:b},c._lineFormat));var h=this._wrapper.group(this._plot,$.extend({class_:b+'Labels',textAnchor:(a?'middle':'end')},c._labelFormat));var i=(a?d._scale.max:-d._scale.min)*f[a?1:0]+(a?e[this.Y]:e[this.X]);this._wrapper.line(g,(a?e[this.X]:i),(a?i:e[this.Y]),(a?e[this.X]+e[this.W]:i),(a?i:e[this.Y]+e[this.H]));if(c._ticks.major){var j=c._ticks.size;var k=Math.floor(c._scale.min/c._ticks.major)*c._ticks.major;k=(k<c._scale.min?k+c._ticks.major:k);var l=(!c._ticks.minor?c._scale.max+1:Math.floor(c._scale.min/c._ticks.minor)*c._ticks.minor);l=(l<c._scale.min?l+c._ticks.minor:l);var m=[(c._ticks.position=='nw'||c._ticks.position=='both'?-1:0),(c._ticks.position=='se'||c._ticks.position=='both'?+1:0)];while(k<=c._scale.max||l<=c._scale.max){var n=Math.min(k,l);var o=(n==k?j:j/2);var p=(a?n-c._scale.min:c._scale.max-n)*f[a?0:1]+(a?e[this.X]:e[this.Y]);this._wrapper.line(g,(a?p:i+o*m[0]),(a?i+o*m[0]:p),(a?p:i+o*m[1]),(a?i+o*m[1]:p));if(n==k&&n!=0){this._wrapper.text(h,(a?p:i-j),(a?i-j:p),''+n)}k+=(n==k?c._ticks.major:0);l+=(n==l?c._ticks.minor:0)}}if(c._title){if(a){this._wrapper.text(this._plotCont,e[this.X]-c._titleOffset,i,c._title,$.extend({textAnchor:'end'},c._titleFormat||{}))}else{this._wrapper.text(this._plotCont,i,e[this.Y]+e[this.H]+c._titleOffset,c._title,$.extend({textAnchor:'middle'},c._titleFormat||{}))}}},_plotFunction:function(a,b){var c=this._getDims();var d=this._getScales();var e=this._wrapper.createPath();var f=a._range||[this.xAxis._scale.min,this.xAxis._scale.max];var g=(f[1]-f[0])/a._points;var h=true;for(var i=0;i<=a._points;i++){var x=f[0]+i*g;if(x>this.xAxis._scale.max+g){break}if(x<this.xAxis._scale.min-g){continue}var j=(x-this.xAxis._scale.min)*d[0]+c[this.X];var k=c[this.H]-((a._fn(x)-this.yAxis._scale.min)*d[1])+c[this.Y];e[(h?'move':'line')+'To'](j,k);h=false}var p=this._wrapper.path(this._plot,e,$.extend({class_:'fn'+b,fill:'none',stroke:a._stroke,strokeWidth:a._strokeWidth},a._settings||{}));this._showStatus(p,a._name)},_drawTitle:function(){this._wrapper.text(this._plotCont,this._getValue(this._plotCont,'width')/2,this._title.offset,this._title.value,this._title.settings)},_drawLegend:function(){if(!this.legend._show){return}var g=this._wrapper.group(this._plotCont,{class_:'legend'});var a=this._getDims(this.legend._area);this._wrapper.rect(g,a[this.X],a[this.Y],a[this.W],a[this.H],this.legend._bgSettings);var b=a[this.W]>a[this.H];var c=this._functions.length;var d=(b?a[this.W]:a[this.H])/c;var e=a[this.X]+5;var f=a[this.Y]+((b?a[this.H]:d)+this.legend._sampleSize)/2;for(var i=0;i<c;i++){var h=this._functions[i];this._wrapper.rect(g,e+(b?i*d:0),f+(b?0:i*d)-this.legend._sampleSize,this.legend._sampleSize,this.legend._sampleSize,{fill:h._stroke});this._wrapper.text(g,e+(b?i*d:0)+this.legend._sampleSize+5,f+(b?0:i*d),h._name,this.legend._textSettings)}},_showStatus:function(b,c){var d=this._onstatus;if(this._onstatus){$(b).hover(function(a){d.apply(this,[c])},function(){d.apply(this,[''])})}}});function SVGPlotFunction(a,b,c,d,e,f,g,h){if(typeof b!='string'){h=g;g=f;f=e;e=d;d=c;c=b;b=null}if(!isArray(d)){h=g;g=f;f=e;e=d;d=null}if(typeof e!='number'){h=g;g=f;f=e;e=null}if(typeof f!='string'){h=g;g=f;f=null}if(typeof g!='number'){h=g;g=null}this._plot=a;this._name=b||'';this._fn=c||identity;this._range=d;this._points=e||100;this._stroke=f||'black';this._strokeWidth=g||1;this._settings=h||{}}$.extend(SVGPlotFunction.prototype,{name:function(a){if(arguments.length==0){return this._name}this._name=a;this._plot._drawPlot();return this},fn:function(a,b){if(arguments.length==0){return this._fn}if(typeof a=='function'){b=a;a=null}this._name=a||this._name;this._fn=b;this._plot._drawPlot();return this},range:function(a,b){if(arguments.length==0){return this._range}this._range=(a==null?null:[a,b]);this._plot._drawPlot();return this},points:function(a){if(arguments.length==0){return this._points}this._points=a;this._plot._drawPlot();return this},format:function(a,b,c){if(arguments.length==0){return $.extend({stroke:this._stroke,strokeWidth:this._strokeWidth},this._settings)}if(typeof b!='number'){c=b;b=null}this._stroke=a||this._stroke;this._strokeWidth=b||this._strokeWidth;$.extend(this._settings,c||{});this._plot._drawPlot();return this},end:function(){return this._plot}});function identity(x){return x}function SVGPlotAxis(a,b,c,d,e,f){this._plot=a;this._title=b||'';this._titleFormat={};this._titleOffset=0;this._labelFormat={};this._lineFormat={stroke:'black',strokeWidth:1};this._ticks={major:e||10,minor:f||0,size:10,position:'both'};this._scale={min:c||0,max:d||100};this._crossAt=0}$.extend(SVGPlotAxis.prototype,{scale:function(a,b){if(arguments.length==0){return this._scale}this._scale.min=a;this._scale.max=b;this._plot._drawPlot();return this},ticks:function(a,b,c,d){if(arguments.length==0){return this._ticks}if(typeof c=='string'){d=c;c=null}this._ticks.major=a;this._ticks.minor=b;this._ticks.size=c||this._ticks.size;this._ticks.position=d||this._ticks.position;this._plot._drawPlot();return this},title:function(a,b,c,d){if(arguments.length==0){return{title:this._title,offset:this._titleOffset,format:this._titleFormat}}if(typeof b!='number'){d=c;c=b;b=null}if(typeof c!='string'){d=c;c=null}this._title=a;this._titleOffset=(b!=null?b:this._titleOffset);if(c||d){this._titleFormat=$.extend(d||{},(c?{fill:c}:{}))}this._plot._drawPlot();return this},format:function(a,b){if(arguments.length==0){return this._labelFormat}if(typeof a!='string'){b=a;a=null}this._labelFormat=$.extend(b||{},(a?{fill:a}:{}));this._plot._drawPlot();return this},line:function(a,b,c){if(arguments.length==0){return this._lineFormat}if(typeof b!='number'){c=b;b=null}$.extend(this._lineFormat,{stroke:a,strokeWidth:b||this._lineFormat.strokeWidth},c||{});this._plot._drawPlot();return this},end:function(){return this._plot}});function SVGPlotLegend(a,b,c){this._plot=a;this._show=true;this._area=[0.9,0.1,1.0,0.9];this._sampleSize=15;this._bgSettings=b||{stroke:'gray'};this._textSettings=c||{}}$.extend(SVGPlotLegend.prototype,{show:function(a){if(arguments.length==0){return this._show}this._show=a;this._plot._drawPlot();return this},area:function(a,b,c,d){if(arguments.length==0){return this._area}this._area=(isArray(a)?a:[a,b,c,d]);this._plot._drawPlot();return this},settings:function(a,b,c){if(arguments.length==0){return{sampleSize:this._sampleSize,bgSettings:this._bgSettings,textSettings:this._textSettings}}if(typeof a=='object'){c=b;b=a;a=null}this._sampleSize=a||this._sampleSize;this._bgSettings=b;this._textSettings=c||this._textSettings;this._plot._drawPlot();return this},end:function(){return this._plot}});function isArray(a){return(a&&a.constructor==Array)}})(jQuery)
\ No newline at end of file
diff --git a/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.pack.js b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.pack.js
new file mode 100644
index 0000000..b40a279
--- /dev/null
+++ b/architecture/httpdlib/html/js/svg/jquerysvg/jquery.svgplot.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG plotting extension for jQuery v1.4.5.
+   Written by Keith Wood (kbwood{at}iinet.com.au) December 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+   Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(r($){$.1S.2r(\'2a\',1T);r 1T(a){4.u=a;4.1i=1j;4.M={11:\'\',1k:25,1z:{1l:\'1A\'}};4.12=[0.1,0.1,0.8,0.9];4.1B={17:\'2b\',U:\'1U\'};4.Q=[];4.1C=18;4.13=[];4.1D=z;4.1V=1m 2s().2t();4.t=4.u.1S(0,0,0,0,{19:\'1S-2a\'});4.G=1m 1E(4);4.G.1n(\'X\',20);4.N=1m 1E(4);4.N.1n(\'Y\',20);4.P=1m 1W(4);4.1i=18}$.K(1T.1F,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,2u:r(a){7(E.D==0){q 4.t}4.t=a;q 4},2c:r(a,b,c,d){7(E.D==0){q 4.12}4.12=(1G(a)?a:[a,b,c,d]);4.F();q 4},1H:r(a,b,c){7(E.D==0){q 4.1B}7(I b==\'2d\'){c=b;b=z}4.1B=$.K({17:a},(b?{U:b}:{}),c||{});4.F();q 4},2v:r(a,b){7(E.D==0){q 4.Q}4.Q=[(I a==\'14\'?{U:a}:a),(I b==\'14\'?{U:b}:b)];7(4.Q[0]==z&&4.Q[1]==z){4.Q=[]}4.F();q 4},2w:r(a){7(E.D==0){q 4.1C}4.1C=a;q 4},1n:r(a,b,c,d){7(E.D==0){q 4.M}7(I b!=\'1e\'){d=c;c=b;b=z}7(I c!=\'14\'){d=c;c=z}4.M={11:a,1k:b||4.M.1k,1z:$.K({1l:\'1A\'},(c?{17:c}:{}),d||{})};4.F();q 4},2x:r(a,b,c,d,e,f,g){4.13.2y(1m 1X(4,a,b,c,d,e,f,g));4.F();q 4},2z:r(i){q(E.D>0?4.13[i]:z)||4.13},2A:r(){4.1i=1j;q 4},2B:r(){4.1i=18;4.F();q 4},2C:r(a){4.1D=a;q 4},F:r(){7(!4.1i){q}1Y(4.t.2e){4.t.2D(4.t.2e)}7(!4.t.2E){4.u.2F.2G(4.t)}7(!4.t.S){4.t.2f(\'S\',1Z(4.t.21(\'S\'),10)||4.u.22())}1o 7(4.t.S.16){4.t.S.16.11=4.t.S.16.11||4.u.22()}1o{4.t.S=4.t.S||4.u.22()}7(!4.t.V){4.t.2f(\'V\',1Z(4.t.21(\'V\'),10)||4.u.23())}1o 7(4.t.V.16){4.t.V.16.11=4.t.V.16.11||4.u.23()}1o{4.t.V=4.t.V||4.u.23()}4.2g();6 a=4.1a();6 b=4.u.2H(4.t,\'2h\',{2I:\'2i\'+4.1V});4.u.1I(b,a[4.X],a[4.Y],a[4.W],a[4.H]);4.A=4.u.1f(4.t,{19:\'2J\',2h:\'2K(#2i\'+4.1V+\')\'});4.24(18);4.24(1j);26(6 i=0;i<4.13.D;i++){4.2j(4.13[i],i)}4.2k();4.2l()},1J:r(a,b){q(!a[b]?1Z(a.21(b),10):(a[b].16?a[b].16.11:a[b]))},1a:r(a){6 b=(a!=z);a=a||4.12;6 c=4.1J(4.t,\'S\');6 d=4.1J(4.t,\'V\');6 e=(a[4.L]>1?a[4.L]:c*a[4.L]);6 f=(a[4.T]>1?a[4.T]:d*a[4.T]);6 g=(a[4.R]>1?a[4.R]:c*a[4.R])-e;6 h=(a[4.B]>1?a[4.B]:d*a[4.B])-f;7(4.1C&&!b){6 i=1p.C(g/(4.G.s.J-4.G.s.C),h/(4.N.s.J-4.N.s.C));g=i*(4.G.s.J-4.G.s.C);h=i*(4.N.s.J-4.N.s.C)}q[e,f,g,h]},1K:r(){6 a=4.1a();q[a[4.W]/(4.G.s.J-4.G.s.C),a[4.H]/(4.N.s.J-4.N.s.C)]},2g:r(a,b){6 c=4.u.1f(4.t,{19:\'2L\'});6 d=4.1a();4.u.1I(c,d[4.X],d[4.Y],d[4.W],d[4.H],4.1B);7(4.Q[0]&&4.N.w.O&&!b){4.27(c,18,4.Q[0],d)}7(4.Q[1]&&4.G.w.O&&!a){4.27(c,1j,4.Q[1],d)}q c},27:r(a,b,c,d){6 g=4.u.1f(a,c);6 e=(b?4.N:4.G);6 f=4.1K();6 h=1p.28(e.s.C/e.w.O)*e.w.O;h+=(h<=e.s.C?e.w.O:0);1Y(h<e.s.J){6 v=(b?e.s.J-h:h-e.s.C)*f[b?1:0]+(b?d[4.Y]:d[4.X]);4.u.1q(g,(b?d[4.X]:v),(b?v:d[4.Y]),(b?d[4.X]+d[4.W]:v),(b?v:d[4.Y]+d[4.H]));h+=e.w.O}},24:r(a){6 b=(a?\'x\':\'y\')+\'2M\';6 c=(a?4.G:4.N);6 d=(a?4.N:4.G);6 e=4.1a();6 f=4.1K();6 g=4.u.1f(4.A,$.K({19:b},c.1r));6 h=4.u.1f(4.A,$.K({19:b+\'2N\',1l:(a?\'1A\':\'1s\')},c.1L));6 i=(a?d.s.J:-d.s.C)*f[a?1:0]+(a?e[4.Y]:e[4.X]);4.u.1q(g,(a?e[4.X]:i),(a?i:e[4.Y]),(a?e[4.X]+e[4.W]:i),(a?i:e[4.Y]+e[4.H]));7(c.w.O){6 j=c.w.1M;6 k=1p.28(c.s.C/c.w.O)*c.w.O;k=(k<c.s.C?k+c.w.O:k);6 l=(!c.w.1b?c.s.J+1:1p.28(c.s.C/c.w.1b)*c.w.1b);l=(l<c.s.C?l+c.w.1b:l);6 m=[(c.w.1c==\'2O\'||c.w.1c==\'29\'?-1:0),(c.w.1c==\'2P\'||c.w.1c==\'29\'?+1:0)];1Y(k<=c.s.J||l<=c.s.J){6 n=1p.C(k,l);6 o=(n==k?j:j/2);6 p=(a?n-c.s.C:c.s.J-n)*f[a?0:1]+(a?e[4.X]:e[4.Y]);4.u.1q(g,(a?p:i+o*m[0]),(a?i+o*m[0]:p),(a?p:i+o*m[1]),(a?i+o*m[1]:p));7(n==k&&n!=0){4.u.1t(h,(a?p:i-j),(a?i-j:p),\'\'+n)}k+=(n==k?c.w.O:0);l+=(n==l?c.w.1b:0)}}7(c.M){7(a){4.u.1t(4.t,e[4.X]-c.1g,i,c.M,$.K({1l:\'1s\'},c.1u||{}))}1o{4.u.1t(4.t,i,e[4.Y]+e[4.H]+c.1g,c.M,$.K({1l:\'1A\'},c.1u||{}))}}},2j:r(a,b){6 c=4.1a();6 d=4.1K();6 e=4.u.2Q();6 f=a.1N||[4.G.s.C,4.G.s.J];6 g=(f[1]-f[0])/a.1v;6 h=18;26(6 i=0;i<=a.1v;i++){6 x=f[0]+i*g;7(x>4.G.s.J+g){2R}7(x<4.G.s.C-g){2S}6 j=(x-4.G.s.C)*d[0]+c[4.X];6 k=c[4.H]-((a.1O(x)-4.N.s.C)*d[1])+c[4.Y];e[(h?\'2T\':\'1q\')+\'2U\'](j,k);h=1j}6 p=4.u.2V(4.A,e,$.K({19:\'2m\'+b,17:\'2b\',U:a.1h,1w:a.1x},a.1P||{}));4.2n(p,a.1d)},2k:r(){4.u.1t(4.t,4.1J(4.t,\'S\')/2,4.M.1k,4.M.11,4.M.1z)},2l:r(){7(!4.P.1Q){q}6 g=4.u.1f(4.t,{19:\'P\'});6 a=4.1a(4.P.12);4.u.1I(g,a[4.X],a[4.Y],a[4.W],a[4.H],4.P.1R);6 b=a[4.W]>a[4.H];6 c=4.13.D;6 d=(b?a[4.W]:a[4.H])/c;6 e=a[4.X]+5;6 f=a[4.Y]+((b?a[4.H]:d)+4.P.Z)/2;26(6 i=0;i<c;i++){6 h=4.13[i];4.u.1I(g,e+(b?i*d:0),f+(b?0:i*d)-4.P.Z,4.P.Z,4.P.Z,{17:h.1h});4.u.1t(g,e+(b?i*d:0)+4.P.Z+5,f+(b?0:i*d),h.1d,4.P.1y)}},2n:r(b,c){6 d=4.1D;7(4.1D){$(b).2W(r(a){d.2o(4,[c])},r(){d.2o(4,[\'\'])})}}});r 1X(a,b,c,d,e,f,g,h){7(I b!=\'14\'){h=g;g=f;f=e;e=d;d=c;c=b;b=z}7(!1G(d)){h=g;g=f;f=e;e=d;d=z}7(I e!=\'1e\'){h=g;g=f;f=e;e=z}7(I f!=\'14\'){h=g;g=f;f=z}7(I g!=\'1e\'){h=g;g=z}4.A=a;4.1d=b||\'\';4.1O=c||2p;4.1N=d;4.1v=e||2q;4.1h=f||\'1U\';4.1x=g||1;4.1P=h||{}}$.K(1X.1F,{2X:r(a){7(E.D==0){q 4.1d}4.1d=a;4.A.F();q 4},2m:r(a,b){7(E.D==0){q 4.1O}7(I a==\'r\'){b=a;a=z}4.1d=a||4.1d;4.1O=b;4.A.F();q 4},2Y:r(a,b){7(E.D==0){q 4.1N}4.1N=(a==z?z:[a,b]);4.A.F();q 4},2Z:r(a){7(E.D==0){q 4.1v}4.1v=a;4.A.F();q 4},1H:r(a,b,c){7(E.D==0){q $.K({U:4.1h,1w:4.1x},4.1P)}7(I b!=\'1e\'){c=b;b=z}4.1h=a||4.1h;4.1x=b||4.1x;$.K(4.1P,c||{});4.A.F();q 4},1s:r(){q 4.A}});r 2p(x){q x}r 1E(a,b,c,d,e,f){4.A=a;4.M=b||\'\';4.1u={};4.1g=0;4.1L={};4.1r={U:\'1U\',1w:1};4.w={O:e||10,1b:f||0,1M:10,1c:\'29\'};4.s={C:c||0,J:d||2q};4.30=0}$.K(1E.1F,{31:r(a,b){7(E.D==0){q 4.s}4.s.C=a;4.s.J=b;4.A.F();q 4},32:r(a,b,c,d){7(E.D==0){q 4.w}7(I c==\'14\'){d=c;c=z}4.w.O=a;4.w.1b=b;4.w.1M=c||4.w.1M;4.w.1c=d||4.w.1c;4.A.F();q 4},1n:r(a,b,c,d){7(E.D==0){q{1n:4.M,1k:4.1g,1H:4.1u}}7(I b!=\'1e\'){d=c;c=b;b=z}7(I c!=\'14\'){d=c;c=z}4.M=a;4.1g=(b!=z?b:4.1g);7(c||d){4.1u=$.K(d||{},(c?{17:c}:{}))}4.A.F();q 4},1H:r(a,b){7(E.D==0){q 4.1L}7(I a!=\'14\'){b=a;a=z}4.1L=$.K(b||{},(a?{17:a}:{}));4.A.F();q 4},1q:r(a,b,c){7(E.D==0){q 4.1r}7(I b!=\'1e\'){c=b;b=z}$.K(4.1r,{U:a,1w:b||4.1r.1w},c||{});4.A.F();q 4},1s:r(){q 4.A}});r 1W(a,b,c){4.A=a;4.1Q=18;4.12=[0.9,0.1,1.0,0.9];4.Z=15;4.1R=b||{U:\'33\'};4.1y=c||{}}$.K(1W.1F,{34:r(a){7(E.D==0){q 4.1Q}4.1Q=a;4.A.F();q 4},2c:r(a,b,c,d){7(E.D==0){q 4.12}4.12=(1G(a)?a:[a,b,c,d]);4.A.F();q 4},1z:r(a,b,c){7(E.D==0){q{35:4.Z,36:4.1R,37:4.1y}}7(I a==\'2d\'){c=b;b=a;a=z}4.Z=a||4.Z;4.1R=b;4.1y=c||4.1y;4.A.F();q 4},1s:r(){q 4.A}});r 1G(a){q(a&&a.38==39)}})(3a)',62,197,'||||this||var|if|||||||||||||||||||return|function|_scale|_plotCont|_wrapper||_ticks|||null|_plot||min|length|arguments|_drawPlot|xAxis||typeof|max|extend||_title|yAxis|major|legend|_gridlines||width||stroke|height||||_sampleSize||value|_area|_functions|string||baseVal|fill|true|class_|_getDims|minor|position|_name|number|group|_titleOffset|_stroke|_drawNow|false|offset|textAnchor|new|title|else|Math|line|_lineFormat|end|text|_titleFormat|_points|strokeWidth|_strokeWidth|_textSettings|settings|middle|_areaFormat|_equalXY|_onstatus|SVGPlotAxis|prototype|isArray|format|rect|_getValue|_getScales|_labelFormat|size|_range|_fn|_settings|_show|_bgSettings|svg|SVGPlot|black|_uuid|SVGPlotLegend|SVGPlotFunction|while|parseInt||getAttribute|_width|_height|_drawAxis||for|_drawGridlines|floor|both|plot|none|area|object|firstChild|setAttribute|_drawChartBackground|clipPath|clip|_plotFunction|_drawTitle|_drawLegend|fn|_showStatus|apply|identity|100|addExtension|Date|getTime|container|gridlines|equalXY|addFunction|push|functions|noDraw|redraw|status|removeChild|parent|_svg|appendChild|other|id|foreground|url|background|Axis|Labels|nw|se|createPath|break|continue|move|To|path|hover|name|range|points|_crossAt|scale|ticks|gray|show|sampleSize|bgSettings|textSettings|constructor|Array|jQuery'.split('|'),0,{}))
\ No newline at end of file
diff --git a/architecture/httpdlib/html/json/faust.json b/architecture/httpdlib/html/json/faust.json
new file mode 100644
index 0000000..b3f7521
--- /dev/null
+++ b/architecture/httpdlib/html/json/faust.json
@@ -0,0 +1,19 @@
+{
+	"name": "karplus32",
+	"address": "macdom.grame.fr",
+	"port": "8000",
+	"ui": [
+		{
+			"type" : "button | togglebutton | checkbutton | verticalslider | horizontalslider | numentry"
+			"label": "name"
+			"init": 
+			"min":
+			"max":
+			"step":
+		}
+		{
+			"group" : "framebox | tabbox | horizontalbox | verticalbox"
+			"label": "name"
+		}
+	]
+}
diff --git a/examples/karplus.dsp b/architecture/httpdlib/html/karplus.dsp
similarity index 100%
copy from examples/karplus.dsp
copy to architecture/httpdlib/html/karplus.dsp
diff --git a/architecture/httpdlib/html/karplus.html b/architecture/httpdlib/html/karplus.html
new file mode 100644
index 0000000..64ad541
--- /dev/null
+++ b/architecture/httpdlib/html/karplus.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+	<title id=titre>Karplus</title>
+	<style>
+		body {
+			background-color:lightgray;	
+			margin: 1cm 1cm 1cm 1cm;
+		}
+		.faustui {
+			margin: 2mm 2mm 2mm 2mm;
+		}
+	</style>
+
+</head>
+
+<body>
+<center>
+<h1> Karplus-Strong </h1>
+<br/>
+
+<table>
+<tr><td><iframe width=440 height=300 src="karplus.dsp" class="faustui"></iframe></td>
+<td><iframe width=400 height=300 src="http://localhost:5510" seamless class="faustui"></iframe></td></tr>
+</table>
+</center>
+
+</body>
+</html>
diff --git a/architecture/osclib/faust/license.txt b/architecture/httpdlib/license.txt
similarity index 100%
copy from architecture/osclib/faust/license.txt
copy to architecture/httpdlib/license.txt
diff --git a/architecture/httpdlib/readme.txt b/architecture/httpdlib/readme.txt
new file mode 100644
index 0000000..eb6378d
--- /dev/null
+++ b/architecture/httpdlib/readme.txt
@@ -0,0 +1,104 @@
+=================================================================
+                         FAUST HTTPD Library
+
+                     Copyright (c) 2012 Grame
+=================================================================
+
+----------------------------------------------------------------------
+ Compiling the library
+----------------------------------------------------------------------
+
+The FAUST HTTPD library project depends on the libmicrohttpd library.
+You should first compile and install this library before compiling 
+the FAUST HTTPD library. 
+(see at http://www.gnu.org/software/libmicrohttpd/).
+
+1) Compiling libmicrohttpd
+-----------------------------------
+Typically on linux or Mac OS systems:
+	> cd location/of/libmicrohttpd
+	> ./configure
+	> make
+	> sudo make
+
+2) Compiling the FAUST HTTPD library
+-----------------------------------
+To compile:
+	change to cmake directory
+	type:  cmake -G "your target generator"
+	run your project/makefile and compile
+
+Typically on linux systems:
+	> cd cmake
+	> cmake -G "Unix Makefiles"
+	> make
+
+The compiler output is a static library named libHTTPDFaust.a and placed 
+in the 'httpdlib' folder. Note that when 'Release' and 'Debug' targets
+apply, only the 'Release' output goes to the 'httpdlib' folder.
+
+----------------------------------------------------------------------
+ Using the library
+----------------------------------------------------------------------
+The library provides a single interface file: HTTPDControler.h
+The following options should be used to compile:
+	-Ihttpdlib/include lmicrohttpd -Lhttpdlib -lHTTPDFaust
+See the faust/readme.txt file for more details about the library.
+
+----------------------------------------------------------------------
+ Note about URLs and the Faust UI names:
+----------------------------------------------------------------------
+Characters in a url could be:
+1. Reserved: ; / ? : @ & = + $ ,
+   These characters delimit URL parts.
+2. Unreserved: alphanum - _ . ! ~ * ' ( )
+   These characters have no special meaning and can be used as is.
+3. Excluded: control characters, space, < > # % ", { } | \ ^ [ ] `
+
+To solve potential conflicts between the Faust UI objects naming scheme and
+the URL allowed characters, the reserved and excluded characters are replaced
+with '-' (hyphen).
+Space or tabulation are replaced with '_' (underscore)
+
+-----------------------------------------------------------------
+    Note about the http messages and urls
+-----------------------------------------------------------------
+The url address space adheres strictly to the hierarchy defined by
+the 'addnode' and 'opengroup' calls.
+A node expects to receive http messages with a single float value 
+as parameter. A Faust server supports both 'GET' and 'POST' transactions.
+When using 'GET', values are expected to be associated to the 'value' key
+(e.g. any/param/url?value=0.8)
+
+*** Faust server root url ***
+A Faust server delivers a web page containing all its user interface 
+from its root url. It delivers the json description of its user
+interface as answer to a value='json' message.
+
+*** Querying values ***
+When sending a message to an url without associated value, a Faust 
+server answers with the corresponding node value.
+
+-----------------------------------------------------------------
+    Note about network management
+-----------------------------------------------------------------
+The default TCP port is chosen in an unassigned range 
+see IANA PORT NUMBERS (last updated 2011-01-24)
+at http://www.iana.org/assignments/port-numbers
+As of today (jan. 27 2011), the range 5507-5552 is unassigned
+and the default listening port number is 5510.
+
+*** Changing the ports numbers with the command line ***
+An HTTPDControler object takes the command line arguments as constructor 
+parameters. It supports the following options to change the UDP ports 
+numbers:
+	-port number
+
+*** Dynamic TCP listening port allocation ***
+When the TCP listening port number is busy, the system automatically 
+looks for the next available port number. 
+
+======================================================================
+In case of trouble, contact me: <fober at grame.fr>
+----------------------------------------------------------------------
+Copyright 2012 (c) Grame 
diff --git a/architecture/httpdlib/src/HTTPDControler.cpp b/architecture/httpdlib/src/HTTPDControler.cpp
new file mode 100644
index 0000000..3bbadf1
--- /dev/null
+++ b/architecture/httpdlib/src/HTTPDControler.cpp
@@ -0,0 +1,227 @@
+/*
+
+  Faust Project
+
+  Copyright (C) 2012-2014 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 11 cours de Verdun Gensoul, 69002 Lyon - France
+  research at grame.fr
+
+*/
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <netdb.h>
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <iostream>
+#include <sstream>
+
+#include "HTTPDControler.h"
+#include "FaustFactory.h"
+#include "HTTPDSetup.h"
+#include "jsonfactory.h"
+#include "htmlfactory.h"
+#include "RootNode.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+#define kVersion	 0.72f
+#define kVersionStr	"0.72"
+
+static const char* kPortOpt	= "-port";
+
+//--------------------------------------------------------------------------
+// utility for command line arguments 
+//--------------------------------------------------------------------------
+static int getPortOption (int argc, char *argv[], const std::string& option, int defaultValue)
+{
+	for (int i=0; i < argc-1; i++) {
+		if (option == argv[i]) {
+			int val = strtol( argv[i+1], 0, 10);
+			if (val) return val;
+		}
+	}
+	return defaultValue;
+}
+
+//--------------------------------------------------------------------------
+// utility for host name and ip address 
+//--------------------------------------------------------------------------
+static bool getNetInfos(string& name, string& ip)
+{
+	char szBuffer[1024];
+
+	if(gethostname(szBuffer, sizeof(szBuffer)))
+	return false;
+	
+	name = szBuffer;
+	struct hostent *host = gethostbyname(szBuffer);
+	if(!host) return false;
+
+	stringstream s;
+	unsigned char * ptr = (unsigned char *)host->h_addr;
+	s << int(ptr[0]) << "." << int(ptr[1]) << "." << int(ptr[2]) << "." << int(ptr[3]);
+	ip = s.str();
+	return true;
+}
+
+
+//--------------------------------------------------------------------------
+HTTPDControler::HTTPDControler (int argc, char *argv[], const char* applicationname, bool init)
+	: fTCPPort(kTCPBasePort), fJson(0), fInit(init)
+{
+	fTCPPort = getPortOption (argc, argv, kPortOpt, fTCPPort);
+	fFactory = new FaustFactory();
+	fHttpd = new HTTPDSetup();
+	
+	string host, ip;
+	getNetInfos (host, ip);
+	if (host.find('.') == string::npos) host.clear();	// ignore non qualifed domain names and uses IP number
+	const char* hostname = host.size() ? host.c_str() : (ip.size() ? ip.c_str() : "localhost");
+	fJson = new jsonfactory(applicationname, hostname, fTCPPort);
+	fHtml = new htmlfactory(applicationname, hostname, fTCPPort);
+}
+
+HTTPDControler::~HTTPDControler ()
+{ 
+	quit(); 
+	delete fFactory;
+	delete fHttpd;
+	delete fJson;
+}
+
+//--------------------------------------------------------------------------
+float HTTPDControler::version()				{ return kVersion; }
+const char* HTTPDControler::versionstr()	{ return kVersionStr; }
+
+//--------------------------------------------------------------------------
+// Add a node in the current group (top of the group stack)
+template<> void HTTPDControler::addnode<float> (const char* type, const char* label, float* zone, float init, float min, float max, float step)
+{
+	fFactory->addnode (label, zone, init, min, max, fInit);
+	fJson->addnode<float> (type, label, init, min, max, step, fCurrentMeta);
+	fHtml->addnode (type, label, init, min, max, step);
+	fCurrentMeta.clear();
+}
+template<> void HTTPDControler::addnode<float> (const char* type, const char* label, float* zone, float min, float max)
+{
+	fFactory->addnode (label, zone, min, max, fInit);
+	fJson->addnode<float> (type, label, min, max, fCurrentMeta);
+	fHtml->addnode (type, label, min, max);
+	fCurrentMeta.clear();
+}
+template<> void HTTPDControler::addnode<float> (const char* type, const char* label, float* zone)
+{
+	fFactory->addnode (label, zone, 0.f, 0.f, 1.f, fInit);
+	fJson->addnode<float> (type, label, fCurrentMeta);
+	fHtml->addnode (type, label);
+	fCurrentMeta.clear();
+}
+
+template<> void HTTPDControler::addnode<double> (const char* type, const char* label, double* zone, double min, double max)
+{
+	fFactory->addnode (label, zone, min, max, fInit);
+	fJson->addnode<double> (type, label, min, max, fCurrentMeta);
+	fHtml->addnode (type, label, min, max);
+	fCurrentMeta.clear();
+}
+
+template<> void HTTPDControler::addnode<double> (const char* type, const char* label, double* zone, double init, double min, double max, double step)
+{
+	fFactory->addnode (label, zone, init, min, max, fInit);
+	fJson->addnode<double> (type, label, init, min, max, step, fCurrentMeta);
+	fHtml->addnode (type, label, init, min, max, step);
+	fCurrentMeta.clear();
+}
+template<> void HTTPDControler::addnode<double> (const char* type, const char* label, double* zone)
+{
+	fFactory->addnode (label, zone, 0., 0., 1., fInit);
+	fJson->addnode<double> (type, label, fCurrentMeta);
+	fHtml->addnode (type, label);
+	fCurrentMeta.clear();
+}
+
+//--------------------------------------------------------------------------
+void HTTPDControler::opengroup (const char* type, const char* label)
+{
+	fFactory->opengroup (label);
+	fJson->opengroup (type, label, fCurrentMeta);
+	fHtml->opengroup (type, label);
+    fCurrentMeta.clear();
+}
+
+//--------------------------------------------------------------------------
+void HTTPDControler::closegroup ()
+{
+	fFactory->closegroup ();
+	fJson->closegroup ();
+	fHtml->closegroup ();
+}
+
+//--------------------------------------------------------------------------
+// start the network services
+void HTTPDControler::run ()
+{
+	SMessageDriven root = fFactory->root();		// first get the root node
+	if (root) {
+		// and cast it to a RootNode
+		RootNode * rootnode = dynamic_cast<RootNode*> ((MessageDriven*)root);
+		// starts the network services
+		if (fHttpd->start (root, fTCPPort)) {
+			stringstream strjson;
+			fJson->root().setPort (fTCPPort);
+			fJson->root().print(strjson);
+			if (rootnode) rootnode->setJSON (strjson.str());
+
+			stringstream strhtml;
+			fHtml->root().setPort (fTCPPort);
+			fHtml->root().print(strhtml, strjson.str());
+			if (rootnode) rootnode->setHtml (strhtml.str());
+			// and outputs a message
+			cout << "Faust httpd server version " << version() <<  " is running on TCP port " << fTCPPort << endl;
+		}
+	}
+}
+
+//--------------------------------------------------------------------------
+void HTTPDControler::quit ()
+{
+	fHttpd->stop();
+}
+
+//------------------------------Accessor to json Interface
+std::string HTTPDControler::getJSONInterface(){        
+    stringstream strjson;
+    fJson->root().print(strjson);
+    return strjson.str();
+}
+    
+void HTTPDControler::setInputs(int numInputs){
+    fJson->root().setInputs(numInputs);
+}
+    
+void HTTPDControler::setOutputs(int numOutputs){
+    fJson->root().setOutputs(numOutputs);
+}
+    
+}
diff --git a/architecture/httpdlib/src/Makefile b/architecture/httpdlib/src/Makefile
new file mode 100644
index 0000000..96e3ca0
--- /dev/null
+++ b/architecture/httpdlib/src/Makefile
@@ -0,0 +1,148 @@
+subprojects := html httpd include json lib msg nodes
+sources = $(wildcard *.cpp) $(wildcard html/*.cpp) $(wildcard httpd/*.cpp)  $(wildcard json/*.cpp) $(wildcard msg/*.cpp) $(wildcard nodes/*.cpp)
+objects = $(sources:.cpp=.o)
+objects += hexa/jsscripts.o
+objects += hexa/stylesheet.o
+
+VPATH = $(subprojects)
+
+system	?= $(shell uname -s)
+
+ifeq ($(system), Darwin)
+##ARCHFLAGS :=  -arch i386 -arch x86_64
+LIB_EXT = dylib
+# Darwin/OS X: default installation name prefix for the dynamic library. This
+# defaults to the installation prefix (a fixed path) if we have one, but
+# depending on usage (plugin or executable) you may want to keep it empty or
+# use some generic prefix such as @loader_path/ instead (see below).
+ifneq ($(PREFIX),)
+INSTALL_PREFIX = $(PREFIX)/lib/
+endif
+ifneq ($(INSTALL_PREFIX),)
+INSTALL_NAME = -install_name "$(INSTALL_PREFIX)libHTTPDFaust.dylib"
+endif
+else
+ARCHFLAGS := 
+ifneq ($(findstring MINGW32, $(system)),)
+LIB_EXT = dll
+else
+CXXFLAGS += -fPIC
+LIB_EXT = so
+endif
+endif
+
+# Here are some useful alternative options for the installation name prefix
+# (cf., e.g., https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath):
+
+# @executable_path: Useful if the dylib is distributed with an application
+# (add path relative to the main executable if needed):
+#INSTALL_PREFIX = @executable_path/
+
+# @loader_path (OS X 10.4+): Useful if the dylib is distributed with a plugin
+# (add path relative to the plugin if needed):
+#INSTALL_PREFIX = @loader_path/
+
+# @rpath (OS X 10.5+): Useful if the dylib is distributed with an application
+# which has an rpath coded into it:
+#INSTALL_PREFIX = @rpath/
+
+CXXFLAGS ?= -O3 -Wall -Wuninitialized $(ARCHFLAGS)
+CXXFLAGS += `pkg-config --cflags libmicrohttpd` -I../../../architecture -I/usr/local/include -Wno-parentheses $(addprefix -I, $(subprojects)) -DINSTALL_PREFIX='"$(prefix)"'
+
+all: ../libHTTPDFaust.a
+
+dynamic : ../libHTTPDFaust.$(LIB_EXT)
+
+../libHTTPDFaust.a : $(objects)
+	rm -f $@
+	ar cq $@ $(objects)
+	ranlib $@
+
+../libHTTPDFaust.dylib :  $(objects)
+	$(CXX) -dynamiclib $(INSTALL_NAME) $(ARCHFLAGS) $(objects) `pkg-config --libs libmicrohttpd` -o $@
+
+../libHTTPDFaust.so  :  $(objects)
+	$(CXX) -shared -fPIC -o $@ $(objects) `pkg-config --libs libmicrohttpd`
+
+../libHTTPDFaust.dll  :  $(objects)
+	$(CXX) -shared -o $@ $(objects) `pkg-config --libs libmicrohttpd` -lwsock32
+	
+depend :
+	makedepend -fMakefile -w120 -Y -- $(CXXFLAGS) -- $(sources)
+	
+clean :
+	rm -f $(objects) hexa/jsscripts hexa/jsscripts.cpp
+	rm -f $(objects) hexa/stylesheet hexa/stylesheet.cpp
+	rm -f ../libHTTPDFaust.a ../libHTTPDFaust.dylib ../libHTTPDFaust.so ../libHTTPDFaust.dll
+	
+
+hexa/jsscripts.o : hexa/jsscripts.cpp
+
+hexa/stylesheet.o : hexa/stylesheet.cpp
+
+hexa/jsscripts.cpp : hexa/jsscripts
+	cd hexa; xxd -i jsscripts jsscripts.cpp
+
+hexa/stylesheet.cpp : hexa/stylesheet
+	cd hexa; xxd -i stylesheet stylesheet.cpp
+
+hexa/jsscripts : ../html/js/svg/*.js ../html/js/svg/jquerysvg/jquery.svg.js
+	cat ../html/js/svg/jquery-1.7.1.min.js > $@
+	echo " " >> $@
+	cat ../html/js/svg/jquerysvg/jquery.svg.min.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/jquerysvg/jquery.svgdom.min.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_proto.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_jquery_svg_backend.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_mobile.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_ui_inits.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_load_external_file.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_ui_objects.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_ui_builder.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_ui_interact.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_ui_audio_bridge.js >> $@
+	echo " " >> $@
+	cat ../html/js/svg/faust_server_communication.js >> $@
+
+hexa/stylesheet : ../html/js/svg/faust_css.css
+	cat ../html/js/svg/faust_css.css > $@
+
+# DO NOT DELETE
+
+HTTPDControler.o: include/HTTPDControler.h nodes/FaustFactory.h nodes/MessageDriven.h msg/MessageProcessor.h
+HTTPDControler.o: lib/smartpointer.h nodes/FaustNode.h msg/Message.h httpd/HTTPDSetup.h json/jsonfactory.h
+HTTPDControler.o: json/jsonroot.h json/jsonnode.h json/jsoncontrol.h html/htmlfactory.h html/htmlpage.h
+HTTPDControler.o: nodes/RootNode.h
+html/htmlfactory.o: html/htmlfactory.h html/htmlpage.h
+html/htmlpage.o: lib/deelx.h html/htmlpage.h html/jsscripts.h html/stylesheet.h
+html/htmlui.o: html/htmlui.h html/htmlfactory.h html/htmlpage.h
+httpd/Address.o: httpd/Address.h
+httpd/HTTPDServer.o: httpd/HTTPDServer.h msg/Message.h lib/smartpointer.h
+httpd/HTTPDServer.o: msg/MessageProcessor.h
+httpd/HTTPDSetup.o: httpd/HTTPDSetup.h httpd/HTTPDServer.h msg/MessageProcessor.h
+json/jsoncontrol.o: json/jsoncontrol.h json/jsonnode.h lib/smartpointer.h
+json/jsonfactory.o: json/jsonfactory.h json/jsonroot.h lib/smartpointer.h json/jsonnode.h json/jsoncontrol.h
+json/jsonfactory.o: json/jsongroup.h
+json/jsonfaustui.o: include/jsonfaustui.h ../../../architecture/faust/gui/meta.h ../../../architecture/faust/gui/UI.h
+json/jsonfaustui.o: json/jsonui.h json/jsonfactory.h json/jsonroot.h lib/smartpointer.h json/jsonnode.h
+json/jsonfaustui.o: json/jsoncontrol.h
+json/jsongroup.o: json/jsongroup.h json/jsonnode.h lib/smartpointer.h
+json/jsonroot.o: json/jsonroot.h lib/smartpointer.h json/jsonnode.h
+json/jsonui.o: json/jsonui.h json/jsonfactory.h json/jsonroot.h lib/smartpointer.h json/jsonnode.h json/jsoncontrol.h
+msg/Message.o: msg/Message.h lib/smartpointer.h
+nodes/FaustFactory.o: nodes/FaustFactory.h nodes/MessageDriven.h msg/MessageProcessor.h lib/smartpointer.h
+nodes/FaustFactory.o: nodes/FaustNode.h msg/Message.h nodes/RootNode.h
+nodes/FaustNode.o: nodes/FaustNode.h nodes/MessageDriven.h msg/MessageProcessor.h lib/smartpointer.h msg/Message.h
+nodes/FaustNode.o: httpd/HTTPDServer.h
+nodes/MessageDriven.o: httpd/Address.h msg/Message.h lib/smartpointer.h nodes/MessageDriven.h msg/MessageProcessor.h
+nodes/MessageDriven.o: httpd/HTTPDServer.h
+nodes/RootNode.o: nodes/RootNode.h nodes/MessageDriven.h msg/MessageProcessor.h lib/smartpointer.h msg/Message.h
diff --git a/architecture/httpdlib/src/hexa/README b/architecture/httpdlib/src/hexa/README
new file mode 100644
index 0000000..902debb
--- /dev/null
+++ b/architecture/httpdlib/src/hexa/README
@@ -0,0 +1,2 @@
+Generated c++ files encoding javascripts and css are placed here.
+
diff --git a/architecture/httpdlib/src/html/htmlfactory.cpp b/architecture/httpdlib/src/html/htmlfactory.cpp
new file mode 100644
index 0000000..437bcc0
--- /dev/null
+++ b/architecture/httpdlib/src/html/htmlfactory.cpp
@@ -0,0 +1,101 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "htmlfactory.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+htmlfactory::htmlfactory(const char *name, const char* address, int port) 
+	: fPage(name, address, port), fSerial(1) 
+{
+	fGroups.push("");
+}
+
+void htmlfactory::addnode (const char* type, const char* label)
+{
+	string stype (type);
+	string url = /*fPage.getUrl() +*/ fGroups.top() + "/";
+	url += label;
+	stringstream id; id << "button" << fSerial++;	// computes slider id
+	if (stype == "button") {
+		fPage << "<tr><td class='label'></td>\n";
+		fPage << "<td class='control'><button id='"<< id.str() << "' name='" << url
+			  << "' onmousedown='fausthandler(\"" << url << "\", 1)'"
+			  << " onmouseup='fausthandler(\"" << url << "\", 0)'>play</button></td>\n";
+		fPage << "<td class='value'></td>\n";
+	}
+	else if ((stype == "togglebutton") ||  (stype == "checkbutton")) {
+		fPage << "<tr><td class='label'></td>\n";
+		fPage << "<td class='control'><input type='checkbox' id='"<< id.str() << "' name='" << url
+			  << "'  value=0 onchange='fausthandler(\"" << url << "\", this.value)'\n";
+		fPage << "<td class='value'></td>\n";
+	}
+}
+
+void htmlfactory::addnode (const char* type, const char* label, float init, float min, float max, float step)
+{
+	string url = /*fPage.getUrl() +*/ fGroups.top() + "/";
+	url += label;
+	stringstream id; id << "slider" << fSerial++;	// computes slider id
+	string vid = "v"; vid += id.str();				// computes text value id
+	fPage << "<tr><td class='label'>" << label << "</td>\n";
+	fPage << "<td class='control'><input type='range' id='" << id.str() << "' name='" << url
+		  << "' min=" << min << " max=" << max << " step=" << step << " value=" << init 
+		  << " onchange='sliderhandler(\"" << url << "\", this.value, \"#" << vid << "\")'></td>\n";
+	fPage << "<td class='value'><input type='text' id='" << vid << "' name='" << url << "' value=" << init << " size=6 "
+		  << "onchange='sliderhandler(\"" << url << "\", this.value, \"#" << id.str() << "\")'></td>\n"
+		  << "</tr>\n";
+}
+
+void htmlfactory::addnode (const char* type, const char* label, float min, float max)
+{
+	// don't know what to do with bargraph 
+}
+
+/**
+ * Open a group in the current group and place it on the top of the stack. 
+ * Takes into account that due to alias, a group can been previously created.  
+ */
+void htmlfactory::opengroup (const char* type, const char* label)
+{
+	string path = fGroups.top() + "/";
+	path += label;
+	fGroups.push (path);
+	if (fGroups.size() == 2)		// first group: actually the address space root
+		fPage.setRoot (fGroups.top());
+}
+
+//--------------------------------------------------------------------------
+void htmlfactory::closegroup ()
+{
+	fGroups.pop ();
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/html/htmlfactory.h b/architecture/httpdlib/src/html/htmlfactory.h
new file mode 100644
index 0000000..a04212f
--- /dev/null
+++ b/architecture/httpdlib/src/html/htmlfactory.h
@@ -0,0 +1,64 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __htmlfactory__
+#define __htmlfactory__
+
+#include <stack>
+#include <string>
+
+#include "htmlpage.h"
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a factory to build a OSC UI hierarchy
+	
+	Actually, makes use of a stack to build the UI hierarchy.
+	It includes a pointer to a OSCIO controler, but just to give it to the root node.
+*/
+class htmlfactory
+{
+	std::stack<std::string>	fGroups;	///< maintains the current hierarchy level
+	htmlpage	fPage;					///< the resulting html page
+	int			fSerial;				///< for html UI objects unique ids
+
+	public:
+				 htmlfactory(const char *name, const char* address, int port);
+		virtual ~htmlfactory() {}
+
+		void addnode (const char* type, const char* label);
+		void addnode (const char* type, const char* label, float init, float min, float max, float step);
+		void addnode (const char* type, const char* label, float min, float max);
+		void opengroup (const char* type, const char* label);
+		void closegroup ();
+
+		htmlpage&	root()			{ return fPage; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/html/htmlpage.cpp b/architecture/httpdlib/src/html/htmlpage.cpp
new file mode 100644
index 0000000..b9bdeb9
--- /dev/null
+++ b/architecture/httpdlib/src/html/htmlpage.cpp
@@ -0,0 +1,155 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <sstream>
+#include "deelx.h"
+#include "htmlpage.h"
+#include "jsscripts.h"
+#include "stylesheet.h"
+
+using namespace std;
+
+void find_and_replace(string &source, const string find, string replace ) {
+
+	size_t j;
+	for ( ; (j = source.find( find )) != string::npos ; ) {
+		source.replace( j, find.length(), replace );
+	}
+}
+
+namespace httpdfaust
+{
+
+static const char * kPortNumberHandler = "__port_number__handler__";
+
+//--------------------------------------------------------------------------
+htmlpage::htmlpage(const char *name, const char* address, int port) 
+					: fName(name), fAddress(address), fPort(port)
+{
+}
+
+//--------------------------------------------------------------------------
+string htmlpage::getUrl() const
+{
+	stringstream url;
+	url << "http://" << fAddress << ":" << kPortNumberHandler;
+	return url.str();
+}
+
+//--------------------------------------------------------------------------
+void htmlpage::print(std::ostream& out) const
+{
+	if (false) {
+		out << "<html>\n<head>\n";
+		out << "	<link id='css' rel='stylesheet' type='text/css' href='css/style1.css' />\n";
+		out << "	<script src='js/jquery-1.7.1.min.js' language='javascript'></script>\n";
+		out << "	<script src='js/faust.js' language='javascript'></script>\n";
+		out << "	<title id=titre>" << fName << "</title>";
+		out << "</head>\n<body>\n";
+		out << "<script>\n\tfunction setStyle(num) { $(\"#css\").attr('href','css/style'+num+'.css');}";
+		out << "\n</script>\n";
+		out << "<center>\n\n";
+	} else {
+		out << "<html>\n<head>\n";
+		out << "	<link id='css' rel='stylesheet' type='text/css' href='http://faust.grame.fr/userinterface/css/style1.css' />\n";
+		out << "	<script src='http://faust.grame.fr/userinterface/js/jquery-1.7.1.min.js' language='javascript'></script>\n";
+		out << "	<script src='http://faust.grame.fr/userinterface/js/faust.js' language='javascript'></script>\n";
+		out << "	<title id=titre>" << fName << "</title>";
+		out << "</head>\n<body>\n";
+		out << "<script>\n\tfunction setStyle(num) { $(\"#css\").attr('href','http://faust.grame.fr/userinterface/css/style'+num+'.css');}";
+		out << "\n</script>\n";
+		out << "<center>\n\n";
+	}
+	
+	out << "<input type='hidden' id='root' value='" << fRoot << "'>\n";
+	out << "<table class='ui'>\n";
+	out << "<tr><td class='name'>karplus</td>\n";
+	out << "<td class='url'>" << fAddress << "</td>\n";
+	out << "<td class='port'>: " << fPort << "</td>\n";
+	out << "</tr>\n";
+	out << "<tr><td colspan=3 class='sep'><hr/></td></tr>\n";
+
+#if 0
+	stringstream port;
+	port << fPort;
+	CRegexpT<char> regexp (kPortNumberHandler);
+	out << regexp.Replace(this->str().c_str(), port.str().c_str());
+#else
+	out << this->str();		// the ui itself, generated byt htmlfactory
+#endif
+
+	out << "<tr><td colspan=3 class='sep'><hr/></td></tr>\n";
+	out << "</table>\n\n";
+	
+	out << "<div id='style'>Style:\n";
+	out << "	<input type='radio' id='style1' name='style' value=1 checked onclick= setStyle(this.value) >\n";
+	out << "	<input type='radio' id='style2' name='style' value=2 onclick= setStyle(this.value) >\n";
+	out << "</div>\n";
+	out << "</center></body>\n</html>\n";
+}
+
+//--------------------------------------------------------------------------
+void htmlpage::print(std::ostream& out, string s) const
+{
+	(void) find_and_replace(s, "\n", " ");
+	(void) find_and_replace(s, "\t", " ");
+	(void) find_and_replace(s, "'", "’");
+	out << "<html>" << endl;
+	out << "  <head>" << endl;
+    
+#ifdef LOADSCRIPTS
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/jquery-1.7.1.min.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/jquerysvg/jquery.svg.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/jquerysvg/jquery.svgdom.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_proto.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_jquery_svg_backend.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_mobile.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_ui_inits.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_load_external_file.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_ui_objects.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_ui_builder.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_ui_interact.js\"></script>" << endl;
+	out << "    <script type=\"text/javascript\" src=\"http://www.mikesolomon.org/faust/svg/faust_server_communication.js\"></script>" << endl;
+	out << "    <link rel=\"stylesheet\" type=\"text/css\" href=\"http://www.mikesolomon.org/faust/svg/faust_css.css\"></link>" << endl;
+#else
+	out << "<style type=\"text/css\">" << endl;
+        for (unsigned int i=0; i < stylesheet_len; i++) { out << stylesheet[i]; } out << endl;
+    out << "</style>" << endl;
+
+    out << "    <script type=\"text/javascript\" >" << endl;
+        for (unsigned int i=0; i < jsscripts_len; i++) { out << jsscripts[i]; } out << endl;
+    out << "    </script>" << endl;
+#endif
+
+	out << "  </head>" << endl;
+	out << "  <body>" << endl;
+	out << "    <script type=\"text/javascript\">" << endl;
+	out << "      _f4u$t.server_update_function = _f4u$t.main('";
+	out << s;
+	out << "', null, _f4u$t.faust_server_handler);" << endl;
+	out << "    </script>" << endl;
+	out << "  </body>" << endl;
+	out << "</html>";
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/html/htmlpage.h b/architecture/httpdlib/src/html/htmlpage.h
new file mode 100644
index 0000000..52a40d8
--- /dev/null
+++ b/architecture/httpdlib/src/html/htmlpage.h
@@ -0,0 +1,60 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __htmlpage__
+#define __htmlpage__
+
+#include <ostream>
+#include <sstream>
+#include <string>
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust root is a terminal node and represents a faust parameter controler
+*/
+class htmlpage : public std::stringstream
+{
+	std::string fName;		// the faust program name
+	std::string fAddress;	// its address (DN or IP address)
+	std::string fRoot;		// the address space root (the faust program name)
+	int			fPort;		// the listening TCP port
+	
+	std::string	getUrl () const;
+
+	public:
+				 htmlpage(const char *name, const char* address, int port);
+		virtual ~htmlpage() {}
+		
+		void	print(std::ostream& out, std::string s) const;
+		void	print(std::ostream& out) const;
+		void	setPort (int port)					{ fPort = port; }
+		void	setRoot (const std::string& root)	{ fRoot = root; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/html/htmlui.cpp b/architecture/httpdlib/src/html/htmlui.cpp
new file mode 100644
index 0000000..205ef7c
--- /dev/null
+++ b/architecture/httpdlib/src/html/htmlui.cpp
@@ -0,0 +1,50 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include "htmlui.h"
+#include "htmlfactory.h"
+
+htmlui::htmlui(const char *name, const char* address, int port) 
+					: fFactory(0) { fFactory = new httpdfaust::htmlfactory(name, address, port); }
+htmlui::~htmlui() { delete fFactory; }
+
+void htmlui::openTabBox(const char* label)			{ fFactory->opengroup( "tgroup", label); }
+void htmlui::openHorizontalBox(const char* label)	{ fFactory->opengroup( "hgroup", label); }
+void htmlui::openVerticalBox(const char* label)		{ fFactory->opengroup( "vgroup", label); }
+void htmlui::closeBox()								{ fFactory->closegroup(); }
+
+void htmlui::addButton(const char* label, float*)
+					{ fFactory->addnode( "button", label); }
+void htmlui::addCheckButton(const char* label, float*)
+					{ fFactory->addnode( "checkbox", label); }
+
+void htmlui::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+					{ fFactory->addnode( "vslider", label, init, min, max, step); }
+void htmlui::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+					{ fFactory->addnode( "hslider", label, init, min, max, step); }
+void htmlui::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+					{ fFactory->addnode( "nentry", label, init, min, max, step); }
+
+void htmlui::addHorizontalBargraph(const char* label, float* zone, float min, float max) {}
+void htmlui::addVerticalBargraph(const char* label, float* zone, float min, float max) {}
+
diff --git a/architecture/httpdlib/src/html/htmlui.h b/architecture/httpdlib/src/html/htmlui.h
new file mode 100644
index 0000000..463462a
--- /dev/null
+++ b/architecture/httpdlib/src/html/htmlui.h
@@ -0,0 +1,60 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __htmlui__
+#define __htmlui__
+
+
+namespace httpdfaust { class htmlfactory; }
+
+class htmlui
+{
+	httpdfaust::htmlfactory* fFactory;
+
+	public:
+				 htmlui(const char *name, const char* address, int port);
+		virtual ~htmlui();
+
+		// -- widget's layouts
+		virtual void openTabBox(const char* label);
+		virtual void openHorizontalBox(const char* label);
+		virtual void openVerticalBox(const char* label);
+		virtual void closeBox();
+
+		// -- active widgets
+		virtual void addButton(const char* label, float* zone);
+		virtual void addCheckButton(const char* label, float* zone);
+		virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+		virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+		virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+		// -- passive widgets
+		virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+		virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+
+		// -- metadata declarations
+
+		virtual void declare(float*, const char*, const char*) {}
+};
+
+#endif
diff --git a/architecture/httpdlib/src/html/jsscripts.h b/architecture/httpdlib/src/html/jsscripts.h
new file mode 100644
index 0000000..bcbf50a
--- /dev/null
+++ b/architecture/httpdlib/src/html/jsscripts.h
@@ -0,0 +1,5 @@
+#ifndef __JSSCRIPTS__
+#define __JSSCRIPTS__
+extern unsigned char jsscripts[];
+extern unsigned int  jsscripts_len;
+#endif
\ No newline at end of file
diff --git a/architecture/httpdlib/src/html/stylesheet.h b/architecture/httpdlib/src/html/stylesheet.h
new file mode 100644
index 0000000..9f25eb9
--- /dev/null
+++ b/architecture/httpdlib/src/html/stylesheet.h
@@ -0,0 +1,7 @@
+#ifndef __STYLESHEET__
+#define __STYLESHEET__
+
+extern unsigned char stylesheet[];
+extern unsigned int  stylesheet_len;
+
+#endif
\ No newline at end of file
diff --git a/architecture/httpdlib/src/httpd/Address.cpp b/architecture/httpdlib/src/httpd/Address.cpp
new file mode 100644
index 0000000..9e6b816
--- /dev/null
+++ b/architecture/httpdlib/src/httpd/Address.cpp
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#include "Address.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+#define kAddressSep	'/'
+//--------------------------------------------------------------------------
+string Address::addressFirst (const string& a)
+{
+	if (a[0] == kAddressSep) {
+		size_t n = a.find_first_of(kAddressSep, 1);
+		if (n == string::npos) n = a.size();
+		return a.substr(1, n-1);
+	}
+	return "";
+}
+
+//--------------------------------------------------------------------------
+string Address::addressLast (const string& a)
+{
+	size_t n = a.find_last_of(kAddressSep);
+	if (n == string::npos) return "";
+	return a.substr(n+1);
+}
+
+//--------------------------------------------------------------------------
+string Address::addressTail (const string& a)
+{
+	if (a[0] == kAddressSep) {
+		size_t n = a.find_first_of(kAddressSep, 1);
+		if (n != string::npos) {
+			return a.substr(n, a.size() - n);
+		}
+	}
+	return "";
+}
+
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/httpd/Address.h b/architecture/httpdlib/src/httpd/Address.h
new file mode 100644
index 0000000..cfe64c2
--- /dev/null
+++ b/architecture/httpdlib/src/httpd/Address.h
@@ -0,0 +1,67 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __Address__
+#define __Address__
+
+#include <string>
+
+namespace httpdfaust
+{
+
+
+//--------------------------------------------------------------------------
+/*! \brief addresses utilities
+*/
+class Address
+{
+	public:
+		/*!
+			\brief address decoding utility.
+			
+			An address has a form similar to a unix path.
+			\param address the osc address to be processed
+			\return the first part of the address (without leading '/')
+		*/
+		static std::string	addressFirst (const std::string& address);
+		/*!
+			\brief address decoding utility.
+			\param address the osc address to be processed
+			\return the last part of an address.
+		*/
+		static std::string	addressLast (const std::string& address);
+		/*!
+			\brief address decoding utility.
+
+			An address has a form similar to a unix path.
+			\param address the osc address to be processed
+			\return the tail of an address after its first part.
+		*/
+		static std::string	addressTail (const std::string& address);
+};
+
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/httpd/HTTPDServer.cpp b/architecture/httpdlib/src/httpd/HTTPDServer.cpp
new file mode 100644
index 0000000..bc986be
--- /dev/null
+++ b/architecture/httpdlib/src/httpd/HTTPDServer.cpp
@@ -0,0 +1,231 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <stdexcept>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "HTTPDServer.h"
+#include "Message.h"
+#include "MessageProcessor.h"
+
+#ifdef _WIN32
+#include <io.h>
+#define lseek _lseek
+#endif
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+#define kPortsScanRange		1000		// scan this number of TCP ports to find a free one (in case of busy port)
+
+//--------------------------------------------------------------------------
+// static functions
+// provided as callbacks to mhttpd
+//--------------------------------------------------------------------------
+static int _answer_to_connection (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, 
+                          const char *upload_data, size_t *upload_data_size, void **con_cls)
+{
+	HTTPDServer* server = (HTTPDServer*)cls;
+	return server->answer(connection, url, method, version, upload_data, upload_data_size, con_cls); 
+}
+
+// Convert string to float. Accepts both . and , as decimal point
+// Syntax is : [ ]*[+|-]n*(.|,)n*
+static float mystrtof(const char* str, const char** endptr)
+{
+	const char* p = str;
+	float		sign = 1.0;
+	float		val = 0;
+	
+	// skip leading white spaces
+	while (isspace(*p)) p++;
+	// analyze sign
+	if (*p == '-') { sign = -1.0; p++; }
+	else if (*p == '+') { sign = 1.0; p++; }
+	// fix part
+	while (isdigit(*p)) { val = val*10 + (*p++ - '0'); }
+	// decimal part
+	if (*p == '.' | *p == ',') {
+		p++;
+		// decimal part
+		int virgule = 10; 
+		while (isdigit(*p)) { 
+			val = val + double((*p++ - '0'))/virgule; 
+			virgule *= 10; 
+		}
+	}
+	*endptr = p;
+	return sign*val;
+}
+
+//--------------------------------------------------------------------------
+// fonct(ion appelée par libmicrohttpd pour tous les parametres de la requète (soit GET soit POST)
+static int _get_params (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
+{
+	Message* msg = (Message*)cls;
+	msg->add (string(key));
+	if (value) {
+		const char* endptr;
+		float fval = mystrtof(value, &endptr);
+		if ((fval == 0) && (endptr == value))		// not a float value
+			msg->add (string(value));
+		else 
+			msg->add (fval);
+	}
+	return MHD_YES;
+}
+
+//--------------------------------------------------------------------------
+// the http server
+//--------------------------------------------------------------------------
+HTTPDServer::HTTPDServer(MessageProcessor* mp)
+	: fProcessor(mp), fServer(0), fDebug(false)
+{
+}
+
+HTTPDServer::~HTTPDServer() { stop(); }
+
+//--------------------------------------------------------------------------
+bool HTTPDServer::start(int port)
+{
+	fServer = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, port, NULL, NULL, _answer_to_connection, this, MHD_OPTION_END);
+	return fServer != 0;
+}
+
+//--------------------------------------------------------------------------
+int HTTPDServer::send (struct MHD_Connection *connection, const char *page, const char* type, int status)
+{
+	struct MHD_Response *response = MHD_create_response_from_buffer (strlen (page), (void *) page, MHD_RESPMEM_MUST_COPY);
+	if (!response) {
+		cerr << "MHD_create_response_from_buffer error: null response\n";
+		return MHD_NO;
+	}
+	MHD_add_response_header (response, "Content-Type", type ? type : "text/plain");
+	MHD_add_response_header (response, "Access-Control-Allow-Origin", "*");
+	int ret = MHD_queue_response (connection, status, response);
+	MHD_destroy_response (response);
+	return ret;
+}
+
+//--------------------------------------------------------------------------
+const char* HTTPDServer::getMIMEType (const string& page)
+{
+	size_t n = page.find_last_of ('.');
+	if (n != string::npos) {
+		string ext = page.substr (n+1);
+		if (ext == "css")	return "text/css";
+		if (ext == "js")	return "application/javascript";
+	}
+	return "text/plain";		// default MIME type
+}
+
+//--------------------------------------------------------------------------
+int HTTPDServer::page (struct MHD_Connection *connection, const char * page)
+{
+	int ret = 0;
+	char * root =  getenv("FAUSTDocumentRoot");
+	string file = root ? root : ".";
+	file += page;
+	const char* type = getMIMEType (file);
+
+	int fd = open (file.c_str(), O_RDONLY);
+	if (fd != -1) {
+		int length = lseek(fd, 0, SEEK_END);
+		lseek(fd, 0, SEEK_SET);
+		
+		struct MHD_Response *response = MHD_create_response_from_fd (length, fd);
+		if (!response ) {
+			cerr << "MHD_create_response_from_fd error: null response\n";
+			return MHD_NO;
+		}
+		MHD_add_response_header (response, "Content-Type", type ? type : "text/plain");
+		MHD_add_response_header (response, "Access-Control-Allow-Origin", "*");
+		ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+		MHD_destroy_response (response);
+	}
+	else {
+		ret = send (connection, "", 0, MHD_HTTP_NOT_FOUND);
+	}
+	return ret;
+}
+
+//--------------------------------------------------------------------------
+int HTTPDServer::send (struct MHD_Connection *connection, std::vector<Message*> msgs)
+{
+	stringstream page;
+	string mime;
+	for (unsigned int i=0; i<msgs.size(); i++) {
+		string currentmime = msgs[i]->mimetype();
+		if (mime.size() && (currentmime != mime)) {					// check for mime type change
+			send (connection, page.str().c_str(), mime.c_str());	// send the current mime data
+			page.str("");											// and clear the stream
+		}
+		mime = currentmime;
+		msgs[i]->print( page);
+		page << endl;
+		delete msgs[i];
+	}
+	return send (connection, page.str().c_str(), mime.c_str());
+}
+
+//--------------------------------------------------------------------------
+// Callback appelée par libmicrohttpd
+//--------------------------------------------------------------------------
+int HTTPDServer::answer (struct MHD_Connection *connection, const char *url, const char *method, const char *version, 
+					const char *upload_data, size_t *upload_data_size, void **con_cls)
+{
+	MHD_ValueKind t = MHD_GET_ARGUMENT_KIND;
+	if (0 == strcmp (method, "GET"))		t = MHD_GET_ARGUMENT_KIND;
+	else if (0 == strcmp (method, "POST"))	t = MHD_POSTDATA_KIND;
+	else {
+		string msg = "Method ";
+		msg += method;
+		msg += " is not supported";
+		return send (connection, msg.c_str(), 0, MHD_HTTP_BAD_REQUEST);
+	}
+
+	Message msg (url);
+	MHD_get_connection_values (connection, t, _get_params, &msg);
+	vector<Message*> outMsgs;
+	if (fDebug) {
+		cout << method << ": ";
+		msg.print(cout);
+		cout << endl;
+	}
+	fProcessor->processMessage (&msg, outMsgs);
+	if (outMsgs.size())
+		send (connection, outMsgs);
+	else 
+		page (connection, url);
+	return MHD_YES;
+}
+
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/httpd/HTTPDServer.h b/architecture/httpdlib/src/httpd/HTTPDServer.h
new file mode 100644
index 0000000..58f078d
--- /dev/null
+++ b/architecture/httpdlib/src/httpd/HTTPDServer.h
@@ -0,0 +1,89 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __HTTPDServer__
+#define __HTTPDServer__
+
+#include <string>
+#include <ostream>
+#include <vector>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#define MHD_PLATFORM_H
+#ifdef __MINGW32__
+typedef size_t socklen_t;
+#endif
+#endif
+
+#include <microhttpd.h>
+
+namespace httpdfaust
+{
+
+class Message;
+class MessageProcessor;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a specific thread to listen incoming osc packets
+*/
+class HTTPDServer
+{
+	MessageProcessor*	fProcessor;
+	struct MHD_Daemon *	fServer;
+	bool				fDebug;
+	
+	int send (struct MHD_Connection *connection, std::vector<Message*> msgs);
+	int page (struct MHD_Connection *connection, const char *page);
+	const char* getMIMEType (const std::string& page);
+
+	public:
+				 HTTPDServer(MessageProcessor* mp);
+		virtual ~HTTPDServer();
+
+		/// \brief starts the httpd server
+		bool start (int port);
+		void stop ()			{ if (fServer) MHD_stop_daemon (fServer); fServer=0; }
+		int answer (struct MHD_Connection *connection, const char *url, const char *method, const char *version, 
+					const char *upload_data, size_t *upload_data_size, void **con_cls);
+
+		static int send (struct MHD_Connection *connection, const char *page, const char *type, int status=MHD_HTTP_OK);
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/httpd/HTTPDSetup.cpp b/architecture/httpdlib/src/httpd/HTTPDSetup.cpp
new file mode 100644
index 0000000..61ca9d1
--- /dev/null
+++ b/architecture/httpdlib/src/httpd/HTTPDSetup.cpp
@@ -0,0 +1,70 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <stdexcept>
+
+#include "HTTPDSetup.h"
+#include "HTTPDServer.h"
+#include "MessageProcessor.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+#define kPortsScanRange		1000		// scan this number of TCP ports to find a free one (in case of busy port)
+
+//--------------------------------------------------------------------------
+HTTPDSetup::~HTTPDSetup()			{ stop(); }
+bool HTTPDSetup::running() const	{ return fServer ? true : false; }
+//bool HTTPDSetup::running() const	{ return fServer ? fServer->isRunning() : false; }
+
+//--------------------------------------------------------------------------
+bool HTTPDSetup::start(MessageProcessor* mp, int& tcpport )
+{
+	int port = tcpport;
+	bool done = false;
+	fServer = new HTTPDServer (mp);
+	do {
+		done = fServer->start(port);
+		if (!done) {
+			if ( port - tcpport > kPortsScanRange) return false;
+			port++;
+		}
+	} while (!done);
+	tcpport = port;
+	return true;
+}
+
+//--------------------------------------------------------------------------
+void HTTPDSetup::stop()
+{
+	if (fServer) {
+		fServer->stop();
+		delete fServer;
+		fServer = 0;
+	}
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/httpd/HTTPDSetup.h b/architecture/httpdlib/src/httpd/HTTPDSetup.h
new file mode 100644
index 0000000..511b52d
--- /dev/null
+++ b/architecture/httpdlib/src/httpd/HTTPDSetup.h
@@ -0,0 +1,55 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __HTTPDSetup__
+#define __HTTPDSetup__
+
+#include <string>
+#include <ostream>
+
+namespace httpdfaust
+{
+
+class HTTPDServer;
+class MessageProcessor;
+//--------------------------------------------------------------------------
+/*!
+	\brief network management utility
+*/
+class HTTPDSetup
+{
+	HTTPDServer*	fServer;		// the server thread
+	public:
+		 		 HTTPDSetup() : fServer(0) {} 
+		virtual ~HTTPDSetup();
+
+		bool start(MessageProcessor* mp, int& port);
+
+		void stop();
+		bool running() const;
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/include/HTTPDControler.h b/architecture/httpdlib/src/include/HTTPDControler.h
new file mode 100644
index 0000000..8b9d927
--- /dev/null
+++ b/architecture/httpdlib/src/include/HTTPDControler.h
@@ -0,0 +1,97 @@
+/*
+
+  Faust Project
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __HTTPDControler__
+#define __HTTPDControler__
+
+#include <string>
+#include <map>
+
+namespace httpdfaust
+{
+
+class HTTPDSetup;
+class JSONDesc;
+class FaustFactory;
+class jsonfactory;
+class htmlfactory;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief the main Faust HTTPD Lib API
+	
+	The HTTPDControler is essentially a glue between the memory representation (in charge of the FaustFactory), 
+	and the network services (in charge of HTTPDSetup).
+*/
+class HTTPDControler
+{
+	int fTCPPort;				// the tcp port number
+	FaustFactory *	fFactory;	// a factory to build the memory representation
+	jsonfactory*	fJson;
+	htmlfactory*	fHtml;
+	HTTPDSetup*		fHttpd;		// the network manager
+	std::string		fHTML;		// the corresponding HTML page
+	std::map<std::string, std::string>	fCurrentMeta;	// the current meta declarations 
+
+    bool            fInit;
+    
+	public:
+		/*
+			base udp port is chosen in an unassigned range from IANA PORT NUMBERS (last updated 2011-01-24)
+			see at http://www.iana.org/assignments/port-numbers
+			5507-5552  Unassigned
+		*/
+		enum { kTCPBasePort = 5510};
+
+				 HTTPDControler (int argc, char *argv[], const char* applicationname, bool init = true);
+		virtual ~HTTPDControler ();
+	
+		//--------------------------------------------------------------------------
+		// addnode, opengroup and closegroup are simply relayed to the factory
+		//--------------------------------------------------------------------------
+		template <typename C> void addnode (const char* type, const char* label, C* zone);
+		template <typename C> void addnode (const char* type, const char* label, C* zone, C min, C max);
+		template <typename C> void addnode (const char* type, const char* label, C* zone, C init, C min, C max, C step);
+							  void declare (const char* key, const char* val ) { fCurrentMeta[key] = val; }
+
+		void opengroup (const char* type, const char* label);
+		void closegroup ();
+
+		//--------------------------------------------------------------------------
+		void run ();				// start the httpd server
+		void quit ();				// stop the httpd server
+		
+		int	getTCPPort()			{ return fTCPPort; }
+        std::string getJSONInterface();
+        void        setInputs(int numInputs);
+        void        setOutputs(int numOutputs);
+
+		static float version();				// the Faust httpd library version number
+		static const char* versionstr();	// the Faust httpd library version number as a string
+};
+
+}
+
+#endif
diff --git a/architecture/httpdlib/src/include/jsonfaustui.h b/architecture/httpdlib/src/include/jsonfaustui.h
new file mode 100644
index 0000000..bd18fc4
--- /dev/null
+++ b/architecture/httpdlib/src/include/jsonfaustui.h
@@ -0,0 +1,82 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __jsonfaustui__
+#define __jsonfaustui__
+
+#include "faust/gui/meta.h"
+#include "faust/gui/UI.h"
+#include <string>
+
+namespace httpdfaust
+{
+
+template <typename C> class jsonui;
+ 
+class jsonfaustui : public UI, public Meta
+{
+	jsonui<FAUSTFLOAT>* fJSON;
+	public:
+
+				 jsonfaustui(const char *name, const char* address, int port);
+		virtual ~jsonfaustui();
+
+		//--------------------------------------------
+		// UI methods
+		//--------------------------------------------
+		// -- widget's layouts
+		virtual void openTabBox(const char* label);
+		virtual void openHorizontalBox(const char* label);
+		virtual void openVerticalBox(const char* label);
+		virtual void closeBox();
+
+		// -- active widgets
+		void addButton(const char* label, FAUSTFLOAT* zone);
+		void addCheckButton(const char* label, FAUSTFLOAT* zone);
+		void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+		void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+		void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+
+		// -- passive widgets
+		void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max);
+		void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, float min, float max);
+
+		// -- metadata declarations
+		void declare(FAUSTFLOAT*, const char*, const char*);
+
+		//--------------------------------------------
+		// additionnal methods (not part of UI)
+		//--------------------------------------------
+		void numInput(int n);			// should be called with the inputs number
+		void numOutput(int n);		// should be called with the outputs number
+		void declare(const char* , const char*); // global metadata declaration
+
+		//--------------------------------------------
+		// and eventually how to get the json as a string
+		//--------------------------------------------
+		std::string	json();
+};
+
+} //end namespace
+
+#endif
diff --git a/architecture/httpdlib/src/json/jsoncontrol.cpp b/architecture/httpdlib/src/json/jsoncontrol.cpp
new file mode 100644
index 0000000..236f0de
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsoncontrol.cpp
@@ -0,0 +1,64 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include "jsoncontrol.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+//void jsoncontrol::print(std::ostream& out, jsonendl& eol) const
+//{
+//	bool button = (fType == "button");
+//	bool bargraph = (fType == "vbargraph") || (fType == "hbargraph");
+//
+//	out << eol << "{"; eol++;
+//	out << eol << "\"type\": \"" << fType << "\",";
+//	out << eol << "\"label\": \"" << fName << "\",";
+//	out << eol << "\"address\": \"" << getAddress() << "\"";
+//	if (fMeta.size()) {
+//		out << eol << "\"meta\": \"" << "[ "; eol++;
+////		for (TMetas::const_iterator i=fMeta.begin(); i!=fMeta.end();) {
+//		TMetas::const_iterator i=fMeta.begin();
+//		while (true) {
+//			out << eol << "{ \"" << i->first << "\": \"" << i->second << "\"}";
+//			if (++i == fMeta.end()) break;
+//			out << ",";			
+//		}
+//		out << --eol << "]";
+//	}
+//
+//	if (button) { out << --eol << "}"; return; }		// done for buttons
+//
+//	if (!bargraph)
+//		out << "," << eol << "\"init\": \"" << fInit << "\",";
+//	out << eol << "\"min\": \"" << fMin << "\",";
+//	out << eol << "\"max\": \"" << fMax << "\",";
+//	if (!bargraph)
+//		out << eol << "\"step\": \"" << fStep << "\"";
+//	out << --eol << "}";
+//}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/json/jsoncontrol.h b/architecture/httpdlib/src/json/jsoncontrol.h
new file mode 100644
index 0000000..abebf71
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsoncontrol.h
@@ -0,0 +1,105 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __jsoncontrol__
+#define __jsoncontrol__
+
+#include <ostream>
+#include <string>
+#include <map>
+#include "jsonnode.h"
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust control is a terminal node and represents a faust parameter controler
+*/
+template <typename C> class jsoncontrol : public jsonnode
+{
+	std::string fName;
+	std::string fType;
+	C fInit, fMin, fMax, fStep;
+	TMetas fMeta;
+		
+	public:
+		
+	static Sjsonnode create (const char *name, const char* type, C min, C max, const TMetas& m)
+			{ return new jsoncontrol (name, type, min, max, m); }
+	static Sjsonnode create (const char *name, const char* type, C init, C min, C max, C step, const TMetas& m)
+			{ return new jsoncontrol (name, type, init, min, max, step, m); }
+	static Sjsonnode create (const char *name, const char* type, const TMetas& m) 
+			{ return new jsoncontrol (name, type, m); }
+
+		virtual void	print(std::ostream& out, jsonendl& eol) const
+		{
+			bool button = (fType == "button") || (fType == "checkbox");
+			bool bargraph = (fType == "vbargraph") || (fType == "hbargraph");
+
+			out << eol << "{"; eol++;
+			out << eol << "\"type\": \"" << fType << "\",";
+			out << eol << "\"label\": \"" << fName << "\",";
+			out << eol << "\"address\": \"" << getAddress() << "\"";
+			if (fMeta.size()) {
+				out << "," << eol << "\"meta\": " << "[ "; eol++;
+				TMetas::const_iterator i=fMeta.begin();
+				while (true) {
+					out << eol << "{ \"" << i->first << "\": \"" << i->second << "\"}";
+					if (++i == fMeta.end()) break;
+					out << ",";			
+				}
+				out << --eol << "]";
+			}
+
+			if (button) { out << --eol << "}"; return; }		// done for buttons
+
+			if (!bargraph) {
+				out << "," << eol << "\"init\": \"" << fInit << "\"";
+			}
+			out << "," << eol << "\"min\": \"" << fMin << "\",";
+			out << eol << "\"max\": \"" << fMax << "\"";
+			if (!bargraph) {
+				out << "," << eol << "\"step\": \"" << fStep << "\"";
+            }
+			out << --eol << "}";
+		}
+	
+	protected:
+
+				 jsoncontrol(const char *name, const char* type, const TMetas& m)
+					: fName(name), fType(type), fInit(0), fMin(0), fMax(1), fStep(1), fMeta(m) {}
+
+				 jsoncontrol(const char *name, const char* type, C min, C max, const TMetas& m)
+					: fName(name), fType(type), fMin(min), fMax(max), fStep(0), fMeta(m) {}
+
+				 jsoncontrol(const char *name, const char* type, C init, C min, C max, C step, const TMetas& m)
+					: fName(name), fType(type), fInit(init), fMin(min), fMax(max), fStep(step), fMeta(m) {}
+
+		virtual ~jsoncontrol() {}
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/json/jsonfactory.cpp b/architecture/httpdlib/src/json/jsonfactory.cpp
new file mode 100644
index 0000000..23deb5c
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonfactory.cpp
@@ -0,0 +1,70 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "jsonfactory.h"
+#include "jsoncontrol.h"
+#include "jsongroup.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+
+/**
+ * Add a node to the OSC UI tree in the current group at the top of the stack 
+ */
+void jsonfactory::addnode (Sjsonnode node, const char* label)
+{
+	string address;
+	if (fNodes.size()) {
+		address = fNodes.top()->getAddress();
+		fNodes.top()->add(node);
+	}
+	else fRoot.add(node);
+	address += "/";
+	address += label;
+	node->setAddress (address);
+}
+
+/**
+ * Open a group in the current group and place it on the top of the stack. 
+ * Takes into account that due to alias, a group can been previously created.  
+ */
+void jsonfactory::opengroup (const char* type, const char* label, const TMetas& m)
+{
+	Sjsonnode node = jsongroup::create (label, type, m);
+	addnode (node, label);
+	fNodes.push (node);
+}
+
+//--------------------------------------------------------------------------
+void jsonfactory::closegroup ()
+{
+	fNodes.pop ();
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/json/jsonfactory.h b/architecture/httpdlib/src/json/jsonfactory.h
new file mode 100644
index 0000000..b05c2e1
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonfactory.h
@@ -0,0 +1,79 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __jsonfactory__
+#define __jsonfactory__
+
+#include <stack>
+#include <string>
+
+#include "jsonroot.h"
+#include "jsoncontrol.h"
+
+namespace httpdfaust
+{
+
+class jsonnode;
+typedef SMARTP<jsonnode>	Sjsonnode;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a factory to build a OSC UI hierarchy
+	
+	Actually, makes use of a stack to build the UI hierarchy.
+	It includes a pointer to a OSCIO controler, but just to give it to the root node.
+*/
+class jsonfactory
+{
+	std::stack<Sjsonnode>	fNodes;		///< maintains the current hierarchy level
+	jsonroot				fRoot;		///< keep track of the root node
+
+	void addnode(Sjsonnode node, const char * label);
+
+	public:
+    
+                jsonfactory(const char *name, const char* address, int port) : fRoot(name, address, port) {}
+		virtual ~jsonfactory() {}
+
+		template <typename C> void addnode (const char* type, const char* label, C min, C max, const TMetas& m) {
+				addnode (jsoncontrol<C>::create (label, type, min, max, m), label);
+			}
+
+		template <typename C> void addnode (const char* type, const char* label, C init, C min, C max, C step, const TMetas& m) {
+				addnode (jsoncontrol<C>::create (label, type, init, min, max, step, m), label);
+			}
+
+		template <typename C> void addnode (const char* type, const char* label, const TMetas& m) {
+				addnode (jsoncontrol<C>::create (label, type, m), label);
+			}
+
+		void opengroup(const char* type, const char* label, const TMetas& m);
+		void closegroup();
+
+		jsonroot&	root()			{ return fRoot; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/json/jsonfaustui.cpp b/architecture/httpdlib/src/json/jsonfaustui.cpp
new file mode 100644
index 0000000..52b1f2c
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonfaustui.cpp
@@ -0,0 +1,78 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include "jsonfaustui.h"
+#include "jsonui.h"
+
+namespace httpdfaust
+{
+
+jsonfaustui::jsonfaustui(const char *name, const char* address, int port)
+{
+	fJSON = new jsonui<FAUSTFLOAT> (name, address, port);
+}
+
+jsonfaustui::~jsonfaustui()		{ delete fJSON; }
+
+//--------------------------------------------
+// UI methods
+//--------------------------------------------
+// -- widget's layouts
+void jsonfaustui::openTabBox(const char* label)				{ fJSON->openTabBox(label); }
+void jsonfaustui::openHorizontalBox(const char* label)		{ fJSON->openHorizontalBox(label); }
+void jsonfaustui::openVerticalBox(const char* label)		{ fJSON->openVerticalBox(label); }
+void jsonfaustui::closeBox()								{ fJSON->closeBox(); }
+
+		// -- active widgets
+void jsonfaustui::addButton(const char* label, FAUSTFLOAT* zone)		{ fJSON->addButton(label, zone); }
+void jsonfaustui::addCheckButton(const char* label, FAUSTFLOAT* zone)	{ fJSON->addCheckButton(label, zone); }
+
+void jsonfaustui::addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{ fJSON->addVerticalSlider(label, zone, init, min, max, step); }
+
+void jsonfaustui::addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{ fJSON->addHorizontalSlider(label, zone, init, min, max, step); }
+
+void jsonfaustui::addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+	{ fJSON->addNumEntry(label, zone, init, min, max, step); }
+
+// -- passive widgets
+void jsonfaustui::addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+	{ fJSON->addHorizontalBargraph(label, zone, min, max); }
+void jsonfaustui::addVerticalBargraph(const char* label, FAUSTFLOAT* zone, float min, float max)
+	{ fJSON->addVerticalBargraph(label, zone, min, max); }
+
+// -- metadata declarations
+void jsonfaustui::declare(FAUSTFLOAT* zone, const char* key, const char* val)		{ fJSON->declare(zone, key, val); }
+
+//--------------------------------------------
+// additionnal methods (not part of UI)
+//--------------------------------------------
+void jsonfaustui::numInput(int n)							{ fJSON->numInput(n);}
+void jsonfaustui::numOutput(int n)                          { fJSON->numOutput(n);}
+void jsonfaustui::declare(const char* key, const char* val)	{ fJSON->declare(key, val); }
+
+std::string	jsonfaustui::json ()							{ return fJSON->json(); }
+
+} //end namespace
+
diff --git a/architecture/httpdlib/src/json/jsongroup.cpp b/architecture/httpdlib/src/json/jsongroup.cpp
new file mode 100644
index 0000000..5efd913
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsongroup.cpp
@@ -0,0 +1,59 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include "jsongroup.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+void jsongroup::print(std::ostream& out, jsonendl& eol) const
+{
+	out << eol << "{"; eol++;
+	out << eol << "\"type\": \"" << fType << "\",";
+	out << eol << "\"label\": \"" << fName << "\",";
+//	out << eol << "\"address\": \"" << getAddress() << "\"";
+    if (fMeta.size()) {
+        out << eol << "\"meta\": " << "[ "; eol++;
+        TMetas::const_iterator i=fMeta.begin();
+        while (true) {
+            out << eol << "{ \"" << i->first << "\": \"" << i->second << "\"}";
+            if (++i == fMeta.end()) break;
+            out << ",";			
+        }
+        out << --eol << "],";
+    }
+	out << eol << "\"items\": ["; eol++;
+	const char* sep = "";
+	for (unsigned int i=0; i< fContent.size(); i++) {
+		out << sep;
+		sep = ",";
+		fContent[i]->print(out, eol);
+	}
+	out << --eol << "]";
+	out << --eol << "}";
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/json/jsongroup.h b/architecture/httpdlib/src/json/jsongroup.h
new file mode 100644
index 0000000..3cc41a9
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsongroup.h
@@ -0,0 +1,61 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __jsongroup__
+#define __jsongroup__
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "jsonnode.h"
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust group is a terminal node and represents a faust parameter controler
+*/
+class jsongroup : public jsonnode
+{
+	std::string fName;
+	std::string fType;
+    TMetas fMeta;
+	std::vector<Sjsonnode> fContent;
+	
+	protected:
+				 jsongroup(const char *name, const char* type, const TMetas& m)  : fName(name), fType(type), fMeta(m) {}
+		virtual ~jsongroup() {}
+		
+	public:
+	static Sjsonnode create (const char *name, const char* type, const TMetas& m) { return new jsongroup (name, type, m); }
+
+		virtual void	add (const Sjsonnode& node)		{ fContent.push_back(node); }
+		virtual void	print(std::ostream& out, jsonendl& eol) const;
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/json/jsonnode.h b/architecture/httpdlib/src/json/jsonnode.h
new file mode 100644
index 0000000..9b84bfc
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonnode.h
@@ -0,0 +1,84 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __jsonnode__
+#define __jsonnode__
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "smartpointer.h"
+
+namespace httpdfaust
+{
+
+class jsonnode;
+typedef SMARTP<jsonnode>	Sjsonnode;
+
+typedef std::map<std::string, std::string>	TMetas;
+
+//______________________________________________________________________________
+/*!
+\internal
+\brief to be used in place of std::endl
+	to provide indentation of the json output.
+*/
+class jsonendl {
+	private:
+		int fIndent;
+	public:
+				 jsonendl() : fIndent(0) {}
+		virtual ~jsonendl() {}
+
+		//! increase the indentation
+		jsonendl& operator++ (int)  { fIndent++; return *this; }	// prefix
+		jsonendl& operator++ ()		{ fIndent++; return *this; }	// postfix
+		//! decrease the indentation
+		jsonendl& operator-- (int)  { fIndent--; return *this; }	// prefix
+		jsonendl& operator-- ()		{ fIndent--; return *this; }	// postfix
+		//! reset the indentation to none
+		void print(std::ostream& os) const;
+};
+std::ostream& operator<< (std::ostream& os, const jsonendl& eol);
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust node is a terminal node and represents a faust parameter controler
+*/
+class jsonnode : public smartable
+{
+	std::string fAddress;
+	public:
+		virtual ~jsonnode() {}
+
+		virtual void	add (const Sjsonnode& node)		{}
+		virtual void	print(std::ostream& out, jsonendl& eol) const = 0;
+		virtual const std::string&	getAddress() const							{ return fAddress; }
+		virtual void				setAddress( const std::string& address) 	{ fAddress = address; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/json/jsonroot.cpp b/architecture/httpdlib/src/json/jsonroot.cpp
new file mode 100644
index 0000000..5c07f97
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonroot.cpp
@@ -0,0 +1,78 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include "jsonroot.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+//______________________________________________________________________________
+ostream& operator<< (ostream& os, const jsonendl& endl)
+{
+    endl.print(os);
+    return os;
+}
+
+//______________________________________________________________________________
+void jsonendl::print(std::ostream& os) const { 
+	int i = fIndent;
+    os << std::endl;
+    while (i-- > 0)  os << "	";
+}
+
+//--------------------------------------------------------------------------
+void jsonroot::print(std::ostream& out) const
+{
+	jsonendl eol;
+	out << "{" << eol++;
+	out << "\"name\": \"" << fName << "\"," << eol;
+	out << "\"address\": \"" << fAddress << "\"," << eol;
+	out << "\"port\": \"" << fPort << "\"," << eol;
+	if (fInputs)	out << "\"inputs\": \"" << fInputs << "\"," << eol;
+	if (fOutputs)	out << "\"outputs\": \"" << fOutputs << "\"," << eol;
+
+	if (fMeta.size()) {
+		out << "\"meta\": [ "; eol++;
+		map<string, string>::const_iterator i=fMeta.begin();
+		while (true) {
+			out << eol << "{ \"" << i->first << "\": \"" << i->second << "\"}";
+			if (++i == fMeta.end()) break;
+			out << ",";			
+		}
+		out << --eol << "]," << eol;
+	}
+
+	out << "\"ui\": ["; eol++;
+	const char* sep = "";
+	for (unsigned int i=0; i< fUi.size(); i++) {
+		out << sep;
+		sep = ",";
+		fUi[i]->print(out, eol);
+	}
+	out << --eol << "]";
+	out << --eol << "}" << eol;
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/json/jsonroot.h b/architecture/httpdlib/src/json/jsonroot.h
new file mode 100644
index 0000000..3e8a941
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonroot.h
@@ -0,0 +1,72 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __jsonroot__
+#define __jsonroot__
+
+#include <ostream>
+#include <string>
+#include <map>
+#include <vector>
+#include <sstream>
+
+#include "smartpointer.h"
+#include "jsonnode.h"
+
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust root is a terminal node and represents a faust parameter controler
+*/
+class jsonroot : public smartable
+{
+	std::string fName;
+	std::string fAddress;
+	int			fPort;
+	int			fInputs;
+	int			fOutputs;
+	std::map<std::string, std::string> fMeta;
+	std::vector<Sjsonnode> fUi;
+	std::stringstream fJSON;
+	
+	public:
+				 jsonroot(const char *name, const char* address, int port)
+					: fName(name), fAddress(address), fPort(port), fInputs(0), fOutputs(0) {}
+		virtual ~jsonroot() {}
+		
+		void	print(std::ostream& out) const;
+		void	add (const Sjsonnode& node)					{ fUi.push_back(node); }
+		void	setPort (int port)							{ fPort = port; }
+		void	declare (const char* key, const char* val)	{ fMeta[key] = val; }
+		void	setInputs (int inputs)						{ fInputs = inputs;}
+		void	setOutputs (int outputs)					{ fOutputs = outputs; }
+		std::string	json ()									{ print(fJSON); return fJSON.str(); }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/json/jsonui.cpp b/architecture/httpdlib/src/json/jsonui.cpp
new file mode 100644
index 0000000..6a6b9fa
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonui.cpp
@@ -0,0 +1,55 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include "jsonui.h"
+#include "jsonfactory.h"
+
+//jsonui::jsonui(const char *name, const char* address, int port) 
+//					: fFactory(0) { fFactory = new httpdfaust::jsonfactory(name, address, port); }
+//jsonui::~jsonui() { delete fFactory; }
+
+//void jsonui::openFrameBox(const char* label)		{ fFactory->opengroup( "framebox", label); }
+//void jsonui::openTabBox(const char* label)			{ fFactory->opengroup( "tabbox", label); }
+//void jsonui::openHorizontalBox(const char* label)	{ fFactory->opengroup( "horizontalbox", label); }
+//void jsonui::openVerticalBox(const char* label)		{ fFactory->opengroup( "verticalbox", label); }
+//void jsonui::closeBox()								{ fFactory->closegroup(); }
+//
+//void jsonui::addButton(const char* label, float*)
+//					{ fFactory->addnode( "button", label); }
+//void jsonui::addToggleButton(const char* label, float*)
+//					{ fFactory->addnode( "togglebutton", label); }
+//void jsonui::addCheckButton(const char* label, float*)
+//					{ fFactory->addnode( "checkbutton", label); }
+//
+//void jsonui::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+//					{ fFactory->addnode( "verticalslider", label, init, min, max, step); }
+//void jsonui::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+//					{ fFactory->addnode( "horizontalslider", label, init, min, max, step); }
+//void jsonui::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+//					{ fFactory->addnode( "numentry", label, init, min, max, step); }
+
+//void jsonui::addNumDisplay(const char* label, float* zone, int precision) {}
+//void jsonui::addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) {}
+//void jsonui::addHorizontalBargraph(const char* label, float* zone, float min, float max) {}
+//void jsonui::addVerticalBargraph(const char* label, float* zone, float min, float max) {}
+
diff --git a/architecture/httpdlib/src/json/jsonui.h b/architecture/httpdlib/src/json/jsonui.h
new file mode 100644
index 0000000..bad3dd3
--- /dev/null
+++ b/architecture/httpdlib/src/json/jsonui.h
@@ -0,0 +1,81 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __jsonui__
+#define __jsonui__
+
+#include "jsonfactory.h"
+
+namespace httpdfaust
+{
+
+class jsonfactory;
+
+template <typename C> class jsonui
+{
+	jsonfactory* fFactory;
+	std::map<std::string, std::string>	fMeta;	// the current meta declarations
+
+	public:
+				 jsonui(const char *name, const char* address, int port) { fFactory = new jsonfactory(name, address, port); }
+		virtual ~jsonui()				{ delete fFactory; }
+
+		// -- widget's layouts
+		virtual void openTabBox(const char* label)					{ fFactory->opengroup("tgroup", label, fMeta); fMeta.clear();}
+		virtual void openHorizontalBox(const char* label)			{ fFactory->opengroup("hgroup", label, fMeta); fMeta.clear();}
+		virtual void openVerticalBox(const char* label)				{ fFactory->opengroup("vgroup", label, fMeta); fMeta.clear();}
+		virtual void closeBox()										{ fFactory->closegroup(); }
+
+		// -- active widgets
+		virtual void addButton(const char* label, C* zone)			{ fFactory->addnode<C>( "button", label, fMeta); fMeta.clear();}
+		virtual void addCheckButton(const char* label, C* zone)		{ fFactory->addnode<C>( "checkbox", label, fMeta); fMeta.clear();}
+		virtual void addVerticalSlider(const char* label, C* zone, C init, C min, C max, C step)
+							{ fFactory->addnode<C>( "vslider", label, init, min, max, step, fMeta); fMeta.clear();}
+		virtual void addHorizontalSlider(const char* label, C* zone, C init, C min, C max, C step)
+							{ fFactory->addnode<C>( "hslider", label, init, min, max, step, fMeta); fMeta.clear();}
+		virtual void addNumEntry(const char* label, C* zone, C init, C min, C max, C step)
+							{ fFactory->addnode<C>( "nentry", label, init, min, max, step, fMeta); fMeta.clear();}
+
+		// -- passive widgets
+		virtual void addHorizontalBargraph(const char* label, C* zone, C min, C max)		{ fFactory->addnode<C>( "hbargraph", label, min, max, fMeta); fMeta.clear();}
+		virtual void addVerticalBargraph(const char* label, C* zone, float min, float max)	{ fFactory->addnode<C>( "vbargraph", label, min, max, fMeta); fMeta.clear();}
+
+		// -- metadata declarations
+		virtual void declare(C* , const char* key, const char* val)		{ fMeta[key] = val; }
+
+		//--------------------------------------------
+		// additionnal methods (not part of UI)
+		//--------------------------------------------
+		void numInput( int n )								{ fFactory->root().setInputs(n); }
+		void numOutput( int n )								{ fFactory->root().setOutputs(n); }
+		void declare(const char* key, const char* val)		{ fFactory->root().declare(key, val);}
+
+		//--------------------------------------------
+		// and eventually how to get the json as a string
+		//--------------------------------------------
+		std::string json ()							{ return fFactory->root().json(); }
+};
+
+} //end namespace
+
+#endif
diff --git a/architecture/httpdlib/src/lib/deelx.h b/architecture/httpdlib/src/lib/deelx.h
new file mode 100644
index 0000000..b8494c6
--- /dev/null
+++ b/architecture/httpdlib/src/lib/deelx.h
@@ -0,0 +1,4182 @@
+// deelx.h
+//
+// DEELX Regular Expression Engine (v1.2)
+//
+// Copyright 2006 (c) RegExLab.com
+// All Rights Reserved.
+//
+// http://www.regexlab.com/deelx/
+//
+// Author: Ê·ÊÙΰ (sswater shi)
+// sswater at gmail.com
+//
+// $Revision: 1.1.2.26 $
+//
+
+#ifndef __DEELX_REGEXP__H__
+#define __DEELX_REGEXP__H__
+
+#ifndef WIN32
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
+
+#include <memory.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+
+//
+// Data Reference
+//
+template <class ELT> class CBufferRefT
+{
+public:
+	CBufferRefT(const ELT * pcsz, int length);
+	CBufferRefT(const ELT * pcsz);
+
+public:
+	int nCompare      (const ELT * pcsz) const;
+	int nCompareNoCase(const ELT * pcsz) const;
+	int  Compare      (const ELT * pcsz) const;
+	int  CompareNoCase(const ELT * pcsz) const;
+	int  Compare      (const CBufferRefT <ELT> &) const;
+	int  CompareNoCase(const CBufferRefT <ELT> &) const;
+
+	ELT At          (int nIndex, ELT def = 0) const;
+	ELT operator [] (int nIndex) const;
+
+	const ELT * GetBuffer() const;
+	int GetSize() const;
+
+public:
+	virtual ~CBufferRefT();
+
+// Content
+protected:
+	const ELT * m_pRef;
+	int         m_nSize;
+};
+
+//
+// Implemenation
+//
+template <class ELT> CBufferRefT <ELT> :: CBufferRefT(const ELT * pcsz, int length)
+{
+	m_pRef  = pcsz;
+	m_nSize = length;
+}
+
+template <class ELT> CBufferRefT <ELT> :: CBufferRefT(const ELT * pcsz)
+{
+	m_pRef  = pcsz;
+	m_nSize = 0;
+
+	if(pcsz != 0) while(m_pRef[m_nSize] != 0) m_nSize ++;
+}
+
+template <class ELT> int CBufferRefT <ELT> :: nCompare(const ELT * pcsz) const
+{
+	for(int i=0; i<m_nSize; i++)
+	{
+		if(m_pRef[i] != pcsz[i])
+			return m_pRef[i] - pcsz[i];
+	}
+
+	return 0;
+}
+
+template <class ELT> int CBufferRefT <ELT> :: nCompareNoCase(const ELT * pcsz) const
+{
+	for(int i=0; i<m_nSize; i++)
+	{
+		if(m_pRef[i] != pcsz[i])
+		{
+			if(toupper((int)m_pRef[i]) != toupper((int)pcsz[i]))
+				return m_pRef[i] - pcsz[i];
+		}
+	}
+
+	return 0;
+}
+
+template <class ELT> inline int CBufferRefT <ELT> :: Compare(const ELT * pcsz) const
+{
+	return nCompare(pcsz) ? 1 : (int)pcsz[m_nSize];
+}
+
+template <class ELT> inline int CBufferRefT <ELT> :: CompareNoCase(const ELT * pcsz) const
+{
+	return nCompareNoCase(pcsz) ? 1 : (int)pcsz[m_nSize];
+}
+
+template <class ELT> inline int CBufferRefT <ELT> :: Compare(const CBufferRefT <ELT> & cref) const
+{
+	return m_nSize == cref.m_nSize ? nCompare(cref.GetBuffer()) : 1;
+}
+
+template <class ELT> inline int CBufferRefT <ELT> :: CompareNoCase(const CBufferRefT <ELT> & cref) const
+{
+	return m_nSize == cref.m_nSize ? nCompareNoCase(cref.GetBuffer()) : 1;
+}
+
+template <class ELT> inline ELT CBufferRefT <ELT> :: At(int nIndex, ELT def) const
+{
+	return nIndex >= m_nSize ? def : m_pRef[nIndex];
+}
+
+template <class ELT> inline ELT CBufferRefT <ELT> :: operator [] (int nIndex) const
+{
+	return nIndex >= m_nSize ? 0 : m_pRef[nIndex];
+}
+
+template <class ELT> const ELT * CBufferRefT <ELT> :: GetBuffer() const
+{
+	static const ELT _def[] = {0}; return m_pRef ? m_pRef : _def;
+}
+
+template <class ELT> inline int CBufferRefT <ELT> :: GetSize() const
+{
+	return m_nSize;
+}
+
+template <class ELT> CBufferRefT <ELT> :: ~CBufferRefT()
+{
+}
+
+//
+// Data Buffer
+//
+template <class ELT> class CBufferT : public CBufferRefT <ELT>
+{
+public:
+	CBufferT(const ELT * pcsz, int length);
+	CBufferT(const ELT * pcsz);
+	CBufferT();
+
+public:
+	ELT & operator [] (int nIndex);
+	const ELT & operator [] (int nIndex) const;
+	void  Append(const ELT * pcsz, int length, int eol = 0);
+	void  Append(ELT el, int eol = 0);
+
+public:
+	void  Push(ELT   el);
+	int   Pop (ELT & el);
+	int   Peek(ELT & el) const;
+
+public:
+	const ELT * GetBuffer() const;
+	ELT * GetBuffer();
+	ELT * Detach();
+	void  Release();
+	void  Prepare(int index, int fill = 0);
+	void  Restore(int size);
+
+public:
+	virtual ~CBufferT();
+
+// Content
+protected:
+	ELT * m_pBuffer;
+	int   m_nMaxLength;
+};
+
+//
+// Implemenation
+//
+template <class ELT> CBufferT <ELT> :: CBufferT(const ELT * pcsz, int length) : CBufferRefT <ELT> (0, length)
+{
+	m_nMaxLength = CBufferRefT <ELT> :: m_nSize + 1;
+
+	CBufferRefT <ELT> :: m_pRef = m_pBuffer = new ELT[m_nMaxLength];
+	memcpy(m_pBuffer, pcsz, sizeof(ELT) * CBufferRefT <ELT> :: m_nSize);
+	m_pBuffer[CBufferRefT <ELT> :: m_nSize] = 0;
+}
+
+template <class ELT> CBufferT <ELT> :: CBufferT(const ELT * pcsz) : CBufferRefT <ELT> (pcsz)
+{
+	m_nMaxLength = CBufferRefT <ELT> :: m_nSize + 1;
+
+	CBufferRefT <ELT> :: m_pRef = m_pBuffer = new ELT[m_nMaxLength];
+	memcpy(m_pBuffer, pcsz, sizeof(ELT) * CBufferRefT <ELT> :: m_nSize);
+	m_pBuffer[CBufferRefT <ELT> :: m_nSize] = 0;
+}
+
+template <class ELT> CBufferT <ELT> :: CBufferT() : CBufferRefT <ELT> (0, 0)
+{
+	m_nMaxLength = 0;
+	m_pBuffer    = 0;
+}
+
+template <class ELT> inline ELT & CBufferT <ELT> :: operator [] (int nIndex)
+{
+	return m_pBuffer[nIndex];
+}
+
+template <class ELT> inline const ELT & CBufferT <ELT> :: operator [] (int nIndex) const
+{
+	return m_pBuffer[nIndex];
+}
+
+template <class ELT> void CBufferT <ELT> :: Append(const ELT * pcsz, int length, int eol)
+{
+	int nNewLength = m_nMaxLength;
+
+	// Check length
+	if(nNewLength < 8)
+		nNewLength = 8;
+
+	if(CBufferRefT <ELT> :: m_nSize + length + eol > nNewLength)
+		nNewLength *= 2;
+
+	if(CBufferRefT <ELT> :: m_nSize + length + eol > nNewLength)
+	{
+		nNewLength  = CBufferRefT <ELT> :: m_nSize + length + eol + 11;
+		nNewLength -= nNewLength % 8;
+	}
+
+	// Realloc
+	if(nNewLength > m_nMaxLength)
+	{
+		ELT * pNewBuffer = new ELT[nNewLength];
+
+		if(m_pBuffer != 0)
+		{
+			memcpy(pNewBuffer, m_pBuffer, sizeof(ELT) * CBufferRefT <ELT> :: m_nSize);
+			delete [] m_pBuffer;
+		}
+
+		CBufferRefT <ELT> :: m_pRef = m_pBuffer = pNewBuffer;
+		m_nMaxLength = nNewLength;
+	}
+
+	// Append
+	memcpy(m_pBuffer + CBufferRefT <ELT> :: m_nSize, pcsz, sizeof(ELT) * length);
+	CBufferRefT <ELT> :: m_nSize += length;
+
+	if(eol > 0) m_pBuffer[CBufferRefT <ELT> :: m_nSize] = 0;
+}
+
+template <class ELT> inline void CBufferT <ELT> :: Append(ELT el, int eol)
+{
+	Append(&el, 1, eol);
+}
+
+template <class ELT> void CBufferT <ELT> :: Push(ELT el)
+{
+	// Realloc
+	if(CBufferRefT <ELT> :: m_nSize >= m_nMaxLength)
+	{
+		int nNewLength = m_nMaxLength * 2;
+		if( nNewLength < 8 ) nNewLength = 8;
+
+		ELT * pNewBuffer = new ELT[nNewLength];
+
+		if(m_pBuffer != 0)
+		{
+			memcpy(pNewBuffer, m_pBuffer, sizeof(ELT) * CBufferRefT <ELT> :: m_nSize);
+			delete [] m_pBuffer;
+		}
+
+		CBufferRefT <ELT> :: m_pRef = m_pBuffer = pNewBuffer;
+		m_nMaxLength = nNewLength;
+	}
+
+	// Append
+	m_pBuffer[CBufferRefT <ELT> :: m_nSize++] = el;
+}
+
+template <class ELT> inline int CBufferT <ELT> :: Pop(ELT & el)
+{
+	if(CBufferRefT <ELT> :: m_nSize > 0)
+	{
+		el = m_pBuffer[--CBufferRefT <ELT> :: m_nSize];
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+template <class ELT> inline int CBufferT <ELT> :: Peek(ELT & el) const
+{
+	if(CBufferRefT <ELT> :: m_nSize > 0)
+	{
+		el = m_pBuffer[CBufferRefT <ELT> :: m_nSize - 1];
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+template <class ELT> const ELT * CBufferT <ELT> :: GetBuffer() const
+{
+	static const ELT _def[] = {0}; return m_pBuffer ? m_pBuffer : _def;
+}
+
+template <class ELT> ELT * CBufferT <ELT> :: GetBuffer()
+{
+	static const ELT _def[] = {0}; return m_pBuffer ? m_pBuffer : (ELT *)_def;
+}
+
+template <class ELT> ELT * CBufferT <ELT> :: Detach()
+{
+	ELT * pBuffer = m_pBuffer;
+
+	CBufferRefT <ELT> :: m_pRef  = m_pBuffer    = 0;
+	CBufferRefT <ELT> :: m_nSize = m_nMaxLength = 0;
+
+	return pBuffer;
+}
+
+template <class ELT> void CBufferT <ELT> :: Release()
+{
+	ELT * pBuffer = Detach();
+
+	if(pBuffer != 0) delete [] pBuffer;
+}
+
+template <class ELT> void CBufferT <ELT> :: Prepare(int index, int fill)
+{
+	int nNewSize = index + 1;
+
+	// Realloc
+	if(nNewSize > m_nMaxLength)
+	{
+		int nNewLength = m_nMaxLength;
+
+		if( nNewLength < 8 )
+			nNewLength = 8;
+
+		if( nNewSize > nNewLength )
+			nNewLength *= 2;
+
+		if( nNewSize > nNewLength )
+		{
+			nNewLength  = nNewSize + 11;
+			nNewLength -= nNewLength % 8;
+		}
+
+		ELT * pNewBuffer = new ELT[nNewLength];
+
+		if(m_pBuffer != 0)
+		{
+			memcpy(pNewBuffer, m_pBuffer, sizeof(ELT) * CBufferRefT <ELT> :: m_nSize);
+			delete [] m_pBuffer;
+		}
+
+		CBufferRefT <ELT> :: m_pRef = m_pBuffer = pNewBuffer;
+		m_nMaxLength = nNewLength;
+	}
+
+	// size
+	if( CBufferRefT <ELT> :: m_nSize < nNewSize )
+	{
+		memset(m_pBuffer + CBufferRefT <ELT> :: m_nSize, fill, sizeof(ELT) * (nNewSize - CBufferRefT <ELT> :: m_nSize));
+		CBufferRefT <ELT> :: m_nSize = nNewSize;
+	}
+}
+
+template <class ELT> inline void CBufferT <ELT> :: Restore(int size)
+{
+	CBufferRefT <ELT> :: m_nSize = size;
+}
+
+template <class ELT> CBufferT <ELT> :: ~CBufferT()
+{
+	if(m_pBuffer != 0) delete [] m_pBuffer;
+}
+
+//
+// Context
+//
+class CContext
+{
+public:
+	CBufferT <int> m_stack;
+	CBufferT <int> m_capturestack, m_captureindex;
+
+public:
+	int    m_nCurrentPos;
+	int    m_nBeginPos;
+	int    m_nLastBeginPos;
+	int    m_nParenZindex;
+
+	void * m_pMatchString;
+	int    m_pMatchStringLength;
+};
+
+//
+// Interface
+//
+class ElxInterface
+{
+public:
+	virtual int Match    (CContext * pContext) const = 0;
+	virtual int MatchNext(CContext * pContext) const = 0;
+
+public:
+	virtual ~ElxInterface() {};
+};
+
+//
+// Alternative
+//
+template <int x> class CAlternativeElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CAlternativeElxT();
+
+public:
+	CBufferT <ElxInterface *> m_elxlist;
+};
+
+typedef CAlternativeElxT <0> CAlternativeElx;
+
+//
+// Assert
+//
+template <int x> class CAssertElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CAssertElxT(ElxInterface * pelx, int byes = 1);
+
+public:
+	ElxInterface * m_pelx;
+	int m_byes;
+};
+
+typedef CAssertElxT <0> CAssertElx;
+
+//
+// Back reference elx
+//
+template <class CHART> class CBackrefElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CBackrefElxT(int nnumber, int brightleft, int bignorecase);
+
+public:
+	int m_nnumber;
+	int m_brightleft;
+	int m_bignorecase;
+
+	CBufferT <CHART> m_szNamed;
+};
+
+//
+// Implementation
+//
+template <class CHART> CBackrefElxT <CHART> :: CBackrefElxT(int nnumber, int brightleft, int bignorecase)
+{
+	m_nnumber     = nnumber;
+	m_brightleft  = brightleft;
+	m_bignorecase = bignorecase;
+}
+
+template <class CHART> int CBackrefElxT <CHART> :: Match(CContext * pContext) const
+{
+	// check number, for named
+	if( m_nnumber < 0 || m_nnumber >= pContext->m_captureindex.GetSize() ) return 0;
+
+	int index = pContext->m_captureindex[m_nnumber];
+	if( index < 0 ) return 0;
+
+	// check enclosed
+	int pos1 = pContext->m_capturestack[index + 1];
+	int pos2 = pContext->m_capturestack[index + 2];
+
+	if( pos2 < 0 ) pos2 = pContext->m_nCurrentPos;
+
+	// info
+	int lpos = pos1 < pos2 ? pos1 : pos2;
+	int rpos = pos1 < pos2 ? pos2 : pos1;
+	int slen = rpos - lpos;
+
+	const CHART * pcsz = (const CHART *)pContext->m_pMatchString;
+	int npos = pContext->m_nCurrentPos;
+	int tlen = pContext->m_pMatchStringLength;
+
+	// compare
+	int bsucc;
+	CBufferRefT <CHART> refstr(pcsz + lpos, slen);
+
+	if( m_brightleft )
+	{
+		if(npos < slen)
+			return 0;
+
+		if(m_bignorecase)
+			bsucc = ! refstr.nCompareNoCase(pcsz + (npos - slen));
+		else
+			bsucc = ! refstr.nCompare      (pcsz + (npos - slen));
+
+		if( bsucc )
+		{
+			pContext->m_stack.Push(npos);
+			pContext->m_nCurrentPos -= slen;
+		}
+	}
+	else
+	{
+		if(npos + slen > tlen)
+			return 0;
+
+		if(m_bignorecase)
+			bsucc = ! refstr.nCompareNoCase(pcsz + npos);
+		else
+			bsucc = ! refstr.nCompare      (pcsz + npos);
+
+		if( bsucc )
+		{
+			pContext->m_stack.Push(npos);
+			pContext->m_nCurrentPos += slen;
+		}
+	}
+
+	return bsucc;
+}
+
+template <class CHART> int CBackrefElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	int npos = 0;
+
+	pContext->m_stack.Pop(npos);
+	pContext->m_nCurrentPos = npos;
+
+	return 0;
+}
+
+// RCHART
+#ifndef RCHART
+	#define RCHART(ch) ((CHART)ch)
+#endif
+
+// BOUNDARY_TYPE
+enum BOUNDARY_TYPE
+{
+	BOUNDARY_FILE_BEGIN, // begin of whole text
+	BOUNDARY_FILE_END  , // end of whole text
+	BOUNDARY_LINE_BEGIN, // begin of line
+	BOUNDARY_LINE_END  , // end of line
+	BOUNDARY_WORD_BEGIN, // begin of word
+	BOUNDARY_WORD_END  , // end of word
+	BOUNDARY_WORD_EDGE ,
+};
+
+//
+// Boundary Elx
+//
+template <class CHART> class CBoundaryElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CBoundaryElxT(int ntype, int byes = 1);
+
+protected:
+	static int IsWordChar(CHART ch);
+
+public:
+	int m_ntype;
+	int m_byes;
+};
+
+//
+// Implementation
+//
+template <class CHART> CBoundaryElxT <CHART> :: CBoundaryElxT(int ntype, int byes)
+{
+	m_ntype = ntype;
+	m_byes  = byes;
+}
+
+template <class CHART> int CBoundaryElxT <CHART> :: Match(CContext * pContext) const
+{
+	const CHART * pcsz  = (const CHART *)pContext->m_pMatchString;
+	int npos = pContext->m_nCurrentPos;
+	int tlen = pContext->m_pMatchStringLength;
+
+	CHART chL = npos > 0    ? pcsz[npos - 1] : 0;
+	CHART chR = npos < tlen ? pcsz[npos    ] : 0;
+
+	int bsucc = 0;
+
+	switch(m_ntype)
+	{
+	case BOUNDARY_FILE_BEGIN:
+		bsucc = (npos <= 0);
+		break;
+
+	case BOUNDARY_FILE_END:
+		bsucc = (npos >= tlen);
+		break;
+
+	case BOUNDARY_LINE_BEGIN:
+		bsucc = (npos <= 0   ) || (chL == RCHART('\n')) || ((chL == RCHART('\r')) && (chR != RCHART('\n')));
+		break;
+
+	case BOUNDARY_LINE_END:
+		bsucc = (npos >= tlen) || (chR == RCHART('\r')) || ((chR == RCHART('\n')) && (chL != RCHART('\r')));
+		break;
+
+	case BOUNDARY_WORD_BEGIN:
+		bsucc = ! IsWordChar(chL) &&   IsWordChar(chR);
+		break;
+
+	case BOUNDARY_WORD_END:
+		bsucc =   IsWordChar(chL) && ! IsWordChar(chR);
+		break;
+
+	case BOUNDARY_WORD_EDGE:
+		bsucc =   IsWordChar(chL) ?  ! IsWordChar(chR) : IsWordChar(chR);
+		break;
+	}
+
+	return bsucc;
+}
+
+template <class CHART> int CBoundaryElxT <CHART> :: MatchNext(CContext *) const
+{
+	return 0;
+}
+
+template <class CHART> inline int CBoundaryElxT <CHART> :: IsWordChar(CHART ch)
+{
+	return (ch >= RCHART('A') && ch <= RCHART('Z')) || (ch >= RCHART('a') && ch <= RCHART('z')) || (ch >= RCHART('0') && ch <= RCHART('9')) || (ch == RCHART('_'));
+}
+
+//
+// Bracket
+//
+template <class CHART> class CBracketElxT : public ElxInterface  
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CBracketElxT(int nnumber, int bright);
+
+public:
+	int m_nnumber;
+	int m_bright;
+
+	CBufferT <CHART> m_szNamed;
+};
+
+template <class CHART> CBracketElxT <CHART> :: CBracketElxT(int nnumber, int bright)
+{
+	m_nnumber = nnumber;
+	m_bright  = bright;
+}
+
+template <class CHART> int CBracketElxT <CHART> :: Match(CContext * pContext) const
+{
+	// check, for named
+	if(m_nnumber < 0) return 0;
+
+	if( ! m_bright )
+	{
+		pContext->m_captureindex.Prepare(m_nnumber, -1);
+		int index = pContext->m_captureindex[m_nnumber];
+
+		// check
+		if(index > 0 && index < pContext->m_capturestack.GetSize() && pContext->m_capturestack[index+2] < 0)
+		{
+			pContext->m_capturestack[index+3] --;
+			return 1;
+		}
+
+		// save
+		pContext->m_captureindex[m_nnumber] = pContext->m_capturestack.GetSize();
+
+		pContext->m_capturestack.Push(m_nnumber);
+		pContext->m_capturestack.Push(pContext->m_nCurrentPos);
+		pContext->m_capturestack.Push(-1);
+		pContext->m_capturestack.Push( 0); // z-index
+	}
+	else
+	{
+		// check
+		int index = pContext->m_captureindex[m_nnumber];
+
+		if(pContext->m_capturestack[index + 3] < 0)
+		{
+			pContext->m_capturestack[index + 3] ++;
+			return 1;
+		}
+
+		// save
+		pContext->m_capturestack[index + 2] = pContext->m_nCurrentPos;
+		pContext->m_capturestack[index + 3] = pContext->m_nParenZindex ++;
+	}
+
+	return 1;
+}
+
+template <class CHART> int CBracketElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	int index = pContext->m_captureindex[m_nnumber];
+
+	if( ! m_bright )
+	{
+		if(pContext->m_capturestack[index + 3] < 0)
+		{
+			pContext->m_capturestack[index + 3] ++;
+			return 0;
+		}
+
+		pContext->m_capturestack.Restore(pContext->m_capturestack.GetSize() - 4);
+
+		// to find
+		index = pContext->m_capturestack.GetSize() - 4;
+		while(index >= 0 && pContext->m_capturestack[index] != m_nnumber) index -= 4;
+
+		// new index
+		pContext->m_captureindex[m_nnumber] = index;
+	}
+	else
+	{
+		if(pContext->m_capturestack[index + 3] < 0)
+		{
+			pContext->m_capturestack[index + 3] --;
+			return 0;
+		}
+
+		pContext->m_capturestack[index + 2] = -1;
+		pContext->m_capturestack[index + 3] =  0;
+	}
+
+	return 0;
+}
+
+//
+// Deletage
+//
+template <class CHART> class CDelegateElxT : public ElxInterface  
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CDelegateElxT(int ndata = 0);
+
+public:
+	ElxInterface * m_pelx;
+	int m_ndata; // +0 : recursive to
+	             // -3 : named recursive
+
+	CBufferT <CHART> m_szNamed;
+};
+
+template <class CHART> CDelegateElxT <CHART> :: CDelegateElxT(int ndata)
+{
+	m_pelx  = 0;
+	m_ndata = ndata;
+}
+
+template <class CHART> int CDelegateElxT <CHART> :: Match(CContext * pContext) const
+{
+	if(m_pelx != 0)
+		return m_pelx->Match(pContext);
+	else
+		return 1;
+}
+
+template <class CHART> int CDelegateElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	if(m_pelx != 0)
+		return m_pelx->MatchNext(pContext);
+	else
+		return 0;
+}
+
+//
+// Empty
+//
+template <int x> class CEmptyElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CEmptyElxT();
+};
+
+typedef CEmptyElxT <0> CEmptyElx;
+
+//
+// Global
+//
+template <int x> class CGlobalElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CGlobalElxT();
+};
+
+typedef CGlobalElxT <0> CGlobalElx;
+
+//
+// Repeat
+//
+template <int x> class CRepeatElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CRepeatElxT(ElxInterface * pelx, int ntimes);
+
+protected:
+	int MatchFixed    (CContext * pContext) const;
+	int MatchNextFixed(CContext * pContext) const;
+
+public:
+	ElxInterface * m_pelx;
+	int m_nfixed;
+};
+
+typedef CRepeatElxT <0> CRepeatElx;
+
+//
+// Greedy
+//
+template <int x> class CGreedyElxT : public CRepeatElxT <x>
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CGreedyElxT(ElxInterface * pelx, int nmin = 0, int nmax = INT_MAX);
+
+protected:
+	int MatchVart    (CContext * pContext) const;
+	int MatchNextVart(CContext * pContext) const;
+
+public:
+	int m_nvart;
+};
+
+typedef CGreedyElxT <0> CGreedyElx;
+
+//
+// Independent
+//
+template <int x> class CIndependentElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CIndependentElxT(ElxInterface * pelx);
+
+public:
+	ElxInterface * m_pelx;
+};
+
+typedef CIndependentElxT <0> CIndependentElx;
+
+//
+// List
+//
+template <int x> class CListElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CListElxT(int brightleft);
+
+public:
+	CBufferT <ElxInterface *> m_elxlist;
+	int m_brightleft;
+};
+
+typedef CListElxT <0> CListElx;
+
+//
+// Posix Elx
+//
+template <class CHART> class CPosixElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CPosixElxT(const char * posix, int brightleft);
+
+protected:
+	static int misblank(int c);
+
+public:
+	int (*m_posixfun)(int);
+	int m_brightleft;
+	int m_byes;
+};
+
+//
+// Implementation
+//
+template <class CHART> CPosixElxT <CHART> :: CPosixElxT(const char * posix, int brightleft)
+{
+	m_brightleft = brightleft;
+
+	if(posix[1] == '^')
+	{
+		m_byes = 0;
+		posix += 2;
+	}
+	else
+	{
+		m_byes = 1;
+		posix += 1;
+	}
+
+	if     (!strncmp(posix, "alnum:", 6)) m_posixfun = isalnum ;
+	else if(!strncmp(posix, "alpha:", 6)) m_posixfun = isalpha ;
+	else if(!strncmp(posix, "ascii:", 6)) m_posixfun = isascii ;
+	else if(!strncmp(posix, "cntrl:", 6)) m_posixfun = iscntrl ;
+	else if(!strncmp(posix, "digit:", 6)) m_posixfun = isdigit ;
+	else if(!strncmp(posix, "graph:", 6)) m_posixfun = isgraph ;
+	else if(!strncmp(posix, "lower:", 6)) m_posixfun = islower ;
+	else if(!strncmp(posix, "print:", 6)) m_posixfun = isprint ;
+	else if(!strncmp(posix, "punct:", 6)) m_posixfun = ispunct ;
+	else if(!strncmp(posix, "space:", 6)) m_posixfun = isspace ;
+	else if(!strncmp(posix, "upper:", 6)) m_posixfun = isupper ;
+	else if(!strncmp(posix, "xdigit:",7)) m_posixfun = isxdigit;
+	else if(!strncmp(posix, "blank:", 6)) m_posixfun = misblank;
+	else                                  m_posixfun = 0       ;
+}
+
+template <class CHART> int CPosixElxT <CHART> :: misblank(int c)
+{
+	return c == 0x20 || c == '\t';
+}
+
+template <class CHART> int CPosixElxT <CHART> :: Match(CContext * pContext) const
+{
+	if(m_posixfun == 0) return 0;
+
+	int tlen = pContext->m_pMatchStringLength;
+	int npos = pContext->m_nCurrentPos;
+
+	// check
+	int at   = m_brightleft ? npos - 1 : npos;
+	if( at < 0 || at >= tlen )
+		return 0;
+
+	CHART ch = ((const CHART *)pContext->m_pMatchString)[at];
+
+	int bsucc = (*m_posixfun)(ch);
+
+	if( ! m_byes )
+		bsucc = ! bsucc;
+
+	if( bsucc )
+		pContext->m_nCurrentPos += m_brightleft ? -1 : 1;
+
+	return bsucc;
+}
+
+template <class CHART> int CPosixElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	pContext->m_nCurrentPos -= m_brightleft ? -1 : 1;
+	return 0;
+}
+
+//
+// Possessive
+//
+template <int x> class CPossessiveElxT : public CGreedyElxT <x>
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CPossessiveElxT(ElxInterface * pelx, int nmin = 0, int nmax = INT_MAX);
+};
+
+typedef CPossessiveElxT <0> CPossessiveElx;
+
+//
+// Range Elx
+//
+template <class CHART> class CRangeElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CRangeElxT(int brightleft, int byes);
+
+public:
+	CBufferT <CHART> m_ranges;
+	CBufferT <CHART> m_chars;
+	CBufferT <ElxInterface *> m_embeds;
+
+public:
+	int m_brightleft;
+	int m_byes;
+};
+
+//
+// Implementation
+//
+template <class CHART> CRangeElxT <CHART> :: CRangeElxT(int brightleft, int byes)
+{
+	m_brightleft = brightleft;
+	m_byes       = byes;
+}
+
+template <class CHART> int CRangeElxT <CHART> :: Match(CContext * pContext) const
+{
+	int tlen = pContext->m_pMatchStringLength;
+	int npos = pContext->m_nCurrentPos;
+
+	// check
+	int at   = m_brightleft ? npos - 1 : npos;
+	if( at < 0 || at >= tlen )
+		return 0;
+
+	CHART ch = ((const CHART *)pContext->m_pMatchString)[at];
+	int bsucc = 0, i;
+
+	// compare
+	for(i=0; !bsucc && i<m_ranges.GetSize(); i+=2)
+	{
+		if(m_ranges[i] <= ch && ch <= m_ranges[i+1]) bsucc = 1;
+	}
+
+	for(i=0; !bsucc && i<m_chars.GetSize(); i++)
+	{
+		if(m_chars[i] == ch) bsucc = 1;
+	}
+
+	for(i=0; !bsucc && i<m_embeds.GetSize(); i++)
+	{
+		if(m_embeds[i]->Match(pContext))
+		{
+			pContext->m_nCurrentPos = npos;
+			bsucc = 1;
+		}
+	}
+
+	if( ! m_byes )
+		bsucc = ! bsucc;
+
+	if( bsucc )
+		pContext->m_nCurrentPos += m_brightleft ? -1 : 1;
+
+	return bsucc;
+}
+
+template <class CHART> int CRangeElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	pContext->m_nCurrentPos -= m_brightleft ? -1 : 1;
+	return 0;
+}
+
+//
+// Reluctant
+//
+template <int x> class CReluctantElxT : public CRepeatElxT <x>
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CReluctantElxT(ElxInterface * pelx, int nmin = 0, int nmax = INT_MAX);
+
+protected:
+	int MatchVart    (CContext * pContext) const;
+	int MatchNextVart(CContext * pContext) const;
+
+public:
+	int m_nvart;
+};
+
+typedef CReluctantElxT <0> CReluctantElx;
+
+//
+// String Elx
+//
+template <class CHART> class CStringElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CStringElxT(const CHART * fixed, int nlength, int brightleft, int bignorecase);
+
+public:
+	CBufferT <CHART> m_szPattern;
+	int m_brightleft;
+	int m_bignorecase;
+};
+
+//
+// Implementation
+//
+template <class CHART> CStringElxT <CHART> :: CStringElxT(const CHART * fixed, int nlength, int brightleft, int bignorecase) : m_szPattern(fixed, nlength)
+{
+	m_brightleft  = brightleft;
+	m_bignorecase = bignorecase;
+}
+
+template <class CHART> int CStringElxT <CHART> :: Match(CContext * pContext) const
+{
+	const CHART * pcsz  = (const CHART *)pContext->m_pMatchString;
+	int npos = pContext->m_nCurrentPos;
+	int tlen = pContext->m_pMatchStringLength;
+	int slen = m_szPattern.GetSize();
+
+	int bsucc;
+
+	if(m_brightleft)
+	{
+		if(npos < slen)
+			return 0;
+
+		if(m_bignorecase)
+			bsucc = ! m_szPattern.nCompareNoCase(pcsz + (npos - slen));
+		else
+			bsucc = ! m_szPattern.nCompare      (pcsz + (npos - slen));
+
+		if( bsucc )
+			pContext->m_nCurrentPos -= slen;
+	}
+	else
+	{
+		if(npos + slen > tlen)
+			return 0;
+
+		if(m_bignorecase)
+			bsucc = ! m_szPattern.nCompareNoCase(pcsz + npos);
+		else
+			bsucc = ! m_szPattern.nCompare      (pcsz + npos);
+
+		if( bsucc )
+			pContext->m_nCurrentPos += slen;
+	}
+
+	return bsucc;
+}
+
+template <class CHART> int CStringElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	int slen = m_szPattern.GetSize();
+
+	if(m_brightleft)
+		pContext->m_nCurrentPos += slen;
+	else
+		pContext->m_nCurrentPos -= slen;
+
+	return 0;
+}
+
+//
+// CConditionElx
+//
+template <class CHART> class CConditionElxT : public ElxInterface
+{
+public:
+	int Match    (CContext * pContext) const;
+	int MatchNext(CContext * pContext) const;
+
+public:
+	CConditionElxT();
+
+public:
+	// backref condition
+	int m_nnumber;
+	CBufferT <CHART> m_szNamed;
+
+	// elx condition
+	ElxInterface * m_pelxask;
+
+	// selection
+	ElxInterface * m_pelxyes, * m_pelxno;
+};
+
+template <class CHART> CConditionElxT <CHART> :: CConditionElxT()
+{
+	m_nnumber = -1;
+}
+
+template <class CHART> int CConditionElxT <CHART> :: Match(CContext * pContext) const
+{
+	// status
+	int nbegin = pContext->m_nCurrentPos;
+	int nsize  = pContext->m_stack.GetSize();
+	int ncsize = pContext->m_capturestack.GetSize();
+
+	// condition result
+	int condition_yes = 0;
+
+	// backref type
+	if( m_nnumber >= 0 )
+	{
+		do
+		{
+			if(m_nnumber >= pContext->m_captureindex.GetSize()) break;
+
+			int index = pContext->m_captureindex[m_nnumber];
+			if( index < 0) break;
+
+			// else valid
+			condition_yes = 1;
+		}
+		while(0);
+	}
+	else
+	{
+		if( m_pelxask == 0 )
+			condition_yes = 1;
+		else
+			condition_yes = m_pelxask->Match(pContext);
+
+		pContext->m_stack.Restore(nsize);
+		pContext->m_nCurrentPos = nbegin;
+	}
+
+	// elx result
+	int bsucc;
+	if( condition_yes )
+		bsucc = m_pelxyes == 0 ? 1 : m_pelxyes->Match(pContext);
+	else
+		bsucc = m_pelxno  == 0 ? 1 : m_pelxno ->Match(pContext);
+
+	if( bsucc )
+	{
+		pContext->m_stack.Push(ncsize);
+		pContext->m_stack.Push(condition_yes);
+	}
+	else
+	{
+		pContext->m_capturestack.Restore(ncsize);
+	}
+
+	return bsucc;
+}
+
+template <class CHART> int CConditionElxT <CHART> :: MatchNext(CContext * pContext) const
+{
+	// pop
+	int ncsize, condition_yes;
+
+	pContext->m_stack.Pop(condition_yes);
+	pContext->m_stack.Pop(ncsize);
+
+	// elx result
+	int bsucc;
+	if( condition_yes )
+		bsucc = m_pelxyes == 0 ? 0 : m_pelxyes->MatchNext(pContext);
+	else
+		bsucc = m_pelxno  == 0 ? 0 : m_pelxno ->MatchNext(pContext);
+
+	if( bsucc )
+	{
+		pContext->m_stack.Push(ncsize);
+		pContext->m_stack.Push(condition_yes);
+	}
+	else
+	{
+		pContext->m_capturestack.Restore(ncsize);
+	}
+
+	return bsucc;
+}
+
+//
+// MatchResult
+//
+template <int x> class MatchResultT
+{
+public:
+	int IsMatched() const;
+
+public:
+	int GetStart() const;
+	int GetEnd  () const;
+
+public:
+	int MaxGroupNumber() const;
+	int GetGroupStart(int nGroupNumber) const;
+	int GetGroupEnd  (int nGroupNumber) const;
+
+public:
+	MatchResultT(CContext * pContext, int nMaxNumber = -1);
+	MatchResultT <x> & operator = (const MatchResultT <x> &);
+	inline operator int() const { return IsMatched(); }
+
+public:
+	CBufferT <int> m_result;
+};
+
+typedef MatchResultT <0> MatchResult;
+
+// Stocked Elx IDs
+enum STOCKELX_ID_DEFINES
+{
+	STOCKELX_EMPTY = 0,
+
+	///////////////////////
+
+	STOCKELX_DOT_ALL,
+	STOCKELX_DOT_NOT_ALL,
+
+	STOCKELX_WORD,
+	STOCKELX_WORD_NOT,
+
+	STOCKELX_SPACE,
+	STOCKELX_SPACE_NOT,
+
+	STOCKELX_DIGITAL,
+	STOCKELX_DIGITAL_NOT,
+
+	//////////////////////
+
+	STOCKELX_DOT_ALL_RIGHTLEFT,
+	STOCKELX_DOT_NOT_ALL_RIGHTLEFT,
+
+	STOCKELX_WORD_RIGHTLEFT,
+	STOCKELX_WORD_RIGHTLEFT_NOT,
+
+	STOCKELX_SPACE_RIGHTLEFT,
+	STOCKELX_SPACE_RIGHTLEFT_NOT,
+
+	STOCKELX_DIGITAL_RIGHTLEFT,
+	STOCKELX_DIGITAL_RIGHTLEFT_NOT,
+
+	/////////////////////
+
+	STOCKELX_COUNT
+};
+
+// REGEX_FLAGS
+#ifndef _REGEX_FLAGS_DEFINED
+	enum REGEX_FLAGS
+	{
+		NO_FLAG        = 0,
+		SINGLELINE     = 0x01,
+		MULTILINE      = 0x02,
+		GLOBAL         = 0x04,
+		IGNORECASE     = 0x08,
+		RIGHTTOLEFT    = 0x10,
+		EXTENDED       = 0x20,
+	};
+	#define _REGEX_FLAGS_DEFINED
+#endif
+
+//
+// Builder T
+//
+template <class CHART> class CBuilderT
+{
+public:
+	typedef CDelegateElxT  <CHART> CDelegateElx;
+	typedef CBracketElxT   <CHART> CBracketElx;
+	typedef CBackrefElxT   <CHART> CBackrefElx;
+	typedef CConditionElxT <CHART> CConditionElx;
+
+// Methods
+public:
+	ElxInterface * Build(const CBufferRefT <CHART> & pattern, int flags);
+	int GetNamedNumber(const CBufferRefT <CHART> & named) const;
+	void Clear();
+
+public:
+	 CBuilderT();
+	~CBuilderT();
+
+// Public Attributes
+public:
+	ElxInterface * m_pTopElx;
+	int            m_nFlags;
+	int            m_nMaxNumber;
+	int            m_nNextNamed;
+	int            m_nGroupCount;
+
+	CBufferT <ElxInterface  *> m_objlist;
+	CBufferT <ElxInterface  *> m_grouplist;
+	CBufferT <CDelegateElx  *> m_recursivelist;
+	CBufferT <CListElx      *> m_namedlist;
+	CBufferT <CBackrefElx   *> m_namedbackreflist;
+	CBufferT <CConditionElx *> m_namedconditionlist;
+
+// CHART_INFO
+protected:
+	struct CHART_INFO
+	{
+	public:
+		CHART ch;
+		int   type;
+		int   pos;
+		int   len;
+
+	public:
+		CHART_INFO(CHART c, int t, int p = 0, int l = 0) { ch = c; type = t; pos = p; len = l;    }
+		inline int operator == (const CHART_INFO & ci)   { return ch == ci.ch && type == ci.type; }
+		inline int operator != (const CHART_INFO & ci)   { return ! operator == (ci);             }
+	};
+
+protected:
+	static unsigned int Hex2Int(const CHART * pcsz, int length, int & used);
+	static int ReadDec(char * & str, unsigned int & dec);
+	void MoveNext();
+	int  GetNext2();
+
+	ElxInterface * BuildAlternative(int vaflags);
+	ElxInterface * BuildList       (int & flags);
+	ElxInterface * BuildRepeat     (int & flags);
+	ElxInterface * BuildSimple     (int & flags);
+	ElxInterface * BuildCharset    (int & flags);
+	ElxInterface * BuildRecursive  (int & flags);
+	ElxInterface * BuildBoundary   (int & flags);
+	ElxInterface * BuildBackref    (int & flags);
+
+	ElxInterface * GetStockElx     (int nStockId);
+	ElxInterface * Keep(ElxInterface * pElx);
+
+// Private Attributes
+protected:
+	CBufferRefT <CHART> m_pattern;
+	CHART_INFO prev, curr, next, nex2;
+	int m_nNextPos;
+	int m_nCharsetDepth;
+	int m_bQuoted;
+	int (*m_quote_fun)(int);
+
+	ElxInterface * m_pStockElxs[STOCKELX_COUNT];
+};
+
+//
+// Implementation
+//
+template <class CHART> CBuilderT <CHART> :: CBuilderT() : m_pattern(0, 0), prev(0, 0), curr(0, 0), next(0, 0), nex2(0, 0)
+{
+	Clear();
+}
+
+template <class CHART> CBuilderT <CHART> :: ~CBuilderT()
+{
+	Clear();
+}
+
+template <class CHART> int CBuilderT <CHART> :: GetNamedNumber(const CBufferRefT <CHART> & named) const
+{
+	for(int i=0; i<m_namedlist.GetSize(); i++)
+	{
+		if( ! ((CBracketElx *)m_namedlist[i]->m_elxlist[0])->m_szNamed.CompareNoCase(named) )
+			return ((CBracketElx *)m_namedlist[i]->m_elxlist[0])->m_nnumber;
+	}
+
+	return -3;
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: Build(const CBufferRefT <CHART> & pattern, int flags)
+{
+	// init
+	m_pattern       = pattern;
+	m_nNextPos      = 0;
+	m_nCharsetDepth = 0;
+	m_nMaxNumber    = 0;
+	m_nNextNamed    = 0;
+	m_nFlags        = flags;
+	m_bQuoted       = 0;
+	m_quote_fun     = 0;
+
+	m_grouplist         .Restore(0);
+	m_recursivelist     .Restore(0);
+	m_namedlist         .Restore(0);
+	m_namedbackreflist  .Restore(0);
+	m_namedconditionlist.Restore(0);
+
+	int i;
+	for(i=0; i<3; i++) MoveNext();
+
+	// build
+	m_pTopElx = BuildAlternative(flags);
+
+	// group 0
+	m_grouplist.Prepare(0);
+	m_grouplist[0] = m_pTopElx;
+
+	// append named to unnamed
+	m_nGroupCount = m_grouplist.GetSize();
+
+	m_grouplist.Prepare(m_nMaxNumber + m_namedlist.GetSize());
+
+	for(i=0; i<m_namedlist.GetSize(); i++)
+	{
+		CBracketElx * pleft  = (CBracketElx *)m_namedlist[i]->m_elxlist[0];
+		CBracketElx * pright = (CBracketElx *)m_namedlist[i]->m_elxlist[2];
+
+		// append
+		m_grouplist[m_nGroupCount ++] = m_namedlist[i];
+
+		if( pleft->m_nnumber > 0 )
+			continue;
+
+		// same name
+		int find_same_name = GetNamedNumber(pleft->m_szNamed);
+		if( find_same_name >= 0 )
+		{
+			pleft ->m_nnumber = find_same_name;
+			pright->m_nnumber = find_same_name;
+		}
+		else
+		{
+			m_nMaxNumber ++;
+
+			pleft ->m_nnumber = m_nMaxNumber;
+			pright->m_nnumber = m_nMaxNumber;
+		}
+	}
+
+	for(i=1; i<m_nGroupCount; i++)
+	{
+		CBracketElx * pleft = (CBracketElx *)((CListElx*)m_grouplist[i])->m_elxlist[0];
+
+		if( pleft->m_nnumber > m_nMaxNumber )
+			m_nMaxNumber = pleft->m_nnumber;
+	}
+
+	// connect recursive
+	for(i=0; i<m_recursivelist.GetSize(); i++)
+	{
+		if( m_recursivelist[i]->m_ndata == -3 )
+			m_recursivelist[i]->m_ndata = GetNamedNumber(m_recursivelist[i]->m_szNamed);
+
+		if( m_recursivelist[i]->m_ndata >= 0 && m_recursivelist[i]->m_ndata < m_grouplist.GetSize() )
+			m_recursivelist[i]->m_pelx = m_grouplist[m_recursivelist[i]->m_ndata];
+	}
+
+	// named backref
+	for(i=0; i<m_namedbackreflist.GetSize(); i++)
+	{
+		m_namedbackreflist[i]->m_nnumber = GetNamedNumber(m_namedbackreflist[i]->m_szNamed);
+	}
+
+	// named condition
+	for(i=0; i<m_namedconditionlist.GetSize(); i++)
+	{
+		int nn = GetNamedNumber(m_namedconditionlist[i]->m_szNamed);
+		if( nn >= 0 )
+		{
+			m_namedconditionlist[i]->m_nnumber = nn;
+			m_namedconditionlist[i]->m_pelxask = 0;
+		}
+	}
+
+	return m_pTopElx;
+}
+
+template <class CHART> void CBuilderT <CHART> :: Clear()
+{
+	for(int i=0; i<m_objlist.GetSize(); i++)
+	{
+		delete m_objlist[i];
+	}
+
+	m_objlist.Restore(0);
+	m_pTopElx = 0;
+
+	memset(m_pStockElxs, 0, sizeof(m_pStockElxs));
+}
+
+//
+// hex to int
+//
+template <class CHART> unsigned int CBuilderT <CHART> :: Hex2Int(const CHART * pcsz, int length, int & used)
+{
+	unsigned int result = 0;
+	int & i = used;
+
+	for(i=0; i<length; i++)
+	{
+		if(pcsz[i] >= RCHART('0') && pcsz[i] <= RCHART('9'))
+			result = (result << 4) + (pcsz[i] - RCHART('0'));
+		else if(pcsz[i] >= RCHART('A') && pcsz[i] <= RCHART('F'))
+			result = (result << 4) + (0x0A + (pcsz[i] - RCHART('A')));
+		else if(pcsz[i] >= RCHART('a') && pcsz[i] <= RCHART('f'))
+			result = (result << 4) + (0x0A + (pcsz[i] - RCHART('a')));
+		else
+			break;
+	}
+
+	return result;
+}
+
+template <class CHART> inline ElxInterface * CBuilderT <CHART> :: Keep(ElxInterface * pelx)
+{
+	m_objlist.Push(pelx);
+	return pelx;
+}
+
+template <class CHART> void CBuilderT <CHART> :: MoveNext()
+{
+	// forwards
+	prev = curr;
+	curr = next;
+	next = nex2;
+
+	// get nex2
+	while( ! GetNext2() ) {};
+}
+
+template <class CHART> int CBuilderT <CHART> :: GetNext2()
+{
+	// check length
+	if(m_nNextPos >= m_pattern.GetSize())
+	{
+		nex2 = CHART_INFO(0, 1, m_nNextPos, 0);
+		return 1;
+	}
+
+	int   delta = 1;
+	CHART ch    = m_pattern[m_nNextPos];
+
+	// if quoted
+	if(m_bQuoted)
+	{
+		if(ch == RCHART('\\'))
+		{
+			if(m_pattern[m_nNextPos + 1] == RCHART('E'))
+			{
+				m_quote_fun = 0;
+				m_bQuoted   = 0;
+				m_nNextPos += 2;
+				return 0;
+			}
+		}
+
+		if(m_quote_fun != 0)
+			nex2 = CHART_INFO((CHART)(*m_quote_fun)((int)ch), 0, m_nNextPos, delta);
+		else
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+
+		m_nNextPos += delta;
+
+		return 1;
+	}
+
+	// common
+	switch(ch)
+	{
+	case RCHART('\\'):
+		{
+			CHART ch1 = m_pattern[m_nNextPos+1];
+
+			// backref
+			if(ch1 >= RCHART('0') && ch1 <= RCHART('9'))
+			{
+				nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+				break;
+			}
+
+			// escape
+			delta     = 2;
+
+			switch(ch1)
+			{
+			case RCHART('A'):
+			case RCHART('Z'):
+			case RCHART('w'):
+			case RCHART('W'):
+			case RCHART('s'):
+			case RCHART('S'):
+			case RCHART('B'):
+			case RCHART('d'):
+			case RCHART('D'):
+			case RCHART('k'):
+			case RCHART('g'):
+				nex2 = CHART_INFO(ch1, 1, m_nNextPos, delta);
+				break;
+
+			case RCHART('b'):
+				if(m_nCharsetDepth > 0)
+					nex2 = CHART_INFO('\b', 0, m_nNextPos, delta);
+				else
+					nex2 = CHART_INFO(ch1, 1, m_nNextPos, delta);
+				break;
+
+			/*
+			case RCHART('<'):
+			case RCHART('>'):
+				if(m_nCharsetDepth > 0)
+					nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);
+				else
+					nex2 = CHART_INFO(ch1, 1, m_nNextPos, delta);
+				break;
+			*/
+
+			case RCHART('x'):
+				if(m_pattern[m_nNextPos+2] != '{')
+				{
+					int red = 0;
+					unsigned int ch2 = Hex2Int(m_pattern.GetBuffer() + m_nNextPos + 2, 2, red);
+
+					delta += red;
+
+					if(red > 0)
+						nex2 = CHART_INFO(RCHART(ch2), 0, m_nNextPos, delta);
+					else
+						nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);
+
+				break;
+				}
+
+			case RCHART('u'):
+				if(m_pattern[m_nNextPos+2] != '{')
+				{
+					int red = 0;
+					unsigned int ch2 = Hex2Int(m_pattern.GetBuffer() + m_nNextPos + 2, 4, red);
+
+					delta += red;
+
+					if(red > 0)
+						nex2 = CHART_INFO(RCHART(ch2), 0, m_nNextPos, delta);
+					else
+						nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);
+				}
+				else
+				{
+					int red = 0;
+					unsigned int ch2 = Hex2Int(m_pattern.GetBuffer() + m_nNextPos + 3, sizeof(int) * 2, red);
+
+					delta += red;
+
+					while(m_nNextPos + delta < m_pattern.GetSize() && m_pattern.At(m_nNextPos + delta) != RCHART('}'))
+						delta ++;
+
+					delta ++; // skip '}'
+
+					nex2 = CHART_INFO(RCHART(ch2), 0, m_nNextPos, delta);
+				}
+				break;
+
+			case RCHART('a'): nex2 = CHART_INFO(RCHART('\a'), 0, m_nNextPos, delta); break;
+			case RCHART('f'): nex2 = CHART_INFO(RCHART('\f'), 0, m_nNextPos, delta); break;
+			case RCHART('n'): nex2 = CHART_INFO(RCHART('\n'), 0, m_nNextPos, delta); break;
+			case RCHART('r'): nex2 = CHART_INFO(RCHART('\r'), 0, m_nNextPos, delta); break;
+			case RCHART('t'): nex2 = CHART_INFO(RCHART('\t'), 0, m_nNextPos, delta); break;
+			case RCHART('v'): nex2 = CHART_INFO(RCHART('\v'), 0, m_nNextPos, delta); break;
+			case RCHART('e'): nex2 = CHART_INFO(RCHART( 27 ), 0, m_nNextPos, delta); break;
+
+			case RCHART('G'):  // skip '\G'
+				if(m_nCharsetDepth > 0)
+				{
+					m_nNextPos += 2;
+					return 0;
+				}
+				else
+				{
+					nex2 = CHART_INFO(ch1, 1, m_nNextPos, delta);
+					break;
+				}
+
+			case RCHART('L'):
+				if( ! m_quote_fun ) m_quote_fun = ::tolower;
+
+			case RCHART('U'):
+				if( ! m_quote_fun ) m_quote_fun = ::toupper;
+
+			case RCHART('Q'):
+				{
+					m_bQuoted   = 1;
+					m_nNextPos += 2;
+					return 0;
+				}
+
+			case RCHART('E'):
+				{
+					m_quote_fun = 0;
+					m_bQuoted   = 0;
+					m_nNextPos += 2;
+					return 0;
+				}
+
+			case 0:
+				if(m_nNextPos+1 >= m_pattern.GetSize())
+				{
+					delta = 1;
+					nex2 = CHART_INFO(ch , 0, m_nNextPos, delta);
+				}
+				else
+					nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta); // common '\0' char
+				break;
+
+			default:
+				nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);
+				break;
+			}
+		}
+		break;
+
+	case RCHART('*'):
+	case RCHART('+'):
+	case RCHART('?'):
+	case RCHART('.'):
+	case RCHART('{'):
+	case RCHART('}'):
+	case RCHART(')'):
+	case RCHART('|'):
+	case RCHART('$'):
+		if(m_nCharsetDepth > 0)
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		else
+			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+		break;
+
+	case RCHART('-'):
+		if(m_nCharsetDepth > 0)
+			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+		else
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		break;
+
+	case RCHART('('):
+		{
+			CHART ch1 = m_pattern[m_nNextPos+1];
+			CHART ch2 = m_pattern[m_nNextPos+2];
+
+			// skip remark
+			if(ch1 == RCHART('?') && ch2 == RCHART('#'))
+			{
+				m_nNextPos += 2;
+				while(m_nNextPos < m_pattern.GetSize())
+				{
+					if(m_pattern[m_nNextPos] == RCHART(')'))
+						break;
+
+					m_nNextPos ++;
+				}
+
+				if(m_pattern[m_nNextPos] == RCHART(')'))
+				{
+					m_nNextPos ++;
+
+					// get next nex2
+					return 0;
+				}
+			}
+			else
+			{
+				if(m_nCharsetDepth > 0)
+					nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+				else
+					nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+			}
+		}
+		break;
+
+	case RCHART('#'):
+		if(m_nFlags & EXTENDED)
+		{
+			// skip remark
+			m_nNextPos ++;
+
+			while(m_nNextPos < m_pattern.GetSize())
+			{
+				if(m_pattern[m_nNextPos] == RCHART('\n') || m_pattern[m_nNextPos] == RCHART('\r'))
+					break;
+
+				m_nNextPos ++;
+			}
+
+			// get next nex2
+			return 0;
+		}
+		else
+		{
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		}
+		break;
+
+	case RCHART(' '):
+	case RCHART('\f'):
+	case RCHART('\n'):
+	case RCHART('\r'):
+	case RCHART('\t'):
+	case RCHART('\v'):
+		if(m_nFlags & EXTENDED)
+		{
+			m_nNextPos ++;
+
+			// get next nex2
+			return 0;
+		}
+		else
+		{
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		}
+		break;
+
+	case RCHART('['):
+		m_nCharsetDepth ++;
+		nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+		break;
+
+	case RCHART(']'):
+		if(m_nCharsetDepth > 0)
+		{
+			m_nCharsetDepth --;
+			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+		}
+		else
+		{
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		}
+		break;
+
+	case RCHART(':'):
+		if(next == CHART_INFO(RCHART('['), 1))
+			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+		else
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		break;
+
+	case RCHART('^'):
+		if(m_nCharsetDepth == 0 || next == CHART_INFO(RCHART('['), 1) || (curr == CHART_INFO(RCHART('['), 1) && next == CHART_INFO(RCHART(':'), 1)))
+			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
+		else
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		break;
+
+	case 0:
+		if(m_nNextPos >= m_pattern.GetSize())
+			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta); // end of string
+		else
+			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta); // common '\0' char
+		break;
+
+	default:
+		nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
+		break;
+	}
+
+	m_nNextPos += delta;
+
+	return 1;
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: GetStockElx(int nStockId)
+{
+	ElxInterface ** pStockElxs = m_pStockElxs;
+
+	// check
+	if(nStockId < 0 || nStockId >= STOCKELX_COUNT)
+		return GetStockElx(0);
+
+	// create if no
+	if(pStockElxs[nStockId] == 0)
+	{
+		switch(nStockId)
+		{
+		case STOCKELX_EMPTY:
+			pStockElxs[nStockId] = Keep(new CEmptyElx());
+			break;
+
+		case STOCKELX_WORD:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 1));
+
+				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
+				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+				pRange->m_chars .Push(RCHART('_'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_WORD_NOT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));
+
+				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
+				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+				pRange->m_chars .Push(RCHART('_'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_DOT_ALL:
+			pStockElxs[nStockId] = Keep(new CRangeElxT <CHART> (0, 0));
+			break;
+
+		case STOCKELX_DOT_NOT_ALL:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));
+
+				pRange->m_chars .Push(RCHART('\n'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_SPACE:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 1));
+
+				pRange->m_chars .Push(RCHART(' '));
+				pRange->m_chars .Push(RCHART('\t'));
+				pRange->m_chars .Push(RCHART('\r'));
+				pRange->m_chars .Push(RCHART('\n'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_SPACE_NOT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));
+
+				pRange->m_chars .Push(RCHART(' '));
+				pRange->m_chars .Push(RCHART('\t'));
+				pRange->m_chars .Push(RCHART('\r'));
+				pRange->m_chars .Push(RCHART('\n'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_DIGITAL:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 1));
+
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_DIGITAL_NOT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));
+
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_WORD_RIGHTLEFT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 1));
+
+				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
+				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+				pRange->m_chars .Push(RCHART('_'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_WORD_RIGHTLEFT_NOT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));
+
+				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
+				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+				pRange->m_chars .Push(RCHART('_'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_DOT_ALL_RIGHTLEFT:
+			pStockElxs[nStockId] = Keep(new CRangeElxT <CHART> (1, 0));
+			break;
+
+		case STOCKELX_DOT_NOT_ALL_RIGHTLEFT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));
+
+				pRange->m_chars .Push(RCHART('\n'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_SPACE_RIGHTLEFT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 1));
+
+				pRange->m_chars .Push(RCHART(' '));
+				pRange->m_chars .Push(RCHART('\t'));
+				pRange->m_chars .Push(RCHART('\r'));
+				pRange->m_chars .Push(RCHART('\n'));
+				pRange->m_chars .Push(RCHART('\f'));
+				pRange->m_chars .Push(RCHART('\v'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_SPACE_RIGHTLEFT_NOT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));
+
+				pRange->m_chars .Push(RCHART(' '));
+				pRange->m_chars .Push(RCHART('\t'));
+				pRange->m_chars .Push(RCHART('\r'));
+				pRange->m_chars .Push(RCHART('\n'));
+				pRange->m_chars .Push(RCHART('\f'));
+				pRange->m_chars .Push(RCHART('\v'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_DIGITAL_RIGHTLEFT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 1));
+
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+
+		case STOCKELX_DIGITAL_RIGHTLEFT_NOT:
+			{
+				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));
+
+				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
+
+				pStockElxs[nStockId] = pRange;
+			}
+			break;
+		}
+	}
+
+	// return
+	return pStockElxs[nStockId];
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildAlternative(int vaflags)
+{
+	if(curr == CHART_INFO(0, 1))
+		return GetStockElx(STOCKELX_EMPTY);
+
+	// flag instance
+	int flags = vaflags;
+
+	// first part
+	ElxInterface * pAlternativeOne = BuildList(flags);
+
+	// check alternative
+	if(curr == CHART_INFO(RCHART('|'), 1))
+	{
+		CAlternativeElx * pAlternative = (CAlternativeElx *)Keep(new CAlternativeElx());
+		pAlternative->m_elxlist.Push(pAlternativeOne);
+
+		// loop
+		while(curr == CHART_INFO(RCHART('|'), 1))
+		{
+			// skip '|' itself
+			MoveNext();
+
+			pAlternativeOne = BuildList(flags);
+			pAlternative->m_elxlist.Push(pAlternativeOne);
+		}
+
+		return pAlternative;
+	}
+
+	return pAlternativeOne;
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildList(int & flags)
+{
+	if(curr == CHART_INFO(0, 1) || curr == CHART_INFO(RCHART('|'), 1) || curr == CHART_INFO(RCHART(')'), 1))
+		return GetStockElx(STOCKELX_EMPTY);
+
+	// first
+	ElxInterface * pListOne = BuildRepeat(flags);
+
+	if(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('|'), 1) && curr != CHART_INFO(RCHART(')'), 1))
+	{
+		CListElx * pList = (CListElx *)Keep(new CListElx(flags & RIGHTTOLEFT));
+		pList->m_elxlist.Push(pListOne);
+
+		while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('|'), 1) && curr != CHART_INFO(RCHART(')'), 1))
+		{
+			pListOne = BuildRepeat(flags);
+
+			// add
+			pList->m_elxlist.Push(pListOne);
+		}
+
+		return pList;
+	}
+
+	return pListOne;
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildRepeat(int & flags)
+{
+	// simple
+	ElxInterface * pSimple = BuildSimple(flags);
+
+	if(curr.type == 0) return pSimple;
+
+	// is quantifier or not
+	int bIsQuantifier = 1;
+
+	// quantifier range
+	unsigned int nMin = 0, nMax = 0;
+
+	switch(curr.ch)
+	{
+	case RCHART('{'):
+		{
+			CBufferT <char> re;
+
+			// skip '{'
+			MoveNext();
+
+			// copy
+			while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('}'), 1))
+			{
+				re.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+				MoveNext();
+			}
+
+			// skip '}'
+			MoveNext();
+
+			// read
+			int red;
+			char * str = re.GetBuffer();
+
+			if( ! ReadDec(str, nMin) )
+				red = 0;
+			else if( *str != ',' )
+				red = 1;
+			else
+			{
+				str ++;
+
+				if( ! ReadDec(str, nMax) )
+					red = 2;
+				else
+					red = 3;
+			}
+
+			// check
+			if(red  <=  1 ) nMax = nMin;
+			if(red  ==  2 ) nMax = INT_MAX;
+			if(nMax < nMin) nMax = nMin;
+		}
+		break;
+
+	case RCHART('?'):
+		nMin = 0;
+		nMax = 1;
+
+		// skip '?'
+		MoveNext();
+		break;
+
+	case RCHART('*'):
+		nMin = 0;
+		nMax = INT_MAX;
+
+		// skip '*'
+		MoveNext();
+		break;
+
+	case RCHART('+'):
+		nMin = 1;
+		nMax = INT_MAX;
+
+		// skip '+'
+		MoveNext();
+		break;
+
+	default:
+		bIsQuantifier = 0;
+		break;
+	}
+
+	// do quantify
+	if(bIsQuantifier)
+	{
+		// 0 times
+		if(nMax == 0)
+			return GetStockElx(STOCKELX_EMPTY);
+
+		// fixed times
+		if(nMin == nMax)
+		{
+			if(curr == CHART_INFO(RCHART('?'), 1) || curr == CHART_INFO(RCHART('+'), 1))
+				MoveNext();
+
+			return Keep(new CRepeatElx(pSimple, nMin));
+		}
+
+		// range times
+		if(curr == CHART_INFO(RCHART('?'), 1))
+		{
+			MoveNext();
+			return Keep(new CReluctantElx(pSimple, nMin, nMax));
+		}
+		else if(curr == CHART_INFO(RCHART('+'), 1))
+		{
+			MoveNext();
+			return Keep(new CPossessiveElx(pSimple, nMin, nMax));
+		}
+		else
+		{
+			return Keep(new CGreedyElx(pSimple, nMin, nMax));
+		}
+	}
+
+	return pSimple;
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildSimple(int & flags)
+{
+	CBufferT <CHART> fixed;
+
+	while(curr != CHART_INFO(0, 1))
+	{
+		if(curr.type == 0)
+		{
+			if(next == CHART_INFO(RCHART('{'), 1) || next == CHART_INFO(RCHART('?'), 1) || next == CHART_INFO(RCHART('*'), 1) || next == CHART_INFO(RCHART('+'), 1))
+			{
+				if(fixed.GetSize() == 0)
+				{
+					fixed.Append(curr.ch, 1);
+					MoveNext();
+				}
+
+				break;
+			}
+			else
+			{
+				fixed.Append(curr.ch, 1);
+				MoveNext();
+			}
+		}
+		else if(curr.type == 1)
+		{
+			CHART vch = curr.ch;
+
+			// end of simple
+			if(vch == RCHART(')') || vch == RCHART('|'))
+				break;
+
+			// has fixed already
+			if(fixed.GetSize() > 0)
+				break;
+
+			// left parentheses
+			if(vch == RCHART('('))
+			{
+				return BuildRecursive(flags);
+			}
+
+			// char set
+			if( vch == RCHART('[') || vch == RCHART('.') || vch == RCHART('w') || vch == RCHART('W') ||
+				vch == RCHART('s') || vch == RCHART('S') || vch == RCHART('d') || vch == RCHART('D')
+			)
+			{
+				return BuildCharset(flags);
+			}
+
+			// boundary
+			if( vch == RCHART('^') || vch == RCHART('$') || vch == RCHART('A') || vch == RCHART('Z') ||
+				vch == RCHART('b') || vch == RCHART('B') || vch == RCHART('G') // vch == RCHART('<') || vch == RCHART('>')
+			)
+			{
+				return BuildBoundary(flags);
+			}
+
+			// backref
+			if(vch == RCHART('\\') || vch == RCHART('k') || vch == RCHART('g'))
+			{
+				return BuildBackref(flags);
+			}
+
+			// treat vchar as char
+			fixed.Append(curr.ch, 1);
+			MoveNext();
+		}
+	}
+
+	if(fixed.GetSize() > 0)
+		return Keep(new CStringElxT <CHART> (fixed.GetBuffer(), fixed.GetSize(), flags & RIGHTTOLEFT, flags & IGNORECASE));
+	else
+		return GetStockElx(STOCKELX_EMPTY);
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildCharset(int & flags)
+{
+	// char
+	CHART ch = curr.ch;
+
+	// skip
+	MoveNext();
+
+	switch(ch)
+	{
+	case RCHART('.'):
+		return GetStockElx(
+			flags & RIGHTTOLEFT ?
+			((flags & SINGLELINE) ? STOCKELX_DOT_ALL_RIGHTLEFT : STOCKELX_DOT_NOT_ALL_RIGHTLEFT) :
+			((flags & SINGLELINE) ? STOCKELX_DOT_ALL : STOCKELX_DOT_NOT_ALL)
+		);
+
+	case RCHART('w'):
+		return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_WORD_RIGHTLEFT : STOCKELX_WORD);
+
+	case RCHART('W'):
+		return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_WORD_RIGHTLEFT_NOT : STOCKELX_WORD_NOT);
+
+	case RCHART('s'):
+		return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_SPACE_RIGHTLEFT : STOCKELX_SPACE);
+
+	case RCHART('S'):
+		return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_SPACE_RIGHTLEFT_NOT : STOCKELX_SPACE_NOT);
+
+	case RCHART('d'):
+		return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_DIGITAL_RIGHTLEFT : STOCKELX_DIGITAL);
+
+	case RCHART('D'):
+		return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_DIGITAL_RIGHTLEFT_NOT : STOCKELX_DIGITAL_NOT);
+
+	case RCHART('['):
+		{
+			CRangeElxT <CHART> * pRange;
+
+			// create
+			if(curr == CHART_INFO(RCHART(':'), 1))
+			{
+				CBufferT <char> posix;
+
+				do {
+					posix.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+					MoveNext();
+				}
+				while(curr.ch != RCHART(0) && curr != CHART_INFO(RCHART(']'), 1));
+
+				MoveNext(); // skip ']'
+
+				// posix
+				return Keep(new CPosixElxT <CHART> (posix.GetBuffer(), flags & RIGHTTOLEFT));
+			}
+			else if(curr == CHART_INFO(RCHART('^'), 1))
+			{
+				MoveNext(); // skip '^'
+				pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (flags & RIGHTTOLEFT, 0));
+			}
+			else
+			{
+				pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (flags & RIGHTTOLEFT, 1));
+			}
+
+			// parse
+			while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART(']'), 1))
+			{
+				ch = curr.ch;
+
+				if(curr.type == 1 && (
+					ch == RCHART('.') || ch == RCHART('w') || ch == RCHART('W') || ch == RCHART('s') || ch == RCHART('S') || ch == RCHART('d') || ch == RCHART('D') ||
+					(ch == RCHART('[') && next == CHART_INFO(RCHART(':'), 1))
+				))
+				{
+					pRange->m_embeds.Push(BuildCharset(flags));
+				}
+				else if(next == CHART_INFO(RCHART('-'), 1) && nex2.type == 0)
+				{
+					pRange->m_ranges.Push(ch); pRange->m_ranges.Push(nex2.ch);
+
+					// next
+					MoveNext();
+					MoveNext();
+					MoveNext();
+				}
+				else
+				{
+					pRange->m_chars.Push(ch);
+
+					// next
+					MoveNext();
+				}
+			}
+
+			// skip ']'
+			MoveNext();
+
+			return pRange;
+		}
+	}
+
+	return GetStockElx(STOCKELX_EMPTY);
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildRecursive(int & flags)
+{
+	// skip '('
+	MoveNext();
+
+	if(curr == CHART_INFO(RCHART('?'), 1))
+	{
+		ElxInterface * pElx = 0;
+
+		// skip '?'
+		MoveNext();
+
+		int bNegative = 0;
+		CHART named_end = RCHART('>');
+
+		switch(curr.ch)
+		{
+		case RCHART('!'):
+			bNegative = 1;
+
+		case RCHART('='):
+			{
+				MoveNext(); // skip '!' or '='
+				pElx = Keep(new CAssertElx(BuildAlternative(flags & ~RIGHTTOLEFT), !bNegative));
+			}
+			break;
+
+		case RCHART('<'):
+			switch(next.ch)
+			{
+			case RCHART('!'):
+				bNegative = 1;
+
+			case RCHART('='):
+				MoveNext(); // skip '<'
+				MoveNext(); // skip '!' or '='
+				{
+					pElx = Keep(new CAssertElx(BuildAlternative(flags | RIGHTTOLEFT), !bNegative));
+				}
+				break;
+
+			default: // named group
+				break;
+			}
+			// break if assertion // else named
+			if(pElx != 0) break;
+
+		case RCHART('P'):
+			if(curr.ch == RCHART('P')) MoveNext(); // skip 'P'
+
+		case RCHART('\''):
+			if     (curr.ch == RCHART('<' )) named_end = RCHART('>' );
+			else if(curr.ch == RCHART('\'')) named_end = RCHART('\'');
+			MoveNext(); // skip '<' or '\''
+			{
+				// named number
+				int nThisBackref = m_nNextNamed ++;
+
+				CListElx    * pList  = (CListElx    *)Keep(new CListElx(flags & RIGHTTOLEFT));
+				CBracketElx * pleft  = (CBracketElx *)Keep(new CBracketElx(-1, flags & RIGHTTOLEFT ? 1 : 0));
+				CBracketElx * pright = (CBracketElx *)Keep(new CBracketElx(-1, flags & RIGHTTOLEFT ? 0 : 1));
+
+				// save name
+				CBufferT <CHART> & name = pleft->m_szNamed;
+				CBufferT <char> num;
+
+				while(curr.ch != RCHART(0) && curr.ch != named_end)
+				{
+					name.Append(curr.ch, 1);
+					num .Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+					MoveNext();
+				}
+				MoveNext(); // skip '>' or '\''
+
+				// check <num>
+				unsigned int number;
+				char * str = num.GetBuffer();
+
+				if( ReadDec(str, number) ? ( *str == '\0') : 0 )
+				{
+					pleft ->m_nnumber = number;
+					pright->m_nnumber = number;
+
+					name.Release();
+				}
+
+				// left, center, right
+				pList->m_elxlist.Push(pleft);
+				pList->m_elxlist.Push(BuildAlternative(flags));
+				pList->m_elxlist.Push(pright);
+
+				// for recursive
+				m_namedlist.Prepare(nThisBackref);
+				m_namedlist[nThisBackref] = pList;
+
+				pElx = pList;
+			}
+			break;
+
+		case RCHART('>'):
+			{
+				MoveNext(); // skip '>'
+				pElx = Keep(new CIndependentElx(BuildAlternative(flags)));
+			}
+			break;
+
+		case RCHART('R'):
+			MoveNext(); // skip 'R'
+			while(curr.ch != RCHART(0) && isspace(curr.ch)) MoveNext(); // skip space
+
+			if(curr.ch == RCHART('<') || curr.ch == RCHART('\''))
+			{
+				named_end = curr.ch == RCHART('<') ? RCHART('>') : RCHART('\'');
+				CDelegateElx * pDelegate = (CDelegateElx *)Keep(new CDelegateElx(-3));
+
+				MoveNext(); // skip '<' or '\\'
+
+				// save name
+				CBufferT <CHART> & name = pDelegate->m_szNamed;
+				CBufferT <char> num;
+
+				while(curr.ch != RCHART(0) && curr.ch != named_end)
+				{
+					name.Append(curr.ch, 1);
+					num .Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+					MoveNext();
+				}
+				MoveNext(); // skip '>' or '\''
+
+				// check <num>
+				unsigned int number;
+				char * str = num.GetBuffer();
+
+				if( ReadDec(str, number) ? ( *str == '\0') : 0 )
+				{
+					pDelegate->m_ndata = number;
+					name.Release();
+				}
+
+				m_recursivelist.Push(pDelegate);
+				pElx = pDelegate;
+			}
+			else
+			{
+				CBufferT <char> rto;
+				while(curr.ch != RCHART(0) && curr.ch != RCHART(')'))
+				{
+					rto.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+					MoveNext();
+				}
+
+				unsigned int rtono = 0;
+				char * str = rto.GetBuffer();
+				ReadDec(str, rtono);
+
+				CDelegateElx * pDelegate = (CDelegateElx *)Keep(new CDelegateElx(rtono));
+
+				m_recursivelist.Push(pDelegate);
+				pElx = pDelegate;
+			}
+			break;
+
+		case RCHART('('):
+			{
+				CConditionElx * pConditionElx = (CConditionElx *)Keep(new CConditionElx());
+
+				// condition
+				ElxInterface * & pCondition = pConditionElx->m_pelxask;
+
+				if(next == CHART_INFO(RCHART('?'), 1))
+				{
+					pCondition = BuildRecursive(flags);
+				}
+				else // named, assert or number
+				{
+					MoveNext(); // skip '('
+					int pos0 = curr.pos;
+
+					// save elx condition
+					pCondition = Keep(new CAssertElx(BuildAlternative(flags), 1));
+
+					// save name
+					pConditionElx->m_szNamed.Append(m_pattern.GetBuffer() + pos0, curr.pos - pos0, 1);
+
+					// save number
+					CBufferT <char> numstr;
+					while(pos0 < curr.pos)
+					{
+						CHART ch = m_pattern[pos0];
+						numstr.Append(((ch & (CHART)0xff) == ch) ? (char)ch : 0, 1);
+						pos0 ++;
+					}
+
+					unsigned int number;
+					char * str = numstr.GetBuffer();
+
+					// valid group number
+					if( ReadDec(str, number) ? ( *str == '\0') : 0 )
+					{
+						pConditionElx->m_nnumber = number;
+						pCondition = 0;
+					}
+					else // maybe elx, maybe named
+					{
+						pConditionElx->m_nnumber = -1;
+						m_namedconditionlist.Push(pConditionElx);
+					}
+
+					MoveNext(); // skip ')'
+				}
+
+				// alternative
+				{
+					int newflags = flags;
+
+					pConditionElx->m_pelxyes = BuildList(newflags);
+				}
+
+				if(curr.ch == RCHART('|'))
+				{
+					MoveNext(); // skip '|'
+
+					pConditionElx->m_pelxno = BuildAlternative(flags);
+				}
+				else
+				{
+					pConditionElx->m_pelxno = 0;
+				}
+
+				pElx = pConditionElx;
+			}
+			break;
+
+		default:
+			while(curr.ch != RCHART(0) && isspace(curr.ch)) MoveNext(); // skip space
+
+			if(curr.ch >= RCHART('0') && curr.ch <= RCHART('9')) // recursive (?1) => (?R1)
+			{
+				CBufferT <char> rto;
+				while(curr.ch != RCHART(0) && curr.ch != RCHART(')'))
+				{
+					rto.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+					MoveNext();
+				}
+
+				unsigned int rtono = 0;
+				char * str = rto.GetBuffer();
+				ReadDec(str, rtono);
+
+				CDelegateElx * pDelegate = (CDelegateElx *)Keep(new CDelegateElx(rtono));
+
+				m_recursivelist.Push(pDelegate);
+				pElx = pDelegate;
+			}
+			else
+			{
+				// flag
+				int newflags = flags;
+				while(curr != CHART_INFO(0, 1) && curr.ch != RCHART(':') && curr.ch != RCHART(')') && curr != CHART_INFO(RCHART('('), 1))
+				{
+					int tochange = 0;
+
+					switch(curr.ch)
+					{
+					case RCHART('i'):
+					case RCHART('I'):
+						tochange = IGNORECASE;
+						break;
+
+					case RCHART('s'):
+					case RCHART('S'):
+						tochange = SINGLELINE;
+						break;
+
+					case RCHART('m'):
+					case RCHART('M'):
+						tochange = MULTILINE;
+						break;
+
+					case RCHART('g'):
+					case RCHART('G'):
+						tochange = GLOBAL;
+						break;
+
+					case RCHART('-'):
+						bNegative = 1;
+						break;
+					}
+
+					if(bNegative)
+						newflags &= ~tochange;
+					else
+						newflags |=  tochange;
+
+					// move to next char
+					MoveNext();
+				}
+
+				if(curr.ch == RCHART(':') || curr == CHART_INFO(RCHART('('), 1))
+				{
+					// skip ':'
+					if(curr.ch == RCHART(':')) MoveNext();
+
+					pElx = BuildAlternative(newflags);
+				}
+				else
+				{
+					// change parent flags
+					flags = newflags;
+
+					pElx = GetStockElx(STOCKELX_EMPTY);
+				}
+			}
+			break;
+		}
+
+		MoveNext(); // skip ')'
+
+		return pElx;
+	}
+	else
+	{
+		// group and number
+		CListElx * pList = (CListElx *)Keep(new CListElx(flags & RIGHTTOLEFT));
+		int nThisBackref = ++ m_nMaxNumber;
+
+		// left, center, right
+		pList->m_elxlist.Push(Keep(new CBracketElx(nThisBackref, flags & RIGHTTOLEFT ? 1 : 0)));
+		pList->m_elxlist.Push(BuildAlternative(flags));
+		pList->m_elxlist.Push(Keep(new CBracketElx(nThisBackref, flags & RIGHTTOLEFT ? 0 : 1)));
+
+		// for recursive
+		m_grouplist.Prepare(nThisBackref);
+		m_grouplist[nThisBackref] = pList;
+
+		// right
+		MoveNext(); // skip ')' 
+
+		return pList;
+	}
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildBoundary(int & flags)
+{
+	// char
+	CHART ch = curr.ch;
+
+	// skip
+	MoveNext();
+
+	switch(ch)
+	{
+	case RCHART('^'):
+		return Keep(new CBoundaryElxT <CHART> ((flags & MULTILINE) ? BOUNDARY_LINE_BEGIN : BOUNDARY_FILE_BEGIN));
+
+	case RCHART('$'):
+		return Keep(new CBoundaryElxT <CHART> ((flags & MULTILINE) ? BOUNDARY_LINE_END : BOUNDARY_FILE_END));
+
+	case RCHART('b'):
+		return Keep(new CBoundaryElxT <CHART> (BOUNDARY_WORD_EDGE));
+
+	case RCHART('B'):
+		return Keep(new CBoundaryElxT <CHART> (BOUNDARY_WORD_EDGE, 0));
+
+	case RCHART('A'):
+		return Keep(new CBoundaryElxT <CHART> (BOUNDARY_FILE_BEGIN));
+
+	case RCHART('Z'):
+		return Keep(new CBoundaryElxT <CHART> (BOUNDARY_FILE_END));
+
+	case RCHART('G'):
+		if(flags & GLOBAL)
+			return Keep(new CGlobalElx());
+		else
+			return GetStockElx(STOCKELX_EMPTY);
+
+	default:
+		return GetStockElx(STOCKELX_EMPTY);
+	}
+}
+
+template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildBackref(int & flags)
+{
+	// skip '\\' or '\k' or '\g'
+	MoveNext();
+
+	if(curr.ch == RCHART('<') || curr.ch == RCHART('\''))
+	{
+		CHART named_end = curr.ch == RCHART('<') ? RCHART('>') : RCHART('\'');
+		CBackrefElxT <CHART> * pbackref = (CBackrefElxT <CHART> *)Keep(new CBackrefElxT <CHART> (-1, flags & RIGHTTOLEFT, flags & IGNORECASE));
+
+		MoveNext(); // skip '<' or '\''
+
+		// save name
+		CBufferT <CHART> & name = pbackref->m_szNamed;
+		CBufferT <char> num;
+
+		while(curr.ch != RCHART(0) && curr.ch != named_end)
+		{
+			name.Append(curr.ch, 1);
+			num .Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
+			MoveNext();
+		}
+		MoveNext(); // skip '>' or '\''
+
+		// check <num>
+		unsigned int number;
+		char * str = num.GetBuffer();
+
+		if( ReadDec(str, number) ? ( *str == '\0') : 0 )
+		{
+			pbackref->m_nnumber = number;
+			name.Release();
+		}
+		else
+		{
+			m_namedbackreflist.Push(pbackref);
+		}
+
+		return pbackref;
+	}
+	else
+	{
+		unsigned int nbackref = 0;
+
+		for(int i=0; i<3; i++)
+		{
+			if(curr.ch >= RCHART('0') && curr.ch <= RCHART('9'))
+				nbackref = nbackref * 10 + (curr.ch - RCHART('0'));
+			else
+				break;
+
+			MoveNext();
+		}
+
+		return Keep(new CBackrefElxT <CHART> (nbackref, flags & RIGHTTOLEFT, flags & IGNORECASE));
+	}
+}
+
+template <class CHART> int CBuilderT <CHART> :: ReadDec(char * & str, unsigned int & dec)
+{
+	int s = 0;
+	while(str[s] != 0 && isspace(str[s])) s++;
+
+	if(str[s] < '0' || str[s] > '9') return 0;
+
+	dec = 0;
+	unsigned int i;
+
+	for(i = s; i<sizeof(CHART)*3 + s; i++)
+	{
+		if(str[i] >= '0' && str[i] <= '9')
+			dec = dec * 10 + (str[i] - '0');
+		else
+			break;
+	}
+
+	while(str[i] != 0 && isspace(str[i])) i++;
+	str += i;
+
+	return 1;
+}
+
+//
+// Regexp
+//
+template <class CHART> class CRegexpT
+{
+public:
+	CRegexpT(const CHART * pattern = 0, int flags = 0);
+	CRegexpT(const CHART * pattern, int length, int flags);
+	void Compile(const CHART * pattern, int flags = 0);
+	void Compile(const CHART * pattern, int length, int flags);
+
+public:
+	MatchResult MatchExact(const CHART * tstring, CContext * pContext = 0) const;
+	MatchResult MatchExact(const CHART * tstring, int length, CContext * pContext = 0) const;
+	MatchResult Match(const CHART * tstring, int start = -1, CContext * pContext = 0) const;
+	MatchResult Match(const CHART * tstring, int length, int start, CContext * pContext = 0) const;
+	MatchResult Match(CContext * pContext) const;
+	CContext * PrepareMatch(const CHART * tstring, int start = -1, CContext * pContext = 0) const;
+	CContext * PrepareMatch(const CHART * tstring, int length, int start, CContext * pContext = 0) const;
+	CHART * Replace(const CHART * tstring, const CHART * replaceto, int start = -1, int ntimes = -1, MatchResult * result = 0, CContext * pContext = 0) const;
+	CHART * Replace(const CHART * tstring, int string_length, const CHART * replaceto, int to_length, int & result_length, int start = -1, int ntimes = -1, MatchResult * result = 0, CContext * pContext = 0) const;
+	int GetNamedGroupNumber(const CHART * group_name) const;
+
+public:
+	static void ReleaseString (CHART    * tstring );
+	static void ReleaseContext(CContext * pContext);
+
+public:
+	CBuilderT <CHART> m_builder;
+};
+
+//
+// Implementation
+//
+template <class CHART> CRegexpT <CHART> :: CRegexpT(const CHART * pattern, int flags)
+{
+	Compile(pattern, CBufferRefT<CHART>(pattern).GetSize(), flags);
+}
+
+template <class CHART> CRegexpT <CHART> :: CRegexpT(const CHART * pattern, int length, int flags)
+{
+	Compile(pattern, length, flags);
+}
+
+template <class CHART> inline void CRegexpT <CHART> :: Compile(const CHART * pattern, int flags)
+{
+	Compile(pattern, CBufferRefT<CHART>(pattern).GetSize(), flags);
+}
+
+template <class CHART> void CRegexpT <CHART> :: Compile(const CHART * pattern, int length, int flags)
+{
+	m_builder.Clear();
+	if(pattern != 0) m_builder.Build(CBufferRefT<CHART>(pattern, length), flags);
+}
+
+template <class CHART> inline MatchResult CRegexpT <CHART> :: MatchExact(const CHART * tstring, CContext * pContext) const
+{
+	return MatchExact(tstring, CBufferRefT<CHART>(tstring).GetSize(), pContext);
+}
+
+template <class CHART> MatchResult CRegexpT <CHART> :: MatchExact(const CHART * tstring, int length, CContext * pContext) const
+{
+	if(m_builder.m_pTopElx == 0)
+		return 0;
+
+	// info
+	int endpos = 0;
+
+	CContext context;
+	if(pContext == 0) pContext = &context;
+
+	pContext->m_stack.Restore(0);
+	pContext->m_capturestack.Restore(0);
+	pContext->m_captureindex.Restore(0);
+
+	pContext->m_nParenZindex  = 0;
+	pContext->m_nLastBeginPos = -1;
+	pContext->m_pMatchString  = (void*)tstring;
+	pContext->m_pMatchStringLength = length;
+
+	if(m_builder.m_nFlags & RIGHTTOLEFT)
+	{
+		pContext->m_nBeginPos   = length;
+		pContext->m_nCurrentPos = length;
+		endpos = 0;
+	}
+	else
+	{
+		pContext->m_nBeginPos   = 0;
+		pContext->m_nCurrentPos = 0;
+		endpos = length;
+	}
+
+	pContext->m_captureindex.Prepare(m_builder.m_nMaxNumber, -1);
+	pContext->m_captureindex[0] = 0;
+	pContext->m_capturestack.Push(0);
+	pContext->m_capturestack.Push(pContext->m_nCurrentPos);
+	pContext->m_capturestack.Push(-1);
+	pContext->m_capturestack.Push(-1);
+
+	// match
+	if( ! m_builder.m_pTopElx->Match( pContext ) )
+		return 0;
+	else
+	{
+		while( pContext->m_nCurrentPos != endpos )
+		{
+			if( ! m_builder.m_pTopElx->MatchNext( pContext ) )
+				return 0;
+			else
+			{
+				if( pContext->m_nLastBeginPos == pContext->m_nBeginPos && pContext->m_nBeginPos == pContext->m_nCurrentPos )
+					return 0;
+				else
+					pContext->m_nLastBeginPos = pContext->m_nCurrentPos;
+			}
+		}
+
+		// end pos
+		pContext->m_capturestack[2] = pContext->m_nCurrentPos;
+
+		return MatchResult( pContext, m_builder.m_nMaxNumber );
+	}
+}
+
+template <class CHART> MatchResult CRegexpT <CHART> :: Match(const CHART * tstring, int start, CContext * pContext) const
+{
+	return Match(tstring, CBufferRefT<CHART>(tstring).GetSize(), start, pContext);
+}
+
+template <class CHART> MatchResult CRegexpT <CHART> :: Match(const CHART * tstring, int length, int start, CContext * pContext) const
+{
+	if(m_builder.m_pTopElx == 0)
+		return 0;
+
+	CContext context;
+	if(pContext == 0) pContext = &context;
+
+	pContext->m_nParenZindex  =  0;
+	pContext->m_nLastBeginPos = -1;
+	pContext->m_pMatchString  = (void*)tstring;
+	pContext->m_pMatchStringLength = length;
+
+	if(start < 0)
+	{
+		if(m_builder.m_nFlags & RIGHTTOLEFT)
+		{
+			pContext->m_nBeginPos   = length;
+			pContext->m_nCurrentPos = length;
+		}
+		else
+		{
+			pContext->m_nBeginPos   = 0;
+			pContext->m_nCurrentPos = 0;
+		}
+	}
+	else
+	{
+		pContext->m_nBeginPos   = start;
+		pContext->m_nCurrentPos = start;
+	}
+
+	return Match( pContext );
+}
+
+template <class CHART> MatchResult CRegexpT <CHART> :: Match(CContext * pContext) const
+{
+	if(m_builder.m_pTopElx == 0)
+		return 0;
+
+	int endpos, delta;
+
+	if(m_builder.m_nFlags & RIGHTTOLEFT)
+	{
+		endpos = -1;
+		delta  = -1;
+	}
+	else
+	{
+		endpos = pContext->m_pMatchStringLength + 1;
+		delta  = 1;
+	}
+
+	while(pContext->m_nCurrentPos != endpos)
+	{
+		pContext->m_captureindex.Restore(0);
+		pContext->m_stack       .Restore(0);
+		pContext->m_capturestack.Restore(0);
+
+		pContext->m_captureindex.Prepare(m_builder.m_nMaxNumber, -1);
+		pContext->m_captureindex[0] = 0;
+		pContext->m_capturestack.Push(0);
+		pContext->m_capturestack.Push(pContext->m_nCurrentPos);
+		pContext->m_capturestack.Push(-1);
+		pContext->m_capturestack.Push(-1);
+
+		if( m_builder.m_pTopElx->Match( pContext ) )
+		{
+			// zero width
+			if( pContext->m_nLastBeginPos == pContext->m_nBeginPos && pContext->m_nBeginPos == pContext->m_nCurrentPos )
+			{
+				pContext->m_nCurrentPos += delta;
+				continue;
+			}
+
+			// save pos
+			pContext->m_nLastBeginPos   = pContext->m_nBeginPos;
+			pContext->m_nBeginPos       = pContext->m_nCurrentPos;
+			pContext->m_capturestack[2] = pContext->m_nCurrentPos;
+
+			// return
+			return MatchResult( pContext, m_builder.m_nMaxNumber );
+		}
+		else
+		{
+			pContext->m_nCurrentPos += delta;
+		}
+	}
+
+	return 0;
+}
+
+template <class CHART> inline CContext * CRegexpT <CHART> :: PrepareMatch(const CHART * tstring, int start, CContext * pContext) const
+{
+	return PrepareMatch(tstring, CBufferRefT<CHART>(tstring).GetSize(), start, pContext);
+}
+
+template <class CHART> CContext * CRegexpT <CHART> :: PrepareMatch(const CHART * tstring, int length, int start, CContext * pContext) const
+{
+	if(m_builder.m_pTopElx == 0)
+		return 0;
+
+	if(pContext == 0) pContext = new CContext();
+
+	pContext->m_nParenZindex  =  0;
+	pContext->m_nLastBeginPos = -1;
+	pContext->m_pMatchString  = (void*)tstring;
+	pContext->m_pMatchStringLength = length;
+
+	if(start < 0)
+	{
+		if(m_builder.m_nFlags & RIGHTTOLEFT)
+		{
+			pContext->m_nBeginPos   = length;
+			pContext->m_nCurrentPos = length;
+		}
+		else
+		{
+			pContext->m_nBeginPos   = 0;
+			pContext->m_nCurrentPos = 0;
+		}
+	}
+	else
+	{
+		pContext->m_nBeginPos   = start;
+		pContext->m_nCurrentPos = start;
+	}
+
+	return pContext;
+}
+
+template <class CHART> inline int CRegexpT <CHART> :: GetNamedGroupNumber(const CHART * group_name) const
+{
+	return m_builder.GetNamedNumber(group_name);
+}
+
+template <class CHART> CHART * CRegexpT <CHART> :: Replace(const CHART * tstring, const CHART * replaceto, int start, int ntimes, MatchResult * result, CContext * pContext) const
+{
+	int result_length = 0;
+	return Replace(tstring, CBufferRefT<CHART>(tstring).GetSize(), replaceto, CBufferRefT<CHART>(replaceto).GetSize(), result_length, start, ntimes, result, pContext);
+}
+
+template <class CHART> CHART * CRegexpT <CHART> :: Replace(const CHART * tstring, int string_length, const CHART * replaceto, int to_length, int & result_length, int start, int ntimes, MatchResult * remote_result, CContext * oContext) const
+{
+	typedef CBufferRefT <CHART> StringRef;
+
+	MatchResult local_result(0), * result = remote_result ? remote_result : & local_result;
+
+	if(m_builder.m_pTopElx == 0) return 0;
+
+	// Prepare
+	CContext * pContext = PrepareMatch(tstring, string_length, start, oContext);
+
+	int flags     = m_builder.m_nFlags;
+	int lastIndex = (flags & RIGHTTOLEFT) ? string_length : 0;
+	int endpos    = (flags & RIGHTTOLEFT) ? 0 : string_length;
+	int toIndex   = 0, toLastIndex = 0;
+	int i, ntime;
+
+	CBufferT <StringRef *> buffer, buf;
+
+	static const CHART rtoptn[] = { RCHART('\\'), RCHART('$' ), RCHART('('), RCHART('?'), RCHART(':'), RCHART('[' ), RCHART('$' ), RCHART('&' ), RCHART('`' ), RCHART('\''), RCHART('+'), RCHART('_' ), RCHART('\\'), RCHART('d'), RCHART(']'), RCHART('|'), RCHART('\\'), RCHART('{'), RCHART('.'), RCHART('*'), RCHART('?'), RCHART('\\'), RCHART('}'), RCHART(')' ), RCHART('\0') };
+	static int   rtoptnlen      = StringRef(rtoptn).GetSize();
+	static CRegexpT <CHART> rtoreg(rtoptn, rtoptnlen, 0);
+
+	// Match
+	for(ntime = 0; ntimes < 0 || ntime < ntimes; ntime ++)
+	{
+		(*result) = Match(pContext);
+
+		if( ! result->IsMatched() )
+			break;
+
+		toIndex = toLastIndex;
+
+		// before
+		if( flags & RIGHTTOLEFT )
+		{
+			int distance = lastIndex - result->GetEnd();
+			if( distance )
+			{
+				buffer.Push(new StringRef(tstring + result->GetEnd(), distance));
+				toIndex -= distance;
+			}
+			lastIndex = result->GetStart();
+		}
+		else
+		{
+			int distance = result->GetStart() - lastIndex;
+			if( distance )
+			{
+				buffer.Push(new StringRef(tstring + lastIndex, distance));
+				toIndex += distance;
+			}
+			lastIndex = result->GetEnd();
+		}
+
+		toLastIndex = toIndex;
+
+		// middle
+		CContext * pCtx = rtoreg.PrepareMatch(replaceto, to_length, -1);
+		int lastI = 0;
+
+		buf.Restore(0);
+
+		while(1)
+		{
+			MatchResult res = rtoreg.Match(pCtx);
+
+			if( ! res.IsMatched() )
+				break;
+
+			// before
+			int distance = res.GetStart() - lastI;
+			if( distance )
+			{
+				buf.Push(new StringRef(replaceto + lastI, distance));
+			}
+			lastI = res.GetStart();
+
+			// middle
+			int delta = 2, nmatch = 0;
+
+			switch(replaceto[res.GetStart() + 1])
+			{
+			case RCHART('$'):
+				buf.Push(new StringRef(rtoptn + 1, 1)); // '$' itself
+				break;
+
+			case RCHART('&'):
+				buf.Push(new StringRef(tstring + result->GetStart(), result->GetEnd() - result->GetStart()));
+				break;
+
+			case RCHART('`'):
+				buf.Push(new StringRef(tstring, result->GetStart()));
+				break;
+
+			case RCHART('\''):
+				buf.Push(new StringRef(tstring + result->GetEnd(), string_length - result->GetEnd()));
+				break;
+
+			case RCHART('+'):
+				for(nmatch = result->MaxGroupNumber(); nmatch >= 0; nmatch --)
+				{
+					if(result->GetGroupStart(nmatch) >= 0) break;
+				}
+				buf.Push(new StringRef(tstring + result->GetGroupStart(nmatch), result->GetGroupEnd(nmatch) - result->GetGroupStart(nmatch)));
+				break;
+
+			case RCHART('_'):
+				buf.Push(new StringRef(tstring, string_length));
+				break;
+
+			case RCHART('{'):
+				delta  = res.GetEnd() - res.GetStart();
+				nmatch = m_builder.GetNamedNumber(StringRef(replaceto + (res.GetStart() + 2), delta - 3));
+
+				if(nmatch > 0 && nmatch <= m_builder.m_nMaxNumber)
+					buf.Push(new StringRef(tstring + result->GetGroupStart(nmatch), result->GetGroupEnd(nmatch) - result->GetGroupStart(nmatch)));
+				else
+					buf.Push(new StringRef(replaceto + res.GetStart(), delta));
+				break;
+
+			default:
+				nmatch = 0;
+				for(delta=1; delta<=3; delta++)
+				{
+					CHART ch = replaceto[lastI + delta];
+
+					if(ch < RCHART('0') || ch > RCHART('9'))
+						break;
+
+					nmatch = nmatch * 10 + (ch - RCHART('0'));
+				}
+
+				if(nmatch > m_builder.m_nMaxNumber)
+				{
+					while(nmatch > m_builder.m_nMaxNumber)
+					{
+						nmatch /= 10;
+						delta --;
+					}
+
+					if(nmatch == 0)
+					{
+						delta = 1;
+					}
+				}
+
+				if(delta == 1)
+					buf.Push(new StringRef(rtoptn + 1, 1)); // '$' itself
+				else
+					buf.Push(new StringRef(tstring + result->GetGroupStart(nmatch), result->GetGroupEnd(nmatch) - result->GetGroupStart(nmatch)));
+				break;
+			}
+
+			lastI += delta;
+		}
+
+		// after
+		if(lastI < to_length)
+			buf.Push(new StringRef(replaceto + lastI, to_length - lastI));
+
+		// append to buffer
+		if(flags & RIGHTTOLEFT)
+		{
+			for(i=buf.GetSize()-1; i>=0; i--)
+			{
+				buffer.Push(buf[i]);
+				toLastIndex -= buf[i]->GetSize();
+			}
+		}
+		else
+		{
+			for(i=0; i<buf.GetSize(); i++)
+			{
+				buffer.Push(buf[i]);
+				toLastIndex += buf[i]->GetSize();
+			}
+		}
+
+		rtoreg.ReleaseContext(pCtx);
+	}
+
+	// after
+	if(flags & RIGHTTOLEFT)
+	{
+		if(endpos < lastIndex) buffer.Push(new StringRef(tstring + endpos, lastIndex - endpos));
+	}
+	else
+	{
+		if(lastIndex < endpos) buffer.Push(new StringRef(tstring + lastIndex, endpos - lastIndex));
+	}
+
+	if(oContext == 0) ReleaseContext(pContext);
+
+	// join string
+	result_length = 0;
+	for(i=0; i<buffer.GetSize(); i++) result_length += buffer[i]->GetSize();
+
+	CBufferT <CHART> result_string;
+	result_string.Prepare(result_length);
+	result_string.Restore(0);
+
+	if(flags & RIGHTTOLEFT)
+	{
+		for(i=buffer.GetSize()-1; i>=0; i--)
+		{
+			result_string.Append(buffer[i]->GetBuffer(), buffer[i]->GetSize());
+			delete buffer[i];
+		}
+	}
+	else
+	{
+		for(i=0; i<buffer.GetSize(); i++)
+		{
+			result_string.Append(buffer[i]->GetBuffer(), buffer[i]->GetSize());
+			delete buffer[i];
+		}
+	}
+
+	result_string[result_length] = 0;
+
+	result->m_result.Append(toIndex < toLastIndex ? toIndex : toLastIndex, 2);
+	result->m_result.Append(toIndex > toLastIndex ? toIndex : toLastIndex);
+	result->m_result.Append(ntime);
+
+	return result_string.Detach();
+}
+
+template <class CHART> inline void CRegexpT <CHART> :: ReleaseString(CHART * tstring)
+{
+	if(tstring != 0) delete [] tstring;
+}
+
+template <class CHART> inline void CRegexpT <CHART> :: ReleaseContext(CContext * pContext)
+{
+	if(pContext != 0) delete pContext;
+}
+
+//
+// All implementations
+//
+template <int x> CAlternativeElxT <x> :: CAlternativeElxT()
+{
+}
+
+template <int x> int CAlternativeElxT <x> :: Match(CContext * pContext) const
+{
+	if(m_elxlist.GetSize() == 0)
+		return 1;
+
+	// try all
+	for(int n = 0; n < m_elxlist.GetSize(); n++)
+	{
+		if(m_elxlist[n]->Match(pContext))
+		{
+			pContext->m_stack.Push(n);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+template <int x> int CAlternativeElxT <x> :: MatchNext(CContext * pContext) const
+{
+	if(m_elxlist.GetSize() == 0)
+		return 0;
+
+	int n = 0;
+
+	// recall prev
+	pContext->m_stack.Pop(n);
+
+	// prev
+	if(m_elxlist[n]->MatchNext(pContext))
+	{
+		pContext->m_stack.Push(n);
+		return 1;
+	}
+	else
+	{
+		// try rest
+		for(n++; n < m_elxlist.GetSize(); n++)
+		{
+			if(m_elxlist[n]->Match(pContext))
+			{
+				pContext->m_stack.Push(n);
+				return 1;
+			}
+		}
+
+		return 0;
+	}
+}
+
+// assertx.cpp: implementation of the CAssertElx class.
+//
+template <int x> CAssertElxT <x> :: CAssertElxT(ElxInterface * pelx, int byes)
+{
+	m_pelx = pelx;
+	m_byes = byes;
+}
+
+template <int x> int CAssertElxT <x> :: Match(CContext * pContext) const
+{
+	int nbegin = pContext->m_nCurrentPos;
+	int nsize  = pContext->m_stack.GetSize();
+	int ncsize = pContext->m_capturestack.GetSize();
+	int bsucc;
+
+	// match
+	if( m_byes )
+		bsucc =   m_pelx->Match(pContext);
+	else
+		bsucc = ! m_pelx->Match(pContext);
+
+	// status
+	pContext->m_stack.Restore(nsize);
+	pContext->m_nCurrentPos = nbegin;
+
+	if( bsucc )
+		pContext->m_stack.Push(ncsize);
+	else
+		pContext->m_capturestack.Restore(ncsize);
+
+	return bsucc;
+}
+
+template <int x> int CAssertElxT <x> :: MatchNext(CContext * pContext) const
+{
+	int ncsize = 0;
+
+	pContext->m_stack.Pop(ncsize);
+	pContext->m_capturestack.Restore(ncsize);
+
+	return 0;
+}
+
+// emptyelx.cpp: implementation of the CEmptyElx class.
+//
+template <int x> CEmptyElxT <x> :: CEmptyElxT()
+{
+}
+
+template <int x> int CEmptyElxT <x> :: Match(CContext *) const
+{
+	return 1;
+}
+
+template <int x> int CEmptyElxT <x> :: MatchNext(CContext *) const
+{
+	return 0;
+}
+
+// globalx.cpp: implementation of the CGlobalElx class.
+//
+template <int x> CGlobalElxT <x> ::CGlobalElxT()
+{
+}
+
+template <int x> int CGlobalElxT <x> :: Match(CContext * pContext) const
+{
+	return pContext->m_nCurrentPos == pContext->m_nBeginPos;
+}
+
+template <int x> int CGlobalElxT <x> :: MatchNext(CContext *) const
+{
+	return 0;
+}
+
+// greedelx.cpp: implementation of the CGreedyElx class.
+//
+template <int x> CGreedyElxT <x> :: CGreedyElxT(ElxInterface * pelx, int nmin, int nmax) : CRepeatElxT <x> (pelx, nmin)
+{
+	m_nvart = nmax - nmin;
+}
+
+template <int x> int CGreedyElxT <x> :: Match(CContext * pContext) const
+{
+	if( ! CRepeatElxT <x> :: MatchFixed(pContext) )
+		return 0;
+
+	while( ! MatchVart(pContext) )
+	{
+		if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+			return 0;
+	}
+
+	return 1;
+}
+
+template <int x> int CGreedyElxT <x> :: MatchNext(CContext * pContext) const
+{
+	if( MatchNextVart(pContext) )
+		return 1;
+
+	if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+		return 0;
+
+	while( ! MatchVart(pContext) )
+	{
+		if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+			return 0;
+	}
+
+	return 1;
+}
+
+template <int x> int CGreedyElxT <x> :: MatchVart(CContext * pContext) const
+{
+	int n      = 0;
+	int nbegin = pContext->m_nCurrentPos;
+
+	while(n < m_nvart && CRepeatElxT <x> :: m_pelx->Match(pContext))
+	{
+		while(pContext->m_nCurrentPos == nbegin)
+		{
+			if( ! CRepeatElxT <x> :: m_pelx->MatchNext(pContext) ) break;
+		}
+
+		if(pContext->m_nCurrentPos == nbegin) break;
+
+		n ++;
+		nbegin = pContext->m_nCurrentPos;
+	}
+
+	pContext->m_stack.Push(n);
+
+	return 1;
+}
+
+template <int x> int CGreedyElxT <x> :: MatchNextVart(CContext * pContext) const
+{
+	int n = 0;
+	pContext->m_stack.Pop(n);
+
+	if(n == 0) return 0;
+
+	if( ! CRepeatElxT <x> :: m_pelx->MatchNext(pContext) )
+	{
+		n --;
+	}
+
+	pContext->m_stack.Push(n);
+
+	return 1;
+}
+
+// indepelx.cpp: implementation of the CIndependentElx class.
+//
+template <int x> CIndependentElxT <x> :: CIndependentElxT(ElxInterface * pelx)
+{
+	m_pelx = pelx;
+}
+
+template <int x> int CIndependentElxT <x> :: Match(CContext * pContext) const
+{
+	int nbegin = pContext->m_nCurrentPos;
+	int nsize  = pContext->m_stack.GetSize();
+	int ncsize = pContext->m_capturestack.GetSize();
+
+	// match
+	int bsucc  = m_pelx->Match(pContext);
+
+	// status
+	pContext->m_stack.Restore(nsize);
+
+	if( bsucc )
+	{
+		pContext->m_stack.Push(nbegin);
+		pContext->m_stack.Push(ncsize);
+	}
+
+	return bsucc;
+}
+
+template <int x> int CIndependentElxT <x> :: MatchNext(CContext * pContext) const
+{
+	int nbegin = 0, ncsize = 0;
+
+	pContext->m_stack.Pop(ncsize);
+	pContext->m_stack.Pop(nbegin);
+
+	pContext->m_capturestack.Restore(ncsize);
+	pContext->m_nCurrentPos = nbegin;
+
+	return 0;
+}
+
+// listelx.cpp: implementation of the CListElx class.
+//
+template <int x> CListElxT <x> :: CListElxT(int brightleft)
+{
+	m_brightleft = brightleft;
+}
+
+template <int x> int CListElxT <x> :: Match(CContext * pContext) const
+{
+	if(m_elxlist.GetSize() == 0)
+		return 1;
+
+	// prepare
+	int bol = m_brightleft ? m_elxlist.GetSize() : -1;
+	int stp = m_brightleft ? -1 : 1;
+	int eol = m_brightleft ? -1 : m_elxlist.GetSize();
+
+	// from first
+	int n = bol + stp;
+
+	// match all
+	while(n != eol)
+	{
+		if(m_elxlist[n]->Match(pContext))
+		{
+			n += stp;
+		}
+		else
+		{
+			n -= stp;
+
+			while(n != bol && ! m_elxlist[n]->MatchNext(pContext))
+				n -= stp;
+
+			if(n != bol)
+				n += stp;
+			else
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+template <int x> int CListElxT <x> :: MatchNext(CContext * pContext) const
+{
+	if(m_elxlist.GetSize() == 0)
+		return 0;
+
+	// prepare
+	int bol = m_brightleft ? m_elxlist.GetSize() : -1;
+	int stp = m_brightleft ? -1 : 1;
+	int eol = m_brightleft ? -1 : m_elxlist.GetSize();
+
+	// from last
+	int n = eol - stp;
+
+	while(n != bol && ! m_elxlist[n]->MatchNext(pContext))
+		n -= stp;
+
+	if(n != bol)
+		n += stp;
+	else
+		return 0;
+
+	// match rest
+	while(n != eol)
+	{
+		if(m_elxlist[n]->Match(pContext))
+		{
+			n += stp;
+		}
+		else
+		{
+			n -= stp;
+
+			while(n != bol && ! m_elxlist[n]->MatchNext(pContext))
+				n -= stp;
+
+			if(n != bol)
+				n += stp;
+			else
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+// mresult.cpp: implementation of the MatchResult class.
+//
+template <int x> MatchResultT <x> :: MatchResultT(CContext * pContext, int nMaxNumber)
+{
+	if(pContext != 0)
+	{
+		m_result.Prepare(nMaxNumber * 2 + 3, -1);
+
+		// matched
+		m_result[0] = 1;
+		m_result[1] = nMaxNumber;
+
+		for(int n = 0; n <= nMaxNumber; n++)
+		{
+			int index = pContext->m_captureindex[n];
+			if( index < 0 ) continue;
+
+			// check enclosed
+			int pos1 = pContext->m_capturestack[index + 1];
+			int pos2 = pContext->m_capturestack[index + 2];
+
+			// info
+			m_result[n*2 + 2] = pos1 < pos2 ? pos1 : pos2;
+			m_result[n*2 + 3] = pos1 < pos2 ? pos2 : pos1;
+		}
+	}
+}
+
+template <int x> inline int MatchResultT <x> :: IsMatched() const
+{
+	return m_result.At(0, 0);
+}
+
+template <int x> inline int MatchResultT <x> :: MaxGroupNumber() const
+{
+	return m_result.At(1, 0);
+}
+
+template <int x> inline int MatchResultT <x> :: GetStart() const
+{
+	return m_result.At(2, -1);
+}
+
+template <int x> inline int MatchResultT <x> :: GetEnd() const
+{
+	return m_result.At(3, -1);
+}
+
+template <int x> inline int MatchResultT <x> :: GetGroupStart(int nGroupNumber) const
+{
+	return m_result.At(2 + nGroupNumber * 2, -1);
+}
+
+template <int x> inline int MatchResultT <x> :: GetGroupEnd(int nGroupNumber) const
+{
+	return m_result.At(2 + nGroupNumber * 2 + 1, -1);
+}
+
+template <int x> MatchResultT <x> & MatchResultT <x> :: operator = (const MatchResultT <x> & result)
+{
+	m_result.Restore(0);
+	if(result.m_result.GetSize() > 0) m_result.Append(result.m_result.GetBuffer(), result.m_result.GetSize());
+
+	return *this;
+}
+
+// posselx.cpp: implementation of the CPossessiveElx class.
+//
+template <int x> CPossessiveElxT <x> :: CPossessiveElxT(ElxInterface * pelx, int nmin, int nmax) : CGreedyElxT <x> (pelx, nmin, nmax)
+{
+}
+
+template <int x> int CPossessiveElxT <x> :: Match(CContext * pContext) const
+{
+	int nbegin = pContext->m_nCurrentPos;
+	int nsize  = pContext->m_stack.GetSize();
+	int ncsize = pContext->m_capturestack.GetSize();
+	int bsucc  = 1;
+
+	// match
+	if( ! CRepeatElxT <x> :: MatchFixed(pContext) )
+	{
+		bsucc = 0;
+	}
+	else
+	{
+		while( ! CGreedyElxT <x> :: MatchVart(pContext) )
+		{
+			if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+			{
+				bsucc = 0;
+				break;
+			}
+		}
+	}
+
+	// status
+	pContext->m_stack.Restore(nsize);
+
+	if( bsucc )
+	{
+		pContext->m_stack.Push(nbegin);
+		pContext->m_stack.Push(ncsize);
+	}
+
+	return bsucc;
+}
+
+template <int x> int CPossessiveElxT <x> :: MatchNext(CContext * pContext) const
+{
+	int nbegin = 0, ncsize = 0;
+
+	pContext->m_stack.Pop(ncsize);
+	pContext->m_stack.Pop(nbegin);
+
+	pContext->m_capturestack.Restore(ncsize);
+	pContext->m_nCurrentPos = nbegin;
+
+	return 0;
+}
+
+// reluctx.cpp: implementation of the CReluctantElx class.
+//
+template <int x> CReluctantElxT <x> :: CReluctantElxT(ElxInterface * pelx, int nmin, int nmax) : CRepeatElxT <x> (pelx, nmin)
+{
+	m_nvart = nmax - nmin;
+}
+
+template <int x> int CReluctantElxT <x> :: Match(CContext * pContext) const
+{
+	if( ! CRepeatElxT <x> :: MatchFixed(pContext) )
+		return 0;
+
+	while( ! MatchVart(pContext) )
+	{
+		if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+			return 0;
+	}
+
+	return 1;
+}
+
+template <int x> int CReluctantElxT <x> :: MatchNext(CContext * pContext) const
+{
+	if( MatchNextVart(pContext) )
+		return 1;
+
+	if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+		return 0;
+
+	while( ! MatchVart(pContext) )
+	{
+		if( ! CRepeatElxT <x> :: MatchNextFixed(pContext) )
+			return 0;
+	}
+
+	return 1;
+}
+
+template <int x> int CReluctantElxT <x> :: MatchVart(CContext * pContext) const
+{
+	pContext->m_stack.Push(0);
+
+	return 1;
+}
+
+template <int x> int CReluctantElxT <x> :: MatchNextVart(CContext * pContext) const
+{
+	int n = 0, nbegin = pContext->m_nCurrentPos;
+
+	pContext->m_stack.Pop(n);
+
+	if(n < m_nvart && CRepeatElxT <x> :: m_pelx->Match(pContext))
+	{
+		while(pContext->m_nCurrentPos == nbegin)
+		{
+			if( ! CRepeatElxT <x> :: m_pelx->MatchNext(pContext) ) break;
+		}
+
+		if(pContext->m_nCurrentPos != nbegin)
+		{
+			n ++;
+
+			pContext->m_stack.Push(nbegin);
+			pContext->m_stack.Push(n);
+
+			return 1;
+		}
+	}
+
+	while(n > 0)
+	{
+		pContext->m_stack.Pop(nbegin);
+
+		while( CRepeatElxT <x> :: m_pelx->MatchNext(pContext) )
+		{
+			if(pContext->m_nCurrentPos != nbegin)
+			{
+				pContext->m_stack.Push(nbegin);
+				pContext->m_stack.Push(n);
+
+				return 1;
+			}
+		}
+
+		n --;
+	}
+
+	return 0;
+}
+
+// repeatx.cpp: implementation of the CRepeatElx class.
+//
+template <int x> CRepeatElxT <x> :: CRepeatElxT(ElxInterface * pelx, int ntimes)
+{
+	m_pelx   = pelx;
+	m_nfixed = ntimes;
+}
+
+template <int x> int CRepeatElxT <x> :: Match(CContext * pContext) const
+{
+	return MatchFixed(pContext);
+}
+
+template <int x> int CRepeatElxT <x> :: MatchNext(CContext * pContext) const
+{
+	return MatchNextFixed(pContext);
+}
+
+template <int x> int CRepeatElxT <x> :: MatchFixed(CContext * pContext) const
+{
+	if(m_nfixed == 0)
+		return 1;
+
+	int n = 0;
+
+	while(n < m_nfixed)
+	{
+		if(m_pelx->Match(pContext))
+		{
+			n ++;
+		}
+		else
+		{
+			n --;
+
+			while(n >= 0 && ! m_pelx->MatchNext(pContext))
+				n --;
+
+			if(n >= 0)
+				n ++;
+			else
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+template <int x> int CRepeatElxT <x> :: MatchNextFixed(CContext * pContext) const
+{
+	if(m_nfixed == 0)
+		return 0;
+
+	// from last
+	int n = m_nfixed - 1;
+
+	while(n >= 0 && ! m_pelx->MatchNext(pContext))
+		n --;
+
+	if(n >= 0)
+		n ++;
+	else
+		return 0;
+
+	// match rest
+	while(n < m_nfixed)
+	{
+		if(m_pelx->Match(pContext))
+		{
+			n ++;
+		}
+		else
+		{
+			n --;
+
+			while(n >= 0 && ! m_pelx->MatchNext(pContext))
+				n --;
+
+			if(n >= 0)
+				n ++;
+			else
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+// Regexp
+typedef CRegexpT <char> CRegexpA;
+typedef CRegexpT <unsigned short> CRegexpW;
+
+#if defined(_UNICODE) || defined(UNICODE)
+	typedef CRegexpW CRegexp;
+#else
+	typedef CRegexpA CRegexp;
+#endif
+
+#endif//__DEELX_REGEXP__H__
diff --git a/architecture/httpdlib/src/lib/smartpointer.h b/architecture/httpdlib/src/lib/smartpointer.h
new file mode 100644
index 0000000..1b41e09
--- /dev/null
+++ b/architecture/httpdlib/src/lib/smartpointer.h
@@ -0,0 +1,133 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __smartpointer__
+#define __smartpointer__
+
+#include <cassert>
+
+namespace httpdfaust
+{
+
+/*!
+\brief the base class for smart pointers implementation
+
+	Any object that want to support smart pointers should
+	inherit from the smartable class which provides reference counting
+	and automatic delete when the reference count drops to zero.
+*/
+class smartable {
+	private:
+		unsigned 	refCount;		
+	public:
+		//! gives the reference count of the object
+		unsigned refs() const         { return refCount; }
+		//! addReference increments the ref count and checks for refCount overflow
+		void addReference()           { refCount++; assert(refCount != 0); }
+		//! removeReference delete the object when refCount is zero		
+		void removeReference()		  { if (--refCount == 0) delete this; }
+		
+	protected:
+		smartable() : refCount(0) {}
+		smartable(const smartable&): refCount(0) {}
+		//! destructor checks for non-zero refCount
+		virtual ~smartable()    { assert (refCount == 0); }
+		smartable& operator=(const smartable&) { return *this; }
+};
+
+/*!
+\brief the smart pointer implementation
+
+	A smart pointer is in charge of maintaining the objects reference count 
+	by the way of pointers operators overloading. It supports class 
+	inheritance and conversion whenever possible.
+\n	Instances of the SMARTP class are supposed to use \e smartable types (or at least
+	objects that implements the \e addReference and \e removeReference
+	methods in a consistent way).
+*/
+template<class T> class SMARTP {
+	private:
+		//! the actual pointer to the class
+		T* fSmartPtr;
+
+	public:
+		//! an empty constructor - points to null
+		SMARTP()	: fSmartPtr(0) {}
+		//! build a smart pointer from a class pointer
+		SMARTP(T* rawptr) : fSmartPtr(rawptr)              { if (fSmartPtr) fSmartPtr->addReference(); }
+		//! build a smart pointer from an convertible class reference
+		template<class T2> 
+		SMARTP(const SMARTP<T2>& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); }
+		//! build a smart pointer from another smart pointer reference
+		SMARTP(const SMARTP& ptr) : fSmartPtr((T*)ptr)     { if (fSmartPtr) fSmartPtr->addReference(); }
+
+		//! the smart pointer destructor: simply removes one reference count
+		~SMARTP()  { if (fSmartPtr) fSmartPtr->removeReference(); }
+		
+		//! cast operator to retrieve the actual class pointer
+		operator T*() const  { return fSmartPtr;	}
+
+		//! '*' operator to access the actual class pointer
+		T& operator*() const {
+			// checks for null dereference
+			assert (fSmartPtr != 0);
+			return *fSmartPtr;
+		}
+
+		//! operator -> overloading to access the actual class pointer
+		T* operator->() const	{ 
+			// checks for null dereference
+			assert (fSmartPtr != 0);
+			return fSmartPtr;
+		}
+
+		//! operator = that moves the actual class pointer
+		template <class T2>
+		SMARTP& operator=(T2 p1_)	{ *this=(T*)p1_; return *this; }
+
+		//! operator = that moves the actual class pointer
+		SMARTP& operator=(T* p_)	{
+			// check first that pointers differ
+			if (fSmartPtr != p_) {
+				// increments the ref count of the new pointer if not null
+				if (p_ != 0) p_->addReference();
+				// decrements the ref count of the old pointer if not null
+				if (fSmartPtr != 0) fSmartPtr->removeReference();
+				// and finally stores the new actual pointer
+				fSmartPtr = p_;
+			}
+			return *this;
+		}
+		//! operator < to support SMARTP map with Visual C++
+		bool operator<(const SMARTP<T>& p_)	const			  { return fSmartPtr < ((T *) p_); }
+		//! operator = to support inherited class reference
+		SMARTP& operator=(const SMARTP<T>& p_)                { return operator=((T *) p_); }
+		//! dynamic cast support
+		template<class T2> SMARTP& cast(T2* p_)               { return operator=(dynamic_cast<T*>(p_)); }
+		//! dynamic cast support
+		template<class T2> SMARTP& cast(const SMARTP<T2>& p_) { return operator=(dynamic_cast<T*>(p_)); }
+};
+
+}
+
+#endif
diff --git a/architecture/httpdlib/src/msg/Message.cpp b/architecture/httpdlib/src/msg/Message.cpp
new file mode 100644
index 0000000..00522f1
--- /dev/null
+++ b/architecture/httpdlib/src/msg/Message.cpp
@@ -0,0 +1,71 @@
+/*
+
+  INScore Project
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "Message.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+// Message implementation
+//--------------------------------------------------------------------------
+static string escape (const string& str) 
+{
+	string out;
+	const char *ptr = str.c_str();
+	while (*ptr) {
+		char c = *ptr++;
+		if (c == '"')
+			out += "\\\"";
+		else out += c;
+	}
+	return out;
+}
+
+//--------------------------------------------------------------------------
+void Message::print(std::ostream& out) const
+{
+	out << address() << " " ;
+	argslist::const_iterator i = params().begin();
+
+	ios::fmtflags f = out.flags ( ios::showpoint );
+	while (i != params().end()) {
+		MsgParam<string>* s = dynamic_cast<MsgParam<string>*>((baseparam*)(*i));
+		if (s) out << "\"" << escape(s->getValue()) << "\" ";
+		MsgParam<int>* ip = dynamic_cast<MsgParam<int>*>((baseparam*)(*i));
+		if (ip) out << ip->getValue() << " ";
+		MsgParam<float>* f = dynamic_cast<MsgParam<float>*>((baseparam*)(*i));
+		if (f) out << f->getValue() << " ";
+		i++;
+	}
+	out.flags ( f );
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/msg/Message.h b/architecture/httpdlib/src/msg/Message.h
new file mode 100644
index 0000000..d7c3233
--- /dev/null
+++ b/architecture/httpdlib/src/msg/Message.h
@@ -0,0 +1,187 @@
+/*
+
+  Copyright (C) 2011  Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __Message__
+#define __Message__
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include "smartpointer.h"
+
+namespace httpdfaust
+{
+
+template <typename T> class MsgParam;
+class baseparam;
+typedef SMARTP<baseparam>	Sbaseparam;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief base class of a message parameters
+*/
+class baseparam : public smartable
+{
+	public:
+		virtual ~baseparam() {}
+
+		/*!
+		 \brief utility for parameter type checking
+		*/
+		template<typename X> bool isType() const { return dynamic_cast<const MsgParam<X>*> (this) != 0; }
+		/*!
+		 \brief utility for parameter convertion
+		 \param errvalue the returned value when no conversion applies
+		 \return the parameter value when the type matches
+		*/
+		template<typename X> X	value(X errvalue) const 
+			{ const MsgParam<X>* o = dynamic_cast<const MsgParam<X>*> (this); return o ? o->getValue() : errvalue; }
+		/*!
+		 \brief utility for parameter comparison
+		*/
+		template<typename X> bool	equal(const baseparam& p) const 
+			{ 
+				const MsgParam<X>* a = dynamic_cast<const MsgParam<X>*> (this); 
+				const MsgParam<X>* b = dynamic_cast<const MsgParam<X>*> (&p);
+				return a && b && (a->getValue() == b->getValue());
+			}
+		/*!
+		 \brief utility for parameter comparison
+		*/
+		bool operator==(const baseparam& p) const 
+			{ 
+				return equal<float>(p) || equal<int>(p) || equal<std::string>(p);
+			}
+		bool operator!=(const baseparam& p) const
+			{ 
+				return !equal<float>(p) && !equal<int>(p) && !equal<std::string>(p);
+			}
+			
+		virtual SMARTP<baseparam> copy() const = 0;
+};
+
+//--------------------------------------------------------------------------
+/*!
+	\brief template for a message parameter
+*/
+template <typename T> class MsgParam : public baseparam
+{
+	T fParam;
+	public:
+				 MsgParam(T val) : fParam(val)	{}
+		virtual ~MsgParam() {}
+		
+		T	getValue() const { return fParam; }
+		
+		virtual SMARTP<baseparam> copy() const { return new MsgParam<T>(fParam); }
+};
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a message description
+	
+	A message is composed of an address (actually the path of an url)
+	a message string that may be viewed as a method name
+	and a list of message parameters.
+*/
+class Message
+{
+	public:
+		typedef SMARTP<baseparam>		argPtr;		///< a message argument ptr type
+		typedef std::vector<argPtr>		argslist;	///< args list type
+
+	private:
+		std::string	fAddress;			///< the message destination address
+		std::string	fMIME;				///< the message MIME type
+		argslist	fArguments;			///< the message arguments
+	
+	public:
+			/*!
+				\brief an empty message constructor
+			*/
+			 Message() : fMIME("text/plain") {}
+			/*!
+				\brief a message constructor
+				\param address the message destination address
+			*/
+			 Message(const std::string& address) : fAddress(address), fMIME("text/plain") {}
+
+	virtual ~Message() {}
+
+	/*!
+		\brief adds a parameter to the message
+		\param val the parameter
+	*/
+	template <typename T> void add(T val)	{ fArguments.push_back(new MsgParam<T>(val)); }
+	
+	/*!
+		\brief adds a parameter to the message
+		\param val the parameter
+	*/
+	void	add( argPtr val )				{ fArguments.push_back( val ); }
+
+	/*!
+		\brief sets the message address
+		\param addr the address
+	*/
+	void				setAddress(const std::string& addr)		{ fAddress = addr; }
+
+	/*!
+		\brief sets the message MIME type
+		\param mime the MIME type
+	*/
+	void				setMIMEType(const std::string& mime)	{ fMIME = mime; }
+	/*!
+		\brief print the message
+		\param out the output stream
+	*/
+	void				print(std::ostream& out) const;
+
+	/// \brief gives the message address
+	const std::string&	address() const		{ return fAddress; }
+	/// \brief gives the message address
+	const std::string&	mimetype() const	{ return fMIME; }
+	/// \brief gives the message parameters list
+	const argslist&		params() const		{ return fArguments; }
+	/// \brief gives the message parameters list
+	argslist&			params()			{ return fArguments; }
+	/// \brief gives the message parameters count
+	int					size() const		{ return fArguments.size(); }
+	
+	bool operator == (const Message& other) const;	
+
+
+	/*!
+		\brief gives a message parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+	*/
+	template <typename T> bool	param(int i, T& val) const	{ val = params()[i]->value<T>(val); return params()[i]->isType<T>(); }
+};
+
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/msg/MessageProcessor.h b/architecture/httpdlib/src/msg/MessageProcessor.h
new file mode 100644
index 0000000..e82f0cd
--- /dev/null
+++ b/architecture/httpdlib/src/msg/MessageProcessor.h
@@ -0,0 +1,46 @@
+/*
+
+  Copyright (C) 2010  Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __MessageProcessor__
+#define __MessageProcessor__
+
+#include <vector>
+
+namespace httpdfaust
+{
+
+class Message;
+//--------------------------------------------------------------------------
+/*!
+	\brief an abstract class for objects able to process OSC messages	
+*/
+class MessageProcessor
+{
+	public:
+		virtual		~MessageProcessor() {}
+		virtual bool processMessage( const Message* msg, std::vector<Message*>& outMsg ) = 0;
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/nodes/FaustFactory.cpp b/architecture/httpdlib/src/nodes/FaustFactory.cpp
new file mode 100644
index 0000000..9732fcd
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/FaustFactory.cpp
@@ -0,0 +1,73 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "FaustFactory.h"
+#include "FaustNode.h"
+#include "RootNode.h"
+#include "MessageDriven.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+
+/**
+ * Open a group in the current group and place it on the top of the stack. 
+ * Takes into account that due to alias, a group can been previously created.  
+ */
+void FaustFactory::opengroup (const char* label)
+{
+	if (fNodes.size() == 0) {	
+		// the stack is empty: creates a root node 
+		fRoot = RootNode::create (label);	
+		fNodes.push (fRoot);					
+		
+	} else {
+		// only create a group if not previously created
+		SMessageDriven node = fNodes.top();
+		int i=0; while ( (i < node->size()) && (node->subnode(i)->name() != label) ) i++;
+		
+		if (i < node->size()) {
+			// found, make it top of stack
+			fNodes.push(node->subnode(i));
+		} else {
+			// not found, create a new group and make it top of stack
+			SMessageDriven group = MessageDriven::create (label, node->getAddress().c_str());
+			node->add( group );
+			fNodes.push (group);
+		}
+
+	}
+}
+
+//--------------------------------------------------------------------------
+void FaustFactory::closegroup ()
+{
+	fNodes.pop ();
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/nodes/FaustFactory.h b/architecture/httpdlib/src/nodes/FaustFactory.h
new file mode 100644
index 0000000..963616b
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/FaustFactory.h
@@ -0,0 +1,88 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __FaustFactory__
+#define __FaustFactory__
+
+#include <stack>
+#include <string>
+
+#include "MessageDriven.h"
+#include "FaustNode.h"
+
+namespace httpdfaust
+{
+
+class MessageDriven;
+typedef class SMARTP<MessageDriven>	SMessageDriven;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a factory to build a OSC UI hierarchy
+	
+	Actually, makes use of a stack to build the UI hierarchy.
+	It includes a pointer to a OSCIO controler, but just to give it to the root node.
+*/
+class FaustFactory
+{
+	std::stack<SMessageDriven>	fNodes;		///< maintains the current hierarchy level
+	SMessageDriven				fRoot;		///< keep track of the root node
+
+	public:
+				 FaustFactory() {}
+		virtual ~FaustFactory() {}
+
+		/**
+		 * Add a node to the OSC UI tree in the current group at the top of the stack 
+		 */
+		template <typename C> void addnode (const char* label, C* zone, C init, C min, C max, bool initZone)
+		{
+			SMessageDriven top = fNodes.size() ? fNodes.top() : fRoot;
+			if (top) {
+				std::string prefix = top->getAddress();
+				top->add( FaustNode<C>::create (label, zone, init, min, max, prefix.c_str(), initZone));
+			}
+		}
+
+		/**
+		 * Add a node to the OSC UI tree in the current group at the top of the stack 
+		 */
+		template <typename C> void addnode (const char* label, C* zone, C min, C max, bool initZone)
+		{
+			SMessageDriven top = fNodes.size() ? fNodes.top() : fRoot;
+			if (top) {
+				std::string prefix = top->getAddress();
+				top->add( FaustNode<C>::create (label, zone, min, max, prefix.c_str(), initZone) );
+			}
+		}
+
+		void opengroup (const char* label);
+		void closegroup ();
+
+		SMessageDriven	root() const	{ return fRoot; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/nodes/FaustNode.cpp b/architecture/httpdlib/src/nodes/FaustNode.cpp
new file mode 100644
index 0000000..c0fbd82
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/FaustNode.cpp
@@ -0,0 +1,69 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <sstream>
+
+#include "FaustNode.h"
+#include "Message.h"
+#include "HTTPDServer.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+//bool FaustNode::store( float val )
+//{
+//	*fZone = fMapping.scale(val);
+//	return true;
+//}
+
+//--------------------------------------------------------------------------
+//bool FaustNode::accept( const Message* msg, vector<Message*>& outMsg )
+//{
+//	if (msg->size() == 2) {			// checks for the message parameters count
+//									// messages with a param count other than 2 are rejected
+//		string key;
+//		if (msg->param(0, key) &&  (key == "value")) {
+//			float val=0;
+//			if (msg->param(1, val)) {
+//				store (val);			// accepts float values
+//			}
+//			get (outMsg);
+//			return true;
+//		}
+//	}
+//	return MessageDriven::accept(msg, outMsg);
+//}
+
+
+//--------------------------------------------------------------------------
+//void FaustNode::get (vector<Message*>& outMsg ) const
+//{
+//	Message * msg = new Message (getAddress());
+//	msg->add (*fZone);
+//	outMsg.push_back(msg);
+//}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/nodes/FaustNode.h b/architecture/httpdlib/src/nodes/FaustNode.h
new file mode 100644
index 0000000..6a95aed
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/FaustNode.h
@@ -0,0 +1,127 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __FaustNode__
+#define __FaustNode__
+
+#include <string>
+#include <vector>
+
+#include "MessageDriven.h"
+#include "Message.h"
+
+namespace httpdfaust
+{
+
+/**
+ * map (rescale) input values to output values
+ */
+template <typename C> struct mapping
+{
+	const C fMinIn;	
+	const C fMaxIn;
+	const C fMinOut;
+	const C fMaxOut;
+	const C fScale;
+
+	mapping(C imin, C imax, C omin, C omax) : fMinIn(imin), fMaxIn(imax), 
+											fMinOut(omin), fMaxOut(omax), 
+											fScale( (fMaxOut-fMinOut)/(fMaxIn-fMinIn) ) {}
+	C scale (C x) { C z = (x < fMinIn) ? fMinIn : (x > fMaxIn) ? fMaxIn : x; return fMinOut + (z - fMinIn) * fScale; }
+};
+
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust node is a terminal node and represents a faust parameter controler
+*/
+template <typename C> class FaustNode : public MessageDriven
+{
+	C *	fZone;			// the parameter memory zone
+	mapping<C>	fMapping;
+	
+	bool store (C val)			{ *fZone = fMapping.scale(val); return true; }
+
+
+	protected:
+		FaustNode(const char *name, C* zone, C min, C max, const char* prefix, bool initZone) 
+			: MessageDriven (name, prefix), fZone(zone), fMapping(min, max, min, max) 
+			{ 
+                if(initZone)
+                    *zone = min; 
+            }
+
+		FaustNode(const char *name, C* zone, C init, C min, C max, const char* prefix, bool initZone)
+			: MessageDriven (name, prefix), fZone(zone), fMapping(min, max, min, max) 
+			{ 
+                if(initZone)
+                    *zone = init; 
+            }
+			
+		FaustNode(const char *name, C* zone,  C imin, C imax, C init, C min, C max, const char* prefix, bool initZone) 
+			: MessageDriven (name, prefix), fZone(zone), fMapping(imin, imax, min, max) 
+			{ 
+                if(initZone)
+                    *zone = init; 
+            }
+		virtual ~FaustNode() {}
+
+	public:
+		typedef SMARTP<FaustNode<C> > SFaustNode;
+		static SFaustNode create (const char* name, C* zone, C min, C max, const char* prefix, bool initZone)
+							{ return new FaustNode(name, zone, min, max, prefix, initZone); }
+		static SFaustNode create (const char* name, C* zone, C init, C min, C max, const char* prefix, bool initZone)	
+							{ return new FaustNode(name, zone, init, min, max, prefix, initZone); }
+		static SFaustNode create (const char* name, C* zone, C imin, C imax, C init, C min, C max, const char* prefix, bool initZone)	
+							{ return new FaustNode(name, zone, imin, imax, init, min, max, prefix, initZone); }
+
+
+		virtual bool	accept( const Message* msg, std::vector<Message*>& outMsg )	///< handler for the 'accept' message
+				{
+					if (msg->size() == 2) {			// checks for the message parameters count
+													// messages with a param count other than 2 are rejected
+						std::string key;
+						if (msg->param(0, key) &&  (key == "value")) {
+							float val=0;
+							if (msg->param(1, val)) {
+								store (val);			// accepts float values
+							}
+							get (outMsg);
+							return true;
+						}
+					}
+					return MessageDriven::accept(msg, outMsg);
+				}
+
+		virtual void	get (std::vector<Message*>& outMsg) const						///< handler for the 'get' message
+				{
+					Message * msg = new Message (getAddress());
+					msg->add (float(*fZone));
+					outMsg.push_back(msg);
+				}
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/nodes/MessageDriven.cpp b/architecture/httpdlib/src/nodes/MessageDriven.cpp
new file mode 100644
index 0000000..6b161cf
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/MessageDriven.cpp
@@ -0,0 +1,128 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "Address.h"
+#include "Message.h"
+#include "MessageDriven.h"
+#include "HTTPDServer.h"
+
+using namespace std;
+namespace httpdfaust
+{
+
+//--------------------------------------------------------------------------
+bool MessageDriven::processMessage( const Message* msg, vector<Message*>& outMsg )
+{
+	const string addr = msg->address();
+
+	// get the message address head
+	string head = Address::addressFirst(addr).c_str();
+	// and call propose with this regexp and with the dest osc address tail
+	return propose (msg, head.c_str(), Address::addressTail (addr), outMsg);
+	
+//	if (addr != "/*") {
+//		// search for alias root (fixme : could be stored in a field)
+//		MessageDriven * aliasroot = 0;
+//		for (int i=0; i<size(); i++) {
+//			if (subnode(i)->name() == "alias") {
+//				aliasroot = subnode(i);
+//			}
+//		}
+//	
+//		// if we have aliases in the tree
+//		// we need to check if the message if for an alias address
+//		if (aliasroot != 0) {
+//			OSCRegexp r2 ("alias");
+//			
+//			if (msg->size() == 1) {
+//				aliasroot->propose (msg, &r2, addr);
+//			} else if (msg->size() > 1) {
+//				// we simulated several messages
+//				for (int i=0; i< msg->size(); i++) {
+//					ostringstream 	as; as << addr << '/' << i;
+//					string 			a(as.str());
+//					Message 		m(a);
+//					float			v;
+//					
+//					msg->param(i, v);
+//					m.add(v);
+//					aliasroot->propose (&m, &r2, a);
+//				}
+//			}
+//		}
+//	}
+}
+
+//--------------------------------------------------------------------------
+// the full address is simply the prefix + '/' + name
+string MessageDriven::getAddress() const
+{
+	string address(fPrefix);
+	address += "/";
+	address += fName;
+	return address;
+}
+
+//--------------------------------------------------------------------------
+// terminal nodes should override the get method
+void MessageDriven::get (vector<Message*>& outMsg) const
+{
+	// basic get handler propagates the get call to subnodes
+	for (vector<SMessageDriven>::const_iterator i = fSubNodes.begin(); i != fSubNodes.end(); i++)
+		(*i)->get (outMsg);
+}
+
+//--------------------------------------------------------------------------
+bool MessageDriven::accept( const Message* msg, vector<Message*>& outMsg )
+{
+	// the basic accept method only checks for the 'get' message
+	if (msg->size() == 0) {
+		get (outMsg);
+		return true;
+	}
+	return false;
+}
+
+//--------------------------------------------------------------------------
+bool MessageDriven::propose( const Message* msg, const char* address, const std::string addrTail, std::vector<Message*>& outMsg)
+{
+	if (name() == address) {			// try to match address with the object name. 
+		if (addrTail.empty() || (addrTail == "/")) {	// it matches and the tail is empty
+			return accept(msg, outMsg);	// then call accept()
+		}
+		else {							// it matches but the tail is not empty
+			string head = Address::addressFirst(addrTail).c_str();
+			for (vector<SMessageDriven>::iterator i = fSubNodes.begin(); i != fSubNodes.end(); i++) {
+				// then propagate propose() to subnodes with a new regexp and a new tail
+				if ((*i)->propose (msg, head.c_str(), Address::addressTail(addrTail), outMsg) )
+					return true;
+			}
+		}
+	}
+	return false;
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/nodes/MessageDriven.h b/architecture/httpdlib/src/nodes/MessageDriven.h
new file mode 100644
index 0000000..e2fef67
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/MessageDriven.h
@@ -0,0 +1,121 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __MessageDriven__
+#define __MessageDriven__
+
+#include <string>
+#include <vector>
+
+#include "MessageProcessor.h"
+#include "smartpointer.h"
+
+namespace httpdfaust
+{
+
+class Message;
+class MessageDriven;
+typedef class SMARTP<MessageDriven>	SMessageDriven;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a base class for objects accepting messages
+	
+	Message driven objects are hierarchically organized in a tree.
+	They provides the necessary to dispatch a message to its destination
+	node, according to the message address. 
+	
+	The principle of the dispatch is the following:
+	- first the processMessage() method should be called on the top level node
+	- next processMessage call propose 
+	
+	
+*/
+class MessageDriven : public MessageProcessor, public smartable
+{
+	std::string						fName;			///< the node name
+	std::string						fPrefix;		///< the node address prefix (Address = fPrefix + '/' + fName)
+	std::vector<SMessageDriven>		fSubNodes;		///< the subnodes of the current node
+
+	protected:
+				 MessageDriven(const char *name, const char *prefix) : fName (name), fPrefix(prefix) {}
+		virtual ~MessageDriven() {}
+
+	public:
+		static SMessageDriven create (const char* name, const char *prefix)	{ return new MessageDriven(name, prefix); }
+
+		/*!
+			\brief message processing method.
+			\param msg the osc message to be processed
+			The method should be called on the top level node.
+		*/
+		virtual bool	processMessage( const Message* msg, std::vector<Message*>& outMsg );
+
+		/*!
+			\brief propose an OSc message at a given hierarchy level.
+			\param msg the osc message currently processed
+			\param regexp a regular expression based on the osc address head
+			\param addrTail the osc address tail
+			
+			The method first tries to match the regular expression with the object name. 
+			When it matches:
+			- it calls \c accept when \c addrTail is empty 
+			- or it \c propose the message to its subnodes when \c addrTail is not empty. 
+			  In this case a new \c regexp is computed with the head of \c addrTail and a new \c addrTail as well.
+		*/
+		virtual bool	propose( const Message* msg, const char* address, const std::string addrTail, std::vector<Message*>& outMsg);
+
+		/*!
+			\brief accept a message. 
+			\param msg the message currently processed
+			\return true when the message is processed by the node
+			
+			The method is called only for the destination nodes. The real message acceptance is the node 
+			responsability and may depend on the message content.
+		*/
+		virtual bool	accept( const Message* msg, std::vector<Message*>& outMsg );
+
+		/*!
+			\brief handler for the \c 'get' message
+			\param ipdest the output message destination IP
+			
+			The \c 'get' message is supported by every node:
+			- it is propagated to the subnodes until it reaches terminal nodes
+			- a terminal node send its state on \c 'get' request to the IP address given as parameter.
+			The \c get method is basically called by the accept method.
+		*/
+		virtual void	get (std::vector<Message*>& outMsg) const;		///< handler for the 'get' message
+
+		void			add ( SMessageDriven node )	{ fSubNodes.push_back (node); }
+		const char*		getName() const				{ return fName.c_str(); }
+		std::string		getAddress() const;
+		int				size () const				{ return fSubNodes.size (); }
+		
+		const std::string&	name() const			{ return fName; }
+		SMessageDriven	subnode (int i) 			{ return fSubNodes[i]; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/src/nodes/RootNode.cpp b/architecture/httpdlib/src/nodes/RootNode.cpp
new file mode 100644
index 0000000..f1633e4
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/RootNode.cpp
@@ -0,0 +1,67 @@
+/*
+
+  Copyright (C) 2012 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#include <string>
+
+#include "RootNode.h"
+#include "Message.h"
+
+using namespace std;
+
+namespace httpdfaust
+{
+
+static const char * kJSONAddr = "/JSON";
+
+
+//--------------------------------------------------------------------------
+bool RootNode::processMessage( const Message* msg, vector<Message*>& outMsg )
+{
+	const string& addr = msg->address();
+	if (addr.empty() || (addr == "/")) {
+		return accept(msg, outMsg);
+	}
+	else if (addr == kJSONAddr) {
+		Message* msg = new Message (fJson);
+		msg->setMIMEType ("application/json");
+		outMsg.push_back (msg);
+		return true;
+	}
+	return MessageDriven::processMessage( msg, outMsg );
+}
+
+//--------------------------------------------------------------------------
+bool RootNode::accept( const Message* msg, vector<Message*>& outMsg )
+{
+	string val;
+	// checks for the 'JSON' message first
+	if ((msg->size() == 0) && (msg->address() == "/")) {
+		Message* msg = new Message (fHtml);
+		msg->setMIMEType ("text/html");
+		outMsg.push_back(msg);
+		return true;
+	}
+	return MessageDriven::accept (msg, outMsg);
+}
+
+} // end namespoace
diff --git a/architecture/httpdlib/src/nodes/RootNode.h b/architecture/httpdlib/src/nodes/RootNode.h
new file mode 100644
index 0000000..5cbd625
--- /dev/null
+++ b/architecture/httpdlib/src/nodes/RootNode.h
@@ -0,0 +1,62 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __RootNode__
+#define __RootNode__
+
+#include <string>
+#include "MessageDriven.h"
+
+namespace httpdfaust
+{
+
+class RootNode;
+typedef class SMARTP<RootNode>	SRootNode;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust program root node
+*/
+class RootNode : public MessageDriven
+{
+	std::string fJson;
+	std::string fHtml;
+	
+	protected:
+				 RootNode(const char *name) : MessageDriven (name, "") {}
+		virtual ~RootNode() {}
+
+	public:
+		static SRootNode create (const char* name) { return new RootNode(name); }
+
+		void			setJSON( const std::string& uidesc )	{ fJson = uidesc; }
+		void			setHtml( const std::string& html )		{ fHtml = html; }
+		//--------------------------------------------------------------------------
+		bool			processMessage( const Message* msg, std::vector<Message*>& outMsg );
+		virtual bool	accept( const Message* msg, std::vector<Message*>& outMsg );
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/httpdlib/todo.txt b/architecture/httpdlib/todo.txt
new file mode 100644
index 0000000..cd2e88b
--- /dev/null
+++ b/architecture/httpdlib/todo.txt
@@ -0,0 +1,17 @@
+=================================================================
+                         FAUST HTTPD Library
+
+                     Copyright (c) 2012 Grame
+=================================================================
+
+----------------------------------------------------------------------
+ todo list
+----------------------------------------------------------------------
+
+- correct host name management across platforms and systems
+- UI groups management
+- define a strategy for FAUSTDocumentRoot
+- embed html folder in mac bundles
+
++
+- sound output streaming
diff --git a/architecture/iOS/Default-568h at 2x.png b/architecture/iOS/Default-568h at 2x.png
new file mode 100644
index 0000000..f51d16c
Binary files /dev/null and b/architecture/iOS/Default-568h at 2x.png differ
diff --git a/architecture/iOS/Default-Landscape at 2x~ipad.png b/architecture/iOS/Default-Landscape at 2x~ipad.png
new file mode 100644
index 0000000..da25c2f
Binary files /dev/null and b/architecture/iOS/Default-Landscape at 2x~ipad.png differ
diff --git a/architecture/iOS/Default-Landscape~ipad.png b/architecture/iOS/Default-Landscape~ipad.png
new file mode 100644
index 0000000..cf94802
Binary files /dev/null and b/architecture/iOS/Default-Landscape~ipad.png differ
diff --git a/architecture/iOS/Default-Portrait at 2x~ipad.png b/architecture/iOS/Default-Portrait at 2x~ipad.png
new file mode 100644
index 0000000..40e7289
Binary files /dev/null and b/architecture/iOS/Default-Portrait at 2x~ipad.png differ
diff --git a/architecture/iOS/Default-Portrait~ipad.png b/architecture/iOS/Default-Portrait~ipad.png
new file mode 100644
index 0000000..2359c9e
Binary files /dev/null and b/architecture/iOS/Default-Portrait~ipad.png differ
diff --git a/architecture/iOS/Default.png b/architecture/iOS/Default.png
new file mode 100644
index 0000000..be259ee
Binary files /dev/null and b/architecture/iOS/Default.png differ
diff --git a/architecture/iOS/Default at 2x.png b/architecture/iOS/Default at 2x.png
new file mode 100644
index 0000000..e5114aa
Binary files /dev/null and b/architecture/iOS/Default at 2x.png differ
diff --git a/architecture/iOS/Icon-72 at 2x.png b/architecture/iOS/Icon-72 at 2x.png
new file mode 100644
index 0000000..b28cd52
Binary files /dev/null and b/architecture/iOS/Icon-72 at 2x.png differ
diff --git a/architecture/iOS/Icon at 2x.png b/architecture/iOS/Icon at 2x.png
new file mode 100644
index 0000000..d0256dc
Binary files /dev/null and b/architecture/iOS/Icon at 2x.png differ
diff --git a/architecture/iOS/iOS.xcodeproj/project.pbxproj b/architecture/iOS/iOS.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..7d7a52e
--- /dev/null
+++ b/architecture/iOS/iOS.xcodeproj/project.pbxproj
@@ -0,0 +1,1337 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		4B01EDED17D5F3BC005F8D54 /* Default-Landscape at 2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDEB17D5F323005F8D54 /* Default-Landscape at 2x~ipad.png */; };
+		4B01EDEF17D5F459005F8D54 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE517D5F31A005F8D54 /* Default-Portrait~ipad.png */; };
+		4B01EDF017D5F45F005F8D54 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE917D5F320005F8D54 /* Default-Landscape~ipad.png */; };
+		4B01EDF117D5F464005F8D54 /* Default-Portrait at 2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE717D5F31E005F8D54 /* Default-Portrait at 2x~ipad.png */; };
+		4B01EDF317D5F79F005F8D54 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDF217D5F79F005F8D54 /* Default.png */; };
+		4B01EDF417D5F7A5005F8D54 /* Default at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE117D5F30D005F8D54 /* Default at 2x.png */; };
+		4B01EDF517D5F7A8005F8D54 /* Default-568h at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE317D5F30F005F8D54 /* Default-568h at 2x.png */; };
+		4B04365216E9E9AD00C0C02A /* Icon-Analyzer.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364916E9E9AD00C0C02A /* Icon-Analyzer.png */; };
+		4B04365316E9E9AD00C0C02A /* Icon-Analyzer.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364916E9E9AD00C0C02A /* Icon-Analyzer.png */; };
+		4B04365416E9E9AD00C0C02A /* Icon-Analyzer136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364A16E9E9AD00C0C02A /* Icon-Analyzer136.png */; };
+		4B04365516E9E9AD00C0C02A /* Icon-Analyzer136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364A16E9E9AD00C0C02A /* Icon-Analyzer136.png */; };
+		4B04365616E9E9AD00C0C02A /* Icon-Analyzer at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364B16E9E9AD00C0C02A /* Icon-Analyzer at 2x.png */; };
+		4B04365716E9E9AD00C0C02A /* Icon-Analyzer at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364B16E9E9AD00C0C02A /* Icon-Analyzer at 2x.png */; };
+		4B04365816E9E9AD00C0C02A /* Icon-Fx.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364C16E9E9AD00C0C02A /* Icon-Fx.png */; };
+		4B04365916E9E9AD00C0C02A /* Icon-Fx.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364C16E9E9AD00C0C02A /* Icon-Fx.png */; };
+		4B04365A16E9E9AD00C0C02A /* Icon-Fx136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364D16E9E9AD00C0C02A /* Icon-Fx136.png */; };
+		4B04365B16E9E9AD00C0C02A /* Icon-Fx136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364D16E9E9AD00C0C02A /* Icon-Fx136.png */; };
+		4B04365C16E9E9AD00C0C02A /* Icon-Fx at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364E16E9E9AD00C0C02A /* Icon-Fx at 2x.png */; };
+		4B04365D16E9E9AD00C0C02A /* Icon-Fx at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364E16E9E9AD00C0C02A /* Icon-Fx at 2x.png */; };
+		4B04365E16E9E9AD00C0C02A /* Icon-Output.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364F16E9E9AD00C0C02A /* Icon-Output.png */; };
+		4B04365F16E9E9AD00C0C02A /* Icon-Output.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364F16E9E9AD00C0C02A /* Icon-Output.png */; };
+		4B04366016E9E9AD00C0C02A /* Icon-Output136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04365016E9E9AD00C0C02A /* Icon-Output136.png */; };
+		4B04366116E9E9AD00C0C02A /* Icon-Output136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04365016E9E9AD00C0C02A /* Icon-Output136.png */; };
+		4B04366216E9E9AD00C0C02A /* Icon-Output at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04365116E9E9AD00C0C02A /* Icon-Output at 2x.png */; };
+		4B04366316E9E9AD00C0C02A /* Icon-Output at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04365116E9E9AD00C0C02A /* Icon-Output at 2x.png */; };
+		4B06EC8D16E77D6A004D2F59 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 65E5ED9E14DB037D00136CFC /* main.m */; };
+		4B06EC8E16E77D6A004D2F59 /* FIAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDA214DB037D00136CFC /* FIAppDelegate.mm */; };
+		4B06EC8F16E77D6A004D2F59 /* FIMainViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDAB14DB037D00136CFC /* FIMainViewController.mm */; };
+		4B06EC9016E77D6A004D2F59 /* FIFlipsideViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDAE14DB037D00136CFC /* FIFlipsideViewController.mm */; };
+		4B06EC9116E77D6A004D2F59 /* FIButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748514ED30F000172A10 /* FIButton.mm */; };
+		4B06EC9216E77D6A004D2F59 /* FIResponder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748714ED30F000172A10 /* FIResponder.mm */; };
+		4B06EC9316E77D6A004D2F59 /* FISlider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748914ED30F000172A10 /* FISlider.mm */; };
+		4B06EC9416E77D6A004D2F59 /* FITextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65510E9414EEC1190014A01F /* FITextField.mm */; };
+		4B06EC9516E77D6A004D2F59 /* FIKnob.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6559E84614F2685A00D3AB9A /* FIKnob.mm */; };
+		4B06EC9616E77D6A004D2F59 /* FIBargraph.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65C1C07314F543E9006464DF /* FIBargraph.mm */; };
+		4B06EC9716E77D6A004D2F59 /* FIBox.mm in Sources */ = {isa = PBXBuildFile; fileRef = 655DAAE814F69C9B0013FAF5 /* FIBox.mm */; };
+		4B06EC9816E77D6A004D2F59 /* FITabView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6560454014FE924400AE84A9 /* FITabView.mm */; };
+		4B06EC9916E77D6A004D2F59 /* FIHint.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65961D4F1546DFD70004BC59 /* FIHint.mm */; };
+		4B06EC9A16E77D6A004D2F59 /* FIScrollView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65FD744E1549993A00E7CB0B /* FIScrollView.mm */; };
+		4B06EC9B16E77D6A004D2F59 /* FISensorFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6528EF041564212100A310B2 /* FISensorFilter.mm */; };
+		4B06EC9D16E77D6A004D2F59 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E85C9A157806C2009F2D7A /* QuartzCore.framework */; };
+		4B06EC9E16E77D6A004D2F59 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65F87430156FFB0C008AE175 /* CoreMotion.framework */; };
+		4B06EC9F16E77D6A004D2F59 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65D1BD1315668A8A00ADCA32 /* CoreLocation.framework */; };
+		4B06ECA016E77D6A004D2F59 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5EDCD14DB055500136CFC /* AudioToolbox.framework */; };
+		4B06ECA116E77D6A004D2F59 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9214DB037D00136CFC /* UIKit.framework */; };
+		4B06ECA216E77D6A004D2F59 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9414DB037D00136CFC /* Foundation.framework */; };
+		4B06ECA316E77D6A004D2F59 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9614DB037D00136CFC /* CoreGraphics.framework */; };
+		4B06ECA416E77D6A004D2F59 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDAA20F16AEF05D00A3499E /* Accelerate.framework */; };
+		4B06ECA616E77D6A004D2F59 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 65E5ED9B14DB037D00136CFC /* InfoPlist.strings */; };
+		4B06ECAA16E77D6A004D2F59 /* close.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E85C9D157806E6009F2D7A /* close.png */; };
+		4B06ECAB16E77D6A004D2F59 /* close at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E85C9E157806E6009F2D7A /* close at 2x.png */; };
+		4B27569C17D5E82E00BAB8B9 /* Icon at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569A17D5E82500BAB8B9 /* Icon at 2x.png */; };
+		4B27569E17D5E83700BAB8B9 /* Icon-72 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569D17D5E83700BAB8B9 /* Icon-72 at 2x.png */; };
+		4B4953581A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4953541A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard */; };
+		4B4953591A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4953541A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard */; };
+		4B49535A1A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4953561A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard */; };
+		4B49535B1A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4953561A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard */; };
+		4B5F800517D5F92000E0F1ED /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569817D5E80D00BAB8B9 /* Icon.png */; };
+		4B5F800617D5F93100E0F1ED /* Icon at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569A17D5E82500BAB8B9 /* Icon at 2x.png */; };
+		4B5F800817D5F93700E0F1ED /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B5F800717D5F93700E0F1ED /* Icon-72.png */; };
+		4B5F800917D5F93900E0F1ED /* Icon-72 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569D17D5E83700BAB8B9 /* Icon-72 at 2x.png */; };
+		4BAD5B9F16F0FA5D000FEF86 /* jack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BAD5B9E16F0FA5D000FEF86 /* jack.framework */; };
+		4BDAA21016AEF05D00A3499E /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDAA20F16AEF05D00A3499E /* Accelerate.framework */; };
+		4BEF91A61B96FFC000F2D974 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 65E5ED9E14DB037D00136CFC /* main.m */; };
+		4BEF91A71B96FFC000F2D974 /* FIAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDA214DB037D00136CFC /* FIAppDelegate.mm */; };
+		4BEF91A81B96FFC000F2D974 /* FIMainViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDAB14DB037D00136CFC /* FIMainViewController.mm */; };
+		4BEF91A91B96FFC000F2D974 /* FIFlipsideViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDAE14DB037D00136CFC /* FIFlipsideViewController.mm */; };
+		4BEF91AA1B96FFC000F2D974 /* FIButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748514ED30F000172A10 /* FIButton.mm */; };
+		4BEF91AB1B96FFC000F2D974 /* FIResponder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748714ED30F000172A10 /* FIResponder.mm */; };
+		4BEF91AC1B96FFC000F2D974 /* FISlider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748914ED30F000172A10 /* FISlider.mm */; };
+		4BEF91AD1B96FFC000F2D974 /* FITextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65510E9414EEC1190014A01F /* FITextField.mm */; };
+		4BEF91AE1B96FFC000F2D974 /* FIKnob.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6559E84614F2685A00D3AB9A /* FIKnob.mm */; };
+		4BEF91AF1B96FFC000F2D974 /* FIBargraph.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65C1C07314F543E9006464DF /* FIBargraph.mm */; };
+		4BEF91B01B96FFC000F2D974 /* FIBox.mm in Sources */ = {isa = PBXBuildFile; fileRef = 655DAAE814F69C9B0013FAF5 /* FIBox.mm */; };
+		4BEF91B11B96FFC000F2D974 /* FITabView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6560454014FE924400AE84A9 /* FITabView.mm */; };
+		4BEF91B21B96FFC000F2D974 /* FIHint.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65961D4F1546DFD70004BC59 /* FIHint.mm */; };
+		4BEF91B31B96FFC000F2D974 /* FIScrollView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65FD744E1549993A00E7CB0B /* FIScrollView.mm */; };
+		4BEF91B41B96FFC000F2D974 /* FISensorFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6528EF041564212100A310B2 /* FISensorFilter.mm */; };
+		4BEF91B51B96FFC000F2D974 /* JackViewPortsViewBackgroundView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 656EE12E176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm */; };
+		4BEF91B71B96FFC000F2D974 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E85C9A157806C2009F2D7A /* QuartzCore.framework */; };
+		4BEF91B81B96FFC000F2D974 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65F87430156FFB0C008AE175 /* CoreMotion.framework */; };
+		4BEF91B91B96FFC000F2D974 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65D1BD1315668A8A00ADCA32 /* CoreLocation.framework */; };
+		4BEF91BA1B96FFC000F2D974 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5EDCD14DB055500136CFC /* AudioToolbox.framework */; };
+		4BEF91BB1B96FFC000F2D974 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9214DB037D00136CFC /* UIKit.framework */; };
+		4BEF91BC1B96FFC000F2D974 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9414DB037D00136CFC /* Foundation.framework */; };
+		4BEF91BD1B96FFC000F2D974 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9614DB037D00136CFC /* CoreGraphics.framework */; };
+		4BEF91BE1B96FFC000F2D974 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDAA20F16AEF05D00A3499E /* Accelerate.framework */; };
+		4BEF91C01B96FFC000F2D974 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 65E5ED9B14DB037D00136CFC /* InfoPlist.strings */; };
+		4BEF91C11B96FFC000F2D974 /* close.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E85C9D157806E6009F2D7A /* close.png */; };
+		4BEF91C21B96FFC000F2D974 /* close at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E85C9E157806E6009F2D7A /* close at 2x.png */; };
+		4BEF91C31B96FFC000F2D974 /* Icon-Analyzer.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364916E9E9AD00C0C02A /* Icon-Analyzer.png */; };
+		4BEF91C41B96FFC000F2D974 /* Icon-Analyzer136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364A16E9E9AD00C0C02A /* Icon-Analyzer136.png */; };
+		4BEF91C51B96FFC000F2D974 /* Icon-Analyzer at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364B16E9E9AD00C0C02A /* Icon-Analyzer at 2x.png */; };
+		4BEF91C61B96FFC000F2D974 /* Icon-Fx.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364C16E9E9AD00C0C02A /* Icon-Fx.png */; };
+		4BEF91C71B96FFC000F2D974 /* Icon-Fx136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364D16E9E9AD00C0C02A /* Icon-Fx136.png */; };
+		4BEF91C81B96FFC000F2D974 /* Icon-Fx at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364E16E9E9AD00C0C02A /* Icon-Fx at 2x.png */; };
+		4BEF91C91B96FFC000F2D974 /* Icon-Output.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04364F16E9E9AD00C0C02A /* Icon-Output.png */; };
+		4BEF91CA1B96FFC000F2D974 /* Icon-Output136.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04365016E9E9AD00C0C02A /* Icon-Output136.png */; };
+		4BEF91CB1B96FFC000F2D974 /* Icon-Output at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B04365116E9E9AD00C0C02A /* Icon-Output at 2x.png */; };
+		4BEF91CC1B96FFC000F2D974 /* Icon-Jack.png in Resources */ = {isa = PBXBuildFile; fileRef = 651BB43C171D91260065CBC9 /* Icon-Jack.png */; };
+		4BEF91CD1B96FFC000F2D974 /* Icon-Jack at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 651BB43D171D91260065CBC9 /* Icon-Jack at 2x.png */; };
+		4BEF91CE1B96FFC000F2D974 /* Icon_Apple.png in Resources */ = {isa = PBXBuildFile; fileRef = 6596C3B4172926BB000AD403 /* Icon_Apple.png */; };
+		4BEF91CF1B96FFC000F2D974 /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4953561A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard */; };
+		4BEF91D01B96FFC000F2D974 /* Icon_Apple at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6596C3B5172926BB000AD403 /* Icon_Apple at 2x.png */; };
+		4BEF91D11B96FFC000F2D974 /* Icon-Delete.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3120E17722C10000E2AFA /* Icon-Delete.png */; };
+		4BEF91D21B96FFC000F2D974 /* Icon-Delete at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3120F17722C10000E2AFA /* Icon-Delete at 2x.png */; };
+		4BEF91D31B96FFC000F2D974 /* Icon-Expand.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3121017722C10000E2AFA /* Icon-Expand.png */; };
+		4BEF91D41B96FFC000F2D974 /* Icon-Expand at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3121117722C10000E2AFA /* Icon-Expand at 2x.png */; };
+		4BEF91D51B96FFC000F2D974 /* jackview-audio-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64117832FB400175F2F /* jackview-audio-off.png */; };
+		4BEF91D61B96FFC000F2D974 /* jackview-audio-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64217832FB400175F2F /* jackview-audio-off at 2x.png */; };
+		4BEF91D71B96FFC000F2D974 /* jackview-audio-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64317832FB400175F2F /* jackview-audio-on.png */; };
+		4BEF91D81B96FFC000F2D974 /* jackview-audio-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64417832FB400175F2F /* jackview-audio-on at 2x.png */; };
+		4BEF91D91B96FFC000F2D974 /* jackview-in.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64517832FB400175F2F /* jackview-in.png */; };
+		4BEF91DA1B96FFC000F2D974 /* jackview-in at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64617832FB400175F2F /* jackview-in at 2x.png */; };
+		4BEF91DB1B96FFC000F2D974 /* jackview-midi-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64717832FB400175F2F /* jackview-midi-off.png */; };
+		4BEF91DC1B96FFC000F2D974 /* jackview-midi-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64817832FB400175F2F /* jackview-midi-off at 2x.png */; };
+		4BEF91DD1B96FFC000F2D974 /* jackview-midi-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64917832FB400175F2F /* jackview-midi-on.png */; };
+		4BEF91DE1B96FFC000F2D974 /* jackview-midi-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64A17832FB400175F2F /* jackview-midi-on at 2x.png */; };
+		4BEF91DF1B96FFC000F2D974 /* jackview-out.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64B17832FB400175F2F /* jackview-out.png */; };
+		4BEF91E01B96FFC000F2D974 /* jackview-out at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64C17832FB400175F2F /* jackview-out at 2x.png */; };
+		4BEF91E11B96FFC000F2D974 /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4953541A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard */; };
+		4BEF91E21B96FFC000F2D974 /* Default-Landscape at 2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDEB17D5F323005F8D54 /* Default-Landscape at 2x~ipad.png */; };
+		4BEF91E31B96FFC000F2D974 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE517D5F31A005F8D54 /* Default-Portrait~ipad.png */; };
+		4BEF91E41B96FFC000F2D974 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE917D5F320005F8D54 /* Default-Landscape~ipad.png */; };
+		4BEF91E51B96FFC000F2D974 /* Default-Portrait at 2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE717D5F31E005F8D54 /* Default-Portrait at 2x~ipad.png */; };
+		4BEF91E61B96FFC000F2D974 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDF217D5F79F005F8D54 /* Default.png */; };
+		4BEF91E71B96FFC000F2D974 /* Default at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE117D5F30D005F8D54 /* Default at 2x.png */; };
+		4BEF91E81B96FFC000F2D974 /* Default-568h at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE317D5F30F005F8D54 /* Default-568h at 2x.png */; };
+		4BEF91E91B96FFC000F2D974 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569817D5E80D00BAB8B9 /* Icon.png */; };
+		4BEF91EA1B96FFC000F2D974 /* Icon at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569A17D5E82500BAB8B9 /* Icon at 2x.png */; };
+		4BEF91EB1B96FFC000F2D974 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B5F800717D5F93700E0F1ED /* Icon-72.png */; };
+		4BEF91EC1B96FFC000F2D974 /* Icon-72 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569D17D5E83700BAB8B9 /* Icon-72 at 2x.png */; };
+		4BFCB7F317D63C1A007DE831 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B27569817D5E80D00BAB8B9 /* Icon.png */; };
+		4BFCB7F617D63C2B007DE831 /* Default-568h at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE317D5F30F005F8D54 /* Default-568h at 2x.png */; };
+		4BFCB7F717D63C37007DE831 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B5F800717D5F93700E0F1ED /* Icon-72.png */; };
+		4BFCB7F917D63C52007DE831 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE517D5F31A005F8D54 /* Default-Portrait~ipad.png */; };
+		4BFCB7FA17D63C56007DE831 /* Default-Portrait at 2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE717D5F31E005F8D54 /* Default-Portrait at 2x~ipad.png */; };
+		4BFCB7FB17D63C58007DE831 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE917D5F320005F8D54 /* Default-Landscape~ipad.png */; };
+		4BFCB7FC17D63C5A007DE831 /* Default-Landscape at 2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDEB17D5F323005F8D54 /* Default-Landscape at 2x~ipad.png */; };
+		4BFCB7FD17D63C61007DE831 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDF217D5F79F005F8D54 /* Default.png */; };
+		4BFCB7FE17D63C63007DE831 /* Default at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B01EDE117D5F30D005F8D54 /* Default at 2x.png */; };
+		651BB43E171D91260065CBC9 /* Icon-Jack.png in Resources */ = {isa = PBXBuildFile; fileRef = 651BB43C171D91260065CBC9 /* Icon-Jack.png */; };
+		651BB43F171D91260065CBC9 /* Icon-Jack.png in Resources */ = {isa = PBXBuildFile; fileRef = 651BB43C171D91260065CBC9 /* Icon-Jack.png */; };
+		651BB440171D91260065CBC9 /* Icon-Jack at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 651BB43D171D91260065CBC9 /* Icon-Jack at 2x.png */; };
+		651BB441171D91260065CBC9 /* Icon-Jack at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 651BB43D171D91260065CBC9 /* Icon-Jack at 2x.png */; };
+		6528EF051564212100A310B2 /* FISensorFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6528EF041564212100A310B2 /* FISensorFilter.mm */; };
+		6534E20F17301716009A4FD2 /* JackViewPortsView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6534E20E17301716009A4FD2 /* JackViewPortsView.mm */; };
+		654EE64D17832FB400175F2F /* jackview-audio-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64117832FB400175F2F /* jackview-audio-off.png */; };
+		654EE64E17832FB400175F2F /* jackview-audio-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64117832FB400175F2F /* jackview-audio-off.png */; };
+		654EE64F17832FB400175F2F /* jackview-audio-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64117832FB400175F2F /* jackview-audio-off.png */; };
+		654EE65017832FB400175F2F /* jackview-audio-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64217832FB400175F2F /* jackview-audio-off at 2x.png */; };
+		654EE65117832FB400175F2F /* jackview-audio-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64217832FB400175F2F /* jackview-audio-off at 2x.png */; };
+		654EE65217832FB400175F2F /* jackview-audio-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64217832FB400175F2F /* jackview-audio-off at 2x.png */; };
+		654EE65317832FB400175F2F /* jackview-audio-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64317832FB400175F2F /* jackview-audio-on.png */; };
+		654EE65417832FB400175F2F /* jackview-audio-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64317832FB400175F2F /* jackview-audio-on.png */; };
+		654EE65517832FB400175F2F /* jackview-audio-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64317832FB400175F2F /* jackview-audio-on.png */; };
+		654EE65617832FB400175F2F /* jackview-audio-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64417832FB400175F2F /* jackview-audio-on at 2x.png */; };
+		654EE65717832FB400175F2F /* jackview-audio-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64417832FB400175F2F /* jackview-audio-on at 2x.png */; };
+		654EE65817832FB400175F2F /* jackview-audio-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64417832FB400175F2F /* jackview-audio-on at 2x.png */; };
+		654EE65917832FB400175F2F /* jackview-in.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64517832FB400175F2F /* jackview-in.png */; };
+		654EE65A17832FB400175F2F /* jackview-in.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64517832FB400175F2F /* jackview-in.png */; };
+		654EE65B17832FB400175F2F /* jackview-in.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64517832FB400175F2F /* jackview-in.png */; };
+		654EE65C17832FB400175F2F /* jackview-in at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64617832FB400175F2F /* jackview-in at 2x.png */; };
+		654EE65D17832FB400175F2F /* jackview-in at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64617832FB400175F2F /* jackview-in at 2x.png */; };
+		654EE65E17832FB400175F2F /* jackview-in at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64617832FB400175F2F /* jackview-in at 2x.png */; };
+		654EE65F17832FB400175F2F /* jackview-midi-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64717832FB400175F2F /* jackview-midi-off.png */; };
+		654EE66017832FB400175F2F /* jackview-midi-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64717832FB400175F2F /* jackview-midi-off.png */; };
+		654EE66117832FB400175F2F /* jackview-midi-off.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64717832FB400175F2F /* jackview-midi-off.png */; };
+		654EE66217832FB400175F2F /* jackview-midi-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64817832FB400175F2F /* jackview-midi-off at 2x.png */; };
+		654EE66317832FB400175F2F /* jackview-midi-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64817832FB400175F2F /* jackview-midi-off at 2x.png */; };
+		654EE66417832FB400175F2F /* jackview-midi-off at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64817832FB400175F2F /* jackview-midi-off at 2x.png */; };
+		654EE66517832FB400175F2F /* jackview-midi-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64917832FB400175F2F /* jackview-midi-on.png */; };
+		654EE66617832FB400175F2F /* jackview-midi-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64917832FB400175F2F /* jackview-midi-on.png */; };
+		654EE66717832FB400175F2F /* jackview-midi-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64917832FB400175F2F /* jackview-midi-on.png */; };
+		654EE66817832FB400175F2F /* jackview-midi-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64A17832FB400175F2F /* jackview-midi-on at 2x.png */; };
+		654EE66917832FB400175F2F /* jackview-midi-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64A17832FB400175F2F /* jackview-midi-on at 2x.png */; };
+		654EE66A17832FB400175F2F /* jackview-midi-on at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64A17832FB400175F2F /* jackview-midi-on at 2x.png */; };
+		654EE66B17832FB400175F2F /* jackview-out.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64B17832FB400175F2F /* jackview-out.png */; };
+		654EE66C17832FB400175F2F /* jackview-out.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64B17832FB400175F2F /* jackview-out.png */; };
+		654EE66D17832FB400175F2F /* jackview-out.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64B17832FB400175F2F /* jackview-out.png */; };
+		654EE66E17832FB400175F2F /* jackview-out at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64C17832FB400175F2F /* jackview-out at 2x.png */; };
+		654EE66F17832FB400175F2F /* jackview-out at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64C17832FB400175F2F /* jackview-out at 2x.png */; };
+		654EE67017832FB400175F2F /* jackview-out at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 654EE64C17832FB400175F2F /* jackview-out at 2x.png */; };
+		65510E9514EEC1190014A01F /* FITextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65510E9414EEC1190014A01F /* FITextField.mm */; };
+		6559E84714F2685A00D3AB9A /* FIKnob.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6559E84614F2685A00D3AB9A /* FIKnob.mm */; };
+		655DAAE914F69C9B0013FAF5 /* FIBox.mm in Sources */ = {isa = PBXBuildFile; fileRef = 655DAAE814F69C9B0013FAF5 /* FIBox.mm */; };
+		6560454114FE924400AE84A9 /* FITabView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6560454014FE924400AE84A9 /* FITabView.mm */; };
+		6566748A14ED30F000172A10 /* FIButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748514ED30F000172A10 /* FIButton.mm */; };
+		6566748B14ED30F000172A10 /* FIResponder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748714ED30F000172A10 /* FIResponder.mm */; };
+		6566748C14ED30F000172A10 /* FISlider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6566748914ED30F000172A10 /* FISlider.mm */; };
+		656EE12F176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 656EE12E176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm */; };
+		656EE130176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 656EE12E176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm */; };
+		65961D501546DFD70004BC59 /* FIHint.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65961D4F1546DFD70004BC59 /* FIHint.mm */; };
+		6596C3B6172926BB000AD403 /* Icon_Apple.png in Resources */ = {isa = PBXBuildFile; fileRef = 6596C3B4172926BB000AD403 /* Icon_Apple.png */; };
+		6596C3B7172926BB000AD403 /* Icon_Apple.png in Resources */ = {isa = PBXBuildFile; fileRef = 6596C3B4172926BB000AD403 /* Icon_Apple.png */; };
+		6596C3B8172926BB000AD403 /* Icon_Apple at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6596C3B5172926BB000AD403 /* Icon_Apple at 2x.png */; };
+		6596C3B9172926BB000AD403 /* Icon_Apple at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6596C3B5172926BB000AD403 /* Icon_Apple at 2x.png */; };
+		65B9D5DB170EB9D5009DE0DC /* JackView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65B9D5DA170EB9D5009DE0DC /* JackView.mm */; };
+		65C1C07414F543E9006464DF /* FIBargraph.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65C1C07314F543E9006464DF /* FIBargraph.mm */; };
+		65D1BD1415668A8A00ADCA32 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65D1BD1315668A8A00ADCA32 /* CoreLocation.framework */; };
+		65E3121217722C10000E2AFA /* Icon-Delete.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3120E17722C10000E2AFA /* Icon-Delete.png */; };
+		65E3121317722C10000E2AFA /* Icon-Delete.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3120E17722C10000E2AFA /* Icon-Delete.png */; };
+		65E3121417722C10000E2AFA /* Icon-Delete at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3120F17722C10000E2AFA /* Icon-Delete at 2x.png */; };
+		65E3121517722C10000E2AFA /* Icon-Delete at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3120F17722C10000E2AFA /* Icon-Delete at 2x.png */; };
+		65E3121617722C10000E2AFA /* Icon-Expand.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3121017722C10000E2AFA /* Icon-Expand.png */; };
+		65E3121717722C10000E2AFA /* Icon-Expand.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3121017722C10000E2AFA /* Icon-Expand.png */; };
+		65E3121817722C10000E2AFA /* Icon-Expand at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3121117722C10000E2AFA /* Icon-Expand at 2x.png */; };
+		65E3121917722C10000E2AFA /* Icon-Expand at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E3121117722C10000E2AFA /* Icon-Expand at 2x.png */; };
+		65E5ED9314DB037D00136CFC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9214DB037D00136CFC /* UIKit.framework */; };
+		65E5ED9514DB037D00136CFC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9414DB037D00136CFC /* Foundation.framework */; };
+		65E5ED9714DB037D00136CFC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9614DB037D00136CFC /* CoreGraphics.framework */; };
+		65E5ED9D14DB037D00136CFC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 65E5ED9B14DB037D00136CFC /* InfoPlist.strings */; };
+		65E5ED9F14DB037D00136CFC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 65E5ED9E14DB037D00136CFC /* main.m */; };
+		65E5EDA314DB037D00136CFC /* FIAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDA214DB037D00136CFC /* FIAppDelegate.mm */; };
+		65E5EDAC14DB037D00136CFC /* FIMainViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDAB14DB037D00136CFC /* FIMainViewController.mm */; };
+		65E5EDAF14DB037D00136CFC /* FIFlipsideViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDAE14DB037D00136CFC /* FIFlipsideViewController.mm */; };
+		65E5EDB714DB037D00136CFC /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5EDB614DB037D00136CFC /* SenTestingKit.framework */; };
+		65E5EDB814DB037D00136CFC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9214DB037D00136CFC /* UIKit.framework */; };
+		65E5EDB914DB037D00136CFC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5ED9414DB037D00136CFC /* Foundation.framework */; };
+		65E5EDC114DB037D00136CFC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 65E5EDBF14DB037D00136CFC /* InfoPlist.strings */; };
+		65E5EDC414DB037D00136CFC /* iOSTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 65E5EDC314DB037D00136CFC /* iOSTests.m */; };
+		65E5EDCE14DB055500136CFC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E5EDCD14DB055500136CFC /* AudioToolbox.framework */; };
+		65E85C9B157806C2009F2D7A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E85C9A157806C2009F2D7A /* QuartzCore.framework */; };
+		65E85C9F157806E6009F2D7A /* close.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E85C9D157806E6009F2D7A /* close.png */; };
+		65E85CA0157806E6009F2D7A /* close at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 65E85C9E157806E6009F2D7A /* close at 2x.png */; };
+		65F87431156FFB0C008AE175 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65F87430156FFB0C008AE175 /* CoreMotion.framework */; };
+		65FD744F1549993A00E7CB0B /* FIScrollView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65FD744E1549993A00E7CB0B /* FIScrollView.mm */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		65E5EDBA14DB037D00136CFC /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 65E5ED8514DB037D00136CFC /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 65E5ED8D14DB037D00136CFC;
+			remoteInfo = iOS;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		4B01EDE117D5F30D005F8D54 /* Default at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default at 2x.png"; sourceTree = "<group>"; };
+		4B01EDE317D5F30F005F8D54 /* Default-568h at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h at 2x.png"; sourceTree = "<group>"; };
+		4B01EDE517D5F31A005F8D54 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
+		4B01EDE717D5F31E005F8D54 /* Default-Portrait at 2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait at 2x~ipad.png"; sourceTree = "<group>"; };
+		4B01EDE917D5F320005F8D54 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
+		4B01EDEB17D5F323005F8D54 /* Default-Landscape at 2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape at 2x~ipad.png"; sourceTree = "<group>"; };
+		4B01EDF217D5F79F005F8D54 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
+		4B04364916E9E9AD00C0C02A /* Icon-Analyzer.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Analyzer.png"; sourceTree = "<group>"; };
+		4B04364A16E9E9AD00C0C02A /* Icon-Analyzer136.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Analyzer136.png"; sourceTree = "<group>"; };
+		4B04364B16E9E9AD00C0C02A /* Icon-Analyzer at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Analyzer at 2x.png"; sourceTree = "<group>"; };
+		4B04364C16E9E9AD00C0C02A /* Icon-Fx.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Fx.png"; sourceTree = "<group>"; };
+		4B04364D16E9E9AD00C0C02A /* Icon-Fx136.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Fx136.png"; sourceTree = "<group>"; };
+		4B04364E16E9E9AD00C0C02A /* Icon-Fx at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Fx at 2x.png"; sourceTree = "<group>"; };
+		4B04364F16E9E9AD00C0C02A /* Icon-Output.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Output.png"; sourceTree = "<group>"; };
+		4B04365016E9E9AD00C0C02A /* Icon-Output136.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Output136.png"; sourceTree = "<group>"; };
+		4B04365116E9E9AD00C0C02A /* Icon-Output at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Output at 2x.png"; sourceTree = "<group>"; };
+		4B06ECAF16E77D6A004D2F59 /* Template_Jack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Template_Jack.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		4B27569817D5E80D00BAB8B9 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; };
+		4B27569A17D5E82500BAB8B9 /* Icon at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon at 2x.png"; sourceTree = "<group>"; };
+		4B27569D17D5E83700BAB8B9 /* Icon-72 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72 at 2x.png"; sourceTree = "<group>"; };
+		4B4953551A9F1D5A005377A7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPad.storyboard; sourceTree = "<group>"; };
+		4B4953571A9F1D5A005377A7 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPhone.storyboard; sourceTree = "<group>"; };
+		4B5F800717D5F93700E0F1ED /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = "<group>"; };
+		4BAD5B9E16F0FA5D000FEF86 /* jack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = jack.framework; sourceTree = "<group>"; };
+		4BDAA20F16AEF05D00A3499E /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
+		4BEF91F01B96FFC000F2D974 /* Template_CoreAudio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Template_CoreAudio.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		651BB43C171D91260065CBC9 /* Icon-Jack.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Jack.png"; sourceTree = "<group>"; };
+		651BB43D171D91260065CBC9 /* Icon-Jack at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Jack at 2x.png"; sourceTree = "<group>"; };
+		6528EF031564212100A310B2 /* FISensorFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FISensorFilter.h; sourceTree = "<group>"; };
+		6528EF041564212100A310B2 /* FISensorFilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FISensorFilter.mm; sourceTree = "<group>"; };
+		6534E20D17301716009A4FD2 /* JackViewPortsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JackViewPortsView.h; sourceTree = "<group>"; };
+		6534E20E17301716009A4FD2 /* JackViewPortsView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JackViewPortsView.mm; sourceTree = "<group>"; };
+		654EE64117832FB400175F2F /* jackview-audio-off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-audio-off.png"; sourceTree = "<group>"; };
+		654EE64217832FB400175F2F /* jackview-audio-off at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-audio-off at 2x.png"; sourceTree = "<group>"; };
+		654EE64317832FB400175F2F /* jackview-audio-on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-audio-on.png"; sourceTree = "<group>"; };
+		654EE64417832FB400175F2F /* jackview-audio-on at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-audio-on at 2x.png"; sourceTree = "<group>"; };
+		654EE64517832FB400175F2F /* jackview-in.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-in.png"; sourceTree = "<group>"; };
+		654EE64617832FB400175F2F /* jackview-in at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-in at 2x.png"; sourceTree = "<group>"; };
+		654EE64717832FB400175F2F /* jackview-midi-off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-midi-off.png"; sourceTree = "<group>"; };
+		654EE64817832FB400175F2F /* jackview-midi-off at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-midi-off at 2x.png"; sourceTree = "<group>"; };
+		654EE64917832FB400175F2F /* jackview-midi-on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-midi-on.png"; sourceTree = "<group>"; };
+		654EE64A17832FB400175F2F /* jackview-midi-on at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-midi-on at 2x.png"; sourceTree = "<group>"; };
+		654EE64B17832FB400175F2F /* jackview-out.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-out.png"; sourceTree = "<group>"; };
+		654EE64C17832FB400175F2F /* jackview-out at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "jackview-out at 2x.png"; sourceTree = "<group>"; };
+		65510E9314EEC1190014A01F /* FITextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FITextField.h; sourceTree = "<group>"; };
+		65510E9414EEC1190014A01F /* FITextField.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FITextField.mm; sourceTree = "<group>"; };
+		6559E84514F2685A00D3AB9A /* FIKnob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIKnob.h; sourceTree = "<group>"; };
+		6559E84614F2685A00D3AB9A /* FIKnob.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIKnob.mm; sourceTree = "<group>"; };
+		655DAAE714F69C9B0013FAF5 /* FIBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIBox.h; sourceTree = "<group>"; };
+		655DAAE814F69C9B0013FAF5 /* FIBox.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIBox.mm; sourceTree = "<group>"; };
+		6560453F14FE924400AE84A9 /* FITabView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FITabView.h; sourceTree = "<group>"; };
+		6560454014FE924400AE84A9 /* FITabView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FITabView.mm; sourceTree = "<group>"; };
+		6566748414ED30F000172A10 /* FIButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIButton.h; sourceTree = "<group>"; };
+		6566748514ED30F000172A10 /* FIButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIButton.mm; sourceTree = "<group>"; };
+		6566748614ED30F000172A10 /* FIResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIResponder.h; sourceTree = "<group>"; };
+		6566748714ED30F000172A10 /* FIResponder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIResponder.mm; sourceTree = "<group>"; };
+		6566748814ED30F000172A10 /* FISlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FISlider.h; sourceTree = "<group>"; };
+		6566748914ED30F000172A10 /* FISlider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FISlider.mm; sourceTree = "<group>"; };
+		656EE12D176B6D8300463CA8 /* JackViewPortsViewBackgroundView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JackViewPortsViewBackgroundView.h; sourceTree = "<group>"; };
+		656EE12E176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JackViewPortsViewBackgroundView.mm; sourceTree = "<group>"; };
+		65961D4E1546DFD60004BC59 /* FIHint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIHint.h; sourceTree = "<group>"; };
+		65961D4F1546DFD70004BC59 /* FIHint.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIHint.mm; sourceTree = "<group>"; };
+		6596C3B4172926BB000AD403 /* Icon_Apple.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon_Apple.png; sourceTree = "<group>"; };
+		6596C3B5172926BB000AD403 /* Icon_Apple at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon_Apple at 2x.png"; sourceTree = "<group>"; };
+		65B9D5D9170EB9D5009DE0DC /* JackView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackView.h; path = iOS/JackView.h; sourceTree = SOURCE_ROOT; };
+		65B9D5DA170EB9D5009DE0DC /* JackView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = JackView.mm; path = iOS/JackView.mm; sourceTree = SOURCE_ROOT; };
+		65C1C07214F543E9006464DF /* FIBargraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIBargraph.h; sourceTree = "<group>"; };
+		65C1C07314F543E9006464DF /* FIBargraph.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIBargraph.mm; sourceTree = "<group>"; };
+		65D1BD1315668A8A00ADCA32 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
+		65E3120E17722C10000E2AFA /* Icon-Delete.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Delete.png"; sourceTree = "<group>"; };
+		65E3120F17722C10000E2AFA /* Icon-Delete at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Delete at 2x.png"; sourceTree = "<group>"; };
+		65E3121017722C10000E2AFA /* Icon-Expand.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Expand.png"; sourceTree = "<group>"; };
+		65E3121117722C10000E2AFA /* Icon-Expand at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Expand at 2x.png"; sourceTree = "<group>"; };
+		65E5ED8E14DB037D00136CFC /* Template_CoreAudio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Template_CoreAudio.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		65E5ED9214DB037D00136CFC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+		65E5ED9414DB037D00136CFC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		65E5ED9614DB037D00136CFC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+		65E5ED9A14DB037D00136CFC /* iOS-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iOS-Info.plist"; sourceTree = "<group>"; };
+		65E5ED9C14DB037D00136CFC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		65E5ED9E14DB037D00136CFC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		65E5EDA014DB037D00136CFC /* iOS-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iOS-Prefix.pch"; sourceTree = "<group>"; };
+		65E5EDA114DB037D00136CFC /* FIAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FIAppDelegate.h; sourceTree = "<group>"; };
+		65E5EDA214DB037D00136CFC /* FIAppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FIAppDelegate.mm; sourceTree = "<group>"; };
+		65E5EDAA14DB037D00136CFC /* FIMainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FIMainViewController.h; sourceTree = "<group>"; };
+		65E5EDAB14DB037D00136CFC /* FIMainViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FIMainViewController.mm; sourceTree = "<group>"; };
+		65E5EDAD14DB037D00136CFC /* FIFlipsideViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FIFlipsideViewController.h; sourceTree = "<group>"; };
+		65E5EDAE14DB037D00136CFC /* FIFlipsideViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FIFlipsideViewController.mm; sourceTree = "<group>"; };
+		65E5EDB514DB037D00136CFC /* iOSTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iOSTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+		65E5EDB614DB037D00136CFC /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+		65E5EDBE14DB037D00136CFC /* iOSTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iOSTests-Info.plist"; sourceTree = "<group>"; };
+		65E5EDC014DB037D00136CFC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		65E5EDC214DB037D00136CFC /* iOSTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iOSTests.h; sourceTree = "<group>"; };
+		65E5EDC314DB037D00136CFC /* iOSTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSTests.m; sourceTree = "<group>"; };
+		65E5EDCD14DB055500136CFC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+		65E85C9A157806C2009F2D7A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+		65E85C9D157806E6009F2D7A /* close.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = close.png; path = iOS/close.png; sourceTree = "<group>"; };
+		65E85C9E157806E6009F2D7A /* close at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "close at 2x.png"; path = "iOS/close at 2x.png"; sourceTree = "<group>"; };
+		65F87430156FFB0C008AE175 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
+		65F8C2DF14DBD59C0042E3FA /* FICocoaUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FICocoaUI.h; sourceTree = "<group>"; };
+		65F8C2E814DBEA410042E3FA /* ios-faust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ios-faust.h"; sourceTree = SOURCE_ROOT; };
+		65FD744D1549993A00E7CB0B /* FIScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIScrollView.h; sourceTree = "<group>"; };
+		65FD744E1549993A00E7CB0B /* FIScrollView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIScrollView.mm; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		4B06EC9C16E77D6A004D2F59 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4B06EC9D16E77D6A004D2F59 /* QuartzCore.framework in Frameworks */,
+				4B06EC9E16E77D6A004D2F59 /* CoreMotion.framework in Frameworks */,
+				4B06EC9F16E77D6A004D2F59 /* CoreLocation.framework in Frameworks */,
+				4B06ECA016E77D6A004D2F59 /* AudioToolbox.framework in Frameworks */,
+				4B06ECA116E77D6A004D2F59 /* UIKit.framework in Frameworks */,
+				4B06ECA216E77D6A004D2F59 /* Foundation.framework in Frameworks */,
+				4B06ECA316E77D6A004D2F59 /* CoreGraphics.framework in Frameworks */,
+				4B06ECA416E77D6A004D2F59 /* Accelerate.framework in Frameworks */,
+				4BAD5B9F16F0FA5D000FEF86 /* jack.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4BEF91B61B96FFC000F2D974 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4BEF91B71B96FFC000F2D974 /* QuartzCore.framework in Frameworks */,
+				4BEF91B81B96FFC000F2D974 /* CoreMotion.framework in Frameworks */,
+				4BEF91B91B96FFC000F2D974 /* CoreLocation.framework in Frameworks */,
+				4BEF91BA1B96FFC000F2D974 /* AudioToolbox.framework in Frameworks */,
+				4BEF91BB1B96FFC000F2D974 /* UIKit.framework in Frameworks */,
+				4BEF91BC1B96FFC000F2D974 /* Foundation.framework in Frameworks */,
+				4BEF91BD1B96FFC000F2D974 /* CoreGraphics.framework in Frameworks */,
+				4BEF91BE1B96FFC000F2D974 /* Accelerate.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		65E5ED8B14DB037D00136CFC /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				65E85C9B157806C2009F2D7A /* QuartzCore.framework in Frameworks */,
+				65F87431156FFB0C008AE175 /* CoreMotion.framework in Frameworks */,
+				65D1BD1415668A8A00ADCA32 /* CoreLocation.framework in Frameworks */,
+				65E5EDCE14DB055500136CFC /* AudioToolbox.framework in Frameworks */,
+				65E5ED9314DB037D00136CFC /* UIKit.framework in Frameworks */,
+				65E5ED9514DB037D00136CFC /* Foundation.framework in Frameworks */,
+				65E5ED9714DB037D00136CFC /* CoreGraphics.framework in Frameworks */,
+				4BDAA21016AEF05D00A3499E /* Accelerate.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		65E5EDB114DB037D00136CFC /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				65E5EDB714DB037D00136CFC /* SenTestingKit.framework in Frameworks */,
+				65E5EDB814DB037D00136CFC /* UIKit.framework in Frameworks */,
+				65E5EDB914DB037D00136CFC /* Foundation.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		4B04364816E9E9AD00C0C02A /* pix */ = {
+			isa = PBXGroup;
+			children = (
+				4B04364916E9E9AD00C0C02A /* Icon-Analyzer.png */,
+				4B04364A16E9E9AD00C0C02A /* Icon-Analyzer136.png */,
+				4B04364B16E9E9AD00C0C02A /* Icon-Analyzer at 2x.png */,
+				4B04364C16E9E9AD00C0C02A /* Icon-Fx.png */,
+				4B04364D16E9E9AD00C0C02A /* Icon-Fx136.png */,
+				4B04364E16E9E9AD00C0C02A /* Icon-Fx at 2x.png */,
+				4B04364F16E9E9AD00C0C02A /* Icon-Output.png */,
+				4B04365016E9E9AD00C0C02A /* Icon-Output136.png */,
+				4B04365116E9E9AD00C0C02A /* Icon-Output at 2x.png */,
+				651BB43C171D91260065CBC9 /* Icon-Jack.png */,
+				651BB43D171D91260065CBC9 /* Icon-Jack at 2x.png */,
+				6596C3B4172926BB000AD403 /* Icon_Apple.png */,
+				6596C3B5172926BB000AD403 /* Icon_Apple at 2x.png */,
+				65E3120E17722C10000E2AFA /* Icon-Delete.png */,
+				65E3120F17722C10000E2AFA /* Icon-Delete at 2x.png */,
+				65E3121017722C10000E2AFA /* Icon-Expand.png */,
+				65E3121117722C10000E2AFA /* Icon-Expand at 2x.png */,
+				654EE64117832FB400175F2F /* jackview-audio-off.png */,
+				654EE64217832FB400175F2F /* jackview-audio-off at 2x.png */,
+				654EE64317832FB400175F2F /* jackview-audio-on.png */,
+				654EE64417832FB400175F2F /* jackview-audio-on at 2x.png */,
+				654EE64517832FB400175F2F /* jackview-in.png */,
+				654EE64617832FB400175F2F /* jackview-in at 2x.png */,
+				654EE64717832FB400175F2F /* jackview-midi-off.png */,
+				654EE64817832FB400175F2F /* jackview-midi-off at 2x.png */,
+				654EE64917832FB400175F2F /* jackview-midi-on.png */,
+				654EE64A17832FB400175F2F /* jackview-midi-on at 2x.png */,
+				654EE64B17832FB400175F2F /* jackview-out.png */,
+				654EE64C17832FB400175F2F /* jackview-out at 2x.png */,
+			);
+			path = pix;
+			sourceTree = SOURCE_ROOT;
+		};
+		6534E2101730171B009A4FD2 /* JackView */ = {
+			isa = PBXGroup;
+			children = (
+				65B9D5D9170EB9D5009DE0DC /* JackView.h */,
+				65B9D5DA170EB9D5009DE0DC /* JackView.mm */,
+				6534E20D17301716009A4FD2 /* JackViewPortsView.h */,
+				6534E20E17301716009A4FD2 /* JackViewPortsView.mm */,
+				656EE12D176B6D8300463CA8 /* JackViewPortsViewBackgroundView.h */,
+				656EE12E176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm */,
+			);
+			name = JackView;
+			sourceTree = "<group>";
+		};
+		655DAAEB14F69CA80013FAF5 /* Faust Responders */ = {
+			isa = PBXGroup;
+			children = (
+				65961D4E1546DFD60004BC59 /* FIHint.h */,
+				65961D4F1546DFD70004BC59 /* FIHint.mm */,
+				6566748614ED30F000172A10 /* FIResponder.h */,
+				6566748714ED30F000172A10 /* FIResponder.mm */,
+				655DAAE714F69C9B0013FAF5 /* FIBox.h */,
+				655DAAE814F69C9B0013FAF5 /* FIBox.mm */,
+				6560453F14FE924400AE84A9 /* FITabView.h */,
+				6560454014FE924400AE84A9 /* FITabView.mm */,
+				6566748414ED30F000172A10 /* FIButton.h */,
+				6566748514ED30F000172A10 /* FIButton.mm */,
+				6566748814ED30F000172A10 /* FISlider.h */,
+				6566748914ED30F000172A10 /* FISlider.mm */,
+				65510E9314EEC1190014A01F /* FITextField.h */,
+				65510E9414EEC1190014A01F /* FITextField.mm */,
+				6559E84514F2685A00D3AB9A /* FIKnob.h */,
+				6559E84614F2685A00D3AB9A /* FIKnob.mm */,
+				65C1C07214F543E9006464DF /* FIBargraph.h */,
+				65C1C07314F543E9006464DF /* FIBargraph.mm */,
+			);
+			name = "Faust Responders";
+			sourceTree = "<group>";
+		};
+		65E5ED8314DB037D00136CFC = {
+			isa = PBXGroup;
+			children = (
+				4B5F800717D5F93700E0F1ED /* Icon-72.png */,
+				4B01EDF217D5F79F005F8D54 /* Default.png */,
+				4B01EDEB17D5F323005F8D54 /* Default-Landscape at 2x~ipad.png */,
+				4B01EDE917D5F320005F8D54 /* Default-Landscape~ipad.png */,
+				4B01EDE717D5F31E005F8D54 /* Default-Portrait at 2x~ipad.png */,
+				4B01EDE517D5F31A005F8D54 /* Default-Portrait~ipad.png */,
+				4B01EDE317D5F30F005F8D54 /* Default-568h at 2x.png */,
+				4B01EDE117D5F30D005F8D54 /* Default at 2x.png */,
+				4B27569D17D5E83700BAB8B9 /* Icon-72 at 2x.png */,
+				4B27569A17D5E82500BAB8B9 /* Icon at 2x.png */,
+				4B27569817D5E80D00BAB8B9 /* Icon.png */,
+				65E5ED9814DB037D00136CFC /* iOS */,
+				65E85CA1157806EE009F2D7A /* Ressources */,
+				65E5EDBC14DB037D00136CFC /* iOSTests */,
+				65E5ED9114DB037D00136CFC /* Frameworks */,
+				65E5ED8F14DB037D00136CFC /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		65E5ED8F14DB037D00136CFC /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				65E5ED8E14DB037D00136CFC /* Template_CoreAudio.app */,
+				65E5EDB514DB037D00136CFC /* iOSTests.octest */,
+				4B06ECAF16E77D6A004D2F59 /* Template_Jack.app */,
+				4BEF91F01B96FFC000F2D974 /* Template_CoreAudio.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		65E5ED9114DB037D00136CFC /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				4BAD5B9E16F0FA5D000FEF86 /* jack.framework */,
+				4BDAA20F16AEF05D00A3499E /* Accelerate.framework */,
+				65E85C9A157806C2009F2D7A /* QuartzCore.framework */,
+				65F87430156FFB0C008AE175 /* CoreMotion.framework */,
+				65D1BD1315668A8A00ADCA32 /* CoreLocation.framework */,
+				65E5EDCD14DB055500136CFC /* AudioToolbox.framework */,
+				65E5ED9214DB037D00136CFC /* UIKit.framework */,
+				65E5ED9414DB037D00136CFC /* Foundation.framework */,
+				65E5ED9614DB037D00136CFC /* CoreGraphics.framework */,
+				65E5EDB614DB037D00136CFC /* SenTestingKit.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		65E5ED9814DB037D00136CFC /* iOS */ = {
+			isa = PBXGroup;
+			children = (
+				4B4953541A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard */,
+				4B4953561A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard */,
+				4B04364816E9E9AD00C0C02A /* pix */,
+				6534E2101730171B009A4FD2 /* JackView */,
+				65E5EDA114DB037D00136CFC /* FIAppDelegate.h */,
+				65E5EDA214DB037D00136CFC /* FIAppDelegate.mm */,
+				65FD744D1549993A00E7CB0B /* FIScrollView.h */,
+				65FD744E1549993A00E7CB0B /* FIScrollView.mm */,
+				65E5EDAA14DB037D00136CFC /* FIMainViewController.h */,
+				65E5EDAB14DB037D00136CFC /* FIMainViewController.mm */,
+				6528EF031564212100A310B2 /* FISensorFilter.h */,
+				6528EF041564212100A310B2 /* FISensorFilter.mm */,
+				65E5EDAD14DB037D00136CFC /* FIFlipsideViewController.h */,
+				65E5EDAE14DB037D00136CFC /* FIFlipsideViewController.mm */,
+				65F8C2DF14DBD59C0042E3FA /* FICocoaUI.h */,
+				655DAAEB14F69CA80013FAF5 /* Faust Responders */,
+				65F8C2E814DBEA410042E3FA /* ios-faust.h */,
+				65E5ED9914DB037D00136CFC /* Supporting Files */,
+			);
+			path = iOS;
+			sourceTree = "<group>";
+		};
+		65E5ED9914DB037D00136CFC /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				65E5ED9A14DB037D00136CFC /* iOS-Info.plist */,
+				65E5ED9B14DB037D00136CFC /* InfoPlist.strings */,
+				65E5ED9E14DB037D00136CFC /* main.m */,
+				65E5EDA014DB037D00136CFC /* iOS-Prefix.pch */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+		65E5EDBC14DB037D00136CFC /* iOSTests */ = {
+			isa = PBXGroup;
+			children = (
+				65E5EDC214DB037D00136CFC /* iOSTests.h */,
+				65E5EDC314DB037D00136CFC /* iOSTests.m */,
+				65E5EDBD14DB037D00136CFC /* Supporting Files */,
+			);
+			path = iOSTests;
+			sourceTree = "<group>";
+		};
+		65E5EDBD14DB037D00136CFC /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				65E5EDBE14DB037D00136CFC /* iOSTests-Info.plist */,
+				65E5EDBF14DB037D00136CFC /* InfoPlist.strings */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+		65E85CA1157806EE009F2D7A /* Ressources */ = {
+			isa = PBXGroup;
+			children = (
+				65E85C9D157806E6009F2D7A /* close.png */,
+				65E85C9E157806E6009F2D7A /* close at 2x.png */,
+			);
+			name = Ressources;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		4B06EC8B16E77D6A004D2F59 /* Template_Jack */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4B06ECAC16E77D6A004D2F59 /* Build configuration list for PBXNativeTarget "Template_Jack" */;
+			buildPhases = (
+				4B06EC8C16E77D6A004D2F59 /* Sources */,
+				4B06EC9C16E77D6A004D2F59 /* Frameworks */,
+				4B06ECA516E77D6A004D2F59 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Template_Jack;
+			productName = iOS;
+			productReference = 4B06ECAF16E77D6A004D2F59 /* Template_Jack.app */;
+			productType = "com.apple.product-type.application";
+		};
+		4BEF91A41B96FFC000F2D974 /* Template_CoreAudio_32bits */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4BEF91ED1B96FFC000F2D974 /* Build configuration list for PBXNativeTarget "Template_CoreAudio_32bits" */;
+			buildPhases = (
+				4BEF91A51B96FFC000F2D974 /* Sources */,
+				4BEF91B61B96FFC000F2D974 /* Frameworks */,
+				4BEF91BF1B96FFC000F2D974 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Template_CoreAudio_32bits;
+			productName = iOS;
+			productReference = 4BEF91F01B96FFC000F2D974 /* Template_CoreAudio.app */;
+			productType = "com.apple.product-type.application";
+		};
+		65E5ED8D14DB037D00136CFC /* Template_CoreAudio */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 65E5EDC714DB037D00136CFC /* Build configuration list for PBXNativeTarget "Template_CoreAudio" */;
+			buildPhases = (
+				65E5ED8A14DB037D00136CFC /* Sources */,
+				65E5ED8B14DB037D00136CFC /* Frameworks */,
+				65E5ED8C14DB037D00136CFC /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Template_CoreAudio;
+			productName = iOS;
+			productReference = 65E5ED8E14DB037D00136CFC /* Template_CoreAudio.app */;
+			productType = "com.apple.product-type.application";
+		};
+		65E5EDB414DB037D00136CFC /* iOSTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 65E5EDCA14DB037D00136CFC /* Build configuration list for PBXNativeTarget "iOSTests" */;
+			buildPhases = (
+				65E5EDB014DB037D00136CFC /* Sources */,
+				65E5EDB114DB037D00136CFC /* Frameworks */,
+				65E5EDB214DB037D00136CFC /* Resources */,
+				65E5EDB314DB037D00136CFC /* ShellScript */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				65E5EDBB14DB037D00136CFC /* PBXTargetDependency */,
+			);
+			name = iOSTests;
+			productName = iOSTests;
+			productReference = 65E5EDB514DB037D00136CFC /* iOSTests.octest */;
+			productType = "com.apple.product-type.bundle.ocunit-test";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		65E5ED8514DB037D00136CFC /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastTestingUpgradeCheck = 0700;
+				LastUpgradeCheck = 0420;
+				TargetAttributes = {
+					65E5ED8D14DB037D00136CFC = {
+						DevelopmentTeam = XN9RP996NW;
+					};
+				};
+			};
+			buildConfigurationList = 65E5ED8814DB037D00136CFC /* Build configuration list for PBXProject "iOS" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 65E5ED8314DB037D00136CFC;
+			productRefGroup = 65E5ED8F14DB037D00136CFC /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				65E5ED8D14DB037D00136CFC /* Template_CoreAudio */,
+				65E5EDB414DB037D00136CFC /* iOSTests */,
+				4B06EC8B16E77D6A004D2F59 /* Template_Jack */,
+				4BEF91A41B96FFC000F2D974 /* Template_CoreAudio_32bits */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		4B06ECA516E77D6A004D2F59 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4B06ECA616E77D6A004D2F59 /* InfoPlist.strings in Resources */,
+				4B06ECAA16E77D6A004D2F59 /* close.png in Resources */,
+				4B06ECAB16E77D6A004D2F59 /* close at 2x.png in Resources */,
+				4B04365316E9E9AD00C0C02A /* Icon-Analyzer.png in Resources */,
+				4B04365516E9E9AD00C0C02A /* Icon-Analyzer136.png in Resources */,
+				4B04365716E9E9AD00C0C02A /* Icon-Analyzer at 2x.png in Resources */,
+				4B04365916E9E9AD00C0C02A /* Icon-Fx.png in Resources */,
+				4B04365B16E9E9AD00C0C02A /* Icon-Fx136.png in Resources */,
+				4B04365D16E9E9AD00C0C02A /* Icon-Fx at 2x.png in Resources */,
+				4B04365F16E9E9AD00C0C02A /* Icon-Output.png in Resources */,
+				4B04366116E9E9AD00C0C02A /* Icon-Output136.png in Resources */,
+				4B04366316E9E9AD00C0C02A /* Icon-Output at 2x.png in Resources */,
+				651BB43F171D91260065CBC9 /* Icon-Jack.png in Resources */,
+				651BB441171D91260065CBC9 /* Icon-Jack at 2x.png in Resources */,
+				6596C3B7172926BB000AD403 /* Icon_Apple.png in Resources */,
+				4B49535B1A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard in Resources */,
+				6596C3B9172926BB000AD403 /* Icon_Apple at 2x.png in Resources */,
+				65E3121317722C10000E2AFA /* Icon-Delete.png in Resources */,
+				65E3121517722C10000E2AFA /* Icon-Delete at 2x.png in Resources */,
+				65E3121717722C10000E2AFA /* Icon-Expand.png in Resources */,
+				65E3121917722C10000E2AFA /* Icon-Expand at 2x.png in Resources */,
+				654EE64F17832FB400175F2F /* jackview-audio-off.png in Resources */,
+				654EE65217832FB400175F2F /* jackview-audio-off at 2x.png in Resources */,
+				654EE65517832FB400175F2F /* jackview-audio-on.png in Resources */,
+				654EE65817832FB400175F2F /* jackview-audio-on at 2x.png in Resources */,
+				654EE65B17832FB400175F2F /* jackview-in.png in Resources */,
+				654EE65E17832FB400175F2F /* jackview-in at 2x.png in Resources */,
+				654EE66117832FB400175F2F /* jackview-midi-off.png in Resources */,
+				654EE66417832FB400175F2F /* jackview-midi-off at 2x.png in Resources */,
+				654EE66717832FB400175F2F /* jackview-midi-on.png in Resources */,
+				654EE66A17832FB400175F2F /* jackview-midi-on at 2x.png in Resources */,
+				654EE66D17832FB400175F2F /* jackview-out.png in Resources */,
+				654EE67017832FB400175F2F /* jackview-out at 2x.png in Resources */,
+				4B4953591A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard in Resources */,
+				4B27569C17D5E82E00BAB8B9 /* Icon at 2x.png in Resources */,
+				4B27569E17D5E83700BAB8B9 /* Icon-72 at 2x.png in Resources */,
+				4BFCB7F317D63C1A007DE831 /* Icon.png in Resources */,
+				4BFCB7F617D63C2B007DE831 /* Default-568h at 2x.png in Resources */,
+				4BFCB7F717D63C37007DE831 /* Icon-72.png in Resources */,
+				4BFCB7F917D63C52007DE831 /* Default-Portrait~ipad.png in Resources */,
+				4BFCB7FA17D63C56007DE831 /* Default-Portrait at 2x~ipad.png in Resources */,
+				4BFCB7FB17D63C58007DE831 /* Default-Landscape~ipad.png in Resources */,
+				4BFCB7FC17D63C5A007DE831 /* Default-Landscape at 2x~ipad.png in Resources */,
+				4BFCB7FD17D63C61007DE831 /* Default.png in Resources */,
+				4BFCB7FE17D63C63007DE831 /* Default at 2x.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4BEF91BF1B96FFC000F2D974 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4BEF91C01B96FFC000F2D974 /* InfoPlist.strings in Resources */,
+				4BEF91C11B96FFC000F2D974 /* close.png in Resources */,
+				4BEF91C21B96FFC000F2D974 /* close at 2x.png in Resources */,
+				4BEF91C31B96FFC000F2D974 /* Icon-Analyzer.png in Resources */,
+				4BEF91C41B96FFC000F2D974 /* Icon-Analyzer136.png in Resources */,
+				4BEF91C51B96FFC000F2D974 /* Icon-Analyzer at 2x.png in Resources */,
+				4BEF91C61B96FFC000F2D974 /* Icon-Fx.png in Resources */,
+				4BEF91C71B96FFC000F2D974 /* Icon-Fx136.png in Resources */,
+				4BEF91C81B96FFC000F2D974 /* Icon-Fx at 2x.png in Resources */,
+				4BEF91C91B96FFC000F2D974 /* Icon-Output.png in Resources */,
+				4BEF91CA1B96FFC000F2D974 /* Icon-Output136.png in Resources */,
+				4BEF91CB1B96FFC000F2D974 /* Icon-Output at 2x.png in Resources */,
+				4BEF91CC1B96FFC000F2D974 /* Icon-Jack.png in Resources */,
+				4BEF91CD1B96FFC000F2D974 /* Icon-Jack at 2x.png in Resources */,
+				4BEF91CE1B96FFC000F2D974 /* Icon_Apple.png in Resources */,
+				4BEF91CF1B96FFC000F2D974 /* MainStoryboard_iPhone.storyboard in Resources */,
+				4BEF91D01B96FFC000F2D974 /* Icon_Apple at 2x.png in Resources */,
+				4BEF91D11B96FFC000F2D974 /* Icon-Delete.png in Resources */,
+				4BEF91D21B96FFC000F2D974 /* Icon-Delete at 2x.png in Resources */,
+				4BEF91D31B96FFC000F2D974 /* Icon-Expand.png in Resources */,
+				4BEF91D41B96FFC000F2D974 /* Icon-Expand at 2x.png in Resources */,
+				4BEF91D51B96FFC000F2D974 /* jackview-audio-off.png in Resources */,
+				4BEF91D61B96FFC000F2D974 /* jackview-audio-off at 2x.png in Resources */,
+				4BEF91D71B96FFC000F2D974 /* jackview-audio-on.png in Resources */,
+				4BEF91D81B96FFC000F2D974 /* jackview-audio-on at 2x.png in Resources */,
+				4BEF91D91B96FFC000F2D974 /* jackview-in.png in Resources */,
+				4BEF91DA1B96FFC000F2D974 /* jackview-in at 2x.png in Resources */,
+				4BEF91DB1B96FFC000F2D974 /* jackview-midi-off.png in Resources */,
+				4BEF91DC1B96FFC000F2D974 /* jackview-midi-off at 2x.png in Resources */,
+				4BEF91DD1B96FFC000F2D974 /* jackview-midi-on.png in Resources */,
+				4BEF91DE1B96FFC000F2D974 /* jackview-midi-on at 2x.png in Resources */,
+				4BEF91DF1B96FFC000F2D974 /* jackview-out.png in Resources */,
+				4BEF91E01B96FFC000F2D974 /* jackview-out at 2x.png in Resources */,
+				4BEF91E11B96FFC000F2D974 /* MainStoryboard_iPad.storyboard in Resources */,
+				4BEF91E21B96FFC000F2D974 /* Default-Landscape at 2x~ipad.png in Resources */,
+				4BEF91E31B96FFC000F2D974 /* Default-Portrait~ipad.png in Resources */,
+				4BEF91E41B96FFC000F2D974 /* Default-Landscape~ipad.png in Resources */,
+				4BEF91E51B96FFC000F2D974 /* Default-Portrait at 2x~ipad.png in Resources */,
+				4BEF91E61B96FFC000F2D974 /* Default.png in Resources */,
+				4BEF91E71B96FFC000F2D974 /* Default at 2x.png in Resources */,
+				4BEF91E81B96FFC000F2D974 /* Default-568h at 2x.png in Resources */,
+				4BEF91E91B96FFC000F2D974 /* Icon.png in Resources */,
+				4BEF91EA1B96FFC000F2D974 /* Icon at 2x.png in Resources */,
+				4BEF91EB1B96FFC000F2D974 /* Icon-72.png in Resources */,
+				4BEF91EC1B96FFC000F2D974 /* Icon-72 at 2x.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		65E5ED8C14DB037D00136CFC /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				65E5ED9D14DB037D00136CFC /* InfoPlist.strings in Resources */,
+				65E85C9F157806E6009F2D7A /* close.png in Resources */,
+				65E85CA0157806E6009F2D7A /* close at 2x.png in Resources */,
+				4B04365216E9E9AD00C0C02A /* Icon-Analyzer.png in Resources */,
+				4B04365416E9E9AD00C0C02A /* Icon-Analyzer136.png in Resources */,
+				4B04365616E9E9AD00C0C02A /* Icon-Analyzer at 2x.png in Resources */,
+				4B04365816E9E9AD00C0C02A /* Icon-Fx.png in Resources */,
+				4B04365A16E9E9AD00C0C02A /* Icon-Fx136.png in Resources */,
+				4B04365C16E9E9AD00C0C02A /* Icon-Fx at 2x.png in Resources */,
+				4B04365E16E9E9AD00C0C02A /* Icon-Output.png in Resources */,
+				4B04366016E9E9AD00C0C02A /* Icon-Output136.png in Resources */,
+				4B04366216E9E9AD00C0C02A /* Icon-Output at 2x.png in Resources */,
+				651BB43E171D91260065CBC9 /* Icon-Jack.png in Resources */,
+				651BB440171D91260065CBC9 /* Icon-Jack at 2x.png in Resources */,
+				6596C3B6172926BB000AD403 /* Icon_Apple.png in Resources */,
+				4B49535A1A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard in Resources */,
+				6596C3B8172926BB000AD403 /* Icon_Apple at 2x.png in Resources */,
+				65E3121217722C10000E2AFA /* Icon-Delete.png in Resources */,
+				65E3121417722C10000E2AFA /* Icon-Delete at 2x.png in Resources */,
+				65E3121617722C10000E2AFA /* Icon-Expand.png in Resources */,
+				65E3121817722C10000E2AFA /* Icon-Expand at 2x.png in Resources */,
+				654EE64D17832FB400175F2F /* jackview-audio-off.png in Resources */,
+				654EE65017832FB400175F2F /* jackview-audio-off at 2x.png in Resources */,
+				654EE65317832FB400175F2F /* jackview-audio-on.png in Resources */,
+				654EE65617832FB400175F2F /* jackview-audio-on at 2x.png in Resources */,
+				654EE65917832FB400175F2F /* jackview-in.png in Resources */,
+				654EE65C17832FB400175F2F /* jackview-in at 2x.png in Resources */,
+				654EE65F17832FB400175F2F /* jackview-midi-off.png in Resources */,
+				654EE66217832FB400175F2F /* jackview-midi-off at 2x.png in Resources */,
+				654EE66517832FB400175F2F /* jackview-midi-on.png in Resources */,
+				654EE66817832FB400175F2F /* jackview-midi-on at 2x.png in Resources */,
+				654EE66B17832FB400175F2F /* jackview-out.png in Resources */,
+				654EE66E17832FB400175F2F /* jackview-out at 2x.png in Resources */,
+				4B4953581A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard in Resources */,
+				4B01EDED17D5F3BC005F8D54 /* Default-Landscape at 2x~ipad.png in Resources */,
+				4B01EDEF17D5F459005F8D54 /* Default-Portrait~ipad.png in Resources */,
+				4B01EDF017D5F45F005F8D54 /* Default-Landscape~ipad.png in Resources */,
+				4B01EDF117D5F464005F8D54 /* Default-Portrait at 2x~ipad.png in Resources */,
+				4B01EDF317D5F79F005F8D54 /* Default.png in Resources */,
+				4B01EDF417D5F7A5005F8D54 /* Default at 2x.png in Resources */,
+				4B01EDF517D5F7A8005F8D54 /* Default-568h at 2x.png in Resources */,
+				4B5F800517D5F92000E0F1ED /* Icon.png in Resources */,
+				4B5F800617D5F93100E0F1ED /* Icon at 2x.png in Resources */,
+				4B5F800817D5F93700E0F1ED /* Icon-72.png in Resources */,
+				4B5F800917D5F93900E0F1ED /* Icon-72 at 2x.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		65E5EDB214DB037D00136CFC /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				65E5EDC114DB037D00136CFC /* InfoPlist.strings in Resources */,
+				654EE64E17832FB400175F2F /* jackview-audio-off.png in Resources */,
+				654EE65117832FB400175F2F /* jackview-audio-off at 2x.png in Resources */,
+				654EE65417832FB400175F2F /* jackview-audio-on.png in Resources */,
+				654EE65717832FB400175F2F /* jackview-audio-on at 2x.png in Resources */,
+				654EE65A17832FB400175F2F /* jackview-in.png in Resources */,
+				654EE65D17832FB400175F2F /* jackview-in at 2x.png in Resources */,
+				654EE66017832FB400175F2F /* jackview-midi-off.png in Resources */,
+				654EE66317832FB400175F2F /* jackview-midi-off at 2x.png in Resources */,
+				654EE66617832FB400175F2F /* jackview-midi-on.png in Resources */,
+				654EE66917832FB400175F2F /* jackview-midi-on at 2x.png in Resources */,
+				654EE66C17832FB400175F2F /* jackview-out.png in Resources */,
+				654EE66F17832FB400175F2F /* jackview-out at 2x.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		65E5EDB314DB037D00136CFC /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		4B06EC8C16E77D6A004D2F59 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4B06EC8D16E77D6A004D2F59 /* main.m in Sources */,
+				4B06EC8E16E77D6A004D2F59 /* FIAppDelegate.mm in Sources */,
+				4B06EC8F16E77D6A004D2F59 /* FIMainViewController.mm in Sources */,
+				4B06EC9016E77D6A004D2F59 /* FIFlipsideViewController.mm in Sources */,
+				4B06EC9116E77D6A004D2F59 /* FIButton.mm in Sources */,
+				4B06EC9216E77D6A004D2F59 /* FIResponder.mm in Sources */,
+				4B06EC9316E77D6A004D2F59 /* FISlider.mm in Sources */,
+				4B06EC9416E77D6A004D2F59 /* FITextField.mm in Sources */,
+				4B06EC9516E77D6A004D2F59 /* FIKnob.mm in Sources */,
+				4B06EC9616E77D6A004D2F59 /* FIBargraph.mm in Sources */,
+				4B06EC9716E77D6A004D2F59 /* FIBox.mm in Sources */,
+				4B06EC9816E77D6A004D2F59 /* FITabView.mm in Sources */,
+				4B06EC9916E77D6A004D2F59 /* FIHint.mm in Sources */,
+				4B06EC9A16E77D6A004D2F59 /* FIScrollView.mm in Sources */,
+				4B06EC9B16E77D6A004D2F59 /* FISensorFilter.mm in Sources */,
+				65B9D5DB170EB9D5009DE0DC /* JackView.mm in Sources */,
+				6534E20F17301716009A4FD2 /* JackViewPortsView.mm in Sources */,
+				656EE130176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4BEF91A51B96FFC000F2D974 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4BEF91A61B96FFC000F2D974 /* main.m in Sources */,
+				4BEF91A71B96FFC000F2D974 /* FIAppDelegate.mm in Sources */,
+				4BEF91A81B96FFC000F2D974 /* FIMainViewController.mm in Sources */,
+				4BEF91A91B96FFC000F2D974 /* FIFlipsideViewController.mm in Sources */,
+				4BEF91AA1B96FFC000F2D974 /* FIButton.mm in Sources */,
+				4BEF91AB1B96FFC000F2D974 /* FIResponder.mm in Sources */,
+				4BEF91AC1B96FFC000F2D974 /* FISlider.mm in Sources */,
+				4BEF91AD1B96FFC000F2D974 /* FITextField.mm in Sources */,
+				4BEF91AE1B96FFC000F2D974 /* FIKnob.mm in Sources */,
+				4BEF91AF1B96FFC000F2D974 /* FIBargraph.mm in Sources */,
+				4BEF91B01B96FFC000F2D974 /* FIBox.mm in Sources */,
+				4BEF91B11B96FFC000F2D974 /* FITabView.mm in Sources */,
+				4BEF91B21B96FFC000F2D974 /* FIHint.mm in Sources */,
+				4BEF91B31B96FFC000F2D974 /* FIScrollView.mm in Sources */,
+				4BEF91B41B96FFC000F2D974 /* FISensorFilter.mm in Sources */,
+				4BEF91B51B96FFC000F2D974 /* JackViewPortsViewBackgroundView.mm in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		65E5ED8A14DB037D00136CFC /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				65E5ED9F14DB037D00136CFC /* main.m in Sources */,
+				65E5EDA314DB037D00136CFC /* FIAppDelegate.mm in Sources */,
+				65E5EDAC14DB037D00136CFC /* FIMainViewController.mm in Sources */,
+				65E5EDAF14DB037D00136CFC /* FIFlipsideViewController.mm in Sources */,
+				6566748A14ED30F000172A10 /* FIButton.mm in Sources */,
+				6566748B14ED30F000172A10 /* FIResponder.mm in Sources */,
+				6566748C14ED30F000172A10 /* FISlider.mm in Sources */,
+				65510E9514EEC1190014A01F /* FITextField.mm in Sources */,
+				6559E84714F2685A00D3AB9A /* FIKnob.mm in Sources */,
+				65C1C07414F543E9006464DF /* FIBargraph.mm in Sources */,
+				655DAAE914F69C9B0013FAF5 /* FIBox.mm in Sources */,
+				6560454114FE924400AE84A9 /* FITabView.mm in Sources */,
+				65961D501546DFD70004BC59 /* FIHint.mm in Sources */,
+				65FD744F1549993A00E7CB0B /* FIScrollView.mm in Sources */,
+				6528EF051564212100A310B2 /* FISensorFilter.mm in Sources */,
+				656EE12F176B6D8300463CA8 /* JackViewPortsViewBackgroundView.mm in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		65E5EDB014DB037D00136CFC /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				65E5EDC414DB037D00136CFC /* iOSTests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		65E5EDBB14DB037D00136CFC /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 65E5ED8D14DB037D00136CFC /* Template_CoreAudio */;
+			targetProxy = 65E5EDBA14DB037D00136CFC /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		4B4953541A9F1D5A005377A7 /* MainStoryboard_iPad.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				4B4953551A9F1D5A005377A7 /* en */,
+			);
+			name = MainStoryboard_iPad.storyboard;
+			sourceTree = "<group>";
+		};
+		4B4953561A9F1D5A005377A7 /* MainStoryboard_iPhone.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				4B4953571A9F1D5A005377A7 /* en */,
+			);
+			name = MainStoryboard_iPhone.storyboard;
+			sourceTree = "<group>";
+		};
+		65E5ED9B14DB037D00136CFC /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				65E5ED9C14DB037D00136CFC /* en */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		65E5EDBF14DB037D00136CFC /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				65E5EDC014DB037D00136CFC /* en */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		4B06ECAD16E77D6A004D2F59 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ENABLE_BITCODE = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)\"",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				GCC_PREPROCESSOR_DEFINITIONS = JACK_IOS;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)\"",
+					../,
+				);
+				INFOPLIST_FILE = "iOS/iOS-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = Template_Jack;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		4B06ECAE16E77D6A004D2F59 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ENABLE_BITCODE = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)\"",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				GCC_PREPROCESSOR_DEFINITIONS = JACK_IOS;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)\"",
+					../,
+				);
+				INFOPLIST_FILE = "iOS/iOS-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = Template_Jack;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		4BEF91EE1B96FFC000F2D974 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				ENABLE_BITCODE = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				HEADER_SEARCH_PATHS = (
+					/usr/local/include,
+					../,
+					.,
+				);
+				INFOPLIST_FILE = "iOS/iOS-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_LDFLAGS = (
+					libOSCFaust.a,
+					liboscpack.a,
+				);
+				PRODUCT_NAME = Template_CoreAudio;
+				PROVISIONING_PROFILE = "";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		4BEF91EF1B96FFC000F2D974 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				ENABLE_BITCODE = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				HEADER_SEARCH_PATHS = (
+					/usr/local/include,
+					../,
+					.,
+				);
+				INFOPLIST_FILE = "iOS/iOS-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_LDFLAGS = (
+					libOSCFaust.a,
+					liboscpack.a,
+				);
+				PRODUCT_NAME = Template_CoreAudio;
+				PROVISIONING_PROFILE = "";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		65E5EDC514DB037D00136CFC /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = YES;
+				ARCHS = "$(ARCHS_STANDARD)";
+				CLANG_ENABLE_OBJC_ARC = NO;
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = s;
+				GCC_PREPROCESSOR_DEFINITIONS = "";
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_VERSION = "";
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				LIBRARY_SEARCH_PATHS = "";
+				MACH_O_TYPE = mh_execute;
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PREBINDING = NO;
+				PROVISIONING_PROFILE = "";
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				USER_HEADER_SEARCH_PATHS = "";
+				VALIDATE_PRODUCT = NO;
+			};
+			name = Debug;
+		};
+		65E5EDC614DB037D00136CFC /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = YES;
+				ARCHS = "$(ARCHS_STANDARD)";
+				CLANG_ENABLE_OBJC_ARC = NO;
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = YES;
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_OPTIMIZATION_LEVEL = s;
+				GCC_PREPROCESSOR_DEFINITIONS = "";
+				GCC_VERSION = "";
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				LIBRARY_SEARCH_PATHS = "";
+				MACH_O_TYPE = mh_execute;
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PREBINDING = NO;
+				PROVISIONING_PROFILE = "";
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				USER_HEADER_SEARCH_PATHS = "";
+				VALIDATE_PRODUCT = NO;
+			};
+			name = Release;
+		};
+		65E5EDC814DB037D00136CFC /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				ENABLE_BITCODE = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				HEADER_SEARCH_PATHS = (
+					/usr/local/include,
+					../,
+					.,
+				);
+				INFOPLIST_FILE = "iOS/iOS-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_LDFLAGS = (
+					libOSCFaust.a,
+					liboscpack.a,
+				);
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				PROVISIONING_PROFILE = "";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		65E5EDC914DB037D00136CFC /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				ENABLE_BITCODE = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				HEADER_SEARCH_PATHS = (
+					/usr/local/include,
+					../,
+					.,
+				);
+				INFOPLIST_FILE = "iOS/iOS-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_LDFLAGS = (
+					libOSCFaust.a,
+					liboscpack.a,
+				);
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				PROVISIONING_PROFILE = "";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		65E5EDCB14DB037D00136CFC /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/iOS.app/iOS";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SDKROOT)/Developer/Library/Frameworks",
+					"$(DEVELOPER_LIBRARY_DIR)/Frameworks",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				GCC_USE_STANDARD_INCLUDE_SEARCHING = NO;
+				INFOPLIST_FILE = "iOSTests/iOSTests-Info.plist";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TEST_HOST = "$(BUNDLE_LOADER)";
+				WRAPPER_EXTENSION = octest;
+			};
+			name = Debug;
+		};
+		65E5EDCC14DB037D00136CFC /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/iOS.app/iOS";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SDKROOT)/Developer/Library/Frameworks",
+					"$(DEVELOPER_LIBRARY_DIR)/Frameworks",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "iOS/iOS-Prefix.pch";
+				GCC_USE_STANDARD_INCLUDE_SEARCHING = NO;
+				INFOPLIST_FILE = "iOSTests/iOSTests-Info.plist";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TEST_HOST = "$(BUNDLE_LOADER)";
+				WRAPPER_EXTENSION = octest;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		4B06ECAC16E77D6A004D2F59 /* Build configuration list for PBXNativeTarget "Template_Jack" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4B06ECAD16E77D6A004D2F59 /* Debug */,
+				4B06ECAE16E77D6A004D2F59 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4BEF91ED1B96FFC000F2D974 /* Build configuration list for PBXNativeTarget "Template_CoreAudio_32bits" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4BEF91EE1B96FFC000F2D974 /* Debug */,
+				4BEF91EF1B96FFC000F2D974 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		65E5ED8814DB037D00136CFC /* Build configuration list for PBXProject "iOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				65E5EDC514DB037D00136CFC /* Debug */,
+				65E5EDC614DB037D00136CFC /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		65E5EDC714DB037D00136CFC /* Build configuration list for PBXNativeTarget "Template_CoreAudio" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				65E5EDC814DB037D00136CFC /* Debug */,
+				65E5EDC914DB037D00136CFC /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		65E5EDCA14DB037D00136CFC /* Build configuration list for PBXNativeTarget "iOSTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				65E5EDCB14DB037D00136CFC /* Debug */,
+				65E5EDCC14DB037D00136CFC /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 65E5ED8514DB037D00136CFC /* Project object */;
+}
diff --git a/architecture/iOS/iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/architecture/iOS/iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..92a9306
--- /dev/null
+++ b/architecture/iOS/iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:iOS.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_CoreAudio.xcscheme b/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_CoreAudio.xcscheme
new file mode 100644
index 0000000..ca3e289
--- /dev/null
+++ b/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_CoreAudio.xcscheme
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "65E5ED8D14DB037D00136CFC"
+               BuildableName = "Template_CoreAudio.app"
+               BlueprintName = "Template_CoreAudio"
+               ReferencedContainer = "container:iOS.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "65E5EDB414DB037D00136CFC"
+               BuildableName = "iOSTests.octest"
+               BlueprintName = "iOSTests"
+               ReferencedContainer = "container:iOS.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "65E5ED8D14DB037D00136CFC"
+            BuildableName = "Template_CoreAudio.app"
+            BlueprintName = "Template_CoreAudio"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "65E5ED8D14DB037D00136CFC"
+            BuildableName = "Template_CoreAudio.app"
+            BlueprintName = "Template_CoreAudio"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "65E5ED8D14DB037D00136CFC"
+            BuildableName = "Template_CoreAudio.app"
+            BlueprintName = "Template_CoreAudio"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Debug"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_CoreAudio_32bits.xcscheme b/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_CoreAudio_32bits.xcscheme
new file mode 100644
index 0000000..23234ec
--- /dev/null
+++ b/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_CoreAudio_32bits.xcscheme
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0510"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "4BEF91A41B96FFC000F2D974"
+               BuildableName = "Template_CoreAudio.app"
+               BlueprintName = "Template_CoreAudio_32bits"
+               ReferencedContainer = "container:iOS.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4BEF91A41B96FFC000F2D974"
+            BuildableName = "Template_CoreAudio.app"
+            BlueprintName = "Template_CoreAudio_32bits"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4BEF91A41B96FFC000F2D974"
+            BuildableName = "Template_CoreAudio.app"
+            BlueprintName = "Template_CoreAudio_32bits"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4BEF91A41B96FFC000F2D974"
+            BuildableName = "Template_CoreAudio.app"
+            BlueprintName = "Template_CoreAudio_32bits"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_Jack.xcscheme b/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_Jack.xcscheme
new file mode 100644
index 0000000..3515578
--- /dev/null
+++ b/architecture/iOS/iOS.xcodeproj/xcshareddata/xcschemes/Template_Jack.xcscheme
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0460"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "4B06EC8B16E77D6A004D2F59"
+               BuildableName = "Template_Jack.app"
+               BlueprintName = "Template_Jack"
+               ReferencedContainer = "container:iOS.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4B06EC8B16E77D6A004D2F59"
+            BuildableName = "Template_Jack.app"
+            BlueprintName = "Template_Jack"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4B06EC8B16E77D6A004D2F59"
+            BuildableName = "Template_Jack.app"
+            BlueprintName = "Template_Jack"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4B06EC8B16E77D6A004D2F59"
+            BuildableName = "Template_Jack.app"
+            BlueprintName = "Template_Jack"
+            ReferencedContainer = "container:iOS.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/architecture/iOS/iOS/FIAppDelegate.h b/architecture/iOS/iOS/FIAppDelegate.h
new file mode 100644
index 0000000..0c7f3af
--- /dev/null
+++ b/architecture/iOS/iOS/FIAppDelegate.h
@@ -0,0 +1,31 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+ at class FIMainViewController;
+
+ at interface FIAppDelegate : UIResponder <UIApplicationDelegate>
+{
+    FIMainViewController*       _mainViewController;
+}
+
+ at property (strong, nonatomic) UIWindow* window;
+ at property (assign, nonatomic) FIMainViewController* mainViewController;
+
+ at end
diff --git a/architecture/iOS/iOS/FIAppDelegate.mm b/architecture/iOS/iOS/FIAppDelegate.mm
new file mode 100644
index 0000000..4d7dc38
--- /dev/null
+++ b/architecture/iOS/iOS/FIAppDelegate.mm
@@ -0,0 +1,81 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIAppDelegate.h"
+#import "FIMainViewController.h"
+
+ at implementation FIAppDelegate
+
+ at synthesize window = _window;
+ at synthesize mainViewController = _mainViewController;
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackOpaque;
+    
+    [UIApplication sharedApplication].idleTimerDisabled = YES;
+    
+    // Default setting that have to be in coherence with what is defined in Interface Builder
+    NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
+                                [NSNumber numberWithInteger:44100], @"sampleRate",
+                                [NSNumber numberWithInteger:256], @"bufferSize",
+                                [NSNumber numberWithBool:TRUE], @"openWidgetPanel",
+                                [NSNumber numberWithBool:TRUE], @"concertUI",nil];
+    
+    
+    [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
+
+    
+    return YES;
+}
+
+// Fast switch testing
+- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
+{
+    return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+     [self.mainViewController saveGui];
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+#ifdef JACK_IOS
+    [_mainViewController closeJackView];
+#endif
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+    [self.mainViewController openAudio];
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+    [self.mainViewController loadGui];
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+    [self.mainViewController closeAudio];
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIBargraph.h b/architecture/iOS/iOS/FIBargraph.h
new file mode 100644
index 0000000..a9a341a
--- /dev/null
+++ b/architecture/iOS/iOS/FIBargraph.h
@@ -0,0 +1,96 @@
+//
+//  F3BarGauge.h
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on F3BarGauge - https://github.com/ChiefPilot/F3BarGauge
+ Copyright (c) 2011 by Brad Benson - https://github.com/ChiefPilot
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ OF SUCH DAMAGE.
+ ************************************************************************
+ ************************************************************************/
+
+
+//---> Pick up required headers <-----------------------------------------
+#import <UIKit/UIKit.h>
+#import "FIResponder.h"
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------|  F3BarGauge class definition  |---------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+ at interface FIBargraph : FIResponder
+{
+ at private
+    BOOL        m_fHoldPeak,            // YES = hold peak value enabled
+                m_fLitEffect,           // YES = draw segments with gradient "lit-up" effect
+                m_fReverseDirection;    // YES = top-to-bottom or right-to-left 
+    float       m_flValue,              // Current value being displayed
+                m_flPeakValue,          // Peak value seen since reset
+                m_flMaxLimit,           // Maximum displayable value
+                m_flMinLimit,           // Minimum displayable value    
+                m_flWarnThreshold,      // Warning threshold (segment color specified by m_clrWarning)
+                m_flDangerThreshold;    // Danger threshold (segment color specified by m_clrDanger)
+    int         m_iNumBars;             // Number of segments
+    UIColor     *m_clrOuterBorder,      // Color of outer border
+                *m_clrInnerBorder,      // Color of inner border
+                *m_clrBackground,       // Background color of gauge
+                *m_clrNormal,           // Normal segment color
+                *m_clrWarning,          // Warning segment color
+                *m_clrDanger;           // Danger segment color
+}
+
+ at property (readwrite, nonatomic)  CGFloat   value;
+ at property (readwrite, nonatomic)  float     warnThreshold;
+ at property (readwrite, nonatomic)  float     dangerThreshold;
+ at property (readwrite, nonatomic)  float     maxLimit;
+ at property (readwrite, nonatomic)  float     minLimit;
+ at property (readwrite, nonatomic)  int       numBars;
+ at property (readonly, nonatomic)   float     peakValue;
+ at property (readwrite, nonatomic)  BOOL      holdPeak;
+ at property (readwrite, nonatomic)  BOOL      litEffect;
+ at property (readwrite, nonatomic)  BOOL      reverse;
+ at property (readwrite, nonatomic)  BOOL      led;
+ at property (readwrite, retain)     UIColor   *outerBorderColor;
+ at property (readwrite, retain)     UIColor   *innerBorderColor;
+ at property (readwrite, retain)     UIColor   *backgroundColor;
+ at property (readwrite, retain)     UIColor   *normalBarColor;
+ at property (readwrite, retain)     UIColor   *warningBarColor;
+ at property (readwrite, retain)     UIColor   *dangerBarColor;
+ at property (readwrite, retain)     UIColor   *ledMinColor;
+ at property (readwrite, retain)     UIColor   *ledMaxColor;
+
+-(void) resetPeak;
+
+
+
+ at end
diff --git a/architecture/iOS/iOS/FIBargraph.mm b/architecture/iOS/iOS/FIBargraph.mm
new file mode 100644
index 0000000..7fd4012
--- /dev/null
+++ b/architecture/iOS/iOS/FIBargraph.mm
@@ -0,0 +1,501 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on F3BarGauge - https://github.com/ChiefPilot/F3BarGauge
+ Copyright (c) 2011 by Brad Benson - https://github.com/ChiefPilot
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ OF SUCH DAMAGE.
+ ************************************************************************
+ ************************************************************************/
+
+
+// Pick up required headers
+#import "FIBargraph.h"
+
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//---------------|  F3BarGauge class implementation  |--------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+
+//===[ Extention for private-ish stuff ]==================================
+ at interface FIBargraph()
+{
+ at private
+    int             m_iOnIdx,               // Point at which segments are on
+    m_iOffIdx,              // Point at which segments are off
+    m_iPeakBarIdx,          // Index of peak value segment
+    m_iWarningBarIdx,       // Index of first warning segment
+    m_iDangerBarIdx;        // Index of first danger segment
+}
+
+// Private methods
+-(void) setDefaults;
+-(void) drawBar:(CGContextRef)a_ctx
+       withRect:(CGRect) a_rect
+       andColor:(UIColor *)a_clr
+            lit:(BOOL)a_lit;
+ at end
+
+
+
+ at implementation FIBargraph
+//===[ Public Methods ]===================================================
+
+//------------------------------------------------------------------------
+//  Method: initWithFrame:
+//    Designated initializer
+//
+-(id) initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if(self) {
+        // Assign default values
+        [self setDefaults];
+    }
+    return self;
+}
+
+
+//------------------------------------------------------------------------
+// Method:  initWithCoder:
+//  Initializes the instance when brought from nib, etc.
+//
+-(id) initWithCoder:(NSCoder *)aDecoder
+{ 
+    self = [super initWithCoder:aDecoder];
+    if(self) {
+        // Assign default values
+        [self setDefaults];
+    }
+    return self;
+}
+
+
+//------------------------------------------------------------------------
+//  Method: dealloc
+//    Clean up instance when released
+//
+-(void) dealloc
+{
+    // Clean up
+    [m_clrBackground release];
+    [m_clrOuterBorder release];
+    [m_clrInnerBorder release];
+    [m_clrNormal release];
+    [m_clrWarning release];
+    [m_clrDanger release];
+    
+    // Call parent
+    [super dealloc];
+}
+
+
+//------------------------------------------------------------------------
+//  Method: resetPeak
+//    Resets peak value.  
+//
+-(void) resetPeak
+{
+    // Reset the value and redraw
+    m_flPeakValue = -INFINITY;
+    m_iPeakBarIdx = -1;
+    [self setNeedsDisplay];
+}
+
+
+//------------------------------------------------------------------------
+//  Method: value accessor
+//
+-(CGFloat) value
+{
+    return m_flValue;
+}
+
+
+//------------------------------------------------------------------------
+//  Method: value setter
+//
+-(void) setValue:(CGFloat)a_value
+{
+    bool      fRedraw = false;
+    
+    // Save value
+    m_flValue = a_value;
+    
+    // Point at which bars start lighting up
+    int iOnIdx = (m_flValue >= m_flMinLimit) ?  0 : m_iNumBars;
+    if( iOnIdx != m_iOnIdx ) {
+        // Changed - save it
+        m_iOnIdx = iOnIdx;
+        fRedraw = true;
+    }
+    
+    // Point at which bars are no longer lit
+    int iOffIdx = ((m_flValue - m_flMinLimit) / (m_flMaxLimit - m_flMinLimit)) * m_iNumBars;
+    if( iOffIdx != m_iOffIdx ) {
+        // Changed - save it
+        m_iOffIdx = iOffIdx;
+        fRedraw = true;
+    }
+    
+    // Are we doing peak?
+    if( m_fHoldPeak && a_value > m_flPeakValue ) {
+        // Yes, save the peak bar index
+        m_flPeakValue = a_value;
+        m_iPeakBarIdx = MIN(m_iOffIdx, m_iNumBars - 1);
+    }
+    
+    // Redraw the display?
+    if( fRedraw ) {
+        // Do it
+        [self setNeedsDisplay];
+    }
+}
+
+
+//------------------------------------------------------------------------
+//  Method: setNumBars:
+//    This method sets the number of bars in the display
+//
+- (void) setNumBars:(int)a_iNumBars
+{
+    // Reset peak value to force it to be updated w/new bar index
+    m_flPeakValue = -INFINITY;
+    
+    // Save it, then update the thresholds
+    m_iNumBars = a_iNumBars;
+    [self setValue:m_flValue];
+    [self setWarnThreshold:m_flWarnThreshold];
+    [self setDangerThreshold:m_flDangerThreshold];
+}
+
+
+//------------------------------------------------------------------------
+//  Method: setWarnThreshold:
+//    Sets the level for which bars should be of the warning color
+//    (dft: yellow)
+//
+- (void) setWarnThreshold:(float)a_flWarnThreshold
+{
+    // Save it and recompute values
+    m_flWarnThreshold = a_flWarnThreshold;
+    m_iWarningBarIdx = ( !isnan(a_flWarnThreshold) && a_flWarnThreshold > 0.0f ) ?
+    (int)( m_flWarnThreshold * (float)m_iNumBars ) :
+    -1;
+}
+
+
+//------------------------------------------------------------------------
+//  Method: setDangerThreshold:
+//    Sets the level for which bars should be of the warning color
+//    (dft: red).
+//
+- (void) setDangerThreshold:(float)a_flDangerThreshold
+{
+    // Save it and recompute values
+    m_flDangerThreshold = a_flDangerThreshold;
+    m_iDangerBarIdx = ( !isnan(a_flDangerThreshold) && a_flDangerThreshold > 0.0f ) ?
+    (int)( m_flDangerThreshold * (float)m_iNumBars ) :
+    -1;
+}
+
+
+//------------------------------------------------------------------------
+//  Synthesized properties
+//
+ at synthesize maxLimit = m_flMaxLimit;
+ at synthesize minLimit = m_flMinLimit;
+ at synthesize numBars = m_iNumBars;
+ at synthesize warnThreshold = m_flWarning;
+ at synthesize dangerThreshold = m_flDanger;
+ at synthesize holdPeak = m_fHoldPeak;
+ at synthesize peakValue = m_flPeakValue;
+ at synthesize litEffect = m_fLitEffect;
+ at synthesize reverse = m_fReverseDirection;
+ at synthesize outerBorderColor = m_clrOuterBorder;
+ at synthesize innerBorderColor = m_clrInnerBorder;
+ at synthesize backgroundColor = m_clrBackground;
+ at synthesize normalBarColor = m_clrNormal;
+ at synthesize warningBarColor = m_clrWarning;
+ at synthesize dangerBarColor = m_clrDanger;
+ at synthesize led;
+ at synthesize ledMinColor;
+ at synthesize ledMaxColor;
+
+
+
+//===[ Private Methods ]==================================================
+
+//------------------------------------------------------------------------
+//  Method: setDefaults
+//    Configure default settings for instance
+//
+-(void) setDefaults
+{
+    // Set view background to clear
+    [self setBackgroundColor:[UIColor clearColor]];
+    
+    // Configure limits
+    m_flMaxLimit  = 1.0f;
+    m_flMinLimit  = 0.0f;
+    m_flValue     = 0.0f;
+    
+    // Set defaults for bar display
+    m_fHoldPeak         = NO;
+    m_iNumBars          = 10;
+    m_iOffIdx           = 0;
+    m_iOnIdx            = 0;
+    m_iPeakBarIdx       = -1;
+    m_fLitEffect        = YES;
+    m_fReverseDirection = NO;
+    [self setWarnThreshold:0.60f];
+    [self setDangerThreshold:0.80f];
+    
+    // Set default colors
+    m_clrBackground       = [[UIColor blackColor] retain];
+    m_clrOuterBorder      = [[UIColor grayColor] retain];
+    m_clrInnerBorder      = [[UIColor blackColor] retain];
+    m_clrNormal           = [[UIColor greenColor] retain];
+    m_clrWarning          = [[UIColor yellowColor] retain];
+    m_clrDanger           = [[UIColor redColor] retain];
+    
+    // Misc.
+    self.clearsContextBeforeDrawing = NO;
+    self.opaque = NO;
+    self.led = NO;
+    self.ledMinColor = [[UIColor blackColor] retain];
+    self.ledMaxColor = [[UIColor redColor] retain];
+}
+
+
+//------------------------------------------------------------------------
+//  Method: drawRect:
+//    Draw the gauge
+//
+-(void) drawRect:(CGRect)rect
+{
+    if (self.hideOnGUI) return;
+    
+    if (self.led)
+    {
+        CGContextRef        ctx;
+        CGFloat             rMin = 0.f;
+        CGFloat             gMin = 0.f;
+        CGFloat             bMin = 0.f;
+        CGFloat             aMin = 0.f;
+        CGFloat             rMax = 0.f;
+        CGFloat             gMax = 0.f;
+        CGFloat             bMax = 0.f;
+        CGFloat             aMax = 0.f;
+        UIColor*            color;
+        float               normedValue = (self.value - self.minLimit) / (self.maxLimit - self.minLimit);
+                
+        if (normedValue < 0.) normedValue = 0.f;
+        else if (normedValue > 1.) normedValue = 1.f;
+        
+        [ledMinColor getRed:&rMin green:&gMin blue:&bMin alpha:&aMin];
+        [ledMaxColor getRed:&rMax green:&gMax blue:&bMax alpha:&aMax];
+        
+        color = [UIColor colorWithRed:rMin * (1. - normedValue) + rMax * normedValue
+                                green:gMin * (1. - normedValue) + gMax * normedValue
+                                 blue:bMin * (1. - normedValue) + bMax * normedValue
+                                alpha:1./*aMin * (1. - normedValue) + aMax * normedValue*/];
+        
+        
+        ctx = UIGraphicsGetCurrentContext();
+        CGContextClearRect(ctx, self.bounds);
+        CGContextSetFillColorWithColor(ctx, color.CGColor);
+        CGContextFillRect(ctx, rect);
+    }
+    else
+    {
+        CGContextRef        ctx;          // Graphics context
+        CGRect              rectBounds,   // Bounding rectangle adjusted for multiple of bar size
+        rectBar;      // Rectangle for individual light bar
+        size_t              iBarSize;     // Size (width or height) of each LED bar
+        
+        // How is the bar oriented?
+        rectBounds = self.bounds;
+        BOOL fIsVertical = (rectBounds.size.height >= rectBounds.size.width);
+        if(fIsVertical) {
+            // Adjust height to be an exact multiple of bar 
+            iBarSize = rectBounds.size.height / m_iNumBars;
+            rectBounds.size.height  = iBarSize * m_iNumBars;
+        }
+        else {
+            // Adjust width to be an exact multiple
+            iBarSize = rectBounds.size.width / m_iNumBars;
+            rectBounds.size.width = iBarSize * m_iNumBars;
+        }
+        
+        // Compute size of bar
+        rectBar.size.width  = (fIsVertical) ? rectBounds.size.width - 2 : iBarSize;
+        rectBar.size.height = (fIsVertical) ? iBarSize : rectBounds.size.height - 2;
+        
+        // Get stuff needed for drawing
+        ctx = UIGraphicsGetCurrentContext();
+        CGContextClearRect(ctx, self.bounds); 
+        
+        // Fill background
+        CGContextSetFillColorWithColor(ctx, m_clrBackground.CGColor);
+        CGContextFillRect(ctx, rectBounds);
+        
+        // Draw LED bars
+        CGContextSetStrokeColorWithColor(ctx, m_clrInnerBorder.CGColor);
+        CGContextSetLineWidth(ctx, 1.0);
+        for( int iX = 0; iX < m_iNumBars; ++iX ) {
+            // Determine position for this bar
+            if(m_fReverseDirection) {
+                // Top-to-bottom or right-to-left
+                rectBar.origin.x = (fIsVertical) ? rectBounds.origin.x + 1 : (CGRectGetMaxX(rectBounds) - (iX+1) * iBarSize);
+                rectBar.origin.y = (fIsVertical) ? (CGRectGetMinY(rectBounds) + iX * iBarSize) : rectBounds.origin.y + 1;
+            }
+            else {
+                // Bottom-to-top or right-to-left
+                rectBar.origin.x = (fIsVertical) ? rectBounds.origin.x + 1 : (CGRectGetMinX(rectBounds) + iX * iBarSize);
+                rectBar.origin.y = (fIsVertical) ? (CGRectGetMaxY(rectBounds) - (iX + 1) * iBarSize) : rectBounds.origin.y + 1;
+            }
+            
+            // Draw top and bottom borders for bar
+            CGContextAddRect(ctx, rectBar);
+            CGContextStrokePath(ctx);
+            
+            // Determine color of bar
+            UIColor   *clrFill = m_clrNormal;
+            if( m_iDangerBarIdx >= 0 && iX >= m_iDangerBarIdx ) {
+                clrFill = m_clrDanger;
+            }
+            else if( m_iWarningBarIdx >= 0 && iX >= m_iWarningBarIdx ) {
+                clrFill = m_clrWarning;
+            }
+            
+            // Determine if bar should be lit
+            BOOL fLit = ((iX >= m_iOnIdx && iX < m_iOffIdx) || iX == m_iPeakBarIdx);
+            
+            // Fill the interior of the bar
+            CGContextSaveGState(ctx);
+            CGRect rectFill = CGRectInset(rectBar, 1.0, 1.0);
+            CGPathRef clipPath = CGPathCreateWithRect(rectFill, NULL);
+            CGContextAddPath(ctx, clipPath);
+            CGContextClip(ctx);
+            [self drawBar:ctx 
+                 withRect:rectFill 
+                 andColor:clrFill 
+                      lit:fLit];
+            CGContextRestoreGState(ctx);
+            CGPathRelease(clipPath);
+        }
+        
+        // Draw border around the control
+        m_clrOuterBorder = [UIColor colorWithRed:0.08 green:0.08 blue:0.08 alpha:1.]; 
+        CGContextSetStrokeColorWithColor(ctx, m_clrOuterBorder.CGColor);
+        CGContextSetLineWidth(ctx, 2.0);
+        CGContextAddRect(ctx, CGRectInset(rectBounds, 1, 1));
+        CGContextStrokePath(ctx);
+    }
+}
+
+
+//------------------------------------------------------------------------
+//  Method: drawBar::::
+//    This method draws a bar
+//
+- (void) drawBar:(CGContextRef)a_ctx 
+        withRect:(CGRect)a_rect
+        andColor:(UIColor *)a_clr
+             lit:(BOOL) a_fLit
+{
+    // Is the bar lit?
+    if(a_fLit) {
+        // Are we doing radial gradient fills?
+        if(m_fLitEffect) {
+            // Yes, set up to draw the bar as a radial gradient
+            static  size_t  num_locations = 2;
+            static  CGFloat locations[]   = { 0.0, 0.5 };
+            CGFloat aComponents[8];
+            CGColorRef clr = a_clr.CGColor;
+            
+            // Set up color components from passed UIColor object
+            if (CGColorGetNumberOfComponents(clr) == 4) {
+                // Extract the components
+                //
+                //  Note that iOS 5.0 provides a nicer way to do this i.e.
+                //    [a_clr getRed:&aComponents[0] 
+                //            green:&aComponents[1] 
+                //             blue:&aComponents[2] 
+                //            alpha:&aComponents[3] ];
+                memcpy(aComponents, CGColorGetComponents(clr), 4*sizeof(CGFloat));
+                
+                // Calculate dark color of gradient
+                aComponents[4] = aComponents[0] - ((aComponents[0] > 0.3) ? 0.3 : 0.0);
+                aComponents[5] = aComponents[1] - ((aComponents[1] > 0.3) ? 0.3 : 0.0);
+                aComponents[6] = aComponents[2] - ((aComponents[2] > 0.3) ? 0.3 : 0.0);
+                aComponents[7] = aComponents[3];
+            }
+            
+            // Calculate radius needed
+            CGFloat width = CGRectGetWidth(a_rect);
+            CGFloat height = CGRectGetHeight(a_rect);
+            CGFloat radius = sqrt( width * width + height * height );
+            
+            // Draw the gradient inside the provided rectangle
+            CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
+            CGGradientRef myGradient = CGGradientCreateWithColorComponents (myColorspace, 
+                                                                            aComponents, 
+                                                                            locations, 
+                                                                            num_locations);
+            CGPoint myStartPoint = { CGRectGetMidX(a_rect), CGRectGetMidY(a_rect) };
+            CGContextDrawRadialGradient(a_ctx, myGradient, myStartPoint, 0.0, myStartPoint, radius, 0);
+            CGColorSpaceRelease(myColorspace);
+            CGGradientRelease(myGradient);
+        }
+        else {
+            // No, solid fill
+            CGContextSetFillColorWithColor(a_ctx, a_clr.CGColor);
+            CGContextFillRect(a_ctx, a_rect);
+        }
+    }
+    else {
+        // No, draw the bar as background color overlayed with a mostly
+        // ... transparent version of the passed color
+        CGColorRef  fillClr = CGColorCreateCopyWithAlpha(a_clr.CGColor, 0.2f);
+        CGContextSetFillColorWithColor(a_ctx, m_clrBackground.CGColor);
+        CGContextFillRect(a_ctx, a_rect);
+        CGContextSetFillColorWithColor(a_ctx, fillClr);
+        CGContextFillRect(a_ctx, a_rect);
+        CGColorRelease(fillClr);  
+    }    
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIBox.h b/architecture/iOS/iOS/FIBox.h
new file mode 100644
index 0000000..4779943
--- /dev/null
+++ b/architecture/iOS/iOS/FIBox.h
@@ -0,0 +1,25 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIResponder.h"
+
+ at interface FIBox : FIResponder
+
+- (void)updateFrame:(CGRect)frame;
+
+ at end
diff --git a/architecture/iOS/iOS/FIBox.mm b/architecture/iOS/iOS/FIBox.mm
new file mode 100644
index 0000000..d27b264
--- /dev/null
+++ b/architecture/iOS/iOS/FIBox.mm
@@ -0,0 +1,62 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIBox.h"
+
+ at implementation FIBox
+
+
+#pragma mark -
+#pragma mark Init
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    return self;
+}
+
+
+- (void)updateFrame:(CGRect)frame
+{
+    self.frame = frame;
+}
+
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+- (void)drawRect:(CGRect)rect
+{
+	CGContextRef context = UIGraphicsGetCurrentContext();
+	CGRect boundsRect = self.bounds;
+    
+	CGContextSaveGState(context);
+	CGContextSetLineWidth(context, 2.f);
+    [self.color set];
+    CGContextAddRect(context, boundsRect);
+    CGContextStrokePath(context);
+	CGContextRestoreGState(context);
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIButton.h b/architecture/iOS/iOS/FIButton.h
new file mode 100644
index 0000000..1fd7624
--- /dev/null
+++ b/architecture/iOS/iOS/FIButton.h
@@ -0,0 +1,39 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIResponder.h"
+
+#define kPushButtonType       0
+#define kToggleButtonType     1
+#define kTabItemButtonType    2
+
+ at interface FIButton : FIResponder
+{
+    int             _type;
+}
+
+ at property CGFloat cornerRadius;				// default: 3.0
+ at property (assign, nonatomic) NSString* title;
+ at property (assign, nonatomic) int type;
+
+- (id)initWithDelegate:(id)aDelegate;
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
+
+ at end
diff --git a/architecture/iOS/iOS/FIButton.mm b/architecture/iOS/iOS/FIButton.mm
new file mode 100644
index 0000000..6c02a47
--- /dev/null
+++ b/architecture/iOS/iOS/FIButton.mm
@@ -0,0 +1,165 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIButton.h"
+
+ at implementation FIButton
+
+ at synthesize cornerRadius;
+ at synthesize title;
+ at synthesize type = _type;
+
+
+#pragma mark -
+#pragma mark Init
+
+- (id)initWithDelegate:(id)aDelegate
+{
+	if ((self = [super initWithDelegate:aDelegate]))
+	{
+        self.type = kPushButtonType;
+		self.cornerRadius = 3.0;
+        UITapGestureRecognizer *doubleTapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)] autorelease];
+		doubleTapGesture.numberOfTapsRequired = 2;
+		[self addGestureRecognizer:doubleTapGesture];
+	}
+	
+	return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+// to setup handle size
+- (void)setFrame:(CGRect)frame
+{
+	[super setFrame:frame];
+}
+
+
+#pragma mark -
+#pragma mark Touch Handling
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    if (self.type == kPushButtonType || self.type == kTabItemButtonType) self.value = 1.f;
+    [self setNeedsDisplay];
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    if (self.type == kToggleButtonType) self.value = 1.f - self.value;
+    else if (self.type == kPushButtonType) self.value = 0.f;
+    [self setNeedsDisplay];
+}
+
+// Function only here to refresh and intercept dble click to prevent zoom of the scroll view
+- (void)doubleTap:(UIGestureRecognizer *)gesture
+{
+    [self setNeedsDisplay];
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    if (self.type == kToggleButtonType) self.value = 1.f - self.value;
+    else if (self.type == kPushButtonType) self.value = 0.f;
+    [self setNeedsDisplay];
+}
+
+#pragma mark -
+#pragma mark Drawing
+
+- (void)drawRect:(CGRect)rect
+{
+    if (self.hideOnGUI) return;
+    
+	CGContextRef context = UIGraphicsGetCurrentContext();
+	CGRect boundsRect = self.bounds;
+	const CGFloat* colorComponents = CGColorGetComponents(self.color.CGColor);
+	UIColor* backgroundColor;
+    
+    // Tab buttons in gray
+    if (self.type == kTabItemButtonType)
+    {
+        if (self.value == 0.f)
+        {
+            backgroundColor = [UIColor colorWithRed:0.1f
+                                              green:0.1f
+                                               blue:0.1f
+                                              alpha:1.f];
+        }
+        else
+        {
+            backgroundColor = [UIColor darkGrayColor];
+        }
+    }
+    
+    // Other buttons in color
+    else
+    {
+        if (self.value == 0.f)
+        {
+            backgroundColor = [UIColor colorWithRed:colorComponents[0]
+                                              green:colorComponents[1]
+                                               blue:colorComponents[2]
+                                              alpha:self.backgroundColorAlpha];
+        }
+        else
+        {
+            backgroundColor = [UIColor colorWithRed:colorComponents[0]
+                                              green:colorComponents[1]
+                                               blue:colorComponents[2]
+                                              alpha:1.f];
+        }
+    }
+    
+	[backgroundColor set];
+	[self context:context addRoundedRect:boundsRect cornerRadius:self.cornerRadius];
+	CGContextFillPath(context);
+    
+    CGSize valueStringSize = [title sizeWithFont:self.labelFont];
+    [self.labelColor set];
+    [title drawInRect:CGRectMake(0 + (self.frame.size.width - valueStringSize.width) / 2,
+                                 0 + (self.frame.size.height - valueStringSize.height) / 2,
+                                 self.frame.size.width,
+                                 self.frame.size.height)
+                   withFont:self.labelFont
+              lineBreakMode:UILineBreakModeTailTruncation];
+    
+    // Draw assignation
+    if (self.assignated)
+    {
+        CGContextSetLineWidth(context, 3.);
+        [self.color set];
+        [self context:context addRoundedRect:boundsRect cornerRadius:self.cornerRadius];
+        CGContextStrokePath(context);
+    }
+    
+    // Draw selection
+    if (self.responderSelected)
+    {
+        CGContextSetLineWidth(context, 15.);
+        [self.color set];
+        [self context:context addRoundedRect:boundsRect cornerRadius:self.cornerRadius];
+        CGContextStrokePath(context);
+    }
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FICocoaUI.h b/architecture/iOS/iOS/FICocoaUI.h
new file mode 100644
index 0000000..5767e16
--- /dev/null
+++ b/architecture/iOS/iOS/FICocoaUI.h
@@ -0,0 +1,2513 @@
+/************************************************************************
+ 
+ IMPORTANT NOTE : this file contains two clearly delimited sections :
+ the ARCHITECTURE section (in two parts) and the USER section. Each section
+ is governed by its own copyright and license. Please check individually
+ each section for license and copyright information.
+ *************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2004-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This Architecture section is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either version 3
+ 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 Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; If not, see <http://www.gnu.org/licenses/>.
+ 
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ 
+ 
+ ************************************************************************
+ ************************************************************************/
+
+#import <UIKit/UIKit.h>
+#import "FIMainViewController.h"
+
+#include "faust/gui/GUI.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+
+#include <list>
+#include <map>
+
+#import "FIKnob.h"
+#import "FISlider.h"
+#import "FIButton.h"
+#import "FITextField.h"
+#import "FIBargraph.h"
+#import "FIBox.h"
+#import "FITabView.h"
+
+using namespace std;
+class CocoaUI;
+class uiCocoaItem;
+class uiBox;
+
+/******************************************************************************
+ *******************************************************************************
+ 
+ GRAPHIC USER INTERFACE (v2)
+ abstract interfaces
+ 
+ *******************************************************************************
+ *******************************************************************************/
+
+
+//=================
+// COCOA part
+//=================
+
+// Widget assignation type
+#define kAssignationNone                0
+#define kAssignationAccelX              1
+#define kAssignationAccelY              2
+#define kAssignationAccelZ              3
+#define kAssignationShake               4
+#define kAssignationCompass             5
+#define kAssignationGyroX               6
+#define kAssignationGyroY               7
+#define kAssignationGyroZ               8
+
+// Current layout mode
+#define kHorizontalLayout               0
+#define kVerticalLayout                 1
+#define kTabLayout                      2
+
+// Global dimensions
+#define kWidgetSlice                    50.f
+#define kOffsetY                        20.f
+#define kSpaceSize                      5.f
+
+// Responders dimensions
+// Boxes
+#define kStdTabHeight                   40.f
+#define kMinBoxWidth                    100.f
+#define kMinBoxHeight                   100.f
+#define kStdBoxLabelHeight              20.0
+#define kStdBoxLabelXOffset             5.0
+
+// Buttons
+#define kStdButtonWidth                 100.0
+#define kStdButtonHeight                40.0
+
+// Num entry
+#define kStdNumEntryWidth               100.0
+#define kStdNumEntryHeight              40.0
+#define kStdNumEntryLabelWidth          100.0
+#define kStdNumEntryLabelHeight         20.0
+
+// Knob
+#define kStdKnobWidth                   100.0
+#define kStdKnobHeight                  100.0
+#define kStdKnobArcWidth                20.0
+#define kStdKnobLabelWidth              100.0
+#define kStdKnobLabelHeight             20.0
+
+// Slider
+#define kMinHorizontalSliderWidth       170.0
+#define kStdHorizontalSliderHeight      40.0
+#define kStdVerticalSliderWidth         40.0
+#define kMinVerticalSliderHeight        170.0
+#define kStdSliderLabelWidth            60.0
+#define kStdSliderLabelHeight           20.0
+
+// Bargraph
+#define kMinHorizontalBargraphWidth     170.0
+#define kStdHorizontalBargraphHeight    30.0
+#define kStdVerticalBargraphWidth       30.0
+#define kMinVerticalBargraphHeight      170.0
+#define kStdLedWidth                    270.0
+#define kStdLedHeight                   270.0
+#define kStdBargraphLabelWidth          60.0
+#define kStdBargraphLabelHeight         20.0
+
+// Routines
+CGPoint inBoxPosition2absolutePosition(float x, float y, uiCocoaItem* box);
+CGPoint absolutePosition(uiCocoaItem* widget);
+
+// All Cocoa widget classes inheritate from uiCocoaItem, which inheritate from Faust uiItem
+class uiCocoaItem : public uiItem
+{
+    
+protected:
+    
+    NSString*               fName;
+    BOOL                    fHidden;
+    uiCocoaItem*            fParent;
+    
+    float                   fx;
+    float                   fy;
+    float                   fw;
+    float                   fh;
+    float                   fAbstractX;
+    float                   fAbstractY;
+    float                   fAbstractW;
+    float                   fAbstractH;
+    BOOL                    fSelected;
+    
+    int                     fInitAssignationType;
+    float                   fInitAssignationRefPointX;
+    float                   fInitAssignationRefPointY;
+    BOOL                    fInitAssignationInverse;
+    BOOL                    fInitAssignationFiltered;
+    float                   fInitAssignationSensibility;
+    float                   fInitR;
+    float                   fInitG;
+    float                   fInitB;
+    int                     fAssignationType;
+    float                   fAssignationRefPointX;
+    float                   fAssignationRefPointY;
+    BOOL                    fAssignationInverse;
+    BOOL                    fAssignationFiltered;
+    float                   fAssignationSensibility;
+    float                   fR;
+    float                   fG;
+    float                   fB;
+    BOOL                    fHideOnGUI;
+    
+public:
+    
+    UILabel*                fLabel;
+    float                   fInit;
+    
+    // Default widget parameter
+    void resetParameters()
+    {
+        fAssignationType = fInitAssignationType;
+        fAssignationRefPointX = fInitAssignationRefPointX;
+        fAssignationRefPointY = fInitAssignationRefPointY;
+        fAssignationInverse = fInitAssignationInverse;
+        fAssignationFiltered = fInitAssignationFiltered;
+        fAssignationSensibility = fInitAssignationSensibility;
+        fR = fInitR;
+        fG = fInitG;
+        fB = fInitB;
+    }
+    
+    // Constructor / Destuctor
+    uiCocoaItem(GUI* ui, float* zone, FIMainViewController* controller, const char* name)
+    : uiItem(ui, zone)
+    {
+        fName = [[NSString alloc] initWithString:[NSString stringWithCString:name encoding:NSASCIIStringEncoding]];
+        fLabel = nil;
+        fHidden = false;
+        fParent = NULL;
+        fx = 0.f;
+        fy = 0.f;
+        fw = 0.f;
+        fh = 0.f;
+        fAbstractX = 0.f;
+        fAbstractY = 0.f;
+        fAbstractW = 0.f;
+        fAbstractH = 0.f;
+        resetParameters();
+        fSelected = false;
+        fInitAssignationType = kAssignationNone;
+        fInitAssignationRefPointX = 0.f;
+        fInitAssignationRefPointY = 0.f;
+        fInitAssignationInverse = false;
+        fInitAssignationFiltered = false;
+        fInitAssignationSensibility = 1.;
+        fInitR = 0.f;
+        fInitG = 0.f;
+        fInitB = 1.f;
+        fHideOnGUI = false;
+        fInit = 0.f;
+    }
+    
+    ~uiCocoaItem()
+    {
+        [fName release];
+    }
+        
+    // Getters, setters 
+    NSString* getName()                                                 {return fName;}
+    
+    virtual void resetInitialValue() = 0;
+    
+    virtual void setHidden(BOOL hidden) = 0;
+    BOOL isHidden()                                                     {return fHidden;}
+    virtual BOOL isHExpandable() = 0;
+    virtual BOOL isVExpandable() = 0;
+    
+    virtual void enableLongPressGestureRecognizer(BOOL enable) = 0;
+    
+    float getX()                                                        {return fx;}
+    float getY()                                                        {return fy;}
+    float getW()                                                        {return fw;}
+    float getH()                                                        {return fh;}
+    virtual void setFrame(float x, float y, float w, float h)           {fx = x; fy = y; fw = w; fh = h;}
+    
+    float getAbstractX()                                                {return fAbstractX;}
+    float getAbstractY()                                                {return fAbstractY;}
+    float getAbstractW()                                                {if (fHideOnGUI) return 0; else return fAbstractW;}
+    float getAbstractH()                                                {if (fHideOnGUI) return 0; else return fAbstractH;}
+    void setAbstractFrame(float x, float y, float w, float h)           {fAbstractX = x; fAbstractY = y; fAbstractW = w; fAbstractH = h;}
+    
+    void setParent(uiCocoaItem* parent)                                 {fParent = parent;}
+    
+    uiCocoaItem* getParent()                                            {return fParent;}
+    
+    BOOL isSelected()                                                   {return fSelected;}
+    virtual void setSelected(BOOL selected)                             {fSelected = selected;}
+
+    int getInitAssignationType()                                        {return fInitAssignationType;}
+    void setInitAssignationType(int assignationType)                    {fInitAssignationType = assignationType; setAssignationType(assignationType);}
+
+    int getAssignationType()                                            {return fAssignationType;}
+    virtual void setAssignationType(int assignationType)                {fAssignationType = assignationType;}
+
+    float getInitAssignationRefPointX()                                 {return fInitAssignationRefPointX;}
+    void setInitAssignationRefPointX(float assignationRefPointX)        {fInitAssignationRefPointX = assignationRefPointX; setAssignationRefPointX(assignationRefPointX);}
+
+    float getAssignationRefPointX()                                     {return fAssignationRefPointX;}
+    void setAssignationRefPointX(float assignationRefPointX)            {fAssignationRefPointX = assignationRefPointX;}
+    
+    float getInitAssignationRefPointY()                                 {return fInitAssignationRefPointY;}
+    void setInitAssignationRefPointY(float assignationRefPointY)        {fInitAssignationRefPointY = assignationRefPointY; setAssignationRefPointY(assignationRefPointY);}
+
+    float getAssignationRefPointY()                                     {return fAssignationRefPointY;}
+    void setAssignationRefPointY(float assignationRefPointY)            {fAssignationRefPointY = assignationRefPointY;}
+
+    BOOL getInitAssignationInverse()                                    {return fInitAssignationInverse;}
+    void setInitAssignationInverse(BOOL assignationInverse)             {fInitAssignationInverse = assignationInverse; setAssignationInverse(assignationInverse);}
+
+    BOOL getAssignationInverse()                                        {return fAssignationInverse;}
+    void setAssignationInverse(BOOL assignationInverse)                 {fAssignationInverse = assignationInverse;}
+
+    BOOL getInitAssignationFiltered()                                   {return fInitAssignationFiltered;}
+    void setInitAssignationFiltered(BOOL assignationFiltered)           {fInitAssignationFiltered = assignationFiltered; setAssignationFiltered(assignationFiltered);}
+
+    BOOL getAssignationFiltered()                                       {return fAssignationFiltered;}
+    void setAssignationFiltered(BOOL assignationFiltered)               {fAssignationFiltered = assignationFiltered;}
+
+    float getInitAssignationSensibility()                               {return fInitAssignationSensibility;}
+    void setInitAssignationSensibility(float assignationSensibility)    {fInitAssignationSensibility = assignationSensibility; setAssignationSensibility(assignationSensibility);}
+
+    float getAssignationSensibility()                                   {return fAssignationSensibility;}
+    void setAssignationSensibility(float assignationSensibility)        {fAssignationSensibility = assignationSensibility;}
+
+    float getInitR()                                                    {return fInitR;}
+    float getInitG()                                                    {return fInitG;}
+    float getInitB()                                                    {return fInitB;}
+    virtual void setInitColor(float r, float g, float b)                {fInitR = r; fInitG = g; fInitB = b; setColor(r, g, b);}
+
+    float getR()                                                        {return fR;}
+    float getG()                                                        {return fG;}
+    float getB()                                                        {return fB;}
+    virtual void setColor(float r, float g, float b)                    {fR = r; fG = g; fB = b;}
+    
+    void setHideOnGUI(BOOL hideOnGUI)                                   {fHideOnGUI = hideOnGUI; if (fLabel) fLabel.hidden = hideOnGUI;}
+    BOOL getHideOnGUI()                                                 {return fHideOnGUI;}
+};
+
+
+// --------------------------- Box ---------------------------
+
+class uiBox : public uiCocoaItem
+{
+
+public:
+    
+    FIBox*                  fBox;
+    FITabView*              fTabView;
+    list <uiCocoaItem*>     fWidgetList;        // if kTabLayout : boxes containing each tab elements ; else : elements within box
+    BOOL                    fClosed;
+    int                     fBoxType;
+    float                   fLastX;
+    float                   fLastY;
+    
+    uiBox(GUI* ui, FIMainViewController* controller, const char* name, int boxType)
+    : uiCocoaItem(ui, NULL, controller, name)
+    {
+        float tabOffset = 0;
+        fBoxType = boxType;
+        fLastX = 0.f;
+        fLastY = 0.f;
+        fTabView = nil;
+        fLabel = nil;
+        
+        if (boxType == kTabLayout)
+        {
+            fTabView = [[[FITabView alloc] initWithDelegate:controller] autorelease];
+            fTabView.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
+            fTabView.labelColor = [UIColor blueColor];
+            fTabView.backgroundColorAlpha = 0.4;
+            fTabView.value = 0.f;
+            fTabView.autoresizingMask = UIViewAutoresizingNone;
+            [controller.dspView addSubview:fTabView];
+            tabOffset = kStdTabHeight;
+        }
+
+        fClosed = FALSE;
+        fBox = [[[FIBox alloc] init] autorelease];
+        fBox.color = [UIColor darkGrayColor];
+        fBox.autoresizingMask = UIViewAutoresizingNone;
+        
+        [controller.dspView addSubview:fBox];
+        
+        if (boxType != kTabLayout)
+        {
+            fLabel = [[[UILabel alloc] init] autorelease];
+            fLabel.font = [UIFont boldSystemFontOfSize:18];
+            fLabel.textAlignment = UITextAlignmentLeft;
+            fLabel.autoresizingMask = UIViewAutoresizingNone;
+            fLabel.text = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
+            fLabel.textColor = [UIColor colorWithWhite:1. alpha:1.];
+            fLabel.backgroundColor = [UIColor clearColor];
+            [controller.dspView addSubview:fLabel];
+            
+            fLastY = kStdBoxLabelHeight;
+        }
+    }
+    
+    ~uiBox()
+    {
+        if (fLabel) [fLabel release];
+        [fBox release];
+    }
+    
+    void resetInitialValue()
+    {
+    }
+    
+    BOOL isHExpandable()
+    {
+        return TRUE;
+    }
+    
+    BOOL isVExpandable()
+    {
+        return FALSE;
+    }
+    
+    void enableLongPressGestureRecognizer(BOOL enable)
+    {
+        // Do nothing
+    }
+    
+    int getNumberOfDirectChildren()
+    {
+        list<uiCocoaItem*>::iterator    i;
+        int                             cpt = 0;
+        
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            if ((*i)->getParent() == this)
+            {
+                cpt++;
+            }
+        }
+        
+        return cpt;
+    }
+    
+    void setFrame(float x, float y, float w, float h)
+    {
+        CGPoint                         pt = inBoxPosition2absolutePosition(x, y, fParent);
+        list<uiCocoaItem*>::iterator    i;
+        float                           labelYOffset = 0.f;
+
+        uiCocoaItem::setFrame(x, y, w, h);
+
+        // For tab views : simply resize the tab corresponding box
+        if (fTabView)
+        {
+            fTabView.frame = CGRectMake(pt.x, pt.y, w, kStdTabHeight);
+            fBox.frame = CGRectMake(pt.x, pt.y + kStdTabHeight, w, h - kStdTabHeight);
+            
+            for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+            {
+                if ((*i)->getW() != w || (*i)->getW() != h - kStdTabHeight)
+                {
+                    (*i)->setFrame((*i)->getX(), (*i)->getY(), w, h - kStdTabHeight);
+                }
+            }
+        }
+        
+        // For vertical and horizontal boxes
+        else
+        {
+            fBox.frame = CGRectMake(pt.x, pt.y, w, h);
+            if (fLabel)
+            {
+                labelYOffset = kStdBoxLabelHeight;
+                fLabel.frame = CGRectMake(pt.x + kStdBoxLabelXOffset, pt.y, w - kStdBoxLabelXOffset, labelYOffset);
+            }
+
+            for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+            {
+                if (fBoxType == kVerticalLayout
+                    && (*i)->getW() < w - 2 * kSpaceSize
+                    && (*i)->getParent() == this)
+                {
+                    (*i)->setFrame((*i)->getX(), (*i)->getY(), w - 2 * kSpaceSize, (*i)->getH());
+                }
+                else if (fBoxType == kHorizontalLayout
+                         && (*i)->getH() < h - 2 * kSpaceSize - labelYOffset
+                         && (*i)->getParent() == this)
+                {
+                    (*i)->setFrame((*i)->getX(), (*i)->getY(), (*i)->getW(), h - 2 * kSpaceSize - labelYOffset);
+                }
+            }
+        }
+    }
+    
+    // Returns minimum size used by widgets within the box
+    CGSize getContentSize()
+    {
+        list<uiCocoaItem*>::iterator    i;
+        float                           maxW = 0.f;
+        float                           maxH = 0.f;
+        
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            if ((*i)->getParent() == this)
+            {
+                maxW = max((*i)->getX() + (*i)->getW(), maxW);
+                maxH = max((*i)->getY() + (*i)->getH(), maxH);
+            }
+        }
+
+        return CGSizeMake(maxW, maxH);
+    }
+    
+    void setHidden(BOOL hidden)
+    {
+        fHidden = hidden;
+        fBox.hidden = hidden || getHideOnGUI();
+        if (fLabel) fLabel.hidden = hidden || getHideOnGUI();
+        
+        list<uiCocoaItem*>::iterator i;
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            (*i)->setHidden(hidden);
+        }
+        
+        [fBox setNeedsDisplay];
+        if (fTabView)
+        {
+            fTabView.hidden = hidden || getHideOnGUI();
+            [fTabView setNeedsDisplay];
+        }
+    }
+    
+    void close(int index)
+    {
+        fClosed = TRUE;
+    }
+    
+    void reflectZone()
+    {
+        [fBox setNeedsDisplay];
+                
+        if (fTabView)
+        {
+            list<uiCocoaItem*>::iterator i;
+            int index = 0;
+            
+            for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+            {
+                if (fTabView.value != index)
+                {
+                    (*i)->setHidden(true);
+                }
+                else
+                {
+                    (*i)->setHidden(false);
+                }
+                ++index;
+            }
+            [fTabView setNeedsDisplay];
+        }
+    }
+};
+
+
+// -------------------------- Knob -----------------------------------
+
+class uiKnob : public uiCocoaItem
+{   
+    
+public :
+    
+    FIKnob*                         fKnob;
+    UILongPressGestureRecognizer*   fLongPressGesture;
+    
+    uiKnob(GUI* ui, FIMainViewController* controller, const char* name, float* zone, float init, float min, float max, float step, BOOL horizontal)
+    : uiCocoaItem(ui, zone, controller, name)
+    {
+        fLabel = [[[UILabel alloc] init] autorelease];
+        fLabel.font = [UIFont boldSystemFontOfSize:12];
+        fLabel.textAlignment = UITextAlignmentCenter;
+        fLabel.text = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
+        fLabel.textColor = [UIColor whiteColor];
+        fLabel.backgroundColor = [UIColor clearColor];
+        [controller.dspView addSubview:fLabel];
+        
+        fKnob = [[[FIKnob alloc] initWithDelegate:controller] autorelease];
+        fKnob.autoresizingMask = UIViewAutoresizingNone;
+        fKnob.labelFont = [UIFont boldSystemFontOfSize:14.0];
+        fKnob.labelColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
+        fKnob.color = [UIColor colorWithRed:fR green:fG blue:fB alpha:1.f];
+        fKnob.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
+        fKnob.min = min;
+        fKnob.max = max;
+        fKnob.step = step;
+        fInit = init;
+        fKnob.value = init;
+        fKnob.valueArcWidth = kStdKnobArcWidth;
+        fKnob.backgroundColorAlpha = 0.4;
+        [controller.dspView addSubview:fKnob];
+                
+        fLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:controller action:@selector(showWidgetPreferencesView:)];
+        fLongPressGesture.delegate = controller;
+		[fKnob addGestureRecognizer:fLongPressGesture];
+    }
+    
+    ~uiKnob()
+    {
+        [fLabel release];
+        [fKnob release];
+        [fLongPressGesture release];
+    }
+    
+    void resetInitialValue()
+    {
+        fKnob.value = fInit;
+    }
+    
+    BOOL isHExpandable()
+    {
+        return FALSE;
+    }
+    
+    BOOL isVExpandable()
+    {
+        return FALSE;
+    }
+
+    void enableLongPressGestureRecognizer(BOOL enable)
+    {
+        if (enable)
+        {
+            [fKnob addGestureRecognizer:fLongPressGesture];
+        }
+        else
+        {
+            [fKnob removeGestureRecognizer:fLongPressGesture];
+        }
+    }
+    
+    void setFrame(float x, float y, float w, float h)
+    {
+        CGPoint         pt = inBoxPosition2absolutePosition(x, y, fParent);
+        
+        uiCocoaItem::setFrame(x, y, w, h);
+
+        fKnob.frame = CGRectMake(   pt.x + (w - kStdKnobWidth) / 2.f,
+                                    pt.y + (h - kStdKnobHeight - kSpaceSize - kStdKnobLabelHeight) / 2.f,
+                                    kStdKnobWidth,
+                                    kStdKnobHeight);
+        
+        fLabel.frame = CGRectMake(  pt.x + (w - kStdKnobLabelWidth) / 2.f,
+                                    pt.y + (h + kStdKnobHeight - kSpaceSize - kStdKnobLabelHeight) / 2.f + kSpaceSize,
+                                    kStdKnobLabelWidth,
+                                    kStdKnobLabelHeight);
+    }
+    
+    void setHidden(BOOL hidden)
+    {
+        fHidden = hidden;
+        fLabel.hidden = hidden || getHideOnGUI();
+        fKnob.hidden = hidden || getHideOnGUI();
+    }
+    
+    void setSelected(BOOL selected)
+    {
+        uiCocoaItem::setSelected(selected);
+        fKnob.responderSelected = selected;
+        [fKnob setNeedsDisplay];
+    }
+    
+    void setColor(float r, float g, float b)
+    {
+        uiCocoaItem::setColor(r, g, b);
+        
+        fKnob.color = [UIColor colorWithRed:fR green:fG blue:fB alpha:1.f];
+        [fKnob setNeedsDisplay];
+    }
+    
+    void setAssignationType(int assignationType)
+    {
+        uiCocoaItem::setAssignationType(assignationType);
+        if (assignationType != kAssignationNone)
+        {
+            fKnob.assignated = true;
+        }
+        else
+        {
+            fKnob.assignated = false;
+        }
+        [fKnob setNeedsDisplay];
+    }
+    
+    void reflectZone()
+    {
+        float v = *fZone;
+        fCache = v;
+        fKnob.value = v;
+    }
+};
+
+// -------------------------- Slider -----------------------------------
+
+class uiSlider : public uiCocoaItem
+{
+
+public :
+    
+    FISlider*                       fSlider;
+    BOOL                            fHorizontal;
+    UILongPressGestureRecognizer*   fLongPressGesture;
+    
+    uiSlider(GUI* ui, FIMainViewController* controller, const char* name, float* zone, float init, float min, float max, float step, BOOL horizontal)
+    : uiCocoaItem(ui, zone, controller, name)
+    {        
+        fLabel = [[[UILabel alloc] init] autorelease];
+        fLabel.font = [UIFont boldSystemFontOfSize:12];
+        if (horizontal) fLabel.textAlignment = UITextAlignmentRight;
+        else fLabel.textAlignment = UITextAlignmentCenter;
+        fLabel.text = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
+        fLabel.textColor = [UIColor whiteColor];
+        fLabel.backgroundColor = [UIColor clearColor];
+        [controller.dspView addSubview:fLabel];
+        
+        fSlider = [[[FISlider alloc] initWithDelegate:controller] autorelease];
+        fSlider.isHorizontalSlider = horizontal;
+        fHorizontal = horizontal;
+        fSlider.autoresizingMask = UIViewAutoresizingNone;
+        fSlider.labelFont = [UIFont boldSystemFontOfSize:14.0];
+        fSlider.labelColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
+        fSlider.color = [UIColor colorWithRed:fR green:fG blue:fB alpha:1.f];
+        fSlider.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
+        fSlider.min = min;
+        fSlider.max = max;
+        fInit = init;
+        fSlider.value = init;
+        fSlider.backgroundColorAlpha = 0.4;
+        fSlider.handleSize = 50;
+        fSlider.step = step;
+        [controller.dspView addSubview:fSlider];
+        fLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:controller action:@selector(showWidgetPreferencesView:)];
+        fLongPressGesture.delegate = controller;
+		[fSlider addGestureRecognizer:fLongPressGesture];
+    }
+    
+    ~uiSlider()
+    {
+        [fLabel release];
+        [fSlider release];
+        [fLongPressGesture release];
+    }
+    
+    void resetInitialValue()
+    {
+        fSlider.value = fInit;
+    }
+    
+    BOOL isHExpandable()
+    {
+        if (fHorizontal)
+        {
+            return TRUE;
+        }
+        return FALSE;
+    }
+    
+    BOOL isVExpandable()
+    {
+        if (fHorizontal)
+        {
+            return FALSE;
+        }
+        return TRUE;
+    }
+    
+    void enableLongPressGestureRecognizer(BOOL enable)
+    {        
+        if (enable)
+        {
+            [fSlider addGestureRecognizer:fLongPressGesture];            
+        }
+        else
+        {
+            [fSlider removeGestureRecognizer:fLongPressGesture];
+        }
+    }
+    
+    void setFrame(float x, float y, float w, float h)
+    {
+        CGPoint         pt = inBoxPosition2absolutePosition(x, y, fParent);
+        
+        uiCocoaItem::setFrame(x, y, w, h);
+
+        if (fHorizontal)
+        {
+            fLabel.frame = CGRectMake(  pt.x,
+                                        pt.y + (h - kStdSliderLabelHeight) / 2.f,
+                                        kStdSliderLabelWidth,
+                                        kStdSliderLabelHeight);
+            
+            fSlider.frame = CGRectMake( pt.x + kStdSliderLabelWidth + kSpaceSize,
+                                        pt.y + (h - kStdHorizontalSliderHeight) / 2.f,
+                                        w - kStdSliderLabelWidth - kSpaceSize,
+                                        kStdHorizontalSliderHeight);
+        }
+        else
+        {
+            fSlider.frame = CGRectMake( pt.x + (w - kStdVerticalSliderWidth) / 2.f,
+                                        pt.y,
+                                        kStdVerticalSliderWidth,
+                                        h - kSpaceSize - kStdSliderLabelHeight);
+            
+            fLabel.frame = CGRectMake(  pt.x + (w - kStdSliderLabelWidth) / 2.f,
+                                        pt.y + h - kSpaceSize - kStdSliderLabelHeight,
+                                        kStdSliderLabelWidth,
+                                        kStdSliderLabelHeight);
+        }
+    }
+    
+    void setHidden(BOOL hidden)
+    {
+        fHidden = hidden;
+        fLabel.hidden = hidden || getHideOnGUI();
+        fSlider.hidden = hidden || getHideOnGUI();
+    }
+    
+    void setColor(float r, float g, float b)
+    {
+        uiCocoaItem::setColor(r, g, b);
+        
+        fSlider.color = [UIColor colorWithRed:fR green:fG blue:fB alpha:1.f];
+        [fSlider setNeedsDisplay];
+    }
+    
+    void setAssignationType(int assignationType)
+    {
+        uiCocoaItem::setAssignationType(assignationType);
+        if (assignationType != kAssignationNone)
+        {
+            fSlider.assignated = true;
+        }
+        else
+        {
+            fSlider.assignated = false;
+        }
+        [fSlider setNeedsDisplay];
+    }
+    
+    void setSelected(BOOL selected)
+    {
+        uiCocoaItem::setSelected(selected);
+        fSlider.responderSelected = selected;
+        [fSlider setNeedsDisplay];
+    }
+    
+    void reflectZone()
+    {
+        float v = *fZone;
+        fCache = v;
+        fSlider.value = v;
+    }
+};
+
+
+// --------------------------- Press button ---------------------------
+
+class uiButton : public uiCocoaItem
+{
+    
+public:
+    
+    FIButton*                       fButton;
+    //UILongPressGestureRecognizer*   fLongPressGesture;
+    
+    uiButton(GUI* ui, FIMainViewController* controller, const char* name, float* zone, int type)
+    : uiCocoaItem(ui, zone, controller, name)
+    {
+        fButton = [[[FIButton alloc] initWithDelegate:controller] autorelease];
+        fButton.autoresizingMask =  UIViewAutoresizingNone;
+        fButton.title = [[NSString alloc] initWithCString:name encoding:NSASCIIStringEncoding];
+		fButton.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
+        fButton.labelColor = [UIColor whiteColor];
+        fButton.backgroundColorAlpha = 0.4;
+        fButton.type = type;
+        fButton.color = [UIColor colorWithRed:fR green:fG blue:fB alpha:1.f];
+        [controller.dspView addSubview:fButton];
+        
+        //fLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:controller action:@selector(showWidgetPreferencesView:)];
+        //fLongPressGesture.delegate = controller;
+		//[fButton addGestureRecognizer:fLongPressGesture];
+    }
+    
+    ~uiButton()
+    {
+        [fButton release];
+        //[fLongPressGesture release];
+    }
+
+    void resetInitialValue()
+    {
+    }
+    
+    BOOL isHExpandable()
+    {
+        return TRUE;
+    }
+    
+    BOOL isVExpandable()
+    {
+        return FALSE;
+    }
+    
+    void enableLongPressGestureRecognizer(BOOL enable)
+    {
+        /*if (enable)
+        {
+            [fButton addGestureRecognizer:fLongPressGesture];
+        }
+        else
+        {
+            [fButton removeGestureRecognizer:fLongPressGesture];
+        }*/
+    }
+    
+    void setFrame(float x, float y, float w, float h)
+    {
+        CGPoint         pt = inBoxPosition2absolutePosition(x, y, fParent);
+        
+        uiCocoaItem::setFrame(x, y, w, h);
+        
+        fButton.frame = CGRectMake( pt.x + (w - kStdButtonWidth) / 2.f,
+                                    pt.y + (h - kStdButtonHeight) / 2.f,
+                                    kStdButtonWidth,
+                                    kStdButtonHeight);
+    }
+    
+    void setHidden(BOOL hidden)
+    {
+        fHidden = hidden;
+        fButton.hidden = hidden || getHideOnGUI();
+    }
+
+    void setSelected(BOOL selected)
+    {
+        uiCocoaItem::setSelected(selected);
+        fButton.responderSelected = selected;
+        [fButton setNeedsDisplay];
+    }
+    
+    void setColor(float r, float g, float b)
+    {
+        uiCocoaItem::setColor(r, g, b);
+        
+        fButton.color = [UIColor colorWithRed:fR green:fG blue:fB alpha:1.f];
+        [fButton setNeedsDisplay];
+    }
+    
+    void setAssignationType(int assignationType)
+    {
+        uiCocoaItem::setAssignationType(assignationType);
+        if (assignationType != kAssignationNone)
+        {
+            fButton.assignated = true;
+        }
+        else
+        {
+            fButton.assignated = false;
+        }
+        [fButton setNeedsDisplay];
+    }
+    
+    void reflectZone()
+    {
+        float v = *fZone;
+        fCache = v;
+        if (fButton.type == kToggleButtonType) fButton.value = v;
+    }
+};
+
+
+// ------------------------------ Num Entry -----------------------------------
+
+class uiNumEntry : public uiCocoaItem
+{
+    
+public:
+    
+    FITextField*        fTextField;
+    
+    uiNumEntry(GUI* ui, FIMainViewController* controller, const char* label, float* zone, float init, float min, float max, float step)
+    : uiCocoaItem(ui, zone, controller, label)
+    {
+        fLabel = [[[UILabel alloc] init] autorelease];
+        fLabel.font = [UIFont boldSystemFontOfSize:12];
+        fLabel.textAlignment = UITextAlignmentCenter;
+        fLabel.text = [NSString stringWithCString:label encoding:NSASCIIStringEncoding];
+        fLabel.textColor = [UIColor whiteColor];
+        fLabel.backgroundColor = [UIColor clearColor];
+        [controller.dspView addSubview:fLabel];
+
+        fTextField = [[[FITextField alloc] initWithDelegate:controller] autorelease];
+        fTextField.autoresizingMask = UIViewAutoresizingNone;
+		fTextField.backgroundColor = [UIColor lightGrayColor];
+        fTextField.textColor = [UIColor whiteColor];
+        fTextField.labelColor = [UIColor whiteColor];
+        fTextField.backgroundColorAlpha = 0.4;
+        fTextField.min = min;
+        fTextField.max = max;
+        fInit = init;
+        fTextField.value = init;
+        fTextField.step = step;
+        [controller.dspView addSubview:fTextField];
+    }
+    
+    ~uiNumEntry()
+    {
+        [fTextField release];
+    }
+    
+    void resetInitialValue()
+    {
+        fTextField.value = fInit;
+    }
+    
+    BOOL isHExpandable()
+    {
+        return FALSE;
+    }
+    
+    BOOL isVExpandable()
+    {
+        return FALSE;
+    }
+    
+    void enableLongPressGestureRecognizer(BOOL enable)
+    {
+        // Do nothing
+    }
+    
+    void setFrame(float x, float y, float w, float h)
+    {
+        CGPoint         pt = inBoxPosition2absolutePosition(x, y, fParent);
+        
+        uiCocoaItem::setFrame(x, y, w, h);
+                
+        fTextField.frame = CGRectMake(  pt.x + (w - kStdNumEntryWidth) / 2.f,
+                                        pt.y + (h - kStdNumEntryHeight - kSpaceSize - kStdNumEntryLabelHeight) / 2.f,
+                                        kStdNumEntryWidth,
+                                        kStdNumEntryHeight);
+        
+        fLabel.frame = CGRectMake(      pt.x + (w - kStdNumEntryLabelWidth) / 2.f,
+                                        pt.y + (h + kStdNumEntryHeight - kSpaceSize - kStdNumEntryLabelHeight) / 2.f + kSpaceSize,
+                                        kStdNumEntryLabelWidth,
+                                        kStdNumEntryLabelHeight);
+    }
+    
+    void setHidden(BOOL hidden)
+    {
+        fHidden = hidden;
+        fLabel.hidden = hidden || getHideOnGUI();
+        fTextField.hidden = hidden || getHideOnGUI();
+    }
+
+    void reflectZone()
+    {
+        float v = *fZone;
+        fCache = v;
+        fTextField.value = v;
+    }
+};
+
+
+// ------------------------------ Bargraph -----------------------------------
+
+class uiBargraph : public uiCocoaItem
+{
+    
+public:
+    
+    FIBargraph*             fBargraph;
+    BOOL                    fHorizontal;
+    BOOL                    fLed;
+    
+    uiBargraph(GUI* ui, FIMainViewController* controller, const char* name, float* zone, float min, float max, BOOL horizontal)
+    : uiCocoaItem(ui, zone, controller, name)
+    {
+        fLed = false;
+        fLabel = [[[UILabel alloc] init] autorelease];
+        fLabel.font = [UIFont boldSystemFontOfSize:12];
+        if (horizontal) fLabel.textAlignment = UITextAlignmentRight;
+        else fLabel.textAlignment = UITextAlignmentCenter;
+        fLabel.text = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
+        fLabel.textColor = [UIColor whiteColor];
+        fLabel.backgroundColor = [UIColor blackColor];
+        [controller.dspView addSubview:fLabel];
+        
+        fBargraph = [[[FIBargraph alloc] initWithFrame:CGRectMake(0.f, 0.f, 0.f, 0.f)] autorelease];
+        fBargraph.autoresizingMask = UIViewAutoresizingNone;
+        fHorizontal = horizontal;
+        fBargraph.value = 0.f;
+        fBargraph.minLimit = min;
+        fBargraph.maxLimit = max;
+        fBargraph.numBars = 8;
+        fBargraph.holdPeak = false;
+        [controller.dspView addSubview:fBargraph];
+    }
+    
+    ~uiBargraph()
+    {
+        [fLabel release];
+        [fBargraph release];
+    }
+    
+    void resetInitialValue()
+    {
+    }
+    
+    BOOL isHExpandable()
+    {
+        /*if (fLed) return YES;
+        else*/ if (fHorizontal) return TRUE;
+        
+        return FALSE;
+    }
+    
+    BOOL isVExpandable()
+    {
+        /*if (fLed) return YES;
+        else*/ if (!fHorizontal) return TRUE;
+        
+        return FALSE;
+    }
+    
+    void enableLongPressGestureRecognizer(BOOL enable)
+    {
+        // Do nothing
+    }
+    
+    void setFrame(float x, float y, float w, float h)
+    {
+        CGPoint         pt = inBoxPosition2absolutePosition(x, y, fParent);
+        
+        uiCocoaItem::setFrame(x, y, w, h);
+        
+        if (fLed)
+        {
+            /*fBargraph.frame = CGRectMake(   pt.x + (w - kStdLedWidth) / 2.f,
+                                            pt.y + (h - kStdLedHeight - kSpaceSize - kStdBargraphLabelHeight) / 2.f,
+                                            kStdLedWidth,
+                                            kStdLedHeight);
+            
+            fLabel.frame = CGRectMake(      pt.x + (w - kStdBargraphLabelWidth) / 2.f,
+                                            pt.y + (h + kStdBargraphLabelHeight - kSpaceSize - kStdBargraphLabelHeight) / 2.f + kSpaceSize,
+                                            kStdBargraphLabelWidth,
+                                            kStdBargraphLabelHeight);*/
+            
+            if (fHorizontal)
+            {
+                fBargraph.frame = CGRectMake(   pt.x + kStdLedWidth + kSpaceSize,
+                                                pt.y + (h - kStdLedHeight) / 2.f,
+                                                w - kStdBargraphLabelWidth - kSpaceSize,
+                                                kStdLedHeight);
+                
+                fLabel.frame = CGRectMake(      pt.x,
+                                                pt.y + (h - kStdBargraphLabelHeight) / 2.f,
+                                                kStdBargraphLabelWidth,
+                                                kStdBargraphLabelHeight);
+            }
+            else
+            {
+                fBargraph.frame = CGRectMake(   pt.x + (w - kStdLedWidth) / 2.f,
+                                                pt.y,
+                                                kStdLedWidth,
+                                                h - kSpaceSize - kStdBargraphLabelHeight);
+                
+                fLabel.frame = CGRectMake(      pt.x + (w - kStdBargraphLabelWidth) / 2.f,
+                                                pt.y + h - kSpaceSize - kStdBargraphLabelHeight,
+                                                kStdBargraphLabelWidth,
+                                                kStdBargraphLabelHeight);
+            }
+        }
+        else if (fHorizontal)
+        {
+            fBargraph.frame = CGRectMake(   pt.x + kStdBargraphLabelWidth + kSpaceSize,
+                                            pt.y + (h - kStdHorizontalBargraphHeight) / 2.f,
+                                            w - kStdBargraphLabelWidth - kSpaceSize,
+                                            kStdHorizontalBargraphHeight);
+            
+            fLabel.frame = CGRectMake(      pt.x,
+                                            pt.y + (h - kStdBargraphLabelHeight) / 2.f,
+                                            kStdBargraphLabelWidth,
+                                            kStdBargraphLabelHeight);
+        }
+        else
+        {
+            fBargraph.frame = CGRectMake(   pt.x + (w - kStdVerticalBargraphWidth) / 2.f,
+                                            pt.y,
+                                            kStdVerticalBargraphWidth,
+                                            h - kSpaceSize - kStdBargraphLabelHeight);
+            
+            fLabel.frame = CGRectMake(      pt.x + (w - kStdBargraphLabelWidth) / 2.f,
+                                            pt.y + h - kSpaceSize - kStdBargraphLabelHeight,
+                                            kStdBargraphLabelWidth,
+                                            kStdBargraphLabelHeight);
+        }
+    }
+    
+    void setHidden(BOOL hidden)
+    {
+        fHidden = hidden;
+        fLabel.hidden = hidden || getHideOnGUI();
+        fBargraph.hidden = hidden || getHideOnGUI();
+    }
+    
+    void setLed(BOOL led)
+    {
+        fLed = led;
+        fBargraph.led = led;
+        
+        if (led)
+        {
+            fLabel.textAlignment = UITextAlignmentCenter;
+        }
+        else
+        {
+            if (fHorizontal) fLabel.textAlignment = UITextAlignmentRight;
+            else fLabel.textAlignment = UITextAlignmentCenter;
+        }
+    }
+    
+    void reflectZone()
+    {
+        float v = *fZone;
+        fCache = v;
+        fBargraph.value = v;
+    }
+};
+
+
+// ------------------------------ CocoaUI -----------------------------------
+
+class CocoaUI : public GUI
+{
+    
+public:
+    list <uiCocoaItem*>             fWidgetList;
+    
+    void setHidden(bool state)
+    {
+        map<float*, bool>::iterator it;
+        for (it = fHideOnGUI.begin(); it != fHideOnGUI.end(); it++) {
+            (*it).second = state;
+        }
+    }
+
+    
+private:
+    
+    UIWindow*                       fWindow;
+    FIMainViewController*           fViewController;
+    MY_Meta*                        fMetadata;
+    map<float*, string>             fUnit;
+    map<float*, int>                fR;
+    map<float*, int>                fG;
+    map<float*, int>                fB;
+    map<float*, int>                fAssignationType;
+    map<float*, bool>               fAssignationFiltered;
+    map<float*, float>              fAssignationSensibility;
+    map<float*, bool>               fAssignationInverse;
+    map<float*, float>              fAssignationRefPointX;
+    map<float*, float>              fAssignationRefPointY;
+    map<float*, bool>               fHideOnGUI;
+    map<float*, bool>               fLed;
+    map<float*, float>              fLedR;
+    map<float*, float>              fLedG;
+    map<float*, float>              fLedB;
+    set<float*>                     fKnobSet;
+    int                             fCurrentLayoutType;
+    bool                            fNextBoxIsHideOnGUI;
+    
+    // Layout management
+    
+    
+    uiBox* getActiveBox()
+    {
+        list<uiCocoaItem*>::reverse_iterator i;
+        
+        // Loop on each widgets, from the last
+        for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++)
+        {
+            uiBox* box = dynamic_cast<uiBox*>(*i);
+            if (box && !box->fClosed) {
+                return box;
+            }
+        }
+        return NULL;        
+    }
+    
+    // General rules to place objet
+    void computeWidgetFrame(uiCocoaItem* widget)
+    {
+        uiBox*      parent = dynamic_cast<uiBox*>(widget->getParent());
+        float       x = 0.f;
+        float       y = 0.f;
+        float       w = 0.f;
+        float       h = 0.f;
+                
+        // If no parent : the widget is the main container and is placed at the origin of the view
+        if (!parent)
+        {
+            x = 0.f;
+            y = 0.f;
+            
+            // If main box : no label
+            uiBox* box = dynamic_cast<uiBox*>(widget);
+            if (box && box->fLabel) {
+                [box->fLabel removeFromSuperview];
+                box->fLabel = nil;
+                box->fLastY = box->fLastY - kStdBoxLabelHeight;
+            }
+        }
+        
+        // Otherwise, computing (x, y) of the widget within its parent box
+        else
+        {
+            // If the box is a tab content box : no label
+            if (parent->fBoxType == kTabLayout)
+            {
+                uiBox* box = dynamic_cast<uiBox*>(widget);
+                if (box && box->fLabel) {
+                    [box->fLabel removeFromSuperview];
+                    box->fLabel = nil;
+                    box->fLastY = box->fLastY - kStdBoxLabelHeight;
+                }
+            }
+            
+            // Check the current layout mode (eg : the layout mode of widget's parent)
+            switch (fCurrentLayoutType)
+            {
+                // Tab layout mode : widget is the box containing the content of a tab
+                case kTabLayout:
+                    x = 0.f;
+                    y = kStdTabHeight;
+                    break;
+                    
+                // Vertical layout mode
+                case kVerticalLayout:
+                    x = kSpaceSize;
+                    y = parent->fLastY + kSpaceSize;
+                    break;
+                   
+                // Horizontal layout mode
+                case kHorizontalLayout:
+                    x = parent->fLastX + kSpaceSize;
+                    if (parent->fLabel) y = kSpaceSize + kStdBoxLabelHeight;
+                    else y = kSpaceSize;
+                    break;
+                    
+                // Shouldn't happen, but if there is a bug, behaves like in vertical default mode
+                default:
+                    x = kSpaceSize;
+                    y = parent->fLastY + kSpaceSize;
+                    break;
+            }
+        }
+        
+        // Set minimum size to widget, regarding its type
+        if (dynamic_cast<uiBox*>(widget))
+        {
+            if (dynamic_cast<uiBox*>(widget)->fBoxType == kTabLayout)
+            {
+                w = kMinBoxWidth;
+                h = kMinBoxHeight + kStdTabHeight;
+            }
+            else
+            {
+                w = kMinBoxWidth;
+                if (parent && parent->fLabel)
+                {
+                    h = kMinBoxHeight + kStdBoxLabelHeight;
+                }
+                else h = kMinBoxHeight;
+            }
+        }
+        else if (dynamic_cast<uiButton*>(widget))
+        {
+            w = kStdButtonWidth;
+            h = kStdButtonHeight;
+        }
+        else if (dynamic_cast<uiNumEntry*>(widget))
+        {
+            w = max(kStdNumEntryWidth, kStdNumEntryLabelWidth);
+            h = kStdNumEntryHeight + kSpaceSize + kStdNumEntryLabelHeight;
+        }
+        else if (dynamic_cast<uiKnob*>(widget))
+        {
+            w = max(kStdKnobWidth, kStdKnobLabelWidth);
+            h = kStdKnobHeight + kSpaceSize + kStdKnobLabelHeight;
+        }
+        else if (dynamic_cast<uiSlider*>(widget))
+        {
+            if (dynamic_cast<uiSlider*>(widget)->fHorizontal)
+            {
+                w = kMinHorizontalSliderWidth + kSpaceSize + kStdSliderLabelWidth;
+                h = max(kStdHorizontalSliderHeight, kStdSliderLabelHeight);
+            }
+            else
+            {
+                w = max(kStdVerticalSliderWidth, kStdSliderLabelWidth);
+                h = kMinVerticalSliderHeight + kSpaceSize + kStdSliderLabelHeight;
+            }
+        }
+        else if (dynamic_cast<uiBargraph*>(widget))
+        {
+            if (dynamic_cast<uiBargraph*>(widget)->fLed)
+            {
+                if (dynamic_cast<uiBargraph*>(widget)->fHorizontal)
+                {
+                    //w = max(kStdLedWidth, kStdBargraphLabelWidth);
+                    //h = kStdLedHeight + kSpaceSize + kStdBargraphLabelHeight;
+                    w = kMinHorizontalBargraphWidth + kSpaceSize + kStdBargraphLabelWidth;
+                    h = max(kStdLedHeight, kStdBargraphLabelHeight);
+                }
+                else
+                {
+                    //w = max(kStdLedWidth, kStdBargraphLabelWidth);
+                    //h = kStdLedHeight + kSpaceSize + kStdBargraphLabelHeight;
+                    //w = max(kStdLedWidth, kStdBargraphLabelWidth);
+                    //h = kMinVerticalBargraphHeight + kSpaceSize + kStdBargraphLabelHeight;
+                    w = max(kStdLedWidth, kStdBargraphLabelWidth);
+                    h = kMinVerticalBargraphHeight + kSpaceSize + kStdBargraphLabelHeight;
+                }
+            }
+            else if (dynamic_cast<uiBargraph*>(widget)->fHorizontal)
+            {
+                w = kMinHorizontalBargraphWidth + kSpaceSize + kStdBargraphLabelWidth;
+                h = max(kStdHorizontalBargraphHeight, kStdBargraphLabelHeight);
+            }
+            else
+            {
+                w = max(kStdVerticalBargraphWidth, kStdBargraphLabelWidth);
+                h = kMinVerticalBargraphHeight + kSpaceSize + kStdBargraphLabelHeight;
+            }
+        }
+        
+        if (widget->getHideOnGUI())
+        {
+            w = 0;
+            h = 0;
+        }
+        
+        // Place widget in the box
+        widget->setFrame(x, y, w, h);
+        
+        // Refresh last x and last y of the parent box
+        if (parent)
+        {
+            parent->fLastX = x + w;
+            parent->fLastY = y + h;            
+        }
+    }
+    
+    void refreshLayout(uiCocoaItem* widget)
+    {
+        uiBox*      parent = dynamic_cast<uiBox*>(widget->getParent());
+        CGSize      contentSize;
+
+        if (parent)
+        {
+            contentSize = parent->getContentSize();
+
+            parent->setFrame(parent->getX(),
+                             parent->getY(),
+                             contentSize.width + kSpaceSize,
+                             contentSize.height + kSpaceSize);
+            
+            parent->fLastX = widget->getX() + widget->getW();
+            parent->fLastY = widget->getY() + widget->getH();
+                        
+            refreshLayout(parent);
+        }
+    }
+    
+    void updateBoxChildren(const char* label, uiCocoaItem* widget)
+    {
+        list<uiCocoaItem*>::reverse_iterator i;
+        uiBox* box = NULL;
+        
+        if (fCurrentLayoutType == kTabLayout)
+        {
+            for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++)
+            {
+                if ((box = dynamic_cast<uiBox*>(*i)))
+                {
+                    if (box->fBoxType == kTabLayout
+                        && box != widget
+                        && !box->fClosed)
+                    {   
+                        // Add FIButton in the fTabView
+                        [box->fTabView addButtonWithLabel:[NSString stringWithCString:label encoding:NSASCIIStringEncoding]];
+                        
+                        // Add uiCocoaItem in the uiBox (*i)
+                        box->fWidgetList.push_back(widget);
+                    }
+                }
+            }
+            
+            list<uiCocoaItem*>::iterator i1 = fWidgetList.begin();
+            box = dynamic_cast<uiBox*>(*i1);
+            
+            if (box->fBoxType == kTabLayout
+                && box != widget)
+            {
+                [box->fTabView addButtonWithLabel:[NSString stringWithCString:label encoding:NSASCIIStringEncoding]];
+                box->fWidgetList.push_back(widget);
+            }
+        }
+        else
+        {
+            for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++)
+            {
+                if ((box = dynamic_cast<uiBox*>(*i)))
+                {
+                    if ((box->fBoxType == kHorizontalLayout
+                        || box->fBoxType == kVerticalLayout)
+                        && box != widget)
+                    {   
+                        // Add uiCocoaItem in the uiBox (*i)
+                        box->fWidgetList.push_back(widget);
+                    }
+                }
+            }   
+       
+            list<uiCocoaItem*>::iterator i1 = fWidgetList.begin();
+            box = dynamic_cast<uiBox*>(*i1);
+            
+            if (((box)->fBoxType == kHorizontalLayout
+                || box->fBoxType == kVerticalLayout)
+                && box != widget)
+            {
+                box->fWidgetList.push_back(widget);
+            }
+        }
+    }
+    
+    void insert(const char* label, uiCocoaItem* widget)
+	{
+        // Link widget to its parent
+        widget->setParent(getActiveBox());
+        
+        // Add widget in the widgts list
+        fWidgetList.push_back(widget);
+        
+        // Set position of the widget
+        computeWidgetFrame(widget);
+        
+        // Manage boxes and current layout type
+        updateBoxChildren(label, widget);        
+        
+        // Refresh whole layout
+        refreshLayout(widget);        
+    }
+    
+    
+public:
+    
+    // -- Labels and metadata
+    
+    // virtual void declare (float* zone, const char* key, const char* value);
+    // virtual int checkLabelOptions (GtkWidget* widget, const string& fullLabel, string& simplifiedLabel);
+    // virtual void checkForTooltip (float* zone, GtkWidget* widget);
+    
+    // -- layout groups
+    
+    CocoaUI(UIWindow* window, FIMainViewController* viewController, MY_Meta* metadata)
+    {
+        fCurrentLayoutType = kVerticalLayout;
+        fViewController = viewController;
+        fWindow = window;
+        fMetadata = metadata;
+        fNextBoxIsHideOnGUI = false;
+        
+        fViewController.dspView.backgroundColor = [UIColor blackColor];
+        fViewController.dspScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
+        
+        [window addSubview:viewController.view];
+        [window makeKeyAndVisible];        
+    }
+    
+    ~CocoaUI()
+    {
+        [fViewController release];
+        [fWindow release];
+    }
+    
+    // Abstract layout : layout computed regardless screen dimensions
+    void saveAbstractLayout()
+    {
+        list<uiCocoaItem*>::iterator    i = fWidgetList.begin();
+        
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            (*i)->setAbstractFrame((*i)->getX(), (*i)->getY(), (*i)->getW(), (*i)->getH());
+        }
+    }
+    
+    void loadAbstractLayout()
+    {
+        list<uiCocoaItem*>::iterator    i = fWidgetList.begin();
+        
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            (*i)->setFrame((*i)->getAbstractX(), (*i)->getAbstractY(), (*i)->getAbstractW(), (*i)->getAbstractH());
+        }
+    }
+    
+    void setHideOnGUI(BOOL state)
+    {
+        list<uiCocoaItem*>::iterator    i = fWidgetList.begin();
+        
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            (*i)->setHideOnGUI(state);
+        }
+    }
+    
+    // Function used to place widgets within a box when the horizontal box is too large or vertical box is too high
+    void expandBoxesContent()
+    {
+        list<uiCocoaItem*>::iterator    i = fWidgetList.begin();
+        list<uiCocoaItem*>::iterator    j = fWidgetList.begin();
+        uiBox*                          box = NULL;
+        CGSize                          contentSize;
+        float                           labelHeight = 0.f;
+        float                           extensibleElementsTotalSize = 0.f;
+        float                           fixedElementsTotalSize = 0.f;
+        float                           rx = 1.f;
+        float                           cpt = 0.f;
+        float                           newVal = 0.f;
+        
+        // Loop on every boxes of the layout
+        for (i = fWidgetList.begin(); i != fWidgetList.end(); i++)
+        {
+            if ((box = dynamic_cast<uiBox*>(*i)))
+            {
+                // Compute content size, ie minimum size used by widgets within the box
+                contentSize = box->getContentSize();
+                
+                // Expand objects if content height is < than box height (vertical box)
+                if (box->fBoxType == kVerticalLayout
+                    && contentSize.height + kSpaceSize < box->getH())
+                {
+                    // Init values
+                    extensibleElementsTotalSize = 0.f;
+                    fixedElementsTotalSize = 0.f;
+                    rx = 1.f;
+                    cpt = 0.f;
+                    newVal = 0.f;
+                    
+                    // Compute extensible and fixed heights
+                    for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+                    {
+                        if ((*j)->getParent() == box)
+                        {
+                            if ((*j)->isVExpandable())
+                            {
+                                extensibleElementsTotalSize += (*j)->getH();
+                            }
+                            else
+                            {
+                                fixedElementsTotalSize += (*j)->getH();
+                            }
+                        }
+                    }
+                    
+                    // If there is at least 1 extensible element, elements will take the whole box height
+                    if (extensibleElementsTotalSize > 0.)
+                    {
+                        // Compute extension ratio
+                        rx = (box->getH() - fixedElementsTotalSize - (box->getNumberOfDirectChildren() + 1) * kSpaceSize - labelHeight) / extensibleElementsTotalSize;
+                        
+                        // Replace elements
+                        for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+                        {
+                            if ((*j)->getParent() == box)
+                            {                                
+                                if ((*j)->isVExpandable())
+                                {
+                                    newVal = (*j)->getH() * rx;
+                                }
+                                else
+                                {
+                                    newVal = (*j)->getH();
+                                }
+                                
+                                (*j)->setFrame((*j)->getX(),
+                                               cpt + kSpaceSize + labelHeight,
+                                               (*j)->getW(),
+                                               newVal);
+                                
+                                cpt += newVal + kSpaceSize + labelHeight;
+                            }
+                        }
+                    }
+                    
+                    // There is no extensible element
+                    else
+                    {
+                        for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+                        {
+                            if ((*j)->getParent() == box)
+                            {
+                                if (box->fLabel) labelHeight = kStdBoxLabelHeight;
+                                else labelHeight = 0.f;
+                                
+                                // Place objects on all the height of the box
+                                float y;
+                                float h;
+                                
+                                if (contentSize.height == kSpaceSize)
+                                {
+                                    y = 0.f;
+                                    h = 0.f;
+                                }
+                                else
+                                {
+                                    float divider = (contentSize.height - kSpaceSize - labelHeight);
+                                    
+                                    if(divider != 0.0)
+                                    {
+                                        y = ((*j)->getY() - kSpaceSize - labelHeight) * ((box->getH() - 2.f * kSpaceSize - labelHeight) / divider) + kSpaceSize + labelHeight;
+                                        h = (*j)->getH() * ((box->getH() - 2.f * kSpaceSize - labelHeight) / divider);
+                                    }
+                                    else
+                                    {
+                                        y = 0.f;
+                                        h = 0.f;
+                                    }
+                                        
+                                }
+                                
+                                (*j)->setFrame((*j)->getX(),
+                                               y,
+                                               (*j)->getW(),
+                                               h);
+                            }
+                        }
+                    }
+                }
+                
+                // Expand objects if content width is < than box width (horizontal box)
+                else if (box->fBoxType == kHorizontalLayout
+                         && contentSize.width + kSpaceSize < box->getW())
+                {
+                    // Init values
+                    extensibleElementsTotalSize = 0.f;
+                    fixedElementsTotalSize = 0.f;
+                    rx = 1.f;
+                    cpt = 0.f;
+                    newVal = 0.f;
+                    
+                    // Compute extensible and fixed widths
+                    for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+                    {
+                        if ((*j)->getParent() == box)
+                        {
+                            if ((*j)->isHExpandable())
+                            {
+                                extensibleElementsTotalSize += (*j)->getW();
+                            }
+                            else
+                            {
+                                fixedElementsTotalSize += (*j)->getW();
+                            }
+                        }
+                    }
+                    
+                    // There is at least 1 extensible element, elements will take the whole box width
+                    if (extensibleElementsTotalSize > 0.)
+                    {
+                        // Compute extension ratio
+                        rx = (box->getW() - fixedElementsTotalSize - (box->getNumberOfDirectChildren() + 1) * kSpaceSize) / extensibleElementsTotalSize;
+                        
+                        // Replace elements
+                        for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+                        {
+                            if ((*j)->getParent() == box)
+                            {                                
+                                if ((*j)->isHExpandable())
+                                {
+                                    newVal = (*j)->getW() * rx;
+                                }
+                                else
+                                {
+                                    newVal = (*j)->getW();
+                                }
+                                
+                                (*j)->setFrame(cpt + kSpaceSize,
+                                               (*j)->getY(),
+                                               newVal,
+                                               (*j)->getH());
+                                
+                                cpt += newVal + kSpaceSize;
+                            }
+                        }
+                    }
+                    
+                    // There is no extensible element
+                    else
+                    {
+                        for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+                        {
+                            if ((*j)->getParent() == box)
+                            {
+                                // Place objects on all the width of the box
+                                float x;
+                                float w;
+                                
+                                if (contentSize.width == kSpaceSize)
+                                {
+                                    x = 0.f;
+                                    w = 0.f;
+                                }
+                                else
+                                {
+                                    x = ((*j)->getX() - kSpaceSize) * ((box->getW() - 2.f * kSpaceSize) / (contentSize.width - kSpaceSize)) + kSpaceSize;
+                                    w = (*j)->getW() * ((box->getW() - 2.f * kSpaceSize) / (contentSize.width - kSpaceSize));
+                                }
+                                
+                                (*j)->setFrame(x,
+                                               (*j)->getY(),
+                                               w,
+                                               (*j)->getH());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    // This function takes abstract layout and adapt it to current screen dimensions
+    void adaptLayoutToWindow(float width, float height)
+    {
+        list<uiCocoaItem*>::iterator    i = fWidgetList.begin();
+        list<uiCocoaItem*>::iterator    j = fWidgetList.begin();
+        BOOL                            hExpandable = NO;
+        BOOL                            vExpandable = NO;
+        float                           newWidth = 0.f;
+        float                           newHeight = 0.f;
+        int                             cpt = 0;
+        uiBox*                          box = NULL;
+        
+        if ((box = dynamic_cast<uiBox*>(*i)))
+        {
+            // Make main box transparent if it is not a tab box
+            if (box->fBoxType != kTabLayout)
+            {
+                box->fBox.color = [UIColor clearColor];
+            }
+            
+            // Load abstract layout
+            loadAbstractLayout();
+            
+            // Algo : window is h exp if (a) there is at least 1 h exp element in the patch
+            // or (b) there is more than 1 column
+            // AND window is v exp if (a) there is at least 1 v exp element in the patch
+            // or (b) there is more than 1 line
+            for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+            {
+                if (!dynamic_cast<uiBox*>(*j))
+                {
+                    if ((*j)->isHExpandable()) hExpandable = TRUE;
+                    if ((*j)->isVExpandable()) vExpandable = TRUE;
+                }
+            }
+            
+            for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+            {
+                if ((box = dynamic_cast<uiBox*>(*j)))
+                {
+                    if (!hExpandable
+                        && box->fBoxType == kHorizontalLayout
+                        && box->getNumberOfDirectChildren() > 1)
+                    {
+                        hExpandable = TRUE;
+                    }
+                    
+                    if (!vExpandable
+                        && box->fBoxType == kVerticalLayout
+                        && box->getNumberOfDirectChildren() > 1)
+                    {
+                        vExpandable = TRUE;
+                    }
+                }
+            }
+            
+            if (hExpandable) newWidth = max((*i)->getAbstractW(), width);
+            else newWidth = (*i)->getAbstractW();
+            
+            if (vExpandable) newHeight = max((*i)->getAbstractH(), height);
+            else newHeight = (*i)->getAbstractH();
+            
+            // Adapt abstract layout to device and orientation
+            (*i)->setFrame((*i)->getX(),
+                           (*i)->getY(),
+                           newWidth,
+                           newHeight);
+            
+            // Finally, if there's only 1 widget in the whole patch, center it
+            for (j = fWidgetList.begin(); j != fWidgetList.end(); j++)
+            {
+                if (!dynamic_cast<uiBox*>(*j))
+                {
+                    cpt++;
+                }
+            }
+            
+            if (cpt == 1)
+            {
+                (*i)->setFrame((*i)->getX(),
+                               (*i)->getY(),
+                               width,
+                               height);
+            }
+        }
+        
+        expandBoxesContent();
+    }
+    
+    CGRect getBoxAbsoluteFrameForWidget(uiCocoaItem* widget)
+    {
+        CGPoint pt = absolutePosition(widget);
+        return CGRectMake(pt.x, pt.y, widget->getW(), widget->getH());
+    }
+    
+    // Returns the box containing the point
+    uiBox* getBoxForPoint(CGPoint pt)
+    {
+        list<uiCocoaItem*>::reverse_iterator i;
+        uiBox* box = NULL;
+        
+        // Loop on each widgets, from the last
+        for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++)
+        {
+            if ((box = dynamic_cast<uiBox*>(*i)))
+            {
+                if (!(*i)->isHidden()
+                    && pt.x >= absolutePosition(*i).x
+                    && pt.x <= absolutePosition(*i).x + (*i)->getW()
+                    && pt.y >= absolutePosition(*i).y
+                    && pt.y <= absolutePosition(*i).y + (*i)->getH())
+                {
+                    if (box->getParent())
+                    {
+                        if (dynamic_cast<uiBox*>(box->getParent())->fBoxType == kTabLayout)
+                        {
+                            return dynamic_cast<uiBox*>(box->getParent());
+                        }
+                    }
+                    
+                    return box;
+                }
+            }
+        }
+        
+        return NULL;
+    }
+    
+    uiBox* getMainBox()
+    {
+         return (fWidgetList.size() > 0) ? dynamic_cast<uiBox*>(*fWidgetList.begin()): NULL;
+    }
+    
+    bool isKnob(float* zone)
+    {
+        return fKnobSet.count(zone) > 0;
+    }
+    
+    virtual void openFrameBox(const char* label)
+    {}
+    virtual void openTabBox(const char* label = "")
+    {
+        uiCocoaItem* item = new uiBox(this, fViewController, label, kTabLayout);
+        insert(label, item);
+        fCurrentLayoutType = kTabLayout;
+    }
+    virtual void openHorizontalBox(const char* label = "")
+    {
+        uiCocoaItem* item = new uiBox(this, fViewController, label, kHorizontalLayout);
+        
+        if (getCurrentOpenedBox()) item->setHideOnGUI(fNextBoxIsHideOnGUI || getCurrentOpenedBox()->getHideOnGUI());
+        else item->setHideOnGUI(fNextBoxIsHideOnGUI);
+        if (fNextBoxIsHideOnGUI) fNextBoxIsHideOnGUI = false;
+
+        insert(label, item);
+        fCurrentLayoutType = kHorizontalLayout;
+    }
+    virtual void openVerticalBox(const char* label = "")
+    {
+        uiCocoaItem* item = new uiBox(this, fViewController, label, kVerticalLayout);
+        
+        if (getCurrentOpenedBox()) item->setHideOnGUI(fNextBoxIsHideOnGUI || getCurrentOpenedBox()->getHideOnGUI());
+        else item->setHideOnGUI(fNextBoxIsHideOnGUI);
+        if (fNextBoxIsHideOnGUI) fNextBoxIsHideOnGUI = false;
+        
+        insert(label, item);
+        fCurrentLayoutType = kVerticalLayout;
+    }
+    
+    // -- extra widget's layouts
+    
+    virtual void openDialogBox(const char* label, float* zone)
+    {}
+    virtual void openEventBox(const char* label = "")
+    {}
+    virtual void openHandleBox(const char* label = "")
+    {}
+    virtual void openExpanderBox(const char* label, float* zone)
+    {}
+    
+    virtual uiBox* getCurrentOpenedBox()
+    {
+        list<uiCocoaItem*>::reverse_iterator i;
+       
+        // Find the last box to close
+        for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++)
+        {
+            uiBox* box = dynamic_cast<uiBox*>(*i);
+            if (box && !box->fClosed) {
+                return box;
+            }
+        }
+        
+        return NULL;
+    }
+    
+    virtual void closeBox()
+    {
+        list<uiCocoaItem*>::reverse_iterator i;
+        
+        for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++) {
+            uiBox* box = dynamic_cast<uiBox*>(*i);
+            if (box && !box->fClosed) {
+                box->close(fWidgetList.size());
+                break;
+            }
+        }
+     
+        for (i = fWidgetList.rbegin(); i != fWidgetList.rend(); i++) {
+            uiBox* box = dynamic_cast<uiBox*>(*i);
+            if (box && !box->fClosed) {
+                fCurrentLayoutType = box->fBoxType;
+                break;
+            }
+        }
+    }
+    
+    //virtual void adjustStack(int n);
+    
+    // -- active widgets
+    
+    virtual void addButton(const char* label, float* zone)
+    {
+        uiCocoaItem* item = new uiButton(this, fViewController, label, zone, kPushButtonType);
+        
+        // Default parameters
+        if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiButton*>(item)->fButton.hideOnGUI = item->getHideOnGUI();
+        
+        insert(label, item);
+    }
+    virtual void addToggleButton(const char* label, float* zone)
+    {
+        uiCocoaItem* item = new uiButton(this, fViewController, label, zone, kToggleButtonType);
+        
+        // Default parameters
+        if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiButton*>(item)->fButton.hideOnGUI = item->getHideOnGUI();
+        
+        insert(label, item);
+    }
+    virtual void addCheckButton(const char* label, float* zone)
+    {
+        uiCocoaItem* item = new uiButton(this, fViewController, label, zone, kToggleButtonType);
+        
+        // Default parameters
+        if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiButton*>(item)->fButton.hideOnGUI = item->getHideOnGUI();
+        
+        insert(label, item);
+    }
+    virtual void addVerticalKnob(const char* label , float* zone, float init, float min, float max, float step)
+	{
+        uiCocoaItem* item = new uiKnob(this, fViewController, label, zone, init, min, max, step, false);
+        if (dynamic_cast<uiKnob*>(item)->fKnob.suffixe) [dynamic_cast<uiKnob*>(item)->fKnob.suffixe release];
+        dynamic_cast<uiKnob*>(item)->fKnob.suffixe = [[NSString alloc] initWithCString:fUnit[zone].c_str() encoding:NSUTF8StringEncoding];
+        
+        // Default parameters
+        if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+        if (fAssignationType[zone]) item->setInitAssignationType(fAssignationType[zone]);
+        if (fAssignationSensibility[zone]) item->setInitAssignationSensibility(fAssignationSensibility[zone]);
+        if (fAssignationInverse[zone]) item->setInitAssignationInverse(fAssignationInverse[zone]);
+        if (fAssignationFiltered[zone]) item->setInitAssignationFiltered(fAssignationFiltered[zone]);
+        if (fAssignationRefPointX[zone]) item->setInitAssignationRefPointX(fAssignationRefPointX[zone]);
+        if (fAssignationRefPointY[zone]) item->setInitAssignationRefPointY(fAssignationRefPointY[zone]);
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiKnob*>(item)->fKnob.hideOnGUI = item->getHideOnGUI();
+        
+        insert(label, item);
+    }
+    virtual void addHorizontalKnob(const char* label , float* zone, float init, float min, float max, float step)
+	{
+        uiCocoaItem* item = new uiKnob(this, fViewController, label, zone, init, min, max, step, true);
+        if (dynamic_cast<uiKnob*>(item)->fKnob.suffixe) [dynamic_cast<uiKnob*>(item)->fKnob.suffixe release];
+        dynamic_cast<uiKnob*>(item)->fKnob.suffixe = [[NSString alloc] initWithCString:fUnit[zone].c_str() encoding:NSUTF8StringEncoding];
+        
+        // Default parameters
+        if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+        if (fAssignationType[zone]) item->setInitAssignationType(fAssignationType[zone]);
+        if (fAssignationSensibility[zone]) item->setInitAssignationSensibility(fAssignationSensibility[zone]);
+        if (fAssignationInverse[zone]) item->setInitAssignationInverse(fAssignationInverse[zone]);
+        if (fAssignationFiltered[zone]) item->setInitAssignationFiltered(fAssignationFiltered[zone]);
+        if (fAssignationRefPointX[zone]) item->setInitAssignationRefPointX(fAssignationRefPointX[zone]);
+        if (fAssignationRefPointY[zone]) item->setInitAssignationRefPointY(fAssignationRefPointY[zone]);
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiKnob*>(item)->fKnob.hideOnGUI = item->getHideOnGUI();
+        
+        insert(label, item);
+    }
+    virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+    {
+        if (isKnob(zone))
+        {
+            addVerticalKnob(label, zone, init, min, max, step);
+        }
+        else
+        {
+            uiCocoaItem* item = new uiSlider(this, fViewController, label, zone, init, min, max, step, false);
+            if (dynamic_cast<uiSlider*>(item)->fSlider.suffixe) [dynamic_cast<uiSlider*>(item)->fSlider.suffixe release];
+            dynamic_cast<uiSlider*>(item)->fSlider.suffixe = [[NSString alloc] initWithCString:fUnit[zone].c_str() encoding:NSUTF8StringEncoding];
+            
+            // Default parameters
+            if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+            if (fAssignationType[zone]) item->setInitAssignationType(fAssignationType[zone]);
+            if (fAssignationSensibility[zone]) item->setInitAssignationSensibility(fAssignationSensibility[zone]);
+            if (fAssignationInverse[zone]) item->setInitAssignationInverse(fAssignationInverse[zone]);
+            if (fAssignationFiltered[zone]) item->setInitAssignationFiltered(fAssignationFiltered[zone]);
+            if (fAssignationRefPointX[zone]) item->setInitAssignationRefPointX(fAssignationRefPointX[zone]);
+            if (fAssignationRefPointY[zone]) item->setInitAssignationRefPointY(fAssignationRefPointY[zone]);
+            if (getCurrentOpenedBox())
+            {
+                if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+            }
+            else
+            {
+                if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+            }
+            dynamic_cast<uiSlider*>(item)->fSlider.hideOnGUI = item->getHideOnGUI();
+            
+            insert(label, item);
+        }
+    }
+    virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+    {
+        if (isKnob(zone))
+        {
+            addHorizontalKnob(label, zone, init, min, max, step);
+        }
+        else
+        {
+            uiCocoaItem* item = new uiSlider(this, fViewController, label, zone, init, min, max, step, true);
+            if (dynamic_cast<uiSlider*>(item)->fSlider.suffixe) [dynamic_cast<uiSlider*>(item)->fSlider.suffixe release];
+            dynamic_cast<uiSlider*>(item)->fSlider.suffixe = [[NSString alloc] initWithCString:fUnit[zone].c_str() encoding:NSUTF8StringEncoding];
+                        
+            // Default parameters
+            if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+            if (fAssignationType[zone]) item->setInitAssignationType(fAssignationType[zone]);
+            if (fAssignationSensibility[zone]) item->setInitAssignationSensibility(fAssignationSensibility[zone]);
+            if (fAssignationInverse[zone]) item->setInitAssignationInverse(fAssignationInverse[zone]);
+            if (fAssignationFiltered[zone]) item->setInitAssignationFiltered(fAssignationFiltered[zone]);
+            if (fAssignationRefPointX[zone]) item->setInitAssignationRefPointX(fAssignationRefPointX[zone]);
+            if (fAssignationRefPointY[zone]) item->setInitAssignationRefPointY(fAssignationRefPointY[zone]);
+            if (getCurrentOpenedBox())
+            {
+                if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+            }
+            else
+            {
+                if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+            }
+            dynamic_cast<uiSlider*>(item)->fSlider.hideOnGUI = item->getHideOnGUI();
+            
+            insert(label, item);
+        }
+    }
+    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+    {
+        if (isKnob(zone))
+        {
+            addVerticalKnob(label, zone, init, min, max, step);
+        }
+        else
+        {
+            uiCocoaItem* item = new uiNumEntry(this, fViewController, label, zone, init, min, max, step);
+            if (dynamic_cast<uiNumEntry*>(item)->fTextField.suffixe) [dynamic_cast<uiNumEntry*>(item)->fTextField.suffixe release];
+            dynamic_cast<uiNumEntry*>(item)->fTextField.suffixe = [[NSString alloc] initWithCString:fUnit[zone].c_str() encoding:NSUTF8StringEncoding];
+            
+            // Default parameters
+            if (fR[zone] && fG[zone] && fB[zone]) item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+            if (getCurrentOpenedBox())
+            {
+                if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+            }
+            else
+            {
+                if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+            }
+            dynamic_cast<uiNumEntry*>(item)->fTextField.hideOnGUI = item->getHideOnGUI();
+            
+            insert(label, item);
+        }
+    }
+    
+    // -- passive display widgets
+    
+    virtual void addNumDisplay(const char* label, float* zone, int precision)
+    {}
+    virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max)
+    {}
+    virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max)
+    {
+        uiCocoaItem* item = new uiBargraph(this, fViewController, label, zone, min, max, true);
+        
+        if (fR[zone] && fG[zone] && fB[zone])
+        {
+            item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+            dynamic_cast<uiBargraph*>(item)->fBargraph.ledMaxColor = [[UIColor colorWithRed:fR[zone] - 1000.
+                                                                                      green:fG[zone] - 1000.
+                                                                                       blue:fB[zone] - 1000.
+                                                                                      alpha:1.] retain];
+        }
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiBargraph*>(item)->setLed(fLed[zone]);
+        
+        if (fLedR[zone] || fLedG[zone] || fLedB[zone])
+        {
+            dynamic_cast<uiBargraph*>(item)->fBargraph.ledMinColor = [[UIColor colorWithRed:fLedR[zone]
+                                                                                      green:fLedG[zone]
+                                                                                       blue:fLedB[zone]
+                                                                                      alpha:1.] retain];
+        }
+        
+        insert(label, item);
+    }
+    virtual void addVerticalBargraph(const char* label, float* zone, float min, float max)
+    {
+        uiCocoaItem* item = new uiBargraph(this, fViewController, label, zone, min, max, false);
+        
+        if (fR[zone] && fG[zone] && fB[zone])
+        {
+            item->setInitColor(fR[zone] - 1000., fG[zone] - 1000., fB[zone] - 1000.);
+            dynamic_cast<uiBargraph*>(item)->fBargraph.ledMaxColor = [[UIColor colorWithRed:fR[zone] - 1000.
+                                                                                      green:fG[zone] - 1000.
+                                                                                       blue:fB[zone] - 1000.
+                                                                                      alpha:1.] retain];
+        }
+        if (getCurrentOpenedBox())
+        {
+            if (fHideOnGUI[zone] || getCurrentOpenedBox()->getHideOnGUI()) item->setHideOnGUI(TRUE);
+        }
+        else
+        {
+            if (fHideOnGUI[zone]) item->setHideOnGUI(TRUE);
+        }
+        dynamic_cast<uiBargraph*>(item)->setLed(fLed[zone]);
+        
+        if (fLedR[zone] || fLedG[zone] || fLedB[zone])
+        {
+            dynamic_cast<uiBargraph*>(item)->fBargraph.ledMinColor = [[UIColor colorWithRed:fLedR[zone]
+                                                                                      green:fLedG[zone]
+                                                                                       blue:fLedB[zone]
+                                                                                      alpha:1.] retain];
+        }
+        
+        insert(label, item);
+    }
+    
+    virtual void show()
+    {}
+    virtual void run()
+    {}
+    
+    virtual void declare(float* zone, const char* key, const char* value)
+    {
+		if (zone == 0)
+        {
+			// special zone 0 means group metadata
+			/*if (strcmp(key,"tooltip")==0)
+            {
+				// only group tooltip are currently implemented
+				gGroupTooltip = formatTooltip(30, value);
+			}*/
+            
+            if (strcmp(key, "hidden") == 0)
+            {
+				NSString* str = [NSString stringWithCString:value encoding:NSUTF8StringEncoding];
+                NSArray* arr = [str componentsSeparatedByString:@" "];
+                
+                if ([((NSString*)[arr objectAtIndex:0]) integerValue] == 1)
+                {
+                    fNextBoxIsHideOnGUI = true;
+                }
+            }
+		}
+        else
+        {
+			if (strcmp(key,"size") == 0)
+            {
+				//fGuiSize[zone]=atof(value);
+			}
+			else if (strcmp(key,"tooltip") == 0)
+            {
+				//fTooltip[zone] = formatTooltip(30, value) ;
+			}
+			else if (strcmp(key,"unit") == 0)
+            {
+				fUnit[zone] = value;
+			}
+            else if (strcmp(key,"hidden") == 0)
+            {
+				NSString* str = [NSString stringWithCString:value encoding:NSUTF8StringEncoding];
+                NSArray* arr = [str componentsSeparatedByString:@" "];
+            
+                if ([((NSString*)[arr objectAtIndex:0]) integerValue] == 1)
+                {
+                    fHideOnGUI[zone] = true;
+                }
+            }
+			else if (strcmp(key,"style") == 0)
+            {
+                NSString* str = [NSString stringWithCString:value encoding:NSUTF8StringEncoding];
+                NSArray* arr = [str componentsSeparatedByString:@" "];
+                
+                if ([arr count] == 0) return;
+                
+				if ([((NSString*)[arr objectAtIndex:0]) compare:@"knob"] == NSOrderedSame)
+                {
+					fKnobSet.insert(zone);
+				}
+                else if ([((NSString*)[arr objectAtIndex:0]) compare:@"led"] == NSOrderedSame)
+                {
+                    fLed[zone] = true;
+                    
+                    fLedR[zone] = 0.f;
+                    fLedG[zone] = 0.f;
+                    fLedB[zone] = 0.f;
+                    
+                    if ([arr count] == 2)
+                    {
+                        fLedR[zone] = (float)[((NSString*)[arr objectAtIndex:1]) integerValue] / 255.f;
+                    }
+                    else if ([arr count] == 3)
+                    {
+                        fLedR[zone] = (float)[((NSString*)[arr objectAtIndex:1]) integerValue] / 255.f;
+                        fLedG[zone] = (float)[((NSString*)[arr objectAtIndex:2]) integerValue] / 255.f;
+                    }
+                    else if ([arr count] == 4)
+                    {
+                        fLedR[zone] = (float)[((NSString*)[arr objectAtIndex:1]) integerValue] / 255.f;
+                        fLedG[zone] = (float)[((NSString*)[arr objectAtIndex:2]) integerValue] / 255.f;
+                        fLedB[zone] = (float)[((NSString*)[arr objectAtIndex:3]) integerValue] / 255.f;
+                    }
+                }
+			}
+            else if (strcmp(key,"color") == 0)
+            {
+                NSString* str = [NSString stringWithCString:value encoding:NSUTF8StringEncoding];
+                NSArray* arr = [str componentsSeparatedByString:@" "];
+                
+                fR[zone] = (float)[((NSString*)[arr objectAtIndex:0]) integerValue] / 255.f + 1000.;
+                fG[zone] = (float)[((NSString*)[arr objectAtIndex:1]) integerValue] / 255.f + 1000.;
+                fB[zone] = (float)[((NSString*)[arr objectAtIndex:2]) integerValue] / 255.f + 1000.;
+            }
+            else if (strcmp(key,"accx") == 0
+                     || strcmp(key,"accy") == 0
+                     || strcmp(key,"accz") == 0
+                     || strcmp(key,"gyrox") == 0
+                     || strcmp(key,"gyroy") == 0
+                     || strcmp(key,"gyroz") == 0
+                     || strcmp(key,"compass") == 0)
+            {
+                float sensibility = 1.f;
+                bool filtered = true;
+                float refPointX = 0.f;
+                float refPointY = 0.f;
+                                   
+                if (strcmp(key,"accx") == 0) fAssignationType[zone] = kAssignationAccelX;
+                else if (strcmp(key,"accy") == 0) fAssignationType[zone] = kAssignationAccelY;
+                else if (strcmp(key,"accz") == 0) fAssignationType[zone] = kAssignationAccelZ;
+                else if (strcmp(key,"gyrox") == 0) fAssignationType[zone] = kAssignationGyroX;
+                else if (strcmp(key,"gyroy") == 0) fAssignationType[zone] = kAssignationGyroY;
+                else if (strcmp(key,"gyroz") == 0) fAssignationType[zone] = kAssignationGyroZ;
+                else if (strcmp(key,"compass") == 0) fAssignationType[zone] = kAssignationCompass;
+
+                NSString* str = [NSString stringWithCString:value encoding:NSUTF8StringEncoding];
+                NSArray* arr = [str componentsSeparatedByString:@" "];
+                
+                if ([arr count] == 0)
+                {
+                    sensibility = 1.f;
+                    refPointX = 0.f;
+                    refPointY = 0.f;
+                    filtered = true;
+                }
+                else if ([arr count] == 1)
+                {
+                    sensibility = [((NSString*)[arr objectAtIndex:0]) floatValue];
+                    refPointX = 0.f;
+                    refPointY = 0.f;
+                    filtered = true;
+                }
+                else if ([arr count] == 2)
+                {
+                    sensibility = [((NSString*)[arr objectAtIndex:0]) floatValue];
+                    refPointX = [((NSString*)[arr objectAtIndex:1]) floatValue];
+                    refPointY = 0.f;
+                    filtered = true;
+                }
+                else if ([arr count] == 3)
+                {
+                    sensibility = [((NSString*)[arr objectAtIndex:0]) floatValue];
+                    refPointX = [((NSString*)[arr objectAtIndex:1]) floatValue];
+                    refPointY = [((NSString*)[arr objectAtIndex:2]) floatValue];
+                    filtered = true;
+                }
+                else
+                {
+                    sensibility = [((NSString*)[arr objectAtIndex:0]) floatValue];
+                    refPointX = [((NSString*)[arr objectAtIndex:1]) floatValue];
+                    refPointY = [((NSString*)[arr objectAtIndex:2]) floatValue];
+                    filtered = [((NSString*)[arr objectAtIndex:3]) boolValue];
+                }
+                
+                if (sensibility < 0.)
+                {
+                    fAssignationSensibility[zone] = -sensibility;
+                    fAssignationInverse[zone] = true;
+                }
+                else
+                {
+                    fAssignationSensibility[zone] = sensibility;
+                    fAssignationInverse[zone] = false;
+                }
+                                
+                fAssignationRefPointX[zone] = refPointX;
+                fAssignationRefPointY[zone] = refPointY;
+                fAssignationFiltered[zone] = filtered;
+            }
+		}
+	}
+};
+
+
+// global static fields
+
+list<GUI*>                   GUI::fGuiList;
+
+CGPoint inBoxPosition2absolutePosition(float x, float y, uiCocoaItem* box)
+{
+    CGPoint     parentBoxOrigin = CGPointMake(0.f, 0.f);
+    CGPoint     absolutePosition = CGPointMake(0.f, 0.f);
+    uiBox*      parent = NULL;
+        
+    if (box)
+    {
+        parent = dynamic_cast<uiBox*>(box->getParent());
+        
+        if (parent)
+        {
+            parentBoxOrigin = inBoxPosition2absolutePosition(box->getX(), box->getY(), parent);
+        }
+    }
+    
+    absolutePosition = CGPointMake(x + parentBoxOrigin.x, y + parentBoxOrigin.y);
+    
+    return absolutePosition;
+}
+                      
+CGPoint absolutePosition(uiCocoaItem* widget)
+{
+    return inBoxPosition2absolutePosition(widget->getX(), widget->getY(), widget->getParent());
+}
\ No newline at end of file
diff --git a/architecture/iOS/iOS/FIFlipsideViewController.h b/architecture/iOS/iOS/FIFlipsideViewController.h
new file mode 100644
index 0000000..1372ca3
--- /dev/null
+++ b/architecture/iOS/iOS/FIFlipsideViewController.h
@@ -0,0 +1,65 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+
+ at class FIFlipsideViewController;
+
+
+ at protocol FIFlipsideViewControllerDelegate
+
+- (void)flipsideViewControllerDidFinish:(FIFlipsideViewController *)controller;
+
+ at end
+
+
+ at interface FIFlipsideViewController : UIViewController <UIAlertViewDelegate>
+{
+    IBOutlet UISlider*              _sampleRateSlider;
+    IBOutlet UILabel*               _sampleRateLabel;
+    IBOutlet UISlider*              _bufferSizeSlider;
+    IBOutlet UILabel*               _bufferSizeLabel;
+    IBOutlet UISwitch*              _openWidgetPanelSwitch;
+    
+    int                             _sampleRate;
+    int                             _bufferSize;
+    BOOL                            _openWidgetPanel;
+}
+
+ at property (assign, nonatomic) IBOutlet id <FIFlipsideViewControllerDelegate> delegate;
+ at property (nonatomic, nonatomic) int sampleRate;
+ at property (nonatomic, nonatomic) int bufferSize;
+ at property (nonatomic, nonatomic) BOOL openWidgetPanel;
+
+
+- (IBAction)done:(id)sender;
+- (IBAction)sampleRateSliderMoved:(id)sender;
+- (IBAction)bufferSizeSliderMoved:(id)sender;
+- (IBAction)openWidgetPanelSwitchMoved:(id)sender;
+- (IBAction)deleteAssignationsButtonClicked:(id)sender;
+
+- (int)sampleRateToSliderValue:(int)sampleRate;
+- (int)sliderValueToSampleRate:(int)sliderValue;
+- (int)bufferSizeToSliderValue:(int)bufferSize;
+- (int)sliderValueToBufferSize:(int)sliderValue;
+
+- (void)disableAudioWidgets;
+- (void)enableAudioWidgets;
+
+ at end
diff --git a/architecture/iOS/iOS/FIFlipsideViewController.mm b/architecture/iOS/iOS/FIFlipsideViewController.mm
new file mode 100644
index 0000000..2f87e42
--- /dev/null
+++ b/architecture/iOS/iOS/FIFlipsideViewController.mm
@@ -0,0 +1,347 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIFlipsideViewController.h"
+#import "FIMainViewController.h"
+
+ at implementation FIFlipsideViewController
+
+ at synthesize delegate = _delegate;
+ at synthesize sampleRate = _sampleRate;
+ at synthesize bufferSize = _bufferSize;
+ at synthesize openWidgetPanel = _openWidgetPanel;
+
+- (void)awakeFromNib
+{
+    self.contentSizeForViewInPopover = CGSizeMake(320.0, 480.0);
+    [super awakeFromNib];
+}
+
+- (void)didReceiveMemoryWarning
+{
+    [super didReceiveMemoryWarning];
+}
+
+
+#pragma mark - View lifecycle
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    
+    // Read user preferences
+    _sampleRate = (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"sampleRate"];
+    _bufferSize = (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"bufferSize"];
+    _openWidgetPanel = [[NSUserDefaults standardUserDefaults] boolForKey:@"openWidgetPanel"];
+    
+    // Update UI
+    _sampleRateSlider.value = [self sampleRateToSliderValue:_sampleRate];
+    _sampleRateLabel.text = [NSString stringWithFormat:@"%i Hz", _sampleRate];
+    
+    _bufferSizeSlider.value = [self bufferSizeToSliderValue:_bufferSize];
+    _bufferSizeLabel.text = [NSString stringWithFormat:@"%i frames", _bufferSize];
+    
+    [_openWidgetPanelSwitch setOn:_openWidgetPanel animated:NO];
+    
+#ifdef JACK_IOS
+    // Test Jack
+    if ([((FIMainViewController*)self.delegate) isJackAudio])
+    {
+        [self disableAudioWidgets];
+    }
+    
+#endif
+}
+
+- (void)viewDidUnload
+{
+    [super viewDidUnload];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+    [super viewWillAppear:animated];
+}
+
+- (void)viewDidAppear:(BOOL)animated
+{
+    [super viewDidAppear:animated];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+	[super viewWillDisappear:animated];
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+	[super viewDidDisappear:animated];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
+    {
+        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+    }
+    else
+    {
+        return YES;
+    }
+}
+
+
+#pragma mark - Actions
+
+- (IBAction)done:(id)sender
+{
+    
+    // Write user preferences
+    [[NSUserDefaults standardUserDefaults] setInteger:_sampleRate forKey:@"sampleRate"];
+    [[NSUserDefaults standardUserDefaults] setInteger:_bufferSize forKey:@"bufferSize"];
+    [[NSUserDefaults standardUserDefaults] setBool:_openWidgetPanel forKey:@"openWidgetPanel"];
+    
+	[[NSUserDefaults standardUserDefaults] synchronize];
+        
+    // Update preferences
+    [((FIMainViewController*)self.delegate) restartAudioWithBufferSize:_bufferSize sampleRate:_sampleRate];
+    [((FIMainViewController*)self.delegate) setOpenWidgetPanel:_openWidgetPanel];
+    
+    // Dismiss view
+    [self.delegate flipsideViewControllerDidFinish:self];
+}
+
+- (IBAction)sampleRateSliderMoved:(id)sender
+{
+    _sampleRate = [self sliderValueToSampleRate:(int)floor(((UISlider*)sender).value)];
+    _sampleRateLabel.text = [NSString stringWithFormat:@"%i Hz", _sampleRate];
+}
+
+- (IBAction)bufferSizeSliderMoved:(id)sender
+{
+    _bufferSize = [self sliderValueToBufferSize:(int)floor(((UISlider*)sender).value)];
+    _bufferSizeLabel.text = [NSString stringWithFormat:@"%i frames", _bufferSize];
+}
+
+- (IBAction)openWidgetPanelSwitchMoved:(id)sender
+{
+    _openWidgetPanel = ((UISwitch*)sender).on;
+}
+
+- (IBAction)deleteAssignationsButtonClicked:(id)sender
+{
+    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Attention"
+                                                        message:@"Are you sure you want to delete all your custom assignations and parameters?"
+                                                       delegate:self
+                                              cancelButtonTitle:@"Cancel"
+                                              otherButtonTitles:@"OK", nil];
+    [alertView show];
+    [alertView release];
+}
+
+#pragma mark - UIAlertView Delegate Methods
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    // Cancel clicked
+	if (buttonIndex == 0)
+    {
+		// Do nothing
+	}
+    
+    // OK clicked
+    else
+    {
+        NSDictionary* dict = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
+        NSArray* keysArray = [dict allKeys];
+        int i = 0;
+        NSString* key = nil;
+        
+        for (i = 0; i < [keysArray count]; ++i)
+        {
+            key = ((NSString*)[keysArray objectAtIndex:i]);
+            if ([key compare:@"sampleRate"] != NSOrderedSame
+                && [key compare:@"bufferSize"] != NSOrderedSame
+                && [key compare:@"openWidgetPanel"] != NSOrderedSame)
+            {
+                [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
+            }
+        }
+        
+        [((FIMainViewController*)self.delegate) resetAllWidgetsPreferences];
+        
+        [[NSUserDefaults standardUserDefaults] synchronize];
+	}
+}
+
+
+- (int)sampleRateToSliderValue:(int)sampleRate
+{
+    switch (sampleRate)
+    {
+        case 8000:
+            return 0;
+            break;
+        case 11025:
+            return 1;
+            break;
+        case 16000:
+            return 2;
+            break;
+        case 22050:
+            return 3;
+            break;
+        case 44100:
+            return 4;
+            break;
+        case 48000:
+            return 5;
+            break;
+        case 96000:
+            return 6;
+            break;
+        default:
+            return 4;
+            break;
+    }
+    
+    return 4;
+}
+
+- (int)sliderValueToSampleRate:(int)sliderValue
+{
+    switch (sliderValue)
+    {
+        case 0:
+            return 8000;
+            break;
+        case 1:
+            return 11025;
+            break;
+        case 2:
+            return 16000;
+            break;
+        case 3:
+            return 22050;
+            break;
+        case 4:
+            return 44100;
+            break;
+        case 5:
+            return 48000;
+            break;
+        case 6:
+            return 96000;
+            break;
+        default:
+            return 44100;
+            break;
+    }
+    
+    return 44100;
+}
+
+- (int)bufferSizeToSliderValue:(int)bufferSize
+{
+    switch (bufferSize)
+    {
+        case 16:
+            return 0;
+            break;
+        case 32:
+            return 1;
+            break;
+        case 64:
+            return 2;
+            break;
+        case 128:
+            return 3;
+            break;
+        case 256:
+            return 4;
+            break;
+        case 512:
+            return 5;
+            break;
+        case 1024:
+            return 6;
+            break;
+        case 2048:
+            return 7;
+            break;
+        default:
+            return 4;
+            break;
+    }
+    
+    return 4;
+}
+
+- (int)sliderValueToBufferSize:(int)sliderValue
+{
+    switch (sliderValue)
+    {
+        case 0:
+            return 16;
+            break;
+        case 1:
+            return 32;
+            break;
+        case 2:
+            return 64;
+            break;
+        case 3:
+            return 128;
+            break;
+        case 4:
+            return 256;
+            break;
+        case 5:
+            return 512;
+            break;
+        case 6:
+            return 1024;
+            break;
+        case 7:
+            return 2048;
+            break;
+        default:
+            return 256;
+            break;
+    }
+    
+    return 256;
+}
+
+- (void)disableAudioWidgets
+{
+    _sampleRateSlider.enabled = NO;
+    _sampleRateLabel.enabled = NO;
+    _bufferSizeSlider.enabled = NO;
+    _bufferSizeLabel.enabled = NO;
+}
+
+- (void)enableAudioWidgets
+{
+    _sampleRateSlider.enabled = YES;
+    _sampleRateLabel.enabled = YES;
+    _bufferSizeSlider.enabled = YES;
+    _bufferSizeLabel.enabled = YES;
+}
+
+ at end
\ No newline at end of file
diff --git a/architecture/iOS/iOS/FIHint.h b/architecture/iOS/iOS/FIHint.h
new file mode 100644
index 0000000..cac9dea
--- /dev/null
+++ b/architecture/iOS/iOS/FIHint.h
@@ -0,0 +1,26 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+ at interface FIHint : UIView
+
+ at property (retain, nonatomic) NSString* title;
+ at property (assign, nonatomic) int position;         // 0: top - 1: bottom, 2: left, 3:right
+
+ at end
diff --git a/architecture/iOS/iOS/FIHint.mm b/architecture/iOS/iOS/FIHint.mm
new file mode 100644
index 0000000..6d5de3a
--- /dev/null
+++ b/architecture/iOS/iOS/FIHint.mm
@@ -0,0 +1,222 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIHint.h"
+
+#define kStdHintWidth           120
+#define kStdHintHeight          50
+
+ at implementation FIHint
+
+ at synthesize title;
+ at synthesize position;
+
+- (id)init
+{
+    self = [super init];
+    if (self)
+    {
+        self.position = 0;
+        self.backgroundColor = [UIColor clearColor];
+        self.title = @"";
+        [self setFrame:CGRectMake(0.f, 0.f, kStdHintWidth, kStdHintHeight)];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect
+{
+	CGContextRef context = UIGraphicsGetCurrentContext();
+    UIFont* labelFont = [UIFont boldSystemFontOfSize:19.0];
+    UIColor* bgColor = [UIColor colorWithWhite:0.1 alpha:0.9];
+    UIColor* textColor = [UIColor whiteColor];
+    
+    self.backgroundColor = [UIColor clearColor];
+    
+    // Top
+    if (self.position == 0)
+    {
+        CGContextSaveGState(context);
+        
+        // Main rect
+        [bgColor set];
+        CGContextAddRect(context, CGRectMake(rect.origin.x,
+                                             rect.origin.y, 
+                                             rect.size.width,
+                                             rect.size.height / 2.f));
+        CGContextFillPath(context);
+        
+        // Triangle
+        CGContextBeginPath(context);
+        CGContextMoveToPoint(context,
+                             rect.origin.x + rect.size.width / 3.f,
+                             rect.origin.y + rect.size.height / 2.f);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + rect.size.width / 2.f,
+                                rect.origin.y + rect.size.height);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + 2 * rect.size.width / 3.f,
+                                rect.origin.y + rect.size.height / 2.f);
+        CGContextClosePath(context);
+        
+        CGContextFillPath(context);
+        
+        CGContextRestoreGState(context);
+        
+        // Text
+        [textColor set];
+        [self.title drawInRect:CGRectMake(rect.origin.x,
+                                          rect.origin.y,
+                                          rect.size.width,
+                                          rect.size.height / 2.f)
+                      withFont:labelFont
+                 lineBreakMode:UILineBreakModeTailTruncation
+                     alignment:UITextAlignmentCenter];
+    }
+    
+    // Bottom
+    else if (self.position == 1)
+    {
+        CGContextSaveGState(context);
+        
+        // Main rect
+        [bgColor set];
+        CGContextAddRect(context, CGRectMake(rect.origin.x,
+                                             rect.origin.y + rect.size.height / 2.f, 
+                                             rect.size.width,
+                                             rect.size.height / 2.f));
+        CGContextFillPath(context);
+        
+        // Triangle
+        CGContextBeginPath(context);
+        CGContextMoveToPoint(context,
+                             rect.origin.x + rect.size.width / 3.f,
+                             rect.origin.y + rect.size.height / 2.f);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + rect.size.width / 2.f,
+                                rect.origin.y - rect.size.height);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + 2 * rect.size.width / 3.f,
+                                rect.origin.y + rect.size.height / 2.f);
+        CGContextClosePath(context);
+        
+        CGContextFillPath(context);
+        
+        CGContextRestoreGState(context);
+        
+        // Text
+        [textColor set];
+        [self.title drawInRect:CGRectMake(rect.origin.x,
+                                          rect.origin.y + rect.size.height / 2.f,
+                                          rect.size.width,
+                                          rect.size.height / 2.f)
+                      withFont:labelFont
+                 lineBreakMode:UILineBreakModeTailTruncation
+                     alignment:UITextAlignmentCenter];
+    }
+    
+    // Left
+    else if (self.position == 2)
+    {
+        CGContextSaveGState(context);
+        
+        // Main rect
+        [bgColor set];
+        CGContextAddRect(context, CGRectMake(rect.origin.x,
+                                             rect.origin.y + rect.size.height / 4.f, 
+                                             3.f * rect.size.width / 4.f,
+                                             rect.size.height / 2.f));
+        CGContextFillPath(context);
+        
+        // Triangle
+        CGContextBeginPath(context);
+        CGContextMoveToPoint(context,
+                             rect.origin.x + 3.f * rect.size.width / 4.f,
+                             rect.origin.y + rect.size.height / 4.f);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + rect.size.width,
+                                rect.origin.y + rect.size.height / 2.f);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + 3.f * rect.size.width / 4.f,
+                                rect.origin.y + 3.f * rect.size.height / 4.f);
+        CGContextClosePath(context);
+        
+        CGContextFillPath(context);
+        
+        CGContextRestoreGState(context);
+        
+        // Text
+        [textColor set];
+        [self.title drawInRect:CGRectMake(rect.origin.x,
+                                          rect.origin.y + rect.size.height / 4.f,
+                                          3.f * rect.size.width / 4.f,
+                                          rect.size.height / 2.f)
+                      withFont:labelFont
+                 lineBreakMode:UILineBreakModeTailTruncation
+                     alignment:UITextAlignmentLeft];
+    }
+    // Right
+    else if (self.position == 3)
+    {
+        CGContextSaveGState(context);
+        
+        // Main rect
+        [bgColor set];
+        CGContextAddRect(context, CGRectMake(rect.origin.x + rect.size.width / 4.f,
+                                             rect.origin.y + rect.size.height / 4.f, 
+                                             3.f * rect.size.width / 4.f,
+                                             rect.size.height / 2.f));
+        CGContextFillPath(context);
+        
+        // Triangle
+        CGContextBeginPath(context);
+        CGContextMoveToPoint(context,
+                             rect.origin.x + rect.size.width / 4.f,
+                             rect.origin.y + rect.size.height / 4.f);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x,
+                                rect.origin.y + rect.size.height / 2.f);
+        CGContextAddLineToPoint(context,
+                                rect.origin.x + rect.size.width / 4.f,
+                                rect.origin.y + 3.f * rect.size.height / 4.f);
+        CGContextClosePath(context);
+        
+        CGContextFillPath(context);
+        
+        CGContextRestoreGState(context);
+        
+        // Text
+        [textColor set];
+        [self.title drawInRect:CGRectMake(rect.origin.x + rect.size.width / 4.f,
+                                          rect.origin.y + rect.size.height / 4.f,
+                                          3.f * rect.size.width / 4.f,
+                                          rect.size.height / 2.f)
+                      withFont:labelFont
+                 lineBreakMode:UILineBreakModeTailTruncation
+                     alignment:UITextAlignmentRight];
+    }
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIKnob.h b/architecture/iOS/iOS/FIKnob.h
new file mode 100644
index 0000000..d3bc665
--- /dev/null
+++ b/architecture/iOS/iOS/FIKnob.h
@@ -0,0 +1,87 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on DCControls - https://github.com/domesticcatsoftware/DCControls
+ Copyright (C) 2011 by Patrick Richards - http://domesticcat.com.au/
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ************************************************************************
+ ************************************************************************/
+
+
+#import "FIResponder.h"
+#import "FIHint.h"
+
+#define kDCKnobRatio (M_PI * ((360.0 - self.cutoutSize) / 360.0))
+
+static inline CGFloat angleBetweenPoints(CGPoint first, CGPoint second)
+{
+	CGFloat height = second.y - first.y;
+	CGFloat width = first.x - second.x;
+	CGFloat rads = atan2(height, width);
+	return rads;
+}
+
+ at interface FIKnob : FIResponder
+{
+	CGAffineTransform initialTransform;
+	CGPoint lastPoint;
+	CGFloat initialAngle;
+    FIHint* _hint;
+}
+
+ at property BOOL biDirectional;					// default: NO
+ at property CGFloat arcStartAngle;				// default: 90 (degrees)
+ at property CGFloat cutoutSize;					// default: 60 (degrees)
+ at property CGFloat valueArcWidth;				// default: 15.0
+
+ at property CGFloat doubleTapValue;				// default: 0%
+ at property CGFloat tripleTapValue;				// default: 0%
+
+/////////////////////////
+// Init/Custom Setters //
+/////////////////////////
+
+- (id)initWithDelegate:(id)aDelegate;
+- (void)setFrame:(CGRect)frame;
+
+////////////////////
+// Touch Handling //
+////////////////////
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)updateHint;
+
+////////////////////
+// Helper Methods //
+////////////////////
+
+- (CGFloat)valueFromPoint:(CGPoint)point;
+- (CGAffineTransform)initialTransform;
+- (CGFloat)newValueFromTransform:(CGAffineTransform)transform;
+
+ at end
diff --git a/architecture/iOS/iOS/FIKnob.mm b/architecture/iOS/iOS/FIKnob.mm
new file mode 100644
index 0000000..0fcef07
--- /dev/null
+++ b/architecture/iOS/iOS/FIKnob.mm
@@ -0,0 +1,436 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on DCControls - https://github.com/domesticcatsoftware/DCControls
+ Copyright (C) 2011 by Patrick Richards - http://domesticcat.com.au/
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIKnob.h"
+
+#define kStdKnobHintSpace         10
+
+ at implementation FIKnob
+ at synthesize biDirectional, arcStartAngle, cutoutSize, valueArcWidth;
+ at synthesize doubleTapValue, tripleTapValue;
+
+
+#pragma mark -
+#pragma mark Init
+
+- (id)initWithDelegate:(id)aDelegate
+{
+	if ((self = [super initWithDelegate:aDelegate]))
+	{
+        _hint = nil;
+		self.arcStartAngle = 90.0;
+		self.cutoutSize = 60.0;
+        
+		// add the gesture recognizers for double & triple taps
+		UITapGestureRecognizer *doubleTapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)] autorelease];
+		doubleTapGesture.numberOfTapsRequired = 2;
+		[self addGestureRecognizer:doubleTapGesture];
+        
+		UITapGestureRecognizer *tripleTapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tripleTap:)] autorelease];
+		tripleTapGesture.numberOfTapsRequired = 3;
+		[self addGestureRecognizer:tripleTapGesture];
+	}
+    
+	return self;
+}
+
+- (void)dealloc
+{
+    if (_hint) [_hint dealloc];
+    [super dealloc];
+}
+
+// overridden to make sure the frame is always square.
+- (void)setFrame:(CGRect)frame
+{
+	if (frame.size.width != frame.size.height)
+	{
+		if (frame.size.width > frame.size.height)
+			frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.width);
+		else
+			frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height);
+	}
+    
+	[super setFrame:frame];
+}
+
+
+#pragma mark -
+#pragma mark Gestures
+
+- (void)doubleTap:(UIGestureRecognizer *)gestureRecognizer
+{    
+	if (self.allowsGestures)
+	{
+        CGPoint thisPoint = [gestureRecognizer locationInView:self];
+        CGFloat newValue = [self valueFromPoint:thisPoint];
+                
+        if (newValue > self.value)
+        {
+            self.value = self.value + self.step;
+        }
+        else if (newValue < self.value)
+        {
+            self.value = self.value - self.step;
+        }
+	}
+}
+
+- (void)tripleTap:(UIGestureRecognizer *)gestureRecognizer
+{    
+}
+
+- (void)setValueFromGesture:(NSNumber *)newValue
+{
+	self.value = [newValue floatValue];
+}
+
+
+#pragma mark -
+#pragma mark Touch Handling
+
+- (void)updateHint
+{
+    if (_hint)
+    {
+        UIView*     scrollView = self.superview.superview.superview;
+        CGRect      absHandleRect = [self convertRect:CGRectMake(0.f, 0.f, self.frame.size.width, self.frame.size.height)
+                                               toView:scrollView];
+
+        _hint.title = [NSString stringWithFormat:@"%2.1f%@", self.value, self.suffixe];
+        
+        // Top
+        if (absHandleRect.origin.y >= _hint.frame.size.height + kStdKnobHintSpace
+            && absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f + _hint.frame.size.width <= scrollView.frame.size.width
+            && absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f >= 0.f)
+        {
+            _hint.position = 0;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f,
+                                       absHandleRect.origin.y - _hint.frame.size.height - kStdKnobHintSpace,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        // Left
+        else if (absHandleRect.origin.x >= _hint.frame.size.width + kStdKnobHintSpace)
+        {
+            _hint.position = 2;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x - _hint.frame.size.width - kStdKnobHintSpace,
+                                       absHandleRect.origin.y,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        // Right
+        else if (scrollView.frame.size.width - absHandleRect.origin.x - absHandleRect.size.width >= _hint.frame.size.width + kStdKnobHintSpace)
+        {
+            _hint.position = 3;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x + absHandleRect.size.width + kStdKnobHintSpace,
+                                       absHandleRect.origin.y,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        // Bottom
+        else
+        {
+            _hint.position = 1;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f,
+                                       absHandleRect.origin.y + absHandleRect.size.height + kStdKnobHintSpace,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        [_hint setNeedsDisplay];
+    }
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{    
+    self.motionBlocked = YES;
+    
+	CGPoint thisPoint = [[touches anyObject] locationInView:self];
+	CGPoint centerPoint = CGPointMake(self.frame.size.width / 2.0, self.frame.size.width / 2.0);
+	initialAngle = angleBetweenPoints(thisPoint, centerPoint);
+    
+	// create the initial angle and initial transform
+	initialTransform = [self initialTransform];
+    
+    if (!_hint)
+    {
+        _hint = [[FIHint alloc] init];
+        [self.superview.superview.superview addSubview:_hint];
+    }
+    
+    if (_hint)
+    {
+        _hint.title = [NSString stringWithFormat:@"%2.1f%@", self.value, self.suffixe];
+        [self updateHint];
+    }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    self.motionBlocked = YES;
+    
+	CGPoint thisPoint = [[touches anyObject] locationInView:self];
+	CGPoint centerPoint = CGPointMake(self.frame.size.width / 2.0, self.frame.size.width / 2.0);
+    
+	CGFloat currentAngle = angleBetweenPoints(thisPoint, centerPoint);
+	CGFloat angleDiff = (initialAngle - currentAngle);
+	CGAffineTransform newTransform = CGAffineTransformRotate(initialTransform, angleDiff);
+    
+	CGFloat newValue = [self newValueFromTransform:newTransform];
+    
+	// only set the new value if it doesn't flip the knob around
+	CGFloat diff = self.value - newValue;
+	diff = (diff < 0) ? -diff : diff;
+	if (diff < (self.max - self.min) / 10.0)
+	{
+		self.value = newValue;
+	}
+	else
+	{
+		// reset the initial angle & transform using the current value
+		initialTransform = [self initialTransform];
+		initialAngle = angleBetweenPoints(thisPoint, centerPoint);
+	}
+    
+    [self updateHint];
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    self.motionBlocked = NO;
+    
+    if (_hint)
+    {
+        [_hint removeFromSuperview];
+        [_hint release];
+        _hint = nil;
+    }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    self.motionBlocked = NO;
+    
+    if (_hint)
+    {
+        [_hint removeFromSuperview];
+        [_hint release];
+        _hint = nil;
+    }
+}
+
+#pragma mark -
+#pragma mark Helper Methods
+
+- (CGFloat)valueFromPoint:(CGPoint)point
+{
+    CGPoint centerPoint = CGPointMake(self.frame.size.width / 2.0, self.frame.size.width / 2.0);
+    CGFloat currentAngle = 450.f + angleBetweenPoints(point, centerPoint) * 57.29577951308232;
+    int normAngle = 360 - ((int)floor(currentAngle) % 360);
+	CGFloat newValue;
+    float course = 360.f - self.cutoutSize;
+    float courseOffset = self.cutoutSize / 2.f;
+    
+    newValue = normAngle - courseOffset;
+    if (newValue < 0.f) newValue = 0.f;
+    else if (newValue > course) newValue = course;
+    
+    newValue = newValue / course;
+    newValue = self.min + newValue * (self.max - self.min);
+    
+	return newValue;
+}
+
+
+- (CGAffineTransform)initialTransform
+{
+	CGFloat pValue = (self.value - self.min) / (self.max - self.min);
+	pValue = (pValue * kDCKnobRatio * 2) - kDCKnobRatio;
+	return CGAffineTransformMakeRotation(pValue);
+}
+
+- (CGFloat)newValueFromTransform:(CGAffineTransform)transform
+{
+	CGFloat newValue = atan2(transform.b, transform.a);
+	newValue = (newValue + kDCKnobRatio) / (kDCKnobRatio * 2);
+	newValue = self.min + (newValue * (self.max - self.min));
+	return newValue;
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+- (void)drawRect:(CGRect)rect
+{
+    if (self.hideOnGUI) return;
+    
+	CGContextRef context = UIGraphicsGetCurrentContext();
+	CGRect boundsRect = self.bounds;
+	CGFloat maxHalf = self.min + (self.max - self.min) / 2;
+	float x = boundsRect.size.width / 2;
+	float y = boundsRect.size.height / 2;
+    
+	CGContextSaveGState(context);
+	CGContextSetLineWidth(context, self.valueArcWidth);
+    
+    self.backgroundColor = [UIColor blackColor];
+	if (self.backgroundColorAlpha > 0.02)
+	{
+		// outline semi circle
+		UIColor *backgroundColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1.];
+		[backgroundColor set];
+        
+		CGContextAddArc(context,
+						x,
+						y,
+						(boundsRect.size.width / 2) - self.valueArcWidth / 2,
+						FIDegreesToRadians(self.arcStartAngle + self.cutoutSize / 2),
+						FIDegreesToRadians(self.arcStartAngle + 360 - self.cutoutSize / 2),
+						0);
+		CGContextStrokePath(context);
+	}
+    
+    // Gradient
+    context = UIGraphicsGetCurrentContext();
+    
+    UIColor *lightGradientColor = [UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1.];
+    UIColor *darkGradientColor = [UIColor colorWithRed:0. green:0. blue:0. alpha:1.];
+    
+    CGFloat locations[2] = {0.0, 1.0};
+    CFArrayRef colors = (CFArrayRef) [NSArray arrayWithObjects:(id)lightGradientColor.CGColor,
+                                      (id)darkGradientColor.CGColor, 
+                                      nil];
+    
+    CGColorSpaceRef colorSpc = CGColorSpaceCreateDeviceRGB();
+    CGGradientRef gradient = CGGradientCreateWithColors(colorSpc, colors, locations);
+    
+    CGContextSetBlendMode(context, kCGBlendModeMultiply);
+    
+    CGContextDrawLinearGradient(context,
+                                gradient, 
+                                CGPointMake(0.0, 0.0), 
+                                CGPointMake(rect.size.width, rect.size.height), 
+                                kCGGradientDrawsAfterEndLocation); //Adjust second point according to your view height
+    
+    CGColorSpaceRelease(colorSpc);
+    CGGradientRelease(gradient);
+    CGContextSetBlendMode(context, kCGBlendModeNormal);
+    // End gradient
+    
+	// draw the value semi circle
+	[self.color set];
+	CGFloat valueAdjusted = (self.value - self.min) / (self.max - self.min);
+	if (self.biDirectional)
+	{
+		CGContextAddArc(context,
+						x,
+						y,
+						(boundsRect.size.width / 2) - self.valueArcWidth / 2,
+						FIDegreesToRadians(self.arcStartAngle + 180),
+						FIDegreesToRadians(self.arcStartAngle + self.cutoutSize / 2 + (360 - self.cutoutSize) * valueAdjusted),
+						self.value <= maxHalf);
+	}
+	else
+	{
+		CGContextAddArc(context,
+						x,
+						y,
+						(boundsRect.size.width / 2) - self.valueArcWidth / 2,
+						FIDegreesToRadians(self.arcStartAngle + self.cutoutSize / 2),
+						FIDegreesToRadians(self.arcStartAngle + self.cutoutSize / 2 + (360 - self.cutoutSize) * valueAdjusted),
+						0);
+	}
+	CGContextStrokePath(context);
+    
+	// draw the value string as needed
+	if (self.displaysValue)
+	{
+		if (self.labelColor)
+			[self.labelColor set];
+		else
+			[self.color set];
+		NSString *valueString = nil;
+        float multiplier = 1.f;
+
+        if ([self.suffixe compare:@""] == NSOrderedSame)
+        {
+            if (self.step < 0.01) valueString = [NSString stringWithFormat:@"%2.3f", self.value];
+            else if (self.step < 0.1) valueString = [NSString stringWithFormat:@"%2.2f", self.value];
+            else valueString = [NSString stringWithFormat:@"%2.1f", self.value];
+        }
+        else
+        {
+            if (self.step < 0.01) valueString = [NSString stringWithFormat:@"%2.3f\r%@", self.value, self.suffixe];
+            else if (self.step < 0.1) valueString = [NSString stringWithFormat:@"%2.2f\r%@", self.value, self.suffixe];
+            else valueString = [NSString stringWithFormat:@"%2.1f\r%@", self.value, self.suffixe];
+            multiplier = 2.f;
+        }   
+		CGSize valueStringSize = [valueString sizeWithFont:self.labelFont
+												  forWidth:boundsRect.size.width
+											 lineBreakMode:UILineBreakModeTailTruncation];
+		[valueString drawInRect:CGRectMake(floorf((boundsRect.size.width - valueStringSize.width) / 2.0 + self.labelOffset.x),
+										   floorf((boundsRect.size.height - valueStringSize.height) / 2.0 + self.labelOffset.y),
+										   valueStringSize.width,
+										   multiplier * valueStringSize.height)
+					   withFont:self.labelFont
+				  lineBreakMode:UILineBreakModeTailTruncation
+                      alignment:UITextAlignmentCenter];		
+	}
+    
+    // Draw assignation
+    if (self.assignated)
+    {
+        CGContextSetLineWidth(context, 3.);
+        [self.color set];
+        [self context:context addRoundedRect:boundsRect cornerRadius:3.f];
+        CGContextStrokePath(context);
+    }
+    
+    // Draw selection
+    if (self.responderSelected)
+    {
+        CGContextSetLineWidth(context, 15.);
+        [self.color set];
+        [self context:context addRoundedRect:boundsRect cornerRadius:3.f];
+        CGContextStrokePath(context);
+    }
+    
+	CGContextRestoreGState(context);
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIMainViewController.h b/architecture/iOS/iOS/FIMainViewController.h
new file mode 100644
index 0000000..76dcecd
--- /dev/null
+++ b/architecture/iOS/iOS/FIMainViewController.h
@@ -0,0 +1,161 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <CoreMotion/CoreMotion.h>
+#import <CoreLocation/CoreLocation.h>
+#import <list>
+#import "FIFlipsideViewController.h"
+#import "FIResponder.h"
+#import "FIScrollView.h"
+#import "FISensorFilter.h"
+
+
+
+#ifdef JACK_IOS
+#import "JackView.h"
+#endif
+
+
+
+using namespace std;
+class uiCocoaItem;
+class uiBox;
+
+ at interface FIMainViewController : UIViewController <    FIFlipsideViewControllerDelegate,
+                                                        UIPopoverControllerDelegate,
+                                                        FIResponderDelegate,
+                                                        UIScrollViewDelegate,
+                                                        UIGestureRecognizerDelegate,
+                                                        CLLocationManagerDelegate>
+{
+    IBOutlet UIView*                    _dspView;
+    IBOutlet FIScrollView*              _dspScrollView;
+    IBOutlet UILabel*                   _titleLabel;                    // iPhone
+    IBOutlet UINavigationItem*          _titleNavigationItem;           // iPad
+    
+    NSTimer*                            _refreshTimer;                  // Used to refresh bargraphes
+    
+    UITapGestureRecognizer*             _tapGesture;
+    uiBox*                              _lockedBox;
+    UIDeviceOrientation                 _currentOrientation;
+    BOOL                                _viewLoaded;  
+    
+    IBOutlet UIView*                    _widgetPreferencesView;
+    IBOutlet UISegmentedControl*        _gyroAxisSegmentedControl;
+    IBOutlet UISwitch*                  _gyroInvertedSwitch;
+    IBOutlet UISwitch*                  _gyroFilteredSwitch;
+    IBOutlet UISlider*                  _gyroSensibilitySlider;
+    IBOutlet UILabel*                   _gyroSensibilityLabel;
+    IBOutlet UILabel*                   _widgetPreferencesTitleLabel;
+    IBOutlet UILabel*                   _gyroInvertedTitleLabel;
+    IBOutlet UILabel*                   _gyroSensibilityTitleLabel;
+    uiCocoaItem*                        _selectedWidget;                // Contains label of the widget
+    list <uiCocoaItem*>                 _assignatedWidgets;
+    FISensorFilter*                     _sensorFilter;
+    CLLocationManager*                  _locationManager;
+    CMMotionManager*                    _motionManager;
+    NSTimer*                            _motionTimer;
+    BOOL                                _blockShake;                    // To avoid several shakes in one movement
+    
+    IBOutlet UILabel*                   _colorLabel;
+    IBOutlet UILabel*                   _rLabel;
+    IBOutlet UILabel*                   _gLabel;
+    IBOutlet UILabel*                   _bLabel;
+    IBOutlet UILabel*                   _colorRLabel;
+    IBOutlet UILabel*                   _colorGLabel;
+    IBOutlet UILabel*                   _colorBLabel;
+    IBOutlet UISlider*                  _colorRSlider;
+    IBOutlet UISlider*                  _colorGSlider;
+    IBOutlet UISlider*                  _colorBSlider;
+    
+    const   char*                       _name;
+    
+    BOOL                                _openPanelChanged;
+    
+
+#ifdef JACK_IOS
+    // Test Jack
+    UISwipeGestureRecognizer*           _swipeRecognizer;
+    UITapGestureRecognizer*             _tapRecognizerToDismissJackView;
+    UIButton*                           _jackButton;
+    JackView*                           _jackView;
+    BOOL                                _orientationIsChanging;
+#endif
+}
+
+ at property (strong, nonatomic) UIPopoverController* flipsidePopoverController;
+ at property (assign, nonatomic) UIView* dspView;
+ at property (assign, nonatomic) UIScrollView* dspScrollView;
+
+// DSP view
+- (void)responderValueDidChange:(float)value sender:(id)sender;
+- (void)saveGui;
+- (void)loadGui;
+- (void)updateGui;
+
+#ifdef JACK_IOS
+- (BOOL)openJack;
+- (BOOL)checkJack;
+- (void)closeJack:(const char*)reason;
+- (BOOL)isJackAudio;
+#endif
+
+- (BOOL)openCoreAudio:(int)bufferSize :(int)sampleRate;
+
+- (void)openAudio;
+- (void)closeAudio;
+
+// Misc GUI
+- (void)orientationChanged:(NSNotification *)notification;
+- (void)displayTitle;
+- (void)refreshObjects:(NSTimer*)timer;
+- (void)zoomToLockedBox;
+- (void)doubleTap;
+- (void)buttonSetToZero:(id)sender;
+- (void)zoomToWidget:(FIResponder*)widget;
+- (void)setOpenWidgetPanel:(BOOL)openWidgetPanelOnLongTouch;
+
+// Audio
+- (void)restartAudioWithBufferSize:(int)bufferSize sampleRate:(int)sampleRate;
+
+// Sensors
+- (void)showWidgetPreferencesView:(UILongPressGestureRecognizer *)gesture;
+- (void)updateWidgetPreferencesView;
+- (IBAction)dismissWidgetPreferencesView:(id)sender;
+- (IBAction)widgetPreferencesChanged:(id)sender;
+- (IBAction)resetWidgetPreferences:(id)sender;
+- (void)resetAllWidgetsPreferences;
+- (void)loadWidgetsPreferences;
+- (void)startMotion;
+- (void)stopMotion;
+- (void)updateMotion;
+- (void)endBlockShake;
+- (NSString*)urlForWidget:(uiCocoaItem*)widget;
+
+- (float)mapping2WithA:(float)a la:(float)la ha:(float)ha lv:(float)lv hv:(float)hv;
+- (float)mapping3WithA:(float)a la:(float)la ma:(float)ma ha:(float)ha lv:(float)lv mv:(float)mv hv:(float)hv;
+
+
+#ifdef JACK_IOS
+// Test Jack
+- (void)openJackView;
+- (void)closeJackView;
+- (void)autoResizeJackViews;
+#endif
+
+ at end
\ No newline at end of file
diff --git a/architecture/iOS/iOS/FIMainViewController.mm b/architecture/iOS/iOS/FIMainViewController.mm
new file mode 100644
index 0000000..ad4e055
--- /dev/null
+++ b/architecture/iOS/iOS/FIMainViewController.mm
@@ -0,0 +1,1935 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <QuartzCore/QuartzCore.h>
+#import "FIMainViewController.h"
+#import "ios-faust.h"
+#import "FIFlipsideViewController.h"
+#import "FIAppDelegate.h"
+#import "FICocoaUI.h"
+
+#include "faust/gui/OSCUI.h"
+
+#define kMenuBarsHeight             66
+#define kMotionUpdateRate           30
+
+#define kRefreshTimerInterval       0.04
+
+// Test Jack
+#define kJackViewHeight 130
+#define kJackViewAnimationDuration 0.2
+
+
+ at implementation FIMainViewController
+
+ at synthesize flipsidePopoverController = _flipsidePopoverController;
+ at synthesize dspView = _dspView;
+ at synthesize dspScrollView = _dspScrollView;
+audio* audio_device = NULL;
+CocoaUI* interface = NULL;
+FUI* finterface = NULL;
+GUI* oscinterface = NULL;
+MY_Meta metadata;
+char rcfilename[256];
+
+int sampleRate = 0;
+int	bufferSize = 0;
+BOOL openWidgetPanel = YES;
+
+- (void)didReceiveMemoryWarning
+{
+    [super didReceiveMemoryWarning];
+}
+
+
+#pragma mark - View lifecycle
+
+- (void)loadView
+{
+    [super loadView];
+}
+
+#ifdef JACK_IOS
+
+static void jack_shutdown_callback(const char* message, void* arg)
+{
+    FIMainViewController* self = (FIMainViewController*)arg;
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [self closeJack :message];
+    });
+}
+
+#endif
+
+- (void)viewDidLoad
+{
+    // General UI initializations
+    _widgetPreferencesView.hidden = YES;
+    _viewLoaded = NO;
+    _currentOrientation = UIDeviceOrientationUnknown;
+    UIView *contentView;
+    [super viewDidLoad];
+    ((FIAppDelegate*)[UIApplication sharedApplication].delegate).mainViewController = self;
+    _openPanelChanged = YES;
+    
+    // Faust initialization
+    DSP.metadata(&metadata);
+    
+    // Read parameters values
+    const char* home = getenv("HOME");
+    if (home == 0) {
+        home = ".";
+    }
+ 
+    if ((*metadata.find("name")).second) {
+        _name = (*metadata.find("name")).second;
+    } else {
+        _name = [[[NSProcessInfo processInfo] processName] UTF8String];
+    }
+    
+    interface = new CocoaUI([UIApplication sharedApplication].keyWindow, self, &metadata);
+    finterface = new FUI();
+    
+    // Read user preferences
+    sampleRate = (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"sampleRate"];
+    bufferSize = (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"bufferSize"];
+    openWidgetPanel = [[NSUserDefaults standardUserDefaults] boolForKey:@"openWidgetPanel"];
+    
+    [self openAudio];
+    [self displayTitle];
+    
+    // Build Faust interface
+    DSP.init(int(sampleRate));
+	DSP.buildUserInterface(interface);
+    DSP.buildUserInterface(finterface);
+    
+    char* argv[3];
+    
+    argv[0] = (char*)_name;
+    argv[1] = "-xmit";
+    argv[2] = "1";
+    
+    oscinterface = new OSCUI(_name, 3, argv);
+    DSP.buildUserInterface(oscinterface);
+    
+    oscinterface->run();
+    
+    snprintf(rcfilename, 256, "%s/Library/Caches/%s", home, _name);
+    finterface->recallState(rcfilename);
+    
+    [self updateGui];
+    
+    // Notification when device orientation changed
+    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
+	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)
+                                        name:UIDeviceOrientationDidChangeNotification object:nil];
+    
+    // Abstract layout is the layout computed without regarding screen dimensions. To be displayed, we adapt it to the device and orientition
+    interface->saveAbstractLayout();
+    
+    // Used to refresh bargraphes
+    _refreshTimer = [NSTimer scheduledTimerWithTimeInterval:kRefreshTimerInterval target:self selector:@selector(refreshObjects:) userInfo:nil repeats:YES];
+    
+    // Views initilizations
+    contentView = [[[UIView alloc] initWithFrame:CGRectMake(0., 0., 10., 10.)] autorelease];
+    [_dspView addSubview:contentView];
+    _dspScrollView.delegate = self;
+    
+    // Double tap registration : used to zoom in the UI
+    _tapGesture =[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap)];
+    _tapGesture.numberOfTapsRequired = 2;
+    [_dspScrollView addGestureRecognizer:_tapGesture];
+    
+    // Locked box is the currently zoomed in box. At launch time, this box is the main box
+    _lockedBox = interface->getMainBox();
+    
+    // Widgets parameters
+    _blockShake = NO;
+    _locationManager = nil;
+    _motionManager = nil;
+    _selectedWidget = nil;
+    [self loadWidgetsPreferences];
+    if (_assignatedWidgets.size() > 0) [self startMotion];
+
+#ifdef JACK_IOS
+    // Test Jack
+    _swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(openJackView)];
+    _swipeRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
+    _swipeRecognizer.numberOfTouchesRequired = 3;
+    [_dspScrollView addGestureRecognizer:_swipeRecognizer];
+    
+    _tapRecognizerToDismissJackView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeJackView)];
+    _tapRecognizerToDismissJackView.numberOfTapsRequired = 1;
+    _tapRecognizerToDismissJackView.numberOfTouchesRequired = 1;
+    [_dspScrollView addGestureRecognizer:_tapRecognizerToDismissJackView];
+    
+    _jackButton = [UIButton buttonWithType:UIButtonTypeCustom];
+    [_jackButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon-Jack" ofType:@"png"]]
+                 forState:UIControlStateNormal];
+    [_jackButton addTarget:self action:@selector(openJackView) forControlEvents:UIControlEventTouchUpInside];
+
+    _jackButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin & UIViewAutoresizingFlexibleTopMargin;
+    [self.view addSubview:_jackButton];
+    
+    [self.view bringSubviewToFront:_widgetPreferencesView];
+    
+    _jackView = nil;
+    _orientationIsChanging = NO;
+#endif
+}
+
+#ifdef JACK_IOS
+
+- (BOOL)checkJack
+{
+    jackaudio audio;
+    
+    if (audio.init("dummy", &DSP)) {
+        audio.stop();
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+- (BOOL)openJack
+{
+    if (!audio_device) {
+        
+        NSString* iconFile;
+        if (DSP.getNumInputs() > 0 && DSP.getNumOutputs() > 0) {
+            iconFile = [[NSBundle mainBundle] pathForResource:@"Icon-Fx136" ofType:@"png"];
+        } else if (DSP.getNumOutputs() > 0) {
+            iconFile = [[NSBundle mainBundle] pathForResource:@"Icon-Output136" ofType:@"png"];
+        } else {
+            iconFile = [[NSBundle mainBundle] pathForResource:@"Icon-Analyzer136" ofType:@"png"];
+        }
+        NSFileHandle* fileHandle = [NSFileHandle fileHandleForReadingAtPath:iconFile];
+        NSData* data = [fileHandle readDataToEndOfFile];
+        const void* icon_data = [data bytes];
+        const size_t size = [data length];
+        NSLog(@"publishAppIcon rawDataSize = %ld", size);
+        [fileHandle closeFile];
+        
+        audio_device = new jackaudio(icon_data, size, true);
+        if (!audio_device->init((_name) ? _name : "Faust", &DSP)) {
+            printf("Cannot connect to JACK server\n");
+            goto error;
+        }
+        
+        if (audio_device->start() < 0) {
+            printf("Cannot start JACK client\n");
+            goto error;
+        }
+    }
+    
+    audio_device->shutdown(jack_shutdown_callback, self);
+    return TRUE;
+    
+error:
+    
+    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Audio warning"
+                                                        message:@"JACK server is not running !" delegate:self
+                                              cancelButtonTitle:@"OK" otherButtonTitles:nil];
+    [alertView show];
+    [alertView release];
+    
+    [self closeAudio];
+    return FALSE;
+}
+
+// Save widgets values
+- (void)closeJack:(const char*)reason 
+{
+    NSString* errorString = [[NSString alloc] initWithCString:reason encoding:NSASCIIStringEncoding];
+    
+    if ([errorString compare:@"Client closed from JACK server!"] != NSOrderedSame)
+    {
+        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Audio error"
+                                                            message:errorString delegate:self
+                                                            cancelButtonTitle:@"OK" otherButtonTitles:nil];
+        [alertView show];
+        [alertView release];
+    }
+
+    [self closeAudio];
+}
+
+- (BOOL)isJackAudio
+{
+    return (dynamic_cast<jackaudio*>(audio_device) != NULL);
+}
+
+#endif
+
+- (BOOL)openCoreAudio:(int)bufferSize :(int)sampleRate
+{
+    if (!audio_device) {
+        audio_device = new iosaudio(sampleRate, bufferSize);
+        
+        if (!audio_device->init((_name) ? _name : "Faust", &DSP)) {
+            printf("Cannot init iOS audio device\n");
+            goto error;
+        }
+        
+        if (audio_device->start() < 0) {
+            printf("Cannot start iOS audio device\n");
+            goto error;
+        }
+    }
+    
+    return TRUE;
+    
+error:
+    
+    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Audio error"
+                                                        message:@"CoreAudio device cannot be opened with the needed in/out parameters" delegate:self
+                                              cancelButtonTitle:@"OK" otherButtonTitles:nil];
+    [alertView show];
+    [alertView release];
+    
+    [self closeAudio];
+    return FALSE;
+}
+
+#ifdef JACK_IOS
+
+- (void)openAudio
+{
+    // If CA audio running and JACK server running, will switch to JACK
+    if (audio_device && dynamic_cast<iosaudio*>(audio_device) && [self checkJack]) {
+        [self closeAudio];
+    }
+    
+    if (![self openJack]) {
+        [self openCoreAudio:bufferSize :sampleRate];
+    }
+}
+
+#else
+
+- (void)openAudio
+{
+    [self openCoreAudio:bufferSize :sampleRate];
+}
+
+#endif
+
+- (void)closeAudio
+{
+    if (audio_device) {
+        audio_device->stop();
+        delete audio_device;
+        audio_device = NULL;
+    }
+}
+
+- (void)viewDidUnload
+{
+    [super viewDidUnload];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+    if (!interface) return;
+    [super viewWillAppear:animated];
+}
+
+- (void)viewDidAppear:(BOOL)animated
+{
+    if (!interface) return;
+    [super viewDidAppear:animated];
+    [self orientationChanged:nil];
+    [self zoomToLockedBox];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+	[super viewWillDisappear:animated];
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+	[super viewDidDisappear:animated];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
+    
+    [_tapGesture release];
+    
+    [self closeAudio];
+    
+    delete interface;
+    delete finterface;
+    delete oscinterface;
+    
+    [_refreshTimer invalidate];
+    [self stopMotion];
+
+#ifdef JACK_IOS
+    // Test Jack
+    [_swipeRecognizer release];
+#endif
+    
+    [super dealloc];
+}
+
+
+#pragma mark - DSP view
+
+// Sends corresponding uiCocoaItem subtype object to the UIReponder subtype object passed in argument
+// Sends NULL if nothing has been found
+
+template <typename T>
+T findCorrespondingUiItem(FIResponder* sender)
+{
+    list<uiCocoaItem*>::iterator i;
+    
+    // Loop on uiCocoaItem elements
+    for (i = ((CocoaUI*)(interface))->fWidgetList.begin(); i != ((CocoaUI*)(interface))->fWidgetList.end(); i++)
+    {
+        // Does current uiCocoaItem match T ?
+        if (dynamic_cast<T>(*i) != nil)
+        {
+            // Test sender type
+            if (typeid(T) == typeid(uiSlider*))
+            {
+                if (sender == dynamic_cast<uiSlider*>(*i)->fSlider) return dynamic_cast<T>(*i);
+            }
+            else if (typeid(T) == typeid(uiButton*))
+            {
+                if (sender == dynamic_cast<uiButton*>(*i)->fButton) return dynamic_cast<T>(*i);
+            }
+            else if (typeid(T) == typeid(uiNumEntry*))
+            {
+                if (sender == dynamic_cast<uiNumEntry*>(*i)->fTextField) return dynamic_cast<T>(*i);
+            }
+            else if (typeid(T) == typeid(uiKnob*))
+            {
+                if (sender == dynamic_cast<uiKnob*>(*i)->fKnob) return dynamic_cast<T>(*i);
+            }
+            else if (typeid(T) == typeid(uiBox*))
+            {
+                if (sender == dynamic_cast<uiBox*>(*i)->fTabView) return dynamic_cast<T>(*i);
+            }
+        }
+    }
+    
+    return NULL;
+}
+
+
+// User actions notifications
+- (void)responderValueDidChange:(float)value sender:(id)sender
+{
+    if ([sender isKindOfClass:[FISlider class]])
+    {
+        uiSlider* slider = findCorrespondingUiItem<uiSlider*>((FIResponder*)sender);
+        if (slider)
+        {
+            // If widget is assigned to a sensor, touch is used to move ref point
+            if ((slider->getAssignationType() == kAssignationAccelX
+                || slider->getAssignationType() == kAssignationAccelY
+                || slider->getAssignationType() == kAssignationAccelZ
+                || slider->getAssignationType() == kAssignationCompass
+                || slider->getAssignationType() == kAssignationGyroX
+                || slider->getAssignationType() == kAssignationGyroY
+                || slider->getAssignationType() == kAssignationGyroZ)
+                && (((FIResponder*)sender).motionBlocked))
+            {
+                //slider->setAssignationRefPointY((((float)((FIResponder*)sender).value) - ((FIResponder*)sender).min) / (((FIResponder*)sender).max - ((FIResponder*)sender).min));
+                slider->setAssignationRefPointY((float)((FIResponder*)sender).value);
+                
+                float sensibility;
+                if (slider->getAssignationInverse()) sensibility = -slider->getAssignationSensibility();
+                else sensibility = slider->getAssignationSensibility();
+                
+                if (slider->getAssignationType() == kAssignationAccelX) slider->setAssignationRefPointX(_motionManager.accelerometerData.acceleration.x * sensibility);
+                else if (slider->getAssignationType() == kAssignationAccelY) slider->setAssignationRefPointX(_motionManager.accelerometerData.acceleration.y * sensibility);
+                else if (slider->getAssignationType() == kAssignationAccelZ) slider->setAssignationRefPointX(_motionManager.accelerometerData.acceleration.z * sensibility);
+                else if (slider->getAssignationType() == kAssignationCompass)
+                {
+                    slider->setAssignationRefPointX(0.f);
+                    slider->setAssignationRefPointY(slider->getAssignationRefPointY() * 360.f - _locationManager.heading.trueHeading);
+                }
+                else if (slider->getAssignationType() == kAssignationGyroX) slider->setAssignationRefPointX(0.);
+                else if (slider->getAssignationType() == kAssignationGyroY) slider->setAssignationRefPointX(0.);
+                else if (slider->getAssignationType() == kAssignationGyroZ) slider->setAssignationRefPointX(0.);
+                                
+                NSString* key = [NSString stringWithFormat:@"%@-assignation-refpoint-x", [self urlForWidget:slider]];
+                [[NSUserDefaults standardUserDefaults] setFloat:slider->getAssignationRefPointX() + 1000. forKey:key];
+                
+                key = [NSString stringWithFormat:@"%@-assignation-refpoint-y", [self urlForWidget:slider]];
+                [[NSUserDefaults standardUserDefaults] setFloat:slider->getAssignationRefPointY() + 1000. forKey:key];
+                
+                [[NSUserDefaults standardUserDefaults] synchronize];                
+            }
+            
+            // Otherwise normal behaviour
+            else
+            {
+                slider->modifyZone((float)((FISlider*)sender).value);
+            }
+        }
+    }
+    else if ([sender isKindOfClass:[FIButton class]])
+    {
+        uiButton* button = findCorrespondingUiItem<uiButton*>((FIResponder*)sender);
+        if (button)
+        {
+            button->modifyZone((float)((FIButton*)sender).value);
+
+            // If push button, force to zero just after to avoid an "anti-rebond" bug
+            /*if ((float)((FIButton*)sender).type == kPushButtonType && (float)((FIButton*)sender).value == 1.)
+            {
+                [self performSelector:@selector(buttonSetToZero:) withObject:sender afterDelay:0.1];
+            }*/
+        }
+    }
+    else if ([sender isKindOfClass:[FITextField class]])
+    {
+        uiNumEntry* numEntry = findCorrespondingUiItem<uiNumEntry*>((FIResponder*)sender);
+        if (numEntry)
+        {
+            numEntry->modifyZone((float)((FITextField*)sender).value);
+        }
+    }
+    else if ([sender isKindOfClass:[FIKnob class]])
+    {
+        uiKnob* knob = findCorrespondingUiItem<uiKnob*>((FIResponder*)sender);
+        if (knob)
+        {
+            // If widget is assigned to a sensor, touch is used to move ref point
+            if ((knob->getAssignationType() == kAssignationAccelX
+                || knob->getAssignationType() == kAssignationAccelY
+                 || knob->getAssignationType() == kAssignationAccelZ
+                 || knob->getAssignationType() == kAssignationCompass
+                 || knob->getAssignationType() == kAssignationGyroX
+                 || knob->getAssignationType() == kAssignationGyroY
+                 || knob->getAssignationType() == kAssignationGyroZ)
+                && (((FIResponder*)sender).motionBlocked))
+            {
+                //knob->setAssignationRefPointY((((float)((FIResponder*)sender).value) - ((FIResponder*)sender).min) / (((FIResponder*)sender).max - ((FIResponder*)sender).min));
+                knob->setAssignationRefPointY((float)((FIResponder*)sender).value);
+                
+                float sensibility;
+                if (knob->getAssignationInverse()) sensibility = -knob->getAssignationSensibility();
+                else sensibility = knob->getAssignationSensibility();
+                
+                if (knob->getAssignationType() == kAssignationAccelX) knob->setAssignationRefPointX(_motionManager.accelerometerData.acceleration.x * sensibility);
+                else if (knob->getAssignationType() == kAssignationAccelY) knob->setAssignationRefPointX(_motionManager.accelerometerData.acceleration.y * sensibility);
+                else if (knob->getAssignationType() == kAssignationAccelZ) knob->setAssignationRefPointX(_motionManager.accelerometerData.acceleration.z * sensibility);
+                else if (knob->getAssignationType() == kAssignationCompass)
+                {
+                    knob->setAssignationRefPointX(0.f);
+                    knob->setAssignationRefPointY(knob->getAssignationRefPointY() * 360.f - _locationManager.heading.trueHeading);
+                }
+                else if (knob->getAssignationType() == kAssignationGyroX) knob->setAssignationRefPointX(0.);
+                else if (knob->getAssignationType() == kAssignationGyroY) knob->setAssignationRefPointX(0.);
+                else if (knob->getAssignationType() == kAssignationGyroZ) knob->setAssignationRefPointX(0.);
+                
+                NSString* key = [NSString stringWithFormat:@"%@-assignation-refpoint-x", [self urlForWidget:knob]];
+                [[NSUserDefaults standardUserDefaults] setFloat:knob->getAssignationRefPointX() + 1000. forKey:key];
+                
+                key = [NSString stringWithFormat:@"%@-assignation-refpoint-y", [self urlForWidget:knob]];
+                [[NSUserDefaults standardUserDefaults] setFloat:knob->getAssignationRefPointY() + 1000. forKey:key];
+                
+                [[NSUserDefaults standardUserDefaults] synchronize];
+            }
+            
+            // Otherwise normal behaviour
+            else
+            {
+                knob->modifyZone((float)((FIKnob*)sender).value);
+            }
+        }
+    }
+    else if ([sender isKindOfClass:[FITabView class]])
+    {
+        uiBox* box = findCorrespondingUiItem<uiBox*>((FIResponder*)sender);
+        if (box)
+        {
+            box->reflectZone();
+        }
+    }
+    else NSLog(@"UIItem not implemented yet :)");
+}
+
+// Save widgets values
+- (void)saveGui
+{
+    if (finterface) {
+        finterface->saveState(rcfilename);
+    }
+}
+
+// Load widgets values
+- (void)loadGui
+{
+    if (finterface) {
+        finterface->recallState(rcfilename);
+    }
+}
+
+// Reflect the whole patch
+- (void)updateGui
+{
+    list<uiCocoaItem*>::iterator i;
+        
+    // Loop on uiCocoaItem elements
+    for (i = ((CocoaUI*)(interface))->fWidgetList.begin(); i != ((CocoaUI*)(interface))->fWidgetList.end(); i++)
+    {
+        // Refresh GUI
+        (*i)->reflectZone();
+        
+        if (_openPanelChanged)
+        {
+            (*i)->enableLongPressGestureRecognizer(openWidgetPanel);
+        }
+    }
+    
+    if (_openPanelChanged) _openPanelChanged = !_openPanelChanged;
+}
+
+// Force push button to go back to 0
+- (void)buttonSetToZero:(id)sender
+{
+    uiButton* button = findCorrespondingUiItem<uiButton*>((FIResponder*)sender);
+    if (button)
+    {
+        button->modifyZone(0.f);
+        ((FIButton*)sender).value = 0.f;
+        [((FIButton*)sender) setNeedsDisplay];
+    }
+}
+
+
+#pragma mark - Misc GUI
+
+- (void)orientationChanged:(NSNotification *)notification
+{
+    float                           width = 0.f;
+    float                           height = 0.f;
+    UIDeviceOrientation             deviceOrientation = [UIDevice currentDevice].orientation;
+    
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone
+        && deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
+    {
+        return;
+    }
+    
+#ifdef JACK_IOS
+    _orientationIsChanging = YES;
+#endif
+    
+    [self updateGui];
+    
+#ifdef JACK_IOS
+    _orientationIsChanging = NO;
+#endif
+    
+    // Compute layout
+    if (deviceOrientation == UIDeviceOrientationPortrait
+        || deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
+    {
+        width = min(_dspScrollView.window.frame.size.width,
+                    _dspScrollView.window.frame.size.height);
+        height = max(_dspScrollView.window.frame.size.width - kMenuBarsHeight,
+                     _dspScrollView.window.frame.size.height - kMenuBarsHeight);
+    }
+    else if (deviceOrientation == UIDeviceOrientationLandscapeLeft
+             || deviceOrientation == UIDeviceOrientationLandscapeRight)
+    {
+        width = max(_dspScrollView.window.frame.size.width,
+                    _dspScrollView.window.frame.size.height);
+        height = min(_dspScrollView.window.frame.size.width - kMenuBarsHeight,
+                     _dspScrollView.window.frame.size.height - kMenuBarsHeight);
+    }
+    else
+    {
+        return;
+    }
+    
+    if (_currentOrientation == deviceOrientation) return;
+    _currentOrientation = deviceOrientation;
+
+    interface->adaptLayoutToWindow(width, height);
+    
+    // Compute min zoom, max zooam and current zoom
+    _dspScrollView.minimumZoomScale = width / (*interface->fWidgetList.begin())->getW();
+    _dspScrollView.maximumZoomScale = 1.;
+    
+    // Compute frame of the content size
+    [_dspView setFrame:CGRectMake(0.f,
+                                  0.f,
+                                  2 * (*interface->fWidgetList.begin())->getW() * _dspScrollView.zoomScale,
+                                  2 * (*interface->fWidgetList.begin())->getH() * _dspScrollView.zoomScale)];
+    
+    [_dspScrollView setContentSize:CGSizeMake((*interface->fWidgetList.begin())->getW() * _dspScrollView.zoomScale,
+                                              (*interface->fWidgetList.begin())->getH() * _dspScrollView.zoomScale)];
+    
+    if (!_viewLoaded)
+    {
+        if (_dspScrollView.minimumZoomScale != 1.)
+        {
+            [_dspScrollView setZoomScale:width / (*interface->fWidgetList.begin())->getW() animated:NO];
+        }
+
+        _viewLoaded = YES;
+    }
+    else
+    {
+        if (_lockedBox)
+        {
+            [self performSelector:@selector(zoomToLockedBox) withObject:nil afterDelay:0.1];
+        }
+    }
+    
+    // Widget preferences window, iPhone only
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
+    {
+        if (deviceOrientation == UIDeviceOrientationPortrait
+            || deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
+        {
+            [_colorLabel setFrame:CGRectMake(15., 282., _colorLabel.frame.size.width, _colorLabel.frame.size.height)];
+            [_rLabel setFrame:CGRectMake(15., 311., _rLabel.frame.size.width, _rLabel.frame.size.height)];
+            [_colorRLabel setFrame:CGRectMake(260., 311., _colorRLabel.frame.size.width, _colorRLabel.frame.size.height)];
+            [_colorRSlider setFrame:CGRectMake(41., 311., 223., 23.)];
+            [_gLabel setFrame:CGRectMake(15., 341., _gLabel.frame.size.width, _gLabel.frame.size.height)];
+            [_colorGLabel setFrame:CGRectMake(259., 341., _colorGLabel.frame.size.width, _colorGLabel.frame.size.height)];
+            [_colorGSlider setFrame:CGRectMake(41., 341., 223., 23.)];
+            [_bLabel setFrame:CGRectMake(15., 371., _bLabel.frame.size.width, _bLabel.frame.size.height)];
+            [_colorBLabel setFrame:CGRectMake(259., 371., _colorBLabel.frame.size.width, _colorBLabel.frame.size.height)];
+            [_colorBSlider setFrame:CGRectMake(41., 371., 223., 23.)];
+        }
+        else if (deviceOrientation == UIDeviceOrientationLandscapeLeft
+                 || deviceOrientation == UIDeviceOrientationLandscapeRight)
+        {
+            [_colorLabel setFrame:CGRectMake(308., 38., _colorLabel.frame.size.width, _colorLabel.frame.size.height)];
+            [_rLabel setFrame:CGRectMake(308., 67., _rLabel.frame.size.width, _rLabel.frame.size.height)];
+            [_colorRLabel setFrame:CGRectMake(420., 67., _colorRLabel.frame.size.width, _colorRLabel.frame.size.height)];
+            [_colorRSlider setFrame:CGRectMake(306., 96., 156., 23.)];
+            [_gLabel setFrame:CGRectMake(308., 331., _gLabel.frame.size.width, _gLabel.frame.size.height)];
+            [_colorGLabel setFrame:CGRectMake(420., 131., _colorGLabel.frame.size.width, _colorGLabel.frame.size.height)];
+            [_colorGSlider setFrame:CGRectMake(306., 160., 156., 23.)];
+            [_bLabel setFrame:CGRectMake(308., 190., _bLabel.frame.size.width, _bLabel.frame.size.height)];
+            [_colorBLabel setFrame:CGRectMake(420., 190., _colorBLabel.frame.size.width, _colorBLabel.frame.size.height)];
+            [_colorBSlider setFrame:CGRectMake(306., 219., 156., 23.)];
+        }
+    }
+
+#ifdef JACK_IOS    
+    // Test Jack
+    if ([self isJackAudio])
+    {
+        [self performSelector:@selector(autoResizeJackViews) withObject:nil afterDelay:0.1];
+    }
+#endif
+}
+
+
+// Locked box : box currently zoomed in
+- (void)zoomToLockedBox
+{
+    if (_lockedBox == interface->getMainBox())
+    {
+        [_dspScrollView setZoomScale:_dspScrollView.minimumZoomScale animated:YES];
+        [_dspScrollView setContentOffset:CGPointZero animated:YES];
+        [_dspView setFrame:CGRectMake(0.f,
+                                      0.f,
+                                      (*interface->fWidgetList.begin())->getW() * _dspScrollView.zoomScale,
+                                      (*interface->fWidgetList.begin())->getH() * _dspScrollView.zoomScale)];
+        
+        [_dspScrollView setContentSize:CGSizeMake((*interface->fWidgetList.begin())->getW() * _dspScrollView.zoomScale,
+                                                  (*interface->fWidgetList.begin())->getH() * _dspScrollView.zoomScale)];
+    }
+    else
+    {
+        if (_dspView.frame.size.height < _dspScrollView.frame.size.height
+            && _dspScrollView.zoomScale == _dspScrollView.maximumZoomScale)
+        {
+            [_dspScrollView scrollRectToVisible:CGRectMake(absolutePosition(_lockedBox).x,
+                                                  absolutePosition(_lockedBox).y,
+                                                  _lockedBox->getW(),
+                                                  _lockedBox->getH())
+                                       animated:YES];
+        }
+        else
+        {
+            [_dspScrollView zoomToRect:CGRectMake(absolutePosition(_lockedBox).x,
+                                                  absolutePosition(_lockedBox).y,
+                                                  _lockedBox->getW(),
+                                                  _lockedBox->getH())
+                              animated:YES];
+        }
+    }
+}
+
+// Display the title, in the bottom (iPhone) or top (iPad) of the screen
+- (void)displayTitle
+{
+    NSString*       titleString = nil;
+    
+    if (*metadata.find("name") != *metadata.end())
+    {
+        const char* name = (*metadata.find("name")).second;
+        titleString = [[NSString alloc] initWithCString:name encoding:NSASCIIStringEncoding];
+    }
+    
+    if (*metadata.find("author") != *metadata.end())
+    {
+        const char* name = (*metadata.find("author")).second;
+        if (titleString)
+        {
+            titleString = [titleString stringByAppendingFormat:@" | %s", name];
+        }
+        else
+        {
+            titleString = [[NSString alloc] initWithCString:name encoding:NSASCIIStringEncoding];
+        }
+    }
+    
+    if (!titleString) titleString = [[NSString alloc] initWithString:@"Faust | Grame"];
+    
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
+    {
+        _titleLabel.text = titleString;
+    }
+    else if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
+    {
+        _titleNavigationItem.title = titleString;
+    }
+}
+
+// Used to periodically refresh objects
+- (void)refreshObjects:(NSTimer*)timer
+{
+    list<uiCocoaItem*>::iterator i;
+
+    // Loop on uiCocoaItem elements
+    for (i = ((CocoaUI*)(interface))->fWidgetList.begin(); i != ((CocoaUI*)(interface))->fWidgetList.end(); i++)
+    {
+        // Refresh uiBargraph objects
+        if (dynamic_cast<uiBargraph*>(*i) != nil)
+        {
+            (*i)->reflectZone();
+            [dynamic_cast<uiBargraph*>(*i)->fBargraph setNeedsDisplay];
+        }
+    }
+    
+    GUI::updateAllGuis();
+}
+
+// Function called just after a pinch or a double click on a box
+- (void)scrollViewDidZoom:(UIScrollView *)scrollView
+{
+    [_dspView setFrame:CGRectMake(  _dspView.frame.origin.x,
+                                    _dspView.frame.origin.y,
+                                    (*interface->fWidgetList.begin())->getW() * _dspScrollView.zoomScale,
+                                    (*interface->fWidgetList.begin())->getH() * _dspScrollView.zoomScale)];
+    [_dspScrollView setContentSize:CGSizeMake(  (*interface->fWidgetList.begin())->getW() * _dspScrollView.zoomScale,
+                                                (*interface->fWidgetList.begin())->getH() * _dspScrollView.zoomScale)];
+
+    // No double click : lose locked box
+    if (_dspScrollView.pinchGestureRecognizer.scale != 1.
+        || _dspScrollView.pinchGestureRecognizer.velocity != 0.f)
+    {
+        _lockedBox = interface->getMainBox();
+    }
+}
+
+- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
+{
+#ifdef JACK_IOS
+    [self closeJackView];
+#endif
+}
+
+// Function called just after scroll view scrolled
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView
+{
+    // No double click : lose locked box
+    if ([_dspScrollView.panGestureRecognizer translationInView:_dspView].x != 0.f
+        && [_dspScrollView.panGestureRecognizer translationInView:_dspView].y != 0.f)
+    {
+        _lockedBox = interface->getMainBox();
+    }    
+}
+
+- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
+{    
+    return _dspView;
+}
+
+// User just double tapped somewhere in the DSP view
+- (void)doubleTap
+{
+#ifdef JACK_IOS
+    // Test Jack
+    [self closeJackView];
+#endif
+    
+    uiBox* tapedBox = interface->getBoxForPoint([_tapGesture locationInView:_dspView]);
+
+    // Avoid a strange bug
+    if (tapedBox == interface->getMainBox()
+        && _lockedBox == interface->getMainBox())
+    {
+        return;
+    }
+    
+    // Click on already locked box : zoom out
+    if (tapedBox == _lockedBox
+        && _lockedBox != interface->getMainBox())
+    {
+        _lockedBox = interface->getMainBox();
+    }
+    
+    // Else, zoom on clicked box
+    else
+    {
+        _lockedBox = interface->getBoxForPoint([_tapGesture locationInView:_dspView]);   
+    }
+    
+    [self zoomToLockedBox];
+}
+
+// Function used when only in one case : a num entry just entered in typing mode
+- (void)zoomToWidget:(FIResponder*)widget
+{    
+    CGRect rect;
+    
+    if ([widget isKindOfClass:[FITextField class]])
+    {
+        uiNumEntry* numEntry = findCorrespondingUiItem<uiNumEntry*>((FIResponder*)widget);
+        if (numEntry)
+        {
+            rect = interface->getBoxAbsoluteFrameForWidget(numEntry);
+            [_dspScrollView zoomToRect:CGRectMake(rect.origin.x + rect.size.width / 2.f, 
+                                                  rect.origin.y + rect.size.height / 2.f + _dspScrollView.window.frame.size.height / 8.f,
+                                                  1.f,
+                                                  1.f) 
+                              animated:YES];
+        }
+    }
+}
+
+- (void)setOpenWidgetPanel:(BOOL)openWidgetPanelOnLongTouch
+{
+    openWidgetPanel = openWidgetPanelOnLongTouch;
+    _openPanelChanged = YES;
+    [self updateGui];
+}
+
+#pragma mark - Audio
+
+- (void)restartAudioWithBufferSize:(int)bufferSize sampleRate:(int)sampleRate
+{
+    finterface->saveState(rcfilename);
+    
+    if (dynamic_cast<iosaudio*>(audio_device)) {
+        
+        audio_device->stop();
+        audio_device = NULL;
+        
+        [self openCoreAudio:bufferSize :sampleRate];
+        
+        DSP.init(long(sampleRate));
+    }
+   
+    finterface->recallState(rcfilename);
+}
+
+
+#pragma mark - Flipside View Controller
+
+- (void)flipsideViewControllerDidFinish:(FIFlipsideViewController *)controller
+{
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
+    {
+        [self dismissModalViewControllerAnimated:YES];
+    }
+    else
+    {
+        [self.flipsidePopoverController dismissPopoverAnimated:YES];
+        self.flipsidePopoverController = nil;
+    }
+}
+
+- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
+{
+    self.flipsidePopoverController = nil;
+}
+
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
+{
+    if ([[segue identifier] isEqualToString:@"showAlternate"]) 
+    {
+    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+        id<NSFileManagerDelegate> tmp = [segue destinationViewController];
+        [tmp setDelegate:self];
+    #else
+        [[segue destinationViewController] setDelegate:self];
+    #endif
+        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
+        {
+            UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController];
+            self.flipsidePopoverController = popoverController;
+            popoverController.delegate = self;
+        }
+    }
+}
+
+- (IBAction)togglePopover:(id)sender
+{
+    // If running in CoreAudio mode...
+    //if (dynamic_cast<iosaudio*>(audio_device))
+    {
+        if (self.flipsidePopoverController)
+        {
+            [self.flipsidePopoverController dismissPopoverAnimated:YES];
+            self.flipsidePopoverController = nil;
+        }
+        else
+        {
+            [self performSegueWithIdentifier:@"showAlternate" sender:sender];
+        }
+    }
+}
+
+
+#pragma mark - Sensors
+
+// Display widget preferences view
+- (void)showWidgetPreferencesView:(UILongPressGestureRecognizer *)gesture
+{
+    list<uiCocoaItem*>::iterator    i;
+        
+    // Deselect all widgets
+    for (i = ((CocoaUI*)(interface))->fWidgetList.begin(); i != ((CocoaUI*)(interface))->fWidgetList.end(); i++)
+    {
+        if (dynamic_cast<uiKnob*>(*i)
+            || dynamic_cast<uiSlider*>(*i)
+            || dynamic_cast<uiButton*>(*i))
+        {
+            (*i)->setSelected(NO);
+        }
+    }
+    
+    // Find corresponding uiCocoaItem
+    if ([gesture.view isKindOfClass:[FIKnob class]])
+    {
+        uiKnob* knob = findCorrespondingUiItem<uiKnob*>((FIResponder*)gesture.view);
+        if (knob)
+        {
+            _selectedWidget = knob;
+        }
+    }
+    else if ([gesture.view isKindOfClass:[FISlider class]])
+    {
+        uiSlider* slider = findCorrespondingUiItem<uiSlider*>((FIResponder*)gesture.view);
+        if (slider)
+        {
+            _selectedWidget = slider;
+        }
+    }
+    else if ([gesture.view isKindOfClass:[FIButton class]])
+    {
+        uiButton* button = findCorrespondingUiItem<uiButton*>((FIResponder*)gesture.view);
+        if (button)
+        {
+            _selectedWidget = button;
+        }
+    }
+    
+    // If no uiCocoaItem found, it's an error so we don't show the window
+    if (!_selectedWidget) return;
+    
+    // SL : 04/09/14 was added for the SF concert ? deactivated for now
+    
+    /*
+    // If widget is hidden we don't show the window
+    if (_selectedWidget->getHideOnGUI()) return;
+    */
+    
+    // Otherwise, set it selected (for selection display)
+    _selectedWidget->setSelected(YES);
+    
+    // Parameter the windows
+    [_gyroAxisSegmentedControl removeAllSegments];
+    
+    if ([gesture.view isKindOfClass:[FIKnob class]]
+        || [gesture.view isKindOfClass:[FISlider class]])
+    {
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"0" atIndex:0 animated:NO];
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"aX" atIndex:1 animated:NO];
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"aY" atIndex:2 animated:NO];
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"aZ" atIndex:3 animated:NO];
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"gX" atIndex:4 animated:NO];
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"gY" atIndex:5 animated:NO];
+        [_gyroAxisSegmentedControl insertSegmentWithTitle:@"gZ" atIndex:6 animated:NO];
+        
+        if ([CLLocationManager headingAvailable])
+        {
+            [_gyroAxisSegmentedControl insertSegmentWithTitle:@"C" atIndex:7 animated:NO];
+        }
+        
+        _gyroInvertedSwitch.hidden = NO;
+        _gyroFilteredSwitch.hidden = NO;
+        _gyroInvertedTitleLabel.hidden = NO;
+        _gyroSensibilityLabel.hidden = NO;
+        _gyroSensibilitySlider.hidden = NO;
+        _gyroSensibilityTitleLabel.hidden = NO;
+
+        _widgetPreferencesTitleLabel.text = _selectedWidget->getName();
+    }
+    
+    else if ([gesture.view isKindOfClass:[FIButton class]])
+    {
+        uiButton* button = findCorrespondingUiItem<uiButton*>((FIResponder*)gesture.view);
+        if (button)
+        {
+            [_gyroAxisSegmentedControl insertSegmentWithTitle:@"0" atIndex:0 animated:NO];
+            [_gyroAxisSegmentedControl insertSegmentWithTitle:@"Shk" atIndex:1 animated:NO];
+            
+            _gyroInvertedSwitch.hidden = YES;
+            _gyroFilteredSwitch.hidden = YES;
+            _gyroInvertedTitleLabel.hidden = YES;
+            _gyroSensibilityLabel.hidden = YES;
+            _gyroSensibilitySlider.hidden = YES;
+            _gyroSensibilityTitleLabel.hidden = YES;
+
+            _widgetPreferencesTitleLabel.text = dynamic_cast<uiButton*>(_selectedWidget)->fButton.title;
+            
+            if (_selectedWidget->getAssignationType() == kAssignationNone) _gyroAxisSegmentedControl.selectedSegmentIndex = 0;
+            else if (_selectedWidget->getAssignationType() == kAssignationShake) _gyroAxisSegmentedControl.selectedSegmentIndex = 1;
+        }
+    }
+    
+    // Display right values for parameters
+    [self updateWidgetPreferencesView];
+    
+    // Show the window
+    _widgetPreferencesView.hidden = NO;
+    
+    // Fade in
+    CATransition *animation = [CATransition animation];
+    [animation setDuration:0.5];
+    [animation setType:kCATransitionFade];
+    [animation setSubtype:kCATransitionFromLeft];
+    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];	
+    
+    [[_dspView.window layer] addAnimation:animation forKey:@"ShowWidgetPreferences"];
+ 
+#ifdef JACK_IOS
+    [self closeJackView];
+#endif
+}
+
+// Display right values for parameters
+- (void)updateWidgetPreferencesView
+{
+    // For knobs and sliders
+    if (dynamic_cast<uiKnob*>(_selectedWidget)
+        || dynamic_cast<uiSlider*>(_selectedWidget))
+    {
+        if (_selectedWidget->getAssignationType() == kAssignationNone) _gyroAxisSegmentedControl.selectedSegmentIndex = 0;
+        else if (_selectedWidget->getAssignationType() == kAssignationAccelX) _gyroAxisSegmentedControl.selectedSegmentIndex = 1;
+        else if (_selectedWidget->getAssignationType() == kAssignationAccelY) _gyroAxisSegmentedControl.selectedSegmentIndex = 2;
+        else if (_selectedWidget->getAssignationType() == kAssignationAccelZ) _gyroAxisSegmentedControl.selectedSegmentIndex = 3;
+        else if (_selectedWidget->getAssignationType() == kAssignationGyroX) _gyroAxisSegmentedControl.selectedSegmentIndex = 4;
+        else if (_selectedWidget->getAssignationType() == kAssignationGyroY) _gyroAxisSegmentedControl.selectedSegmentIndex = 5;
+        else if (_selectedWidget->getAssignationType() == kAssignationGyroZ) _gyroAxisSegmentedControl.selectedSegmentIndex = 6;
+        else if (_selectedWidget->getAssignationType() == kAssignationCompass) _gyroAxisSegmentedControl.selectedSegmentIndex = 7;
+
+        
+        //_gyroAxisSegmentedControl.selectedSegmentIndex = _selectedWidget->getAssignationType();
+    }
+    
+    // For buttons
+    else if (dynamic_cast<uiButton*>(_selectedWidget))
+    {
+        if (_selectedWidget->getAssignationType() == kAssignationNone) _gyroAxisSegmentedControl.selectedSegmentIndex = 0;
+        else if (_selectedWidget->getAssignationType() == kAssignationShake) _gyroAxisSegmentedControl.selectedSegmentIndex = 1;
+        _gyroAxisSegmentedControl.selectedSegmentIndex = _selectedWidget->getAssignationType();
+        
+    }
+    
+    // Common parameters for all types
+    _gyroInvertedSwitch.on = _selectedWidget->getAssignationInverse();
+    _gyroFilteredSwitch.on = _selectedWidget->getAssignationFiltered();
+    _gyroSensibilitySlider.value = _selectedWidget->getAssignationSensibility();
+    _gyroSensibilityLabel.text = [NSString stringWithFormat:@"%1.1f", _selectedWidget->getAssignationSensibility()];
+    _colorRSlider.value = _selectedWidget->getR();
+    _colorRLabel.text = [NSString stringWithFormat:@"%1.1f", _selectedWidget->getR()];
+    _colorGSlider.value = _selectedWidget->getG();
+    _colorGLabel.text = [NSString stringWithFormat:@"%1.1f", _selectedWidget->getG()];
+    _colorBSlider.value = _selectedWidget->getB();
+    _colorBLabel.text = [NSString stringWithFormat:@"%1.1f", _selectedWidget->getB()];
+}
+
+// Hide widget preferences view
+- (IBAction)dismissWidgetPreferencesView:(id)sender;
+{
+    // Unselect widget
+    _selectedWidget->setSelected(NO);
+    _selectedWidget = NULL;
+    
+    // Hide it
+    _widgetPreferencesView.hidden = YES;
+    
+    // Fade out
+    CATransition *animation = [CATransition animation];
+    [animation setDuration:0.5];
+    [animation setType:kCATransitionFade];
+    [animation setSubtype:kCATransitionFromLeft];
+    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];	
+    
+    [[_dspView.window layer] addAnimation:animation forKey:@"DismissWidgetPreferences"];
+}
+
+// Function called each time a parameter has been changed
+- (IBAction)widgetPreferencesChanged:(id)sender
+{
+    list<uiCocoaItem*>::iterator    i;
+    NSString*                       key;
+    NSString*                       str;
+    BOOL                            found = false;
+    
+    // If user changed the sensor assignation, program resets ref point to default values
+    if (sender == _gyroAxisSegmentedControl)
+    {
+        // Get title of selected tab for sensor assignation
+        str = [NSString stringWithString:[_gyroAxisSegmentedControl titleForSegmentAtIndex:_gyroAxisSegmentedControl.selectedSegmentIndex]];
+
+        // Set default values regarding assignation type
+        if ([str compare:@"0"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationNone);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+        else if ([str compare:@"aX"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationAccelX);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.5);
+        }
+        else if ([str compare:@"aY"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationAccelY);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.5);
+        }
+        else if ([str compare:@"aZ"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationAccelZ);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.5);
+        }
+        else if ([str compare:@"Shk"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationShake);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+        else if ([str compare:@"C"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationCompass);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+        else if ([str compare:@"gX"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationGyroX);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+        else if ([str compare:@"gY"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationGyroY);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+        else if ([str compare:@"gZ"] == NSOrderedSame)
+        {
+            _selectedWidget->setAssignationType(kAssignationGyroZ);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+        else
+        {
+            _selectedWidget->setAssignationType(kAssignationNone);
+            //_selectedWidget->setAssignationRefPointX(0.);
+            //_selectedWidget->setAssignationRefPointY(0.);
+        }
+    }
+    
+    // Write parameters in the widget object
+    _selectedWidget->setAssignationInverse(_gyroInvertedSwitch.on);
+    _selectedWidget->setAssignationFiltered(_gyroFilteredSwitch.on);
+    _selectedWidget->setAssignationSensibility(_gyroSensibilitySlider.value);
+    _gyroSensibilityLabel.text = [NSString stringWithFormat:@"%1.1f", _gyroSensibilitySlider.value];
+    
+    _selectedWidget->setColor(_colorRSlider.value, _colorGSlider.value, _colorBSlider.value);
+    _colorRLabel.text = [NSString stringWithFormat:@"%1.1f", _colorRSlider.value];
+    _colorGLabel.text = [NSString stringWithFormat:@"%1.1f", _colorGSlider.value];
+    _colorBLabel.text = [NSString stringWithFormat:@"%1.1f", _colorBSlider.value];
+    
+    // If default parameters : remove widget from list
+    if (_selectedWidget->getAssignationType() == kAssignationNone)
+    {
+        for (i = _assignatedWidgets.begin(); i != _assignatedWidgets.end(); i++)
+        {
+            if (*i == _selectedWidget)
+            {
+                _assignatedWidgets.erase(i);
+            }
+        }
+    }
+    
+    // If assignated : add widget in list if it's not the case already
+    else
+    {
+        for (i = _assignatedWidgets.begin(); i != _assignatedWidgets.end(); i++)
+        {
+            if (*i == _selectedWidget)
+            {
+                found = true;
+            }
+        }
+        if (!found) _assignatedWidgets.push_back(_selectedWidget);
+    }
+
+    // Save parameters in user defaults
+    key = [NSString stringWithFormat:@"%@-assignation-type", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setInteger:_selectedWidget->getAssignationType() + 1000 forKey:key];
+    
+    key = [NSString stringWithFormat:@"%@-assignation-inverse", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setInteger:_selectedWidget->getAssignationInverse() + 1000 forKey:key];
+
+    key = [NSString stringWithFormat:@"%@-assignation-filtered", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setInteger:_selectedWidget->getAssignationFiltered() + 1000 forKey:key];
+
+    key = [NSString stringWithFormat:@"%@-assignation-sensibility", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setFloat:_selectedWidget->getAssignationSensibility() + 1000. forKey:key];
+    
+    key = [NSString stringWithFormat:@"%@-assignation-refpoint-x", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setFloat:_selectedWidget->getAssignationRefPointX() + 1000. forKey:key];
+    
+    key = [NSString stringWithFormat:@"%@-assignation-refpoint-y", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setFloat:_selectedWidget->getAssignationRefPointY() + 1000. forKey:key];
+        
+    key = [NSString stringWithFormat:@"%@-r", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setFloat:_selectedWidget->getR() + 1000. forKey:key];
+    
+    key = [NSString stringWithFormat:@"%@-g", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setFloat:_selectedWidget->getG() + 1000. forKey:key];
+    
+    key = [NSString stringWithFormat:@"%@-b", [self urlForWidget:_selectedWidget]];
+    [[NSUserDefaults standardUserDefaults] setFloat:_selectedWidget->getB() + 1000. forKey:key];
+    
+    [[NSUserDefaults standardUserDefaults] synchronize];
+    
+    // If assignation type is not kAssignationNone, we start motion
+    if (_assignatedWidgets.size() > 0) [self startMotion];
+    else [self stopMotion];
+}
+
+// Reset widget parameters
+- (IBAction)resetWidgetPreferences:(id)sender
+{
+    _selectedWidget->resetParameters();
+    [self updateWidgetPreferencesView];
+    [self widgetPreferencesChanged:_gyroAxisSegmentedControl];
+}
+
+- (void)resetAllWidgetsPreferences
+{
+    list<uiCocoaItem*>::iterator    i;
+    
+    for (i = _assignatedWidgets.begin(); i != _assignatedWidgets.end(); i++)
+    {
+        (*i)->resetParameters();
+        _assignatedWidgets.erase(i);
+    }
+    
+    [self loadWidgetsPreferences];
+    
+    
+    for (i = interface->fWidgetList.begin(); i != interface->fWidgetList.end(); i++)
+    {
+        (*i)->resetInitialValue();
+    }
+}
+
+// At application launch time, loading preferences for all widgets
+- (void)loadWidgetsPreferences
+{
+    list<uiCocoaItem*>::iterator    i;
+    NSString*                       key;
+    NSString*                       key2;
+    NSString*                       key3;
+    int                             intValue = 0;
+    float                           floatValue = 0.;
+    
+    
+    for (i = interface->fWidgetList.begin(); i != interface->fWidgetList.end(); i++)
+    {
+        if (dynamic_cast<uiKnob*>(*i)
+            || dynamic_cast<uiSlider*>(*i)
+            || dynamic_cast<uiButton*>(*i))
+        {
+            // Sensor assignation
+            key = [NSString stringWithFormat:@"%@-assignation-type", [self urlForWidget:(*i)]];
+            intValue = [[NSUserDefaults standardUserDefaults] integerForKey:key];
+            if (intValue != 0) (*i)->setAssignationType(intValue - 1000);
+            else (*i)->setAssignationType((*i)->getInitAssignationType());
+            
+            key = [NSString stringWithFormat:@"%@-assignation-inverse", [self urlForWidget:(*i)]];
+            intValue = [[NSUserDefaults standardUserDefaults] integerForKey:key];
+            if (intValue != 0) (*i)->setAssignationInverse((bool)(intValue - 1000));
+            else (*i)->setAssignationInverse((*i)->getInitAssignationInverse());
+            
+            key = [NSString stringWithFormat:@"%@-assignation-filtered", [self urlForWidget:(*i)]];
+            intValue = [[NSUserDefaults standardUserDefaults] integerForKey:key];
+            if (intValue != 0) (*i)->setAssignationFiltered((bool)(intValue - 1000));
+            else (*i)->setAssignationFiltered((*i)->getInitAssignationFiltered());
+            
+            key = [NSString stringWithFormat:@"%@-assignation-sensibility", [self urlForWidget:(*i)]];
+            floatValue = [[NSUserDefaults standardUserDefaults] floatForKey:key];
+            if (floatValue != 0.) (*i)->setAssignationSensibility(floatValue - 1000.);
+            else (*i)->setAssignationSensibility((*i)->getInitAssignationSensibility());
+            
+            key = [NSString stringWithFormat:@"%@-assignation-refpoint-x", [self urlForWidget:(*i)]];
+            floatValue = [[NSUserDefaults standardUserDefaults] floatForKey:key];
+            if (floatValue != 0.) (*i)->setAssignationRefPointX(floatValue - 1000.);
+            else (*i)->setAssignationRefPointX((*i)->getInitAssignationRefPointX());
+                        
+            key = [NSString stringWithFormat:@"%@-assignation-refpoint-y", [self urlForWidget:(*i)]];
+            floatValue = [[NSUserDefaults standardUserDefaults] floatForKey:key];
+            if (floatValue != 0.) (*i)->setAssignationRefPointY(floatValue - 1000.);
+            else (*i)->setAssignationRefPointY((*i)->getInitAssignationRefPointY());
+            
+            // Color
+            key = [NSString stringWithFormat:@"%@-r", [self urlForWidget:(*i)]];
+            key2 = [NSString stringWithFormat:@"%@-g", [self urlForWidget:(*i)]];
+            key3 = [NSString stringWithFormat:@"%@-b", [self urlForWidget:(*i)]];
+            (*i)->setColor([[NSUserDefaults standardUserDefaults] floatForKey:key] - 1000.,
+                           [[NSUserDefaults standardUserDefaults] floatForKey:key2] - 1000.,
+                           [[NSUserDefaults standardUserDefaults] floatForKey:key3] - 1000.);
+            
+            // Default color
+            if ((*i)->getR() == -1000
+                && (*i)->getG() == -1000
+                && (*i)->getB() == -1000)
+            {
+                (*i)->setColor((*i)->getInitR(), (*i)->getInitG(), (*i)->getInitB());
+            }
+            
+            // Add in assignation list if there is a sensor assignation and / or color is not default
+            if ((*i)->getAssignationType() != 0)
+            {
+                _assignatedWidgets.push_back(*i);
+            }
+        }
+    }
+}
+
+// Start updating sensors
+- (void)startMotion
+{
+    // Motion
+    if (_motionManager == nil)
+    {
+        _motionManager = [[CMMotionManager alloc] init];
+        _sensorFilter = [[FISensorFilter alloc] initWithSampleRate:kMotionUpdateRate * 10 cutoffFrequency:100];
+        [_motionManager startAccelerometerUpdates];
+        [_motionManager startGyroUpdates];
+        _motionTimer = [NSTimer scheduledTimerWithTimeInterval:1./kMotionUpdateRate
+                                                        target:self 
+                                                      selector:@selector(updateMotion)
+                                                      userInfo:nil 
+                                                       repeats:YES];
+    }
+    
+    // Location
+    if (_locationManager == nil)
+    {
+        _locationManager = [[CLLocationManager alloc] init];
+        _locationManager.delegate = self;
+        [_locationManager startUpdatingHeading];
+    }
+}
+
+// Stop updating sensors
+- (void)stopMotion
+{
+    // Motion
+    if (_motionManager != nil)
+    {
+        [_motionManager stopAccelerometerUpdates];
+        [_motionManager stopGyroUpdates];
+        [_motionManager release];
+        _motionManager = nil;
+        [_motionTimer invalidate];
+    }
+    
+    // Location
+    if (_locationManager)
+    {
+        [_locationManager stopUpdatingHeading];
+        [_locationManager release];
+        _locationManager = nil;
+    }
+}
+
+- (void)endBlockShake
+{
+    _blockShake = NO;
+}
+
+// The function periodically called to refresh motion sensors
+- (void)updateMotion
+{
+    list<uiCocoaItem*>::iterator    i;
+    float                           coef = 0.f;
+    float                           value = 0.f;
+    float                           a = 0.;
+    float                           b = 0.;
+    float                           sign = 1.;
+    
+    [_sensorFilter addAccelerationX:_motionManager.accelerometerData.acceleration.x
+                                  y:_motionManager.accelerometerData.acceleration.y
+                                  z:_motionManager.accelerometerData.acceleration.z];
+    
+    [_sensorFilter addGyroX:_motionManager.gyroData.rotationRate.x / 10.
+                          y:_motionManager.gyroData.rotationRate.y / 10.
+                          z:_motionManager.gyroData.rotationRate.z / 10.];
+
+    for (i = _assignatedWidgets.begin(); i != _assignatedWidgets.end(); i++)
+    {
+        if ((dynamic_cast<uiKnob*>(*i) && !dynamic_cast<uiKnob*>(*i)->fKnob.motionBlocked)
+            || (dynamic_cast<uiSlider*>(*i) && !dynamic_cast<uiSlider*>(*i)->fSlider.motionBlocked)
+            || dynamic_cast<uiButton*>(*i))
+        {
+            coef = 0.f;
+            
+            if ((*i)->getAssignationType() == kAssignationAccelX)
+            {
+                if ((*i)->getAssignationFiltered()) coef = _sensorFilter.xAccel;//* (*i)->getAssignationSensibility();
+                else coef = _motionManager.accelerometerData.acceleration.x;//* (*i)->getAssignationSensibility();
+            }
+            else if ((*i)->getAssignationType() == kAssignationAccelY)
+            {
+                if ((*i)->getAssignationFiltered()) coef = _sensorFilter.yAccel;// * (*i)->getAssignationSensibility();
+                else coef = _motionManager.accelerometerData.acceleration.y;// * (*i)->getAssignationSensibility();
+            }
+            else if ((*i)->getAssignationType() == kAssignationAccelZ)
+            {
+                if ((*i)->getAssignationFiltered()) coef = _sensorFilter.zAccel;// * (*i)->getAssignationSensibility();
+                else coef = _motionManager.accelerometerData.acceleration.z;// * (*i)->getAssignationSensibility();
+            }
+            else if ((*i)->getAssignationType() == kAssignationGyroX)
+            {
+                if ((*i)->getAssignationFiltered()) coef = _sensorFilter.xGyro;// * (*i)->getAssignationSensibility();
+                else coef = _motionManager.gyroData.rotationRate.x / 10.;// * (*i)->getAssignationSensibility();
+            }
+            else if ((*i)->getAssignationType() == kAssignationGyroY)
+            {
+                if ((*i)->getAssignationFiltered()) coef = _sensorFilter.yGyro;// * (*i)->getAssignationSensibility();
+                else coef = _motionManager.gyroData.rotationRate.y / 10.;// * (*i)->getAssignationSensibility();
+            }
+            else if ((*i)->getAssignationType() == kAssignationGyroZ)
+            {
+                if ((*i)->getAssignationFiltered()) coef = _sensorFilter.zGyro;// * (*i)->getAssignationSensibility();
+                else coef = _motionManager.gyroData.rotationRate.z / 10.;// * (*i)->getAssignationSensibility();
+            }
+            else if ((*i)->getAssignationType() == kAssignationShake)
+            {
+                // Shake detection
+                if (!_blockShake
+                    && (fabsf(_sensorFilter.xAccel) > 1.4
+                        || fabsf(_sensorFilter.yAccel) > 1.4
+                        || fabsf(_sensorFilter.zAccel) > 1.4))
+                {
+                    coef = 1.f;
+                    _blockShake = YES;
+                    [self performSelector:@selector(endBlockShake) withObject:nil afterDelay:0.3];
+                }
+                else
+                {
+                    coef = 0.f;
+                }
+            }
+            else
+            {
+                continue;
+            }
+            
+            if ((*i)->getAssignationInverse()) sign = -1.;
+            else sign = 1.;
+            
+            ////
+            if (dynamic_cast<uiSlider*>(*i))
+            {
+                value = [self mapping3WithA:sign * coef * (*i)->getAssignationSensibility()
+                                         la:-1.
+                                         ma:(*i)->getAssignationRefPointX()
+                                         ha:1.
+                                         lv:dynamic_cast<uiSlider*>(*i)->fSlider.min
+                                         mv:(*i)->getAssignationRefPointY()
+                                         hv:dynamic_cast<uiSlider*>(*i)->fSlider.max];
+            }
+            else if (dynamic_cast<uiKnob*>(*i))
+            {
+                value = [self mapping3WithA:sign * coef * (*i)->getAssignationSensibility()
+                                         la:-1.
+                                         ma:(*i)->getAssignationRefPointX()
+                                         ha:1.
+                                         lv:dynamic_cast<uiKnob*>(*i)->fKnob.min
+                                         mv:(*i)->getAssignationRefPointY()
+                                         hv:dynamic_cast<uiKnob*>(*i)->fKnob.max];
+            }
+            
+            //NSLog(@"val %f", value);
+            ////
+            
+            // CASE 1: two curves
+            /*float x1 = 0.;
+            float y1 = 0.;
+            float x2 = 0.;
+            float y2 = 0.;
+            float va = sign * coef;//* (*i)->getAssignationSensibility();    // Accelerometer value
+            float la = -1.;//* (*i)->getAssignationSensibility();     // Down accelerometer limit
+            float ha = 1.;//* (*i)->getAssignationSensibility();      // Top accelerometer limit
+            float x = sign * (*i)->getAssignationRefPointX(); // (*i)->getAssignationSensibility(); // ref point x
+            float y;
+            
+            NSLog(@"%f %f", (*i)->getAssignationRefPointX(), (*i)->getAssignationRefPointY());
+            
+            if (dynamic_cast<uiKnob*>(*i))
+            {
+                y = (((*i)->getAssignationRefPointY()) / (1.) * (dynamic_cast<uiKnob*>(*i)->fKnob.max - dynamic_cast<uiKnob*>(*i)->fKnob.min) + dynamic_cast<uiKnob*>(*i)->fKnob.min);
+            }
+            else if (dynamic_cast<uiSlider*>(*i))
+            {
+                y = (((*i)->getAssignationRefPointY()) / (1.) * (dynamic_cast<uiSlider*>(*i)->fSlider.max - dynamic_cast<uiSlider*>(*i)->fSlider.min) + dynamic_cast<uiSlider*>(*i)->fSlider.min);
+            }
+            
+            float ls; // Down slider limit
+            float hs; // TOp slider limit
+            if (dynamic_cast<uiKnob*>(*i))
+            {
+                ls = dynamic_cast<uiKnob*>(*i)->fKnob.min;
+                hs = dynamic_cast<uiKnob*>(*i)->fKnob.max;
+            }
+            else if (dynamic_cast<uiSlider*>(*i))
+            {
+                ls = dynamic_cast<uiSlider*>(*i)->fSlider.min;
+                hs = dynamic_cast<uiSlider*>(*i)->fSlider.max;
+            }
+            
+            //NSLog(@"%f %f", va, x);
+
+            if (va <= x)
+            {
+                //NSLog(@"<=");
+                x1 = la / (*i)->getAssignationSensibility();
+                x2 = x;
+                y1 = ls;
+                y2 = y;
+                
+                if (x1 >= x || fabs(x1 - x) < 0.01) x1 = x - 0.01;
+            }
+            else if (va > x)
+            {
+                //NSLog(@">");
+                x1 = x;
+                x2 = ha / (*i)->getAssignationSensibility();
+                y1 = y;
+                y2 = hs;
+                
+                if (x2 <= x || fabs(x2 - x) < 0.01) x2 = x + 0.01;
+            }
+
+            if (x1 == x2) a = 0.;
+            else a = (y2 - y1) / (x2 - x1);
+            b = y1 - a * x1;
+            value = a * va + b;*/
+            
+            /*NSLog(@"va %f", va);
+            NSLog(@"la %f - ha %f - x %f - y %f - ls %f - hs %f", la, ha, x, y, ls, hs);
+            NSLog(@"%f %f %f %f", x1, x2, y1, y2);
+            NSLog(@"%f %f", a, b);
+            NSLog(@"assignation %f %f", (*i)->getAssignationRefPointX(), (*i)->getAssignationRefPointY());*/
+            
+            // CASE 2: simple offset
+            /*a = sign * (*i)->getAssignationSensibility();
+            b = (*i)->getAssignationRefPointY() - a * (*i)->getAssignationRefPointX();
+            
+            value = a * coef + b;*/
+            
+            /*if (dynamic_cast<uiKnob*>(*i))
+            {
+                value = value * (dynamic_cast<uiKnob*>(*i)->fKnob.max - dynamic_cast<uiKnob*>(*i)->fKnob.min) + dynamic_cast<uiKnob*>(*i)->fKnob.min;
+            }
+            else if (dynamic_cast<uiSlider*>(*i))
+            {
+                value = value * (dynamic_cast<uiSlider*>(*i)->fSlider.max - dynamic_cast<uiSlider*>(*i)->fSlider.min) + dynamic_cast<uiSlider*>(*i)->fSlider.min;
+            }
+            else if (dynamic_cast<uiButton*>(*i))
+            {
+                if (coef == 0.f)
+                {
+                    continue;
+                }
+                else if (coef == 1.f && dynamic_cast<uiButton*>(*i)->fButton.type == kPushButtonType)
+                {
+                    value = 1.f;
+                }
+                else if (coef == 1.f && dynamic_cast<uiButton*>(*i)->fButton.type == kToggleButtonType)
+                {
+                    if (dynamic_cast<uiButton*>(*i)->fButton.value == 1) value = 0;
+                    else if (dynamic_cast<uiButton*>(*i)->fButton.value == 0) value = 1;
+                }
+            }*/
+   
+            //NSLog(@"va %f", va);
+            //NSLog(@"VALUE %f", value);
+            
+            (*i)->modifyZone(value);
+            (*i)->reflectZone();
+            
+            // Force button refresh (otherwise nothing happens)
+            if (dynamic_cast<uiButton*>(*i) && dynamic_cast<uiButton*>(*i)->fButton.type == kPushButtonType)
+            {
+                dynamic_cast<uiButton*>(*i)->fButton.value = value;
+                [dynamic_cast<uiButton*>(*i)->fButton setNeedsDisplay];
+            }
+        }
+    }
+}
+
+- (float)mapping2WithA:(float)a la:(float)la ha:(float)ha lv:(float)lv hv:(float)hv
+{
+    if (a < la)
+    {
+        return lv;
+    }
+    else if (a > ha)
+    {
+        return hv;
+    }
+    else
+    {
+        return (a - la) / (ha - la) * (hv - lv) + lv;
+    }
+}
+
+- (float)mapping3WithA:(float)a la:(float)la ma:(float)ma ha:(float)ha lv:(float)lv mv:(float)mv hv:(float)hv
+{
+    if (a > ma)
+    {
+        return [self mapping2WithA:a la:ma ha:ha lv:mv hv:hv];
+    }
+    else
+    {
+        return [self mapping2WithA:a la:la ha:ma lv:lv hv:mv];
+    }
+}
+
+
+// The function called when compass has moved
+- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)heading
+{
+    list<uiCocoaItem*>::iterator    i;
+    float                           coef = 0.f;
+    float                           value = 0.f;
+    
+    [_sensorFilter addHeading:heading.magneticHeading];
+
+    for (i = _assignatedWidgets.begin(); i != _assignatedWidgets.end(); i++)
+    {
+        if (dynamic_cast<uiKnob*>(*i) || dynamic_cast<uiSlider*>(*i) || dynamic_cast<uiButton*>(*i))
+        {
+            coef = 0.f;
+            
+            if ((*i)->getAssignationType() == kAssignationCompass)
+            {
+                coef = (int)round(_sensorFilter.heading * (*i)->getAssignationSensibility() + (*i)->getAssignationRefPointY()) % 360;
+                value = coef / 360.f;
+                if ((*i)->getAssignationInverse()) value = 1.f - value;
+                
+                if (dynamic_cast<uiKnob*>(*i))
+                {
+                    value = value * (dynamic_cast<uiKnob*>(*i)->fKnob.max - dynamic_cast<uiKnob*>(*i)->fKnob.min) + dynamic_cast<uiKnob*>(*i)->fKnob.min;
+                }
+                else if (dynamic_cast<uiSlider*>(*i))
+                {
+                    value = value * (dynamic_cast<uiSlider*>(*i)->fSlider.max - dynamic_cast<uiSlider*>(*i)->fSlider.min) + dynamic_cast<uiSlider*>(*i)->fSlider.min;
+                }
+                
+                (*i)->modifyZone(value);
+                (*i)->reflectZone();
+            }
+        }
+    }
+}
+
+// Error updating compass value
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
+{
+    if ([error code] == kCLErrorDenied)
+    {
+        [manager stopUpdatingHeading];
+    }
+    else if ([error code] == kCLErrorHeadingFailure)
+    {
+    }
+}
+
+- (NSString*)urlForWidget:(uiCocoaItem*)widget
+{
+    list<uiCocoaItem*>::iterator    i = interface->fWidgetList.end();
+    uiCocoaItem*                    currentWidget = widget;
+    NSString*                       result = @"";
+    
+    while (currentWidget != *interface->fWidgetList.begin())
+    {
+        if (currentWidget->getParent() == (*i))
+        {
+            result = [NSString stringWithFormat:@"%@-%@", (*i)->getName(), result];
+            currentWidget = (*i);
+        }
+        
+        i--;
+    }
+    
+    result = [NSString stringWithFormat:@"%@-%@", result, widget->getName()];
+    
+    return result;
+}
+
+#ifdef JACK_IOS
+// Test Jack
+- (void)openJackView
+{
+    if (_jackView) return;
+    
+    // Construct view
+    _jackView = [[JackView alloc] initWithFrame:CGRectMake(0,
+                                                           _dspScrollView.frame.size.height,
+                                                           _dspScrollView.frame.size.width,
+                                                           kJackViewHeight)];
+    _jackView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+    
+    // Load client in view
+    [_jackView loadJackClient:dynamic_cast<jackaudio*>(audio_device)->get_client()];
+    
+    // Insert view in super view
+    [_dspScrollView.superview addSubview:_jackView];
+    
+    // Gesture recognizers
+    [_swipeRecognizer removeTarget:self action:@selector(openJackView)];
+    [_swipeRecognizer addTarget:self action:@selector(closeJackView)];
+    _swipeRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
+    
+    // Animation
+    [UIView animateWithDuration:kJackViewAnimationDuration
+                    delay:0.0
+                    options:UIViewAnimationOptionCurveLinear
+                    animations:^
+     {
+         [_jackView setFrame:CGRectMake(0,
+                                        _dspScrollView.frame.size.height - kJackViewHeight + 44,
+                                        _dspScrollView.frame.size.width,
+                                        kJackViewHeight)];
+     }
+                     completion:^(BOOL finished)
+     {
+     }];
+}
+
+- (void)closeJackView
+{
+    if (!_jackView) return;
+    
+    // Gesture recognizers
+    [_swipeRecognizer removeTarget:self action:@selector(closeJackView)];
+    [_swipeRecognizer addTarget:self action:@selector(openJackView)];
+    _swipeRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
+        
+    // Animation
+    [UIView animateWithDuration:kJackViewAnimationDuration
+                          delay:0.0
+                        options:UIViewAnimationOptionCurveLinear
+                     animations:^
+     {
+         [_jackView setFrame:CGRectMake(0,
+                                        _dspScrollView.frame.size.height + 44,
+                                        _dspScrollView.frame.size.width,
+                                        kJackViewHeight)];
+     }
+                     completion:^(BOOL finished)
+     {
+         [_jackView removeFromSuperview];
+         [_jackView release];
+         _jackView = nil;
+     }];
+}
+
+- (void)autoResizeJackViews
+{
+    if (_jackView)
+    {
+        [_jackView setFrame:CGRectMake(0,
+                                       _dspScrollView.frame.size.height - kJackViewHeight + 44,
+                                       _dspScrollView.frame.size.width,
+                                       kJackViewHeight)];
+    }
+    
+    if (_jackButton)
+    {
+        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
+        {
+            [_jackButton setFrame:CGRectMake(_dspScrollView.frame.size.width - 70 - 50,
+                                             _dspScrollView.frame.size.height,
+                                             70,
+                                             32)];
+        }
+        else
+        {
+            [_jackButton setFrame:CGRectMake(_dspScrollView.frame.size.width - 70 - 10,
+                                             _dspScrollView.frame.size.height,
+                                             70,
+                                             32)];
+        }
+    }
+}
+
+#endif
+ at end
diff --git a/architecture/iOS/iOS/FIResponder.h b/architecture/iOS/iOS/FIResponder.h
new file mode 100644
index 0000000..4d254bd
--- /dev/null
+++ b/architecture/iOS/iOS/FIResponder.h
@@ -0,0 +1,76 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on DCControls - https://github.com/domesticcatsoftware/DCControls
+ Copyright (C) 2011 by Patrick Richards - http://domesticcat.com.au/
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ************************************************************************
+ ************************************************************************/
+
+
+#import <UIKit/UIKit.h>
+
+#define FIDegreesToRadians(x) (M_PI * (x) / 180.0)
+#define FIRadiansToDegrees(x) ((x) * 180.0 / M_PI)
+
+ at protocol FIResponderDelegate <NSObject>
+
+ at required
+
+- (void)responderValueDidChange:(float)value sender:(id)sender;
+
+ at end
+
+
+ at interface FIResponder : UIControl
+
+ at property (nonatomic, assign) id delegate;
+ at property (nonatomic, retain) UIColor *color;			// default: black
+ at property CGFloat backgroundColorAlpha;					// default: 0.3
+
+ at property (nonatomic, retain) UIFont *labelFont;		// default: bold, system, 12.5
+ at property (nonatomic, retain) UIColor *labelColor;		// default: use self.color
+ at property CGPoint labelOffset;							// default: CGPointZero
+
+ at property CGFloat min;									// default: 0.0
+ at property CGFloat max;									// default: 1.0
+ at property (nonatomic) CGFloat value;					// default: 0.0
+ at property (nonatomic) CGFloat step;                     // default: 0.1
+ at property (assign, nonatomic) NSString* suffixe;        // default: @""
+
+ at property BOOL displaysValue;							// default: YES
+ at property BOOL allowsGestures;							// default: YES
+ at property BOOL responderSelected;                       // default: NO
+ at property BOOL motionBlocked;                           // default: NO
+ at property BOOL assignated;                              // default: NO
+ at property BOOL hideOnGUI;                               // default: NO
+
+- (id)initWithDelegate:(id)aDelegate;
+
+- (void)context:(CGContextRef)context addRoundedRect:(CGRect)rect cornerRadius:(float)cornerRadius;
+
+ at end
diff --git a/architecture/iOS/iOS/FIResponder.mm b/architecture/iOS/iOS/FIResponder.mm
new file mode 100644
index 0000000..b649564
--- /dev/null
+++ b/architecture/iOS/iOS/FIResponder.mm
@@ -0,0 +1,143 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on DCControls - https://github.com/domesticcatsoftware/DCControls
+ Copyright (C) 2011 by Patrick Richards - http://domesticcat.com.au/
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIResponder.h"
+
+ at implementation FIResponder
+
+ at synthesize delegate;
+ at synthesize color, backgroundColorAlpha;
+ at synthesize labelFont, labelColor, labelOffset;
+ at synthesize min, max, value, step;
+ at synthesize displaysValue, allowsGestures;
+ at synthesize suffixe;
+ at synthesize responderSelected;
+ at synthesize motionBlocked;
+ at synthesize assignated;
+
+- (void)dealloc
+{
+	delegate = nil;
+	[color release];
+	[labelFont release];
+	[labelColor release];
+    [suffixe release];
+    
+	[super dealloc];
+}
+
+#pragma mark -
+
+- (id)initWithDelegate:(id)aDelegate
+{
+	if ((self = [super init]))
+	{
+		self.delegate = aDelegate;
+        
+		// setup defaults
+		self.backgroundColor = [UIColor blackColor];
+		self.backgroundColorAlpha = 0.3;
+		self.color = [UIColor blueColor];
+		self.min = 0.0;
+		self.max = 1.0;
+		self.displaysValue = YES;
+		self.allowsGestures = YES;
+		self.labelFont = [UIFont boldSystemFontOfSize:12.5];
+        self.step = 0.1;
+        self.value = 0.0;
+		self.clipsToBounds = NO;
+		self.opaque = YES;
+        self.suffixe = [[NSString alloc] initWithString:@""];
+        self.responderSelected = NO;
+        self.assignated = NO;
+        self.motionBlocked = NO;
+        self.hideOnGUI = NO;
+	}
+    
+	return self;
+}
+
+- (void)setValue:(CGFloat)newValue
+{
+	if (newValue > self.max)
+		value = self.max;
+	else if (newValue < self.min)
+		value = self.min;
+	else
+		value = newValue;
+	if (self.delegate)
+		[self.delegate responderValueDidChange:self.value sender:self];
+    
+	[self setNeedsDisplay];
+}
+
+#pragma mark -
+#pragma mark Helper Methods
+
+- (void)context:(CGContextRef)c addRoundedRect:(CGRect)rect cornerRadius:(float)cornerRadius
+{
+	rect.size.width += 0.5;
+	int x_left = rect.origin.x;
+	int x_left_center = rect.origin.x + cornerRadius;
+	int x_right_center = rect.origin.x + rect.size.width - cornerRadius;
+	int x_right = rect.origin.x + rect.size.width;
+	int y_top = rect.origin.y;
+	int y_top_center = rect.origin.y + cornerRadius;
+	int y_bottom_center = rect.origin.y + rect.size.height - cornerRadius;
+	int y_bottom = rect.origin.y + rect.size.height;
+    
+	/* Begin! */
+	CGContextBeginPath(c);
+	CGContextMoveToPoint(c, x_left, y_top_center);
+    
+	/* First corner */
+	CGContextAddArcToPoint(c, x_left, y_top, x_left_center, y_top, cornerRadius);
+	CGContextAddLineToPoint(c, x_right_center, y_top);
+    
+	/* Second corner */
+	CGContextAddArcToPoint(c, x_right, y_top, x_right, y_top_center, cornerRadius);
+	CGContextAddLineToPoint(c, x_right, y_bottom_center);
+    
+	/* Third corner */
+	CGContextAddArcToPoint(c, x_right, y_bottom, x_right_center, y_bottom, cornerRadius);
+	CGContextAddLineToPoint(c, x_left_center, y_bottom);
+    
+	/* Fourth corner */
+	CGContextAddArcToPoint(c, x_left, y_bottom, x_left, y_bottom_center, cornerRadius);
+	CGContextAddLineToPoint(c, x_left, y_top_center);
+    
+	/* Done */
+	CGContextClosePath(c);	
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIScrollView.h b/architecture/iOS/iOS/FIScrollView.h
new file mode 100644
index 0000000..937067b
--- /dev/null
+++ b/architecture/iOS/iOS/FIScrollView.h
@@ -0,0 +1,25 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+ at interface FIScrollView : UIScrollView
+{
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FIScrollView.mm b/architecture/iOS/iOS/FIScrollView.mm
new file mode 100644
index 0000000..781fa0c
--- /dev/null
+++ b/architecture/iOS/iOS/FIScrollView.mm
@@ -0,0 +1,58 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIScrollView.h"
+#import "FIBox.h"
+
+ at implementation FIScrollView
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+    }
+    return self;
+}
+
+- (void)awakeFromNib
+{
+    self.canCancelContentTouches = NO;
+    self.delaysContentTouches = NO;
+}
+
+-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
+{
+    return YES;
+}
+
+- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
+{
+    if ([view isKindOfClass:[FIBox class]])
+    {
+        return NO;
+    }
+    else
+    {
+        return YES;
+    }
+    
+    return YES;
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FISensorFilter.h b/architecture/iOS/iOS/FISensorFilter.h
new file mode 100644
index 0000000..76c2c1c
--- /dev/null
+++ b/architecture/iOS/iOS/FISensorFilter.h
@@ -0,0 +1,47 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on Apple AccelerometerGraph - http://developer.apple.com/library/ios/#samplecode/AccelerometerGraph
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ ************************************************************************
+ ************************************************************************/
+
+
+#import <Foundation/Foundation.h>
+
+ at interface FISensorFilter : NSObject
+{
+    double      _filterConstant;
+}
+
+ at property(nonatomic, assign) float xAccel;
+ at property(nonatomic, assign) float yAccel;
+ at property(nonatomic, assign) float zAccel;
+ at property(nonatomic, assign) float xGyro;
+ at property(nonatomic, assign) float yGyro;
+ at property(nonatomic, assign) float zGyro;
+ at property(nonatomic, assign) float heading;
+
+- (id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq;
+- (void)addAccelerationX:(float)x y:(float)y z:(float)z;
+- (void)addGyroX:(float)x y:(float)y z:(float)z;
+- (void)addHeading:(float)h;
+
+ at end
diff --git a/architecture/iOS/iOS/FISensorFilter.mm b/architecture/iOS/iOS/FISensorFilter.mm
new file mode 100644
index 0000000..9cd4fbb
--- /dev/null
+++ b/architecture/iOS/iOS/FISensorFilter.mm
@@ -0,0 +1,84 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on Apple AccelerometerGraph - http://developer.apple.com/library/ios/#samplecode/AccelerometerGraph
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ ************************************************************************
+ ************************************************************************/
+
+
+#import "FISensorFilter.h"
+
+ at implementation FISensorFilter
+
+ at synthesize xAccel;
+ at synthesize yAccel;
+ at synthesize zAccel;
+ at synthesize xGyro;
+ at synthesize yGyro;
+ at synthesize zGyro;
+ at synthesize heading;
+
+-(id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq
+{
+	self = [super init];
+    
+	if(self != nil)
+	{
+		double dt = 1.0 / rate;
+		double RC = 1.0 / freq;
+		_filterConstant = dt / (dt + RC);
+        self.xAccel = 0.;
+        self.yAccel = 0.;
+        self.zAccel = 0.;
+        self.xGyro = 0.;
+        self.yGyro = 0.;
+        self.zGyro = 0.;
+        self.heading = 0.;
+	}
+	return self;
+}
+
+- (void)addAccelerationX:(float)x y:(float)y z:(float)z
+{
+	double alpha = _filterConstant;
+	
+	self.xAccel = x * alpha + self.xAccel * (1.0 - alpha);
+	self.yAccel = y * alpha + self.yAccel * (1.0 - alpha);
+	self.zAccel = z * alpha + self.zAccel * (1.0 - alpha);
+}
+
+- (void)addGyroX:(float)x y:(float)y z:(float)z
+{
+	double alpha = _filterConstant;
+	
+	self.xGyro = x * alpha + self.xGyro * (1.0 - alpha);
+	self.yGyro = y * alpha + self.yGyro * (1.0 - alpha);
+	self.zGyro = z * alpha + self.zGyro * (1.0 - alpha);
+}
+
+- (void)addHeading:(float)h
+{
+	double alpha = _filterConstant;
+	
+	self.heading = h * alpha + self.heading * (1.0 - alpha);
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FISlider.h b/architecture/iOS/iOS/FISlider.h
new file mode 100644
index 0000000..eaaf835
--- /dev/null
+++ b/architecture/iOS/iOS/FISlider.h
@@ -0,0 +1,58 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on DCControls - https://github.com/domesticcatsoftware/DCControls
+ Copyright (C) 2011 by Patrick Richards - http://domesticcat.com.au/
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ************************************************************************
+ ************************************************************************/
+
+
+#import "FIResponder.h"
+#import "FIHint.h"
+
+ at interface FISlider : FIResponder
+{
+	CGFloat touchHandleOffset;
+    FIHint* _hint;
+}
+
+ at property CGFloat handleSize;				// default: longest side / 6 (minimum of 35.0)
+ at property CGFloat cornerRadius;				// default: 3.0
+ at property BOOL isHorizontalSlider;			// default: NO
+ at property BOOL biDirectional;				// default: NO
+
+- (id)initWithDelegate:(id)aDelegate;
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
+
+- (CGRect)rectForHandle;
+
+- (void)updateHint;
+
+ at end
diff --git a/architecture/iOS/iOS/FISlider.mm b/architecture/iOS/iOS/FISlider.mm
new file mode 100644
index 0000000..0e9562d
--- /dev/null
+++ b/architecture/iOS/iOS/FISlider.mm
@@ -0,0 +1,434 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+/************************************************************************
+ ************************************************************************
+ Based on DCControls - https://github.com/domesticcatsoftware/DCControls
+ Copyright (C) 2011 by Patrick Richards - http://domesticcat.com.au/
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FISlider.h"
+
+#define kStdSliderHintSpace         10
+
+ at implementation FISlider
+ at synthesize handleSize, cornerRadius, isHorizontalSlider, biDirectional;
+
+
+#pragma mark -
+#pragma mark Init
+
+- (id)initWithDelegate:(id)aDelegate
+{
+	if ((self = [super initWithDelegate:aDelegate]))
+	{
+        _hint = nil;
+		// add the double tap gesture for jumping the value straight to that point
+		UITapGestureRecognizer *doubleTapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)] autorelease];
+		doubleTapGesture.numberOfTapsRequired = 2;
+		[self addGestureRecognizer:doubleTapGesture];
+        
+		self.cornerRadius = 3.0;
+	}
+	
+	return self;
+}
+
+- (void)dealloc
+{
+    if (_hint) [_hint dealloc];
+    [super dealloc];
+}
+
+// to setup handle size
+- (void)setFrame:(CGRect)frame
+{
+	[super setFrame:frame];
+
+	if (self.handleSize < 35.0)
+		self.handleSize = 35.0;
+}
+
+
+#pragma mark -
+#pragma mark Touch Handling
+
+- (void)updateHint
+{
+    if (_hint)
+    {
+        UIView*     scrollView = self.superview.superview.superview;
+        CGRect      handleRect = [self rectForHandle];
+        CGRect      absHandleRect = [self convertRect:handleRect
+                                               toView:scrollView];
+        
+        _hint.title = [NSString stringWithFormat:@"%2.1f%@", self.value, self.suffixe];
+        
+        // Top
+        if (absHandleRect.origin.y >= _hint.frame.size.height + kStdSliderHintSpace
+            && absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f + _hint.frame.size.width <= scrollView.frame.size.width
+            && absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f >= 0.f)
+        {
+            _hint.position = 0;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f,
+                                       absHandleRect.origin.y - _hint.frame.size.height - kStdSliderHintSpace,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        // Left
+        else if (absHandleRect.origin.x >= _hint.frame.size.width + kStdSliderHintSpace)
+        {
+            _hint.position = 2;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x - _hint.frame.size.width - kStdSliderHintSpace,
+                                       absHandleRect.origin.y,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        // Right
+        else if (scrollView.frame.size.width - absHandleRect.origin.x - absHandleRect.size.width >= _hint.frame.size.width + kStdSliderHintSpace)
+        {
+            _hint.position = 3;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x + absHandleRect.size.width + kStdSliderHintSpace,
+                                       absHandleRect.origin.y,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        // Bottom
+        else
+        {
+            _hint.position = 1;
+            [_hint setFrame:CGRectMake(absHandleRect.origin.x + (absHandleRect.size.width - _hint.frame.size.width) / 2.f,
+                                       absHandleRect.origin.y + absHandleRect.size.height + kStdSliderHintSpace,
+                                       _hint.frame.size.width,
+                                       _hint.frame.size.height)];
+        }
+        
+        [_hint setNeedsDisplay];
+    }
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+	UITouch *touch = [touches anyObject];
+	CGPoint touchPosition = [touch locationInView:self];
+	CGFloat handleOrigin;
+	CGFloat valueInternal = (self.value - self.min) / (self.max - self.min);
+        
+    self.motionBlocked = YES;
+    
+	if (self.isHorizontalSlider)
+		handleOrigin = (self.bounds.size.width - self.handleSize) * valueInternal;
+	else
+		handleOrigin = self.bounds.size.height - self.handleSize - (self.bounds.size.height - self.handleSize) * valueInternal;
+    
+	// if the touch is inside the handle then save the offset of the touch from the handle
+	if ((self.isHorizontalSlider && touchPosition.x > handleOrigin && touchPosition.x < handleOrigin + handleSize)
+		|| (!self.isHorizontalSlider && touchPosition.y > handleOrigin && touchPosition.y < handleOrigin + handleSize))
+	{
+		touchHandleOffset = (self.isHorizontalSlider) ? touchPosition.x - handleOrigin : touchPosition.y - handleOrigin;
+	}
+	else
+	{
+		// set the handle offset to -1 so touchesmoved events are ignored
+		touchHandleOffset = -1;
+	}
+    
+    if (!_hint)
+    {
+        _hint = [[FIHint alloc] init];
+        [self.superview.superview.superview addSubview:_hint];
+    }
+    
+    if (_hint)
+    {
+        _hint.title = [NSString stringWithFormat:@"%2.1f%@", self.value, self.suffixe];
+        [self updateHint];
+    }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+	if (touchHandleOffset == -1)
+		return;
+
+    self.motionBlocked = YES;
+    
+	UITouch *touch = [touches anyObject];
+	CGPoint touchPosition = [touch locationInView:self];
+    
+	CGFloat newValue;
+    
+	if (self.isHorizontalSlider)
+		newValue = (touchPosition.x - touchHandleOffset) / (self.bounds.size.width - self.handleSize);
+	else
+		newValue = 1 - (touchPosition.y - touchHandleOffset) / (self.bounds.size.height - self.handleSize);
+
+	[self setValue:self.min + newValue * (self.max - self.min)];
+
+    [self updateHint];
+}
+
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    self.motionBlocked = NO;
+    
+    if (_hint)
+    {
+        [_hint removeFromSuperview];
+        [_hint release];
+        _hint = nil;
+    }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    self.motionBlocked = NO;
+    
+    if (_hint)
+    {
+        [_hint removeFromSuperview];
+        [_hint release];
+        _hint = nil;
+    }
+}
+
+- (void)doubleTap:(UIGestureRecognizer *)gesture
+{
+	if (!self.allowsGestures)
+		return;
+	
+	CGPoint tapPoint = [gesture locationInView:self];	
+    CGRect handleRect = [self rectForHandle];
+    
+    if (self.isHorizontalSlider)
+    {
+        if (tapPoint.x > handleRect.origin.x + handleRect.size.width / 2.f)
+        {
+            self.value = self.value + self.step;
+        }
+        else if (tapPoint.x < handleRect.origin.x + handleRect.size.width / 2.f)
+        {
+            self.value = self.value - self.step;
+        }
+    }
+    else
+    {
+        if (tapPoint.y < handleRect.origin.y + handleRect.size.height / 2.f)
+        {
+            self.value = self.value + self.step;
+        }
+        else if (tapPoint.y > handleRect.origin.y + handleRect.size.height / 2.f)
+        {
+            self.value = self.value - self.step;
+        }
+    }
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+- (void)drawRect:(CGRect)rect
+{
+    if (self.hideOnGUI) return;
+    
+	CGContextRef context = UIGraphicsGetCurrentContext();
+	CGRect boundsRect = self.bounds;
+	const CGFloat *colorComponents = CGColorGetComponents(self.color.CGColor);
+	UIColor *backgroundColor = [UIColor colorWithRed:colorComponents[0]
+											   green:colorComponents[1]
+												blue:colorComponents[2]
+											   alpha:self.backgroundColorAlpha];
+	UIColor *lighterBackgroundColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1.];
+
+	// draw background of slider
+    self.backgroundColor = [UIColor blackColor];
+	[lighterBackgroundColor set];
+	[self context:context addRoundedRect:boundsRect cornerRadius:self.cornerRadius];
+	CGContextFillPath(context);
+    
+    
+    // Gradient
+    context = UIGraphicsGetCurrentContext();
+    
+    UIColor *lightGradientColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.];
+    UIColor *darkGradientColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1.];
+    
+    CGFloat locations[2] = {0.0, 1.0};
+    CFArrayRef colors = (CFArrayRef) [NSArray arrayWithObjects:(id)lightGradientColor.CGColor,
+                                      (id)darkGradientColor.CGColor, 
+                                      nil];
+    
+    CGColorSpaceRef colorSpc = CGColorSpaceCreateDeviceRGB();
+    CGGradientRef gradient = CGGradientCreateWithColors(colorSpc, colors, locations);
+    
+    CGContextSetBlendMode(context, kCGBlendModeMultiply);
+    
+    CGContextDrawLinearGradient(context,
+                                gradient, 
+                                CGPointMake(0.0, 0.0), 
+                                CGPointMake(rect.size.width, rect.size.height), 
+                                kCGGradientDrawsAfterEndLocation); //Adjust second point according to your view height
+    
+    CGColorSpaceRelease(colorSpc);
+    CGGradientRelease(gradient);
+    CGContextSetBlendMode(context, kCGBlendModeNormal);
+    // End gradient
+    
+    
+	// draw the 'filled' section to the left of the handle (or from the handle if in bidirectional mode)
+	CGRect valueRect;
+	[backgroundColor set];
+	if (self.isHorizontalSlider)
+	{
+		CGFloat handlePos = CGRectGetMinX([self rectForHandle]);
+		CGFloat handleMid = CGRectGetMidX([self rectForHandle]);
+		CGFloat handleMax = CGRectGetMaxX([self rectForHandle]);
+		if (self.biDirectional)
+		{
+			if (self.value > (self.max - self.min) / 2)
+				valueRect = CGRectMake(self.bounds.size.width / 2.0, 0, handleMid - self.bounds.size.width / 2.0, self.bounds.size.height);
+			else
+				valueRect = CGRectMake(handleMid, 0, (self.bounds.size.width - handleMid - self.bounds.size.width / 2.0), self.bounds.size.height);
+			[self context:context addRoundedRect:valueRect cornerRadius:0];
+		}
+		else
+		{
+			valueRect = CGRectMake(0, 0, self.bounds.size.width - (self.bounds.size.width - handleMax), self.bounds.size.height);
+			[self context:context addRoundedRect:valueRect cornerRadius:self.cornerRadius];
+		}
+        
+		CGContextFillPath(context);
+        
+		valueRect = CGRectMake(handlePos, 0, handleSize, self.bounds.size.height);
+	}
+	else
+	{
+		// draw the 'filled' section below the handle (or from the handle if in bidirectional mode) using a colour slightly lighter than the theme
+		CGFloat handlePos = CGRectGetMinY([self rectForHandle]);
+		CGFloat handleMid = CGRectGetMidY([self rectForHandle]);
+		CGFloat handleMin = CGRectGetMinY([self rectForHandle]);
+		if (self.biDirectional)
+		{
+			if (self.value > (self.max - self.min) / 2)
+				valueRect = CGRectMake(0, handleMid, self.bounds.size.width, self.bounds.size.height / 2.0 - handleMid);
+			else
+				valueRect = CGRectMake(0, self.bounds.size.height / 2.0, self.bounds.size.width, handleMid - self.bounds.size.height / 2.0);
+			[self context:context addRoundedRect:valueRect cornerRadius:0];
+		}
+		else
+		{
+			valueRect = CGRectMake(0, handleMin, self.bounds.size.width, self.bounds.size.height - handleMin);
+			[self context:context addRoundedRect:valueRect cornerRadius:self.cornerRadius];
+		}
+        
+		CGContextFillPath(context);
+        
+		valueRect = CGRectMake(0, handlePos, self.bounds.size.width, handleSize);
+	}
+    
+	// draw the handle
+	[self.color set];
+	[self context:context addRoundedRect:valueRect cornerRadius:self.cornerRadius];
+	CGContextFillPath(context);
+    
+	// draw value string as needed
+	if (self.displaysValue)
+	{
+		[self.labelColor set];
+		NSString *valueString = nil;
+        float multiplier = 1.f;
+
+        if ([self.suffixe compare:@""] == NSOrderedSame)
+        {
+            if (self.step < 0.01) valueString = [NSString stringWithFormat:@"%2.3f", self.value];
+            else if (self.step < 0.1) valueString = [NSString stringWithFormat:@"%2.2f", self.value];
+            else valueString = [NSString stringWithFormat:@"%2.1f", self.value];
+        }
+        else
+        {
+            if (self.step < 0.01) valueString = [NSString stringWithFormat:@"%2.3f\r%@", self.value, self.suffixe];
+            else if (self.step < 0.1) valueString = [NSString stringWithFormat:@"%2.2f\r%@", self.value, self.suffixe];
+            else valueString = [NSString stringWithFormat:@"%2.1f\r%@", self.value, self.suffixe];
+            multiplier = 2.f;
+        }
+		
+		CGSize valueStringSize = [valueString sizeWithFont:self.labelFont];
+		CGRect handleRect = [self rectForHandle];
+
+        [valueString drawInRect:CGRectMake(handleRect.origin.x,
+										   handleRect.origin.y + (handleRect.size.height - multiplier * valueStringSize.height) / 2.f,
+										   handleRect.size.width,
+										   multiplier * valueRect.size.height)
+					   withFont:self.labelFont
+				  lineBreakMode:UILineBreakModeMiddleTruncation
+                      alignment:UITextAlignmentCenter];        
+	}
+    
+    // Draw assignation
+    if (self.assignated)
+    {
+        CGContextSetLineWidth(context, 3.);
+        [self.color set];
+        [self context:context addRoundedRect:boundsRect cornerRadius:self.cornerRadius];
+        CGContextStrokePath(context);
+    }
+    
+    // Draw selection
+    if (self.responderSelected)
+    {
+        CGContextSetLineWidth(context, 15.);
+        [self.color set];
+        [self context:context addRoundedRect:boundsRect cornerRadius:self.cornerRadius];
+        CGContextStrokePath(context);
+    }
+}
+
+- (CGRect)rectForHandle
+{
+	CGRect valueRect;
+    
+	if (self.isHorizontalSlider)
+	{
+		float handlePos = (self.bounds.size.width - handleSize) * ((self.value - self.min) / (self.max - self.min));
+		valueRect = CGRectMake(handlePos, 0, handleSize, self.bounds.size.height);
+	}
+	else
+	{
+		float handlePos = (self.bounds.size.height - handleSize) - ((self.bounds.size.height - handleSize) * ((self.value - self.min) / (self.max - self.min)));
+		valueRect = CGRectMake(0, handlePos, self.bounds.size.width, handleSize);
+	}
+    
+	return valueRect;
+}
+
+
+ at end
diff --git a/architecture/iOS/iOS/FITabView.h b/architecture/iOS/iOS/FITabView.h
new file mode 100644
index 0000000..2822873
--- /dev/null
+++ b/architecture/iOS/iOS/FITabView.h
@@ -0,0 +1,34 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIResponder.h"
+#import "FIButton.h"
+
+ at interface FITabView : FIResponder <FIResponderDelegate>
+{
+    NSMutableArray*             _buttons;
+}
+
+ at property CGFloat cornerRadius;				// default: 3.0
+
+- (id)initWithDelegate:(id)aDelegate;
+- (void)addButtonWithLabel:(NSString *)label;
+
+- (void)responderValueDidChange:(float)value sender:(id)sender;
+
+ at end
diff --git a/architecture/iOS/iOS/FITabView.mm b/architecture/iOS/iOS/FITabView.mm
new file mode 100644
index 0000000..77aed05
--- /dev/null
+++ b/architecture/iOS/iOS/FITabView.mm
@@ -0,0 +1,133 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FITabView.h"
+
+ at implementation FITabView
+
+ at synthesize cornerRadius;
+
+
+#pragma mark -
+#pragma mark Init
+
+- (id)initWithDelegate:(id)aDelegate
+{
+	if ((self = [super initWithDelegate:aDelegate]))
+	{
+		self.cornerRadius = 3.0;
+        self.autoresizingMask = UIViewAutoresizingFlexibleWidth |
+                                UIViewAutoresizingFlexibleRightMargin |
+                                UIViewAutoresizingFlexibleLeftMargin;
+        _buttons = [[NSMutableArray alloc] initWithCapacity:0];
+        self.min = 0.f;
+        self.max = 0.f;
+	}
+	
+	return self;
+}
+
+- (void)dealloc
+{
+    [_buttons release];
+    [super dealloc];
+}
+
+// to setup handle size
+- (void)setFrame:(CGRect)frame
+{
+	[super setFrame:frame];
+}
+
+- (void)addButtonWithLabel:(NSString *)label
+{
+    FIButton*   button = [[[FIButton alloc] initWithDelegate:self] autorelease];
+    NSUInteger  nbButtons = 0;
+    float       viewWidth = self.frame.size.width;
+    float       viewHeight = self.frame.size.height;
+    int         i = 0;
+
+    [_buttons addObject:button];
+    nbButtons = [_buttons count];
+    if (nbButtons == 1) ((FIButton*)[_buttons objectAtIndex:i]).value = 1.f;
+    
+    for (i = 0; i < nbButtons; ++i)
+    {
+        ((FIButton*)[_buttons objectAtIndex:i]).frame = CGRectMake(i * viewWidth / nbButtons,
+                                                                   0.f,
+                                                                   viewWidth / nbButtons,
+                                                                   viewHeight);
+    }
+    
+    button.autoresizingMask =   UIViewAutoresizingFlexibleWidth |
+                                UIViewAutoresizingFlexibleRightMargin |
+                                UIViewAutoresizingFlexibleLeftMargin;
+    
+    button.title = [[NSString alloc] initWithString:label];
+    button.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
+    button.labelFont = [UIFont boldSystemFontOfSize:18];
+    button.labelColor = [UIColor colorWithWhite:1. alpha:1.];
+    button.backgroundColorAlpha = 0.4;
+    button.type = kTabItemButtonType;
+    self.max = nbButtons - 1;
+    [self addSubview:button];
+}
+
+
+#pragma mark -
+#pragma mark Touch Handling
+
+- (void)responderValueDidChange:(float)value sender:(id)sender
+{
+    if (value == 1)
+    {
+        int         i = 0;
+        NSUInteger  nbButtons = [_buttons count];
+        
+        for (i = 0; i < nbButtons; ++i)
+        {
+            if (sender != ((FIButton*)[_buttons objectAtIndex:i]))
+            {
+                ((FIButton*)[_buttons objectAtIndex:i]).value = 0;
+            }
+            else
+            {
+                self.value = i;
+            }
+        }
+    }
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+- (void)drawRect:(CGRect)rect
+{
+    int         i = 0;
+    NSUInteger  nbButtons = [_buttons count];
+    
+    if (self.hideOnGUI) return;
+    
+    for (i = 0; i < nbButtons; ++i)
+    {
+        [((FIButton*)[_buttons objectAtIndex:i]) setNeedsDisplay];
+    }
+}
+
+ at end
diff --git a/architecture/iOS/iOS/FITextField.h b/architecture/iOS/iOS/FITextField.h
new file mode 100644
index 0000000..6e249d1
--- /dev/null
+++ b/architecture/iOS/iOS/FITextField.h
@@ -0,0 +1,50 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FIResponder.h"
+#import "FIMainViewController.h"
+
+ at interface FITextField : FIResponder <  UITextViewDelegate,
+                                        UIGestureRecognizerDelegate>
+{
+    UITextView*             _messageTextView;
+    UIView*                 _inputAccView;
+    UIButton*               _doneButton;
+    UIButton*               _minusButton;
+    UIButton*               _cancelButton;
+    UILabel*                _rangeLabel;
+    NSNumberFormatter*      _numberFormatter;
+    UIColor*                _backgroundColor;
+    UIColor*                _textColor;
+    float                   _valueBeforeCancel;
+}
+
+ at property CGFloat cornerRadius;				// default: 3.0
+ at property (assign, nonatomic) UIColor* backgroundColor;
+ at property (assign, nonatomic) UIColor* textColor;
+
+- (id)initWithDelegate:(id)aDelegate;
+
+- (void)minus;
+- (void)doneTyping;
+- (void)cancel;
+- (void)createInputAccessoryView;
+
+- (void)pan:(UIPanGestureRecognizer *)gesture;
+
+ at end
diff --git a/architecture/iOS/iOS/FITextField.mm b/architecture/iOS/iOS/FITextField.mm
new file mode 100644
index 0000000..887c765
--- /dev/null
+++ b/architecture/iOS/iOS/FITextField.mm
@@ -0,0 +1,242 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import "FITextField.h"
+
+#define kAccViewHeight          40.0
+
+ at implementation FITextField
+
+ at synthesize cornerRadius;
+ at synthesize backgroundColor = _backgroundColor;
+ at synthesize textColor = _textColor;
+
+#pragma mark -
+#pragma mark Init
+
+- (id)initWithDelegate:(id)aDelegate
+{
+	if ((self = [super initWithDelegate:aDelegate]))
+	{
+        _valueBeforeCancel = 0.f;
+        
+        // UI parameters
+		self.cornerRadius = 3.0;
+        
+        // Message text view creation
+        _messageTextView = [[UITextView alloc] initWithFrame:self.bounds];
+        [_messageTextView setAutocorrectionType:UITextAutocorrectionTypeNo];
+        [_messageTextView setReturnKeyType:UIReturnKeyGo];
+        _backgroundColor = [UIColor whiteColor];
+        _textColor = [UIColor blackColor];
+        _messageTextView.textColor = [UIColor whiteColor];
+        _messageTextView.backgroundColor = [UIColor darkGrayColor];
+        _messageTextView.delegate = self;
+        _messageTextView.font = [UIFont boldSystemFontOfSize:14];
+        _messageTextView.textAlignment = UITextAlignmentCenter;
+        [self addSubview:_messageTextView];
+        
+        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
+        {
+            _messageTextView.keyboardType = UIKeyboardTypeDecimalPad;
+        }
+        else
+        {
+            _messageTextView.keyboardType = UIKeyboardTypeNumberPad;
+        }
+                
+        // Input accessory view
+        [self createInputAccessoryView];
+        _messageTextView.inputAccessoryView = _inputAccView;
+        
+        // Number formatter
+        _numberFormatter = [[NSNumberFormatter alloc] init];
+        [_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
+        [_numberFormatter setRoundingMode:NSNumberFormatterRoundDown];
+        
+        UIPanGestureRecognizer *panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)] autorelease];
+        panGesture.delegate = self;
+		[self addGestureRecognizer:panGesture];
+	}
+	
+	return self;
+}
+
+// to setup handle size
+- (void)setFrame:(CGRect)frame
+{
+	[super setFrame:frame];
+}
+
+- (void)dealloc
+{
+    [_messageTextView release];
+    [_inputAccView release];
+    [_doneButton release];
+    [_rangeLabel release];
+    
+    [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+- (void)drawRect:(CGRect)rect
+{
+    if (self.hideOnGUI) return;
+    
+    _messageTextView.frame = CGRectMake(rect.origin.x,
+                                        rect.origin.y,
+                                        rect.size.width,
+                                        rect.size.height);
+    if (self.step < 0.01) _messageTextView.text = [NSString stringWithFormat:@"%2.3f%@", self.value, self.suffixe];
+    else if (self.step < 0.1) _messageTextView.text = [NSString stringWithFormat:@"%2.2f%@", self.value, self.suffixe];
+    else _messageTextView.text = [NSString stringWithFormat:@"%2.1f%@", self.value, self.suffixe];
+}
+
+
+#pragma mark - UITextView Delegate Methods
+
+-(void)textViewDidBeginEditing:(UITextView *)textView
+{
+    _valueBeforeCancel = self.value;
+    [((FIMainViewController*)self.delegate) zoomToWidget:self];
+    if (self.step < 0.01) _rangeLabel.text = [NSString stringWithFormat:@"Range : %2.3f - %2.3f", self.min, self.max];
+    else if (self.step < 0.1) _rangeLabel.text = [NSString stringWithFormat:@"Range : %2.2f - %2.2f", self.min, self.max];
+    else _rangeLabel.text = [NSString stringWithFormat:@"Range : %2.1f - %2.1f", self.min, self.max];
+    [_messageTextView setText:@""];
+}
+
+- (void)minus
+{
+    if ([_messageTextView.text length] == 0)
+    {
+        _messageTextView.text = @"-";
+    }
+    else if ([_messageTextView.text characterAtIndex:0] != 45) //45 for minus
+    {
+        _messageTextView.text = [NSString stringWithFormat:@"-%@", _messageTextView.text];
+    }
+    else
+    {
+        _messageTextView.text = [_messageTextView.text substringFromIndex:1];
+    }    
+}
+
+- (void)doneTyping
+{
+    float value;
+    
+    // Hide the keyboard
+    [_messageTextView resignFirstResponder];
+    value = [[_numberFormatter numberFromString:_messageTextView.text] floatValue];
+    if (value < self.min) value = self.min;
+    else if (value > self.max) value = self.max;
+    
+    [self setValue:value];
+    
+    [self setNeedsDisplay];
+}
+
+- (void)cancel
+{    
+    // Hide the keyboard
+    [_messageTextView resignFirstResponder];
+    
+    [self setValue:_valueBeforeCancel];
+    
+    [self setNeedsDisplay];
+}
+
+- (void)createInputAccessoryView
+{
+    float viewWidth = _messageTextView.inputView.frame.size.width;
+
+    _inputAccView = [[UIView alloc] initWithFrame:CGRectMake(10.0, 0.0, viewWidth, kAccViewHeight)];
+    _inputAccView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+    
+    viewWidth = _inputAccView.frame.size.width;
+    _inputAccView.backgroundColor = [UIColor blackColor];
+
+    _rangeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, kAccViewHeight)];
+    _rangeLabel.backgroundColor = [UIColor blackColor];
+    _rangeLabel.textColor = [UIColor whiteColor];
+    _rangeLabel.textAlignment = UITextAlignmentLeft;
+    [_inputAccView addSubview:_rangeLabel];
+    
+    _minusButton =[UIButton buttonWithType:UIButtonTypeCustom];
+    [_minusButton setFrame:CGRectMake(viewWidth - 120.f, 0.0f, 40.0f, kAccViewHeight)];
+    _minusButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
+    [_minusButton setTitle:@"-" forState:UIControlStateNormal];
+    [_minusButton setBackgroundColor:[UIColor blueColor]];
+    [_minusButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+    [_minusButton addTarget:self action:@selector(minus) forControlEvents:UIControlEventTouchUpInside];
+    [_inputAccView addSubview:_minusButton];
+    
+    _cancelButton =[UIButton buttonWithType:UIButtonTypeCustom];
+    [_cancelButton setFrame:CGRectMake(viewWidth - 80.f, 0.0f, 40.0f, kAccViewHeight)];
+    _cancelButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
+    [_cancelButton setTitle:@"X" forState:UIControlStateNormal];
+    [_cancelButton setBackgroundColor:[UIColor blueColor]];
+    [_cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+    [_cancelButton addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];
+    [_inputAccView addSubview:_cancelButton];
+    
+    _doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
+    [_doneButton setFrame:CGRectMake(viewWidth - 40.f, 0.0f, 40.0f, kAccViewHeight)];
+    _doneButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
+    [_doneButton setTitle:@"OK" forState:UIControlStateNormal];
+    [_doneButton setBackgroundColor:[UIColor blueColor]];
+    [_doneButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+    [_doneButton addTarget:self action:@selector(doneTyping) forControlEvents:UIControlEventTouchUpInside];
+    [_inputAccView addSubview:_doneButton];
+}
+
+
+#pragma mark -
+#pragma mark Touch Handling
+
+- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
+{
+    UIScrollView*     scrollView = (UIScrollView*)self.superview.superview;
+    
+    scrollView.scrollEnabled = NO;
+    
+    return YES;
+}
+
+- (void)pan:(UIPanGestureRecognizer *)gesture
+{
+    UIScrollView*     scrollView = (UIScrollView*)self.superview.superview;
+    float value = 0.f - [gesture velocityInView:scrollView].y;
+    value = value / 200.;
+        
+    if ([gesture velocityInView:scrollView].y < 0)
+    {
+        [self setValue:self.value + (floor(value) + 1.) * self.step];
+    }
+    else
+    {
+        [self setValue:self.value + floor(value) * self.step];
+    }
+    
+    scrollView.scrollEnabled = YES;
+}
+
+ at end
diff --git a/architecture/iOS/iOS/JackView.h b/architecture/iOS/iOS/JackView.h
new file mode 100644
index 0000000..b99b4bd
--- /dev/null
+++ b/architecture/iOS/iOS/JackView.h
@@ -0,0 +1,163 @@
+//
+//  JackView.h
+//  iOS
+//
+//  Created by Olivier Guillerminet on 02/04/13.
+//
+//
+
+
+#import <UIKit/UIKit.h>
+#import "jack/jack.h"
+#import "jack/custom.h"
+#import "JackViewPortsView.h"
+
+
+#define kJackViewExtHMargins 5
+#define kJackViewExtTopVMargins 30
+#define kJackViewExtBottomVMargins 5
+#define kJackViewIntHMargins 10
+
+#define kJackViewBottomMargin 20
+#define kJackViewTitlesYOffset 3
+#define kJackViewStrokeYOffset 16
+
+#define kJackViewCurrentAppIconBottomMargin 30
+
+#define kJackViewButtonWidth 70
+#define kJackViewButtonHeight 85
+#define kJackViewIconMargins 4
+
+#define kJackViewTabsX 5
+#define kJackViewTabsY 1
+#define kJackViewTabsWidth 150
+#define kJackViewTabsHeight 28
+
+ at class JackViewClient;
+ at class JackView;
+
+ at interface JackViewButton : UIControl
+{
+    UITapGestureRecognizer*             _singleTapRecognizer;
+    UITapGestureRecognizer*             _doubleTapRecognizer;
+    UILongPressGestureRecognizer*       _longPressRecognizer;
+}
+
+ at property (assign, nonatomic) JackViewClient* jackViewClient;
+ at property (assign, nonatomic) JackView* jackView;
+ at property (assign, nonatomic) int audioMidi;        // 0: undefined, 1: audio; 2: midi
+ at property (assign, nonatomic) int inputOutput;      // 0: undefined, 1: input, 2:
+
+- (void)buttonClicked;
+- (void)buttonDoubleClicked;
+- (void)buttonLongPressed;
+
+- (void)fastSwitch;
+- (void)fastConnect;
+- (void)displayPortsView;
+
+ at end
+
+
+ at interface JackViewPort : NSObject
+
+ at property (assign, nonatomic) NSString* name;
+ at property (assign, nonatomic) int audioMidi;        // 0: undefined, 1: audio; 2: midi
+ at property (assign, nonatomic) int inputOutput;      // 0: undefined, 1: input, 2: output
+
+ at end
+
+
+
+ at interface JackViewClient : NSObject
+
+ at property (assign, nonatomic) NSString* name;
+ at property (assign, nonatomic) UIImage* icon;
+ at property (assign, readwrite) NSMutableArray* ports;
+ at property (assign, nonatomic) JackViewButton* audioInputButton;
+ at property (assign, nonatomic) JackViewButton* audioOutputButton;
+ at property (assign, nonatomic) JackViewButton* midiInputButton;
+ at property (assign, nonatomic) JackViewButton* midiOutputButton;
+
+- (NSArray*)compatiblePortsWithInputOutput:(int)inputOutput audioMidi:(int)audioMidi;
+
+ at end
+
+
+ at interface JackView : UIView <UIScrollViewDelegate>
+{
+    jack_client_t*          _jackClient;
+    
+    NSMutableArray*         _clients;
+    NSString*               _currentClientName;
+    
+    UIScrollView*           _audioInputsScrollView;
+    UIScrollView*           _audioOutputsScrollView;
+    UIScrollView*           _midiInputsScrollView;
+    UIScrollView*           _midiOutputsScrollView;
+        
+    UITapGestureRecognizer* _singleTapRecognizer;    
+}
+
+ at property (assign, readwrite) CGPoint srcPt;
+ at property (assign, readwrite) CGPoint dstPt;
+ at property (assign, readwrite) JackViewPortsView* portsView;
+ at property (assign, readwrite) JackViewButton* currentClientButton;
+ at property (assign, readwrite) UIButton* audioButton;
+ at property (assign, readwrite) UIButton* midiButton;
+
+- (void)orientationChanged:(NSNotification *)notification;
+- (void)resizeView;
+- (void)resizePortsView;
+
+- (void)audioButtonClicked;
+- (void)midiButtonClicked;
+
+- (void)loadJackClient:(jack_client_t*)jackClient;
+- (jack_client_t*)jackClient;
+
+- (BOOL)doesClientExist:(NSString*)clientName;
+- (JackViewClient*)clientWithName:(NSString*)clientName;
+- (JackViewPort*)portWithName:(NSString*)portName;
+- (void)makeButtonsSymetric;
+
+- (BOOL)hasCurrentClientCompatiblePortWithInputOutput:(int)inputOutput audioMidi:(int)audioMidi;
+
+- (BOOL)isClient:(JackViewClient*)client
+connectedToCurrentClientInputOutput:(int)inputOutput
+       audioMidi:(int)audioMidi;
+- (BOOL)isPort:(JackViewPort*)port
+connectedToCurrentClientInputOutput:(int)inputOutput
+     audioMidi:(int)audioMidi;
+- (BOOL)isPort:(NSString*)portName1
+connectedWithPort:(NSString*)portName2;
+- (NSArray*)getCurrentClientPortConnectedTo:(NSString*)portName;
+
+- (BOOL)quicklyConnectAppToClient:(NSString*)clientName
+                      inputOutput:(int)inputOutput
+                        audioMidi:(int)audioMidi;
+- (BOOL)quicklyDisconnectAppToClient:(NSString*)clientName
+                         inputOutput:(int)inputOutput
+                           audioMidi:(int)audioMidi;
+- (void)connectPort:(NSString*)inputPort
+           withPort:(NSString*)outputPort;
+- (void)disconnectPort:(NSString*)inputPort
+              withPort:(NSString*)outputPort;
+
+
+- (BOOL)isPointInsideCurrentAppIcon:(CGPoint)pt;
+- (BOOL)isPointInsideView:(CGPoint)pt;
+
+- (int)numberOfCurrentAppPortsWithInputOutput:(int)inputOutput
+                                    audioMidi:(int)audioMidi;
+- (void)displayCurrentAppPortsWithInputOutput:(int)inputOutput
+                                    audioMidi:(int)audioMidi;
+
+- (void)viewClicked;
+- (void)dismissPortsView;
+
+- (void)fsToClient;
+
+- (void)showHideScrollViews;
+
+ at end
\ No newline at end of file
diff --git a/architecture/iOS/iOS/JackView.mm b/architecture/iOS/iOS/JackView.mm
new file mode 100644
index 0000000..f6c682d
--- /dev/null
+++ b/architecture/iOS/iOS/JackView.mm
@@ -0,0 +1,1714 @@
+//
+//  JackView.m
+//  iOS
+//
+//  Created by Olivier Guillerminet on 02/04/13.
+//
+//
+
+#import <QuartzCore/QuartzCore.h>
+#import "JackView.h"
+
+ at implementation JackViewButton
+
+ at synthesize jackViewClient;
+ at synthesize jackView;
+ at synthesize audioMidi;
+ at synthesize inputOutput;
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    
+    if (self)
+    {
+        self.jackViewClient = nil;
+        self.jackView = nil;
+        self.audioMidi = 0;
+        self.inputOutput = 0;
+        
+        _singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(buttonClicked)];
+        _singleTapRecognizer.numberOfTapsRequired = 1;
+        [self addGestureRecognizer:_singleTapRecognizer];
+        
+        _doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDoubleClicked)];
+        _doubleTapRecognizer.numberOfTapsRequired = 2;
+        [self addGestureRecognizer:_doubleTapRecognizer];
+        
+        [_singleTapRecognizer requireGestureRecognizerToFail:_doubleTapRecognizer];
+        
+        _longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonLongPressed)];
+        [self addGestureRecognizer:_longPressRecognizer];
+        
+        self.backgroundColor = [UIColor clearColor];
+        self.frame = frame;
+    }
+    
+    return self;
+}
+
+- (void)dealloc
+{
+    [jackView.portsView removeFromSuperview];
+    [jackView.portsView release];
+    jackView.portsView = nil;
+    [jackView.superview setNeedsDisplay];
+    
+    [super dealloc];
+}
+
+- (void)buttonClicked
+{
+    if (jackView.portsView) [jackView dismissPortsView];
+    else [self fastConnect];
+}
+
+- (void)buttonDoubleClicked
+{    
+    [self fastSwitch];
+}
+
+- (void)buttonLongPressed
+{
+    [self displayPortsView];
+}
+
+- (void)fastSwitch
+{
+    // Switch to Jack server
+    if ([self.jackViewClient.name compare:@"system"] == NSOrderedSame
+        || [self.jackViewClient.name compare:@"system_midi"] == NSOrderedSame)
+    {
+        jack_gui_switch_to_client([jackView jackClient], "jack");
+    }
+    
+    // Switch to other client
+    else
+    {
+        jack_gui_switch_to_client([jackView jackClient], [self.jackViewClient.name cStringUsingEncoding:NSUTF8StringEncoding]);
+    }
+}
+
+- (void)fastConnect
+{
+    // Connect
+    if (!self.isSelected)
+    {
+        if ([self.jackView quicklyConnectAppToClient:self.jackViewClient.name
+                                         inputOutput:inputOutput
+                                           audioMidi:audioMidi])
+        {
+            self.selected = YES;
+        }
+    }
+    
+    // Disconnect
+    else
+    {
+        if ([self.jackView quicklyDisconnectAppToClient:self.jackViewClient.name
+                                            inputOutput:inputOutput
+                                              audioMidi:audioMidi])
+        {
+            self.selected = NO;
+        }
+    }
+    
+    [self setNeedsDisplay];
+}
+
+- (void)displayPortsView
+{
+    float x = 0.f;
+    float y = 0.f;
+    float w = 0.f;
+    float h = 0.f;
+    float utilH = 0.f;
+    int i = 0;
+    NSArray* compatiblePorts = [self.jackViewClient compatiblePortsWithInputOutput:self.inputOutput audioMidi:self.audioMidi];
+    CGPoint pt = [self convertPoint:CGPointMake(0., 0.) toView:jackView.superview];
+    CGPoint defPt;
+    
+    x = 0;
+    w = jackView.frame.size.width;
+    utilH = fmaxf([compatiblePorts count] * kPortsViewItemHeight,
+                  [jackView numberOfCurrentAppPortsWithInputOutput:self.inputOutput audioMidi:self.audioMidi] * kPortsViewItemHeight);
+    h = fminf(utilH, kPortsViewMaxHeight) + kPortsViewArrowHeight + kPortsViewFSButtonHeight;
+    y = 0. - h;
+    
+    if (jackView.portsView)
+    {
+        [jackView.portsView removeFromSuperview];
+        [jackView.portsView release];
+        jackView.portsView = nil;
+        [jackView.superview setNeedsDisplay];
+        
+        if (self == self.jackView.currentClientButton) return;
+    }
+    else if (self == self.jackView.currentClientButton) return;
+    
+    defPt = [self convertPoint:CGPointMake(x, y) toView:jackView.superview];
+    
+    jackView.portsView = [[JackViewPortsView alloc] initWithFrame:CGRectMake(x, defPt.y, w, h)];
+    [jackView.portsView setUtilHeight:utilH];
+    jackView.portsView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
+    jackView.portsView.clientButton = self;
+    
+    if (pt.x + kPortsViewItemWidth < jackView.frame.size.width) jackView.portsView.clientX = pt.x;
+    else jackView.portsView.clientX = jackView.frame.size.width - kPortsViewItemWidth;
+    
+    jackView.portsView.currentAppX = [jackView convertPoint:jackView.currentClientButton.frame.origin toView:jackView.superview].x;
+    
+    for (i = 0; i < [compatiblePorts count]; ++i)
+    {
+        if ([[compatiblePorts objectAtIndex:i] isKindOfClass:[JackViewPort class]])
+        {            
+            JackViewPortsViewItem* item = [[JackViewPortsViewItem alloc] initWithFrame:CGRectMake(jackView.portsView.clientX,
+                                                                                                  i * kPortsViewItemHeight,
+                                                                                                  kPortsViewItemWidth,
+                                                                                                  kPortsViewItemHeight)];
+        
+            item.longName = ((JackViewPort*)([compatiblePorts objectAtIndex:i])).name;
+            item.selected = [jackView isPort:((JackViewPort*)([compatiblePorts objectAtIndex:i]))
+         connectedToCurrentClientInputOutput:((JackViewPort*)([compatiblePorts objectAtIndex:i])).inputOutput
+                                   audioMidi:((JackViewPort*)([compatiblePorts objectAtIndex:i])).audioMidi];
+        
+            [jackView.portsView addItem:item];
+        }
+    }
+    
+    if (self.inputOutput == 1) [jackView displayCurrentAppPortsWithInputOutput:2 audioMidi:self.audioMidi];
+    else if (self.inputOutput == 2) [jackView displayCurrentAppPortsWithInputOutput:1 audioMidi:self.audioMidi];
+    
+    [jackView resizePortsView];
+    
+    jackView.portsView.fsButton = [UIButton buttonWithType:UIButtonTypeCustom];
+    [jackView.portsView.fsButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon-Expand" ofType:@"png"]]
+                                 forState:UIControlStateNormal];
+    [jackView.portsView.fsButton setFrame:CGRectMake(jackView.portsView.clientX,
+                                                     jackView.portsView.frame.size.height - kPortsViewArrowHeight - kPortsViewFSButtonHeight,
+                                                     kPortsViewFSButtonWidth,
+                                                     kPortsViewFSButtonHeight)];
+    [jackView.portsView.fsButton addTarget:jackView action:@selector(fsToClient) forControlEvents:UIControlEventTouchUpInside];
+    
+    [jackView.portsView addSubview:jackView.portsView.fsButton];
+    
+    [jackView.superview addSubview:jackView.portsView];
+    [jackView.portsView refreshLinks];
+    [jackView.portsView setNeedsDisplay];
+    [jackView.portsView.backgroundView setNeedsDisplay];
+    
+    // Fade in
+    CATransition *animation = [CATransition animation];
+    [animation setDuration:0.3];
+    [animation setType:kCATransitionFade];
+    [animation setSubtype:kCATransitionFromLeft];
+    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+    
+    [[self.window layer] addAnimation:animation forKey:@"DisplayPortsView"];
+}
+
+
+// Refresh view
+- (void)drawRect:(CGRect)rect
+{
+    UIFont* font = [UIFont systemFontOfSize:11.0f];
+    CGRect iconRect = CGRectMake(rect.origin.x + 1,
+                                 rect.origin.y + 1,
+                                 kJackViewButtonWidth - 2,
+                                 kJackViewButtonWidth - 2);
+    
+    // Draw selection
+    if (self.selected)
+    {
+        UIBezierPath* path = [UIBezierPath bezierPath];
+        
+        [[UIColor blueColor] set];
+        
+        [path moveToPoint:CGPointMake(rect.origin.x, rect.origin.y)];
+        [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y)];
+        [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height)];
+        [path addLineToPoint:CGPointMake(rect.origin.x, rect.origin.y + rect.size.height)];
+        [path closePath];
+        path.lineWidth = 2;
+        [path fillWithBlendMode:kCGBlendModeNormal alpha:0.7];
+    }
+    
+    // Translucent background
+    self.backgroundColor = [UIColor clearColor];
+    
+    // Draw icon
+    if (self.jackViewClient)
+    {
+        if (self.enabled) [self.jackViewClient.icon drawInRect:iconRect];
+        else [self.jackViewClient.icon drawInRect:iconRect blendMode:kCGBlendModeNormal alpha:0.5];
+    }
+    
+    // Draw text
+    if (self.jackViewClient.name)
+    {
+        if (self.selected) [[UIColor whiteColor] set];
+        else [[UIColor blackColor] set];
+        CGSize stringBoundingBox = [self.jackViewClient.name sizeWithFont:font];
+        [self.jackViewClient.name drawAtPoint:CGPointMake(rect.origin.x + (kJackViewButtonWidth - stringBoundingBox.width) / 2.,
+                                                          rect.origin.y - 1. + kJackViewButtonWidth)
+                                     withFont:font];
+    }
+}
+
+
+ at end
+
+
+ at implementation JackViewPort
+
+ at synthesize name;
+ at synthesize audioMidi;
+ at synthesize inputOutput;
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self)
+    {
+        self.name = nil;
+        self.audioMidi = 0;
+        self.inputOutput = 0;
+    }
+    
+    return self;
+}
+
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+ at end
+
+
+ at implementation JackViewClient
+
+ at synthesize name;
+ at synthesize icon;
+ at synthesize ports;
+ at synthesize audioInputButton;
+ at synthesize audioOutputButton;
+ at synthesize midiInputButton;
+ at synthesize midiOutputButton;
+
+- (id)init
+{
+    self = [super init];
+    
+    if (self)
+    {
+        self.name = nil;
+        self.icon = nil;
+        self.ports = [[NSMutableArray alloc] initWithCapacity:0];
+        self.audioInputButton = nil;
+        self.audioOutputButton = nil;
+        self.midiInputButton = nil;
+        self.midiOutputButton = nil;
+    }
+    
+    return self;
+}
+
+
+- (void)dealloc
+{
+    [self.ports release];
+    [super dealloc];
+}
+
+- (NSArray*)compatiblePortsWithInputOutput:(int)inputOutput audioMidi:(int)audioMidi
+{
+    JackViewPort* port = nil;
+    int nbPorts = [self.ports count];
+    int i = 0;
+    NSMutableArray* portsArray = [NSMutableArray arrayWithCapacity:0];
+        
+    for (i = 0; i < nbPorts; ++i)
+    {
+        port = [self.ports objectAtIndex:i];
+
+        if (((port.inputOutput == 1 && inputOutput == 2) || (port.inputOutput == 2 && inputOutput == 1))
+            && port.audioMidi == audioMidi)
+        {
+            [portsArray addObject:port];
+        }
+    }
+    
+    return portsArray;
+}
+
+ at end
+
+
+ at implementation JackView
+
+ at synthesize srcPt;
+ at synthesize dstPt;
+ at synthesize portsView;
+ at synthesize currentClientButton;
+ at synthesize audioButton;
+ at synthesize midiButton;
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    
+    if (self)
+    {
+        self.portsView = nil;
+        _jackClient = nil;
+        self.currentClientButton = nil;
+        self.backgroundColor = [UIColor clearColor];
+        
+        _singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClicked)];
+        _singleTapRecognizer.numberOfTapsRequired = 1;
+        [self addGestureRecognizer:_singleTapRecognizer];
+        
+        float w = (frame.size.width - kJackViewButtonWidth - 2. * kJackViewIntHMargins - 2. * kJackViewExtHMargins) / 2.;
+        
+        self.audioButton = [UIButton buttonWithType:UIButtonTypeCustom];
+        [self.audioButton setFrame:CGRectMake((frame.size.width - kJackViewTabsWidth) / 2.,
+                                              kJackViewTabsY,
+                                              kJackViewTabsWidth / 2.,
+                                              kJackViewTabsHeight)];
+        [self.audioButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jackview-audio-off" ofType:@"png"]]
+                          forState:UIControlStateNormal];
+        [self.audioButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jackview-audio-on" ofType:@"png"]]
+                          forState:UIControlStateSelected];
+        [self.audioButton addTarget:self action:@selector(audioButtonClicked) forControlEvents:UIControlEventTouchUpInside];
+        [self addSubview:self.audioButton];
+        
+        self.midiButton = [UIButton buttonWithType:UIButtonTypeCustom];
+        [self.midiButton setFrame:CGRectMake((frame.size.width - kJackViewTabsWidth) / 2. + kJackViewTabsWidth / 2.,
+                                              kJackViewTabsY,
+                                              kJackViewTabsWidth / 2.,
+                                              kJackViewTabsHeight)];
+        [self.midiButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jackview-midi-off" ofType:@"png"]]
+                         forState:UIControlStateNormal];
+        [self.midiButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jackview-midi-on" ofType:@"png"]]
+                         forState:UIControlStateSelected];
+        [self.midiButton addTarget:self action:@selector(midiButtonClicked) forControlEvents:UIControlEventTouchUpInside];
+        [self addSubview:self.midiButton];
+        
+        self.audioButton.selected = YES;
+        self.midiButton.selected = NO;
+                
+        _audioInputsScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kJackViewExtHMargins,
+                                                                                kJackViewExtTopVMargins,
+                                                                                w,
+                                                                                kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+        
+        _audioOutputsScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kJackViewExtHMargins + 2. * kJackViewIntHMargins + kJackViewButtonWidth + w,
+                                                                                 kJackViewExtTopVMargins,
+                                                                                 w,
+                                                                                 kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+        
+        _midiInputsScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kJackViewExtHMargins,
+                                                                               kJackViewExtTopVMargins,
+                                                                               w,
+                                                                               kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+        
+        _midiOutputsScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kJackViewExtHMargins + 2. * kJackViewIntHMargins + kJackViewButtonWidth + w,
+                                                                                kJackViewExtTopVMargins,
+                                                                                w,
+                                                                                kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+        
+        UIColor* color = [UIColor clearColor];
+        _audioInputsScrollView.backgroundColor = color;
+        _audioOutputsScrollView.backgroundColor = color;
+        _midiInputsScrollView.backgroundColor = color;
+        _midiOutputsScrollView.backgroundColor = color;
+        
+        _audioInputsScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
+        _audioOutputsScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
+        _midiInputsScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
+        _midiOutputsScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
+        
+        _audioInputsScrollView.hidden = NO;
+        _audioOutputsScrollView.hidden = NO;
+        _midiInputsScrollView.hidden = YES;
+        _midiOutputsScrollView.hidden = YES;
+        
+        _audioInputsScrollView.delegate = self;
+        _audioOutputsScrollView.delegate = self;
+        _midiInputsScrollView.delegate = self;
+        _midiOutputsScrollView.delegate = self;
+        
+        [self addSubview:_audioInputsScrollView];
+        [self addSubview:_audioOutputsScrollView];
+        [self addSubview:_midiInputsScrollView];
+        [self addSubview:_midiOutputsScrollView];
+        
+        _clients = [[NSMutableArray alloc] initWithCapacity:0];
+        
+        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)
+                                                     name:UIDeviceOrientationDidChangeNotification object:nil];
+        
+        [self setNeedsDisplay];
+    }
+    
+    return self;
+}
+
+- (void)orientationChanged:(NSNotification *)notification
+{
+    [self resizeView];
+}
+
+- (void)audioButtonClicked
+{
+    if (!self.audioButton.selected)
+    {
+        self.audioButton.selected = YES;
+        self.midiButton.selected = NO;
+        
+        _audioInputsScrollView.hidden = NO;
+        _audioOutputsScrollView.hidden = NO;
+        _midiInputsScrollView.hidden = YES;
+        _midiOutputsScrollView.hidden = YES;
+    }
+    
+    [self showHideScrollViews];
+    [self setNeedsDisplay];
+}
+
+- (void)midiButtonClicked
+{
+    if (!self.midiButton.selected)
+    {
+        self.midiButton.selected = YES;
+        self.audioButton.selected = NO;
+        
+        _audioInputsScrollView.hidden = YES;
+        _audioOutputsScrollView.hidden = YES;
+        _midiInputsScrollView.hidden = NO;
+        _midiOutputsScrollView.hidden = NO;
+    }
+    
+    [self showHideScrollViews];
+    [self setNeedsDisplay];
+}
+
+- (void)resizeView
+{
+    CGRect frame = self.frame;
+    float w = (frame.size.width - kJackViewButtonWidth - 2. * kJackViewIntHMargins - 2. * kJackViewExtHMargins) / 2.;
+    
+    [_audioInputsScrollView setFrame:CGRectMake(kJackViewExtHMargins,
+                                                kJackViewExtTopVMargins,
+                                                w,
+                                                kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+    
+    [_audioOutputsScrollView setFrame:CGRectMake(kJackViewExtHMargins + 2. * kJackViewIntHMargins + kJackViewButtonWidth + w,
+                                                 kJackViewExtTopVMargins,
+                                                 w,
+                                                 kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+    
+    [_midiInputsScrollView setFrame:CGRectMake(kJackViewExtHMargins,
+                                               kJackViewExtTopVMargins,
+                                               w,
+                                               kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+    
+    [_midiOutputsScrollView setFrame:CGRectMake(kJackViewExtHMargins + 2. * kJackViewIntHMargins + kJackViewButtonWidth + w,
+                                                kJackViewExtTopVMargins,
+                                                w,
+                                                kJackViewButtonHeight + 2. * kJackViewIconMargins)];
+    
+    [self.audioButton setFrame:CGRectMake((frame.size.width - kJackViewTabsWidth) / 2.,
+                                          kJackViewTabsY,
+                                          kJackViewTabsWidth / 2.,
+                                          kJackViewTabsHeight)];
+    
+    [self.midiButton setFrame:CGRectMake((frame.size.width - kJackViewTabsWidth) / 2. + kJackViewTabsWidth / 2.,
+                                         kJackViewTabsY,
+                                         kJackViewTabsWidth / 2.,
+                                         kJackViewTabsHeight)];
+    
+    if (self.currentClientButton)
+    {
+        [self.currentClientButton setFrame:CGRectMake(self.frame.size.width / 2. - kJackViewButtonWidth / 2.,
+                                                      kJackViewExtTopVMargins + kJackViewIconMargins,
+                                                      kJackViewButtonWidth,
+                                                      self.frame.size.height - 2. * kJackViewExtBottomVMargins - 2. * kJackViewIconMargins)];
+    }
+    
+    if (self.portsView)
+    {
+        JackViewButton* clientButton = self.portsView.clientButton;
+        [clientButton performSelector:@selector(displayPortsView) withObject:nil afterDelay:0.1];
+    }
+    
+    [self makeButtonsSymetric];
+    [self setNeedsDisplay];
+}
+
+- (void)resizePortsView
+{
+    int i = 0;
+    CGPoint pt = [self.portsView.clientButton convertPoint:CGPointMake(0., 0.) toView:self.superview];
+    float oldClientX = self.portsView.clientX;
+    float oldCurrentAppX = self.portsView.currentAppX;
+    JackViewPortsViewItem* item = nil;
+    
+    [self.portsView setFrame:CGRectMake(self.portsView.frame.origin.x,
+                                        self.portsView.frame.origin.y,
+                                        self.frame.size.width,
+                                        self.portsView.frame.size.height)];
+    
+    if (pt.x + kPortsViewItemWidth < self.frame.size.width) self.portsView.clientX = pt.x;
+    else self.portsView.clientX = self.frame.size.width - kPortsViewItemWidth;
+    
+    self.portsView.currentAppX = [self convertPoint:self.currentClientButton.frame.origin toView:self.superview].x;
+    
+    for (i = 0; i < [[self.portsView portsItems] count]; ++i)
+    {
+        if ([[[self.portsView portsItems] objectAtIndex:i] isKindOfClass:[JackViewPortsViewItem class]])
+        {
+            JackViewPortsViewItem* item = ((JackViewPortsViewItem*)[[self.portsView portsItems] objectAtIndex:i]);
+            if (item.frame.origin.x == oldClientX)
+            {
+                [item setFrame:CGRectMake(self.portsView.clientX,
+                                          item.frame.origin.y,
+                                          kPortsViewItemWidth,
+                                          kPortsViewItemHeight)];
+            }
+            else if (item.frame.origin.x == oldCurrentAppX)
+            {
+                [item setFrame:CGRectMake(self.portsView.currentAppX,
+                                          item.frame.origin.y,
+                                          kPortsViewItemWidth,
+                                          kPortsViewItemHeight)];
+            }
+        }
+    }
+    
+    if (fabs(self.portsView.clientX - self.portsView.currentAppX) <= kPortsViewMinXBetweenItems + kPortsViewItemWidth)
+    {
+        float newClientX = 0.f;
+        float newCurrentAppX = 0.f;
+        
+        if (self.portsView.currentAppX < self.portsView.clientX)
+        {
+            // Re-position current app X
+            newCurrentAppX = fmaxf(self.portsView.clientX - kPortsViewMinXBetweenItems - kPortsViewItemWidth, 0.);
+                        
+            for (i = 0; i < [[self.portsView portsItems] count]; ++i)
+            {
+                item = [[self.portsView portsItems] objectAtIndex:i];
+                
+                if ([item isKindOfClass:[JackViewPortsViewItem class]])
+                {                    
+                    if (item.frame.origin.x == self.portsView.currentAppX)
+                    {
+                        [item setFrame:CGRectMake(newCurrentAppX, item.frame.origin.y, item.frame.size.width, item.frame.size.height)];
+                    }
+                }
+            }
+            
+            self.portsView.currentAppX = newCurrentAppX;
+            
+            // If still not enough, re-position client x
+            if (fabs(self.portsView.clientX - self.portsView.currentAppX) <= kPortsViewMinXBetweenItems + kPortsViewItemWidth)
+            {
+                newClientX = fminf(self.portsView.currentAppX + kPortsViewItemWidth + kPortsViewMinXBetweenItems, self.frame.size.width - kPortsViewItemWidth);
+                
+                for (i = 0; i < [[self.portsView portsItems] count]; ++i)
+                {
+                    item = [[self.portsView portsItems] objectAtIndex:i];
+                    
+                    if ([item isKindOfClass:[JackViewPortsViewItem class]])
+                    {
+                        if (item.frame.origin.x == self.portsView.clientX)
+                        {
+                            [item setFrame:CGRectMake(newClientX, item.frame.origin.y, item.frame.size.width, item.frame.size.height)];
+                        }
+                    }
+                }
+                
+                self.portsView.clientX = newClientX;
+            }
+        }
+        
+        else if (self.portsView.clientX < self.portsView.currentAppX)
+        {
+            // Re-position current app X
+            newCurrentAppX = fminf(self.portsView.clientX + kPortsViewMinXBetweenItems + kPortsViewItemWidth, self.frame.size.width - kPortsViewItemWidth);
+                        
+            for (i = 0; i < [[self.portsView portsItems] count]; ++i)
+            {
+                item = [[self.portsView portsItems] objectAtIndex:i];
+                
+                if ([item isKindOfClass:[JackViewPortsViewItem class]])
+                {
+                    if (item.frame.origin.x == self.portsView.currentAppX)
+                    {
+                        [item setFrame:CGRectMake(newCurrentAppX, item.frame.origin.y, item.frame.size.width, item.frame.size.height)];
+                    }
+                }
+            }
+            
+            self.portsView.currentAppX = newCurrentAppX;
+            
+            // If still not enough, re-position client x
+            if (fabs(self.portsView.clientX - self.portsView.currentAppX) <= kPortsViewMinXBetweenItems + kPortsViewItemWidth)
+            {
+                newClientX = fmaxf(self.portsView.currentAppX - kPortsViewMinXBetweenItems - kPortsViewItemWidth, 0.);
+                
+                for (i = 0; i < [[self.portsView portsItems] count]; ++i)
+                {
+                    item = [[self.portsView portsItems] objectAtIndex:i];
+                    
+                    if ([item isKindOfClass:[JackViewPortsViewItem class]])
+                    {
+                        if (item.frame.origin.x == self.portsView.clientX)
+                        {
+                            [item setFrame:CGRectMake(newClientX, item.frame.origin.y, item.frame.size.width, item.frame.size.height)];
+                        }
+                    }
+                }
+                
+                self.portsView.clientX = newClientX;
+            }
+        }
+    }
+    
+    if (self.portsView.fsButton)
+    {
+        [self.portsView.fsButton setFrame:CGRectMake(self.portsView.clientX,
+                                                     self.portsView.fsButton.frame.origin.y,
+                                                     self.portsView.fsButton.frame.size.width,
+                                                     self.portsView.fsButton.frame.size.height)];
+    }
+}
+
+- (void)dealloc
+{
+    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    
+    [_clients release];
+    [_audioInputsScrollView release];
+    [_audioOutputsScrollView release];
+    [_midiInputsScrollView release];
+    [_midiOutputsScrollView release];
+    
+    [self dismissPortsView];
+    
+    [super dealloc];
+}
+
+- (void)loadJackClient:(jack_client_t*)jackClient
+{
+	jack_status_t status;
+	const char **ports;
+	int show_aliases = 0;
+	char* aliases[2];
+	jack_port_t *port;
+    int i;
+    
+    _jackClient = jackClient;
+    
+    
+    if (show_aliases)
+    {
+        aliases[0] = (char *) malloc (jack_port_name_size());
+        aliases[1] = (char *) malloc (jack_port_name_size());
+    }
+    
+    if (_jackClient == NULL)
+    {
+		if (status & JackServerFailed)
+        {
+			fprintf (stderr, "JACK server not running\n");
+		}
+        else
+        {
+			fprintf (stderr, "jack_client_open() failed, "
+                     "status = 0x%2.0x\n", status);
+		}
+		return;
+	}
+    
+    ports = jack_get_ports (_jackClient, NULL, NULL, 0);
+    
+    if (!ports)
+    {
+        NSLog(@"ERROR");
+        return;
+    }
+    
+    for (i = 0; ports && ports[i]; ++i)
+    {
+		port = jack_port_by_name (_jackClient, ports[i]);
+        
+        int res = 0;
+        NSString* clientName = nil;
+        size_t size = 0;
+        void* rawData = NULL;
+        NSData* data = nil;
+        JackViewClient* jackViewClient = nil;
+        int audioMidi = 0; // 0: undefined, 1: audio; 2: midi
+        int inputOutput = 0; // 0: undefined, 1: input, 2: output
+        NSString* portType = nil;
+        
+        _currentClientName = [[NSString alloc] initWithCString:jack_get_client_name(_jackClient) encoding:NSUTF8StringEncoding];
+        
+        clientName = [NSString stringWithCString:ports[i] encoding:NSUTF8StringEncoding];
+        clientName = [[clientName componentsSeparatedByString:@":"] objectAtIndex:0];
+        
+        // Check if client doesn't exist already
+        if (![self doesClientExist:clientName])
+        {            
+            // If needed, create it
+            jackViewClient = [[JackViewClient alloc] init];
+            
+            // Set its name
+            jackViewClient.name = [[NSString alloc] initWithString:clientName];
+            
+            // Set its icon
+            if ([clientName compare:@"system"] == NSOrderedSame
+                || [clientName compare:@"system_midi"] == NSOrderedSame)
+            {
+                res = jack_custom_get_data(_jackClient, "jack", "icon.png", &rawData, &size);
+            }
+            else
+            {
+                res = jack_custom_get_data(_jackClient, [clientName cStringUsingEncoding:NSUTF8StringEncoding], "icon.png", &rawData, &size);
+            }
+            
+            if (res == 0)
+            {
+                data = [NSData dataWithBytes:rawData length:size];
+                jackViewClient.icon = [[UIImage alloc] initWithData:data];
+                
+            }
+            else
+            {
+                jackViewClient.icon = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_Apple" ofType:@"png"]];
+            }
+        }
+        else
+        {
+            jackViewClient = [self clientWithName:clientName];
+        }
+        
+        // Input / output ?
+        int flags = jack_port_flags (port);
+
+        if (flags & JackPortIsInput) inputOutput = 1;
+        else if (flags & JackPortIsOutput) inputOutput = 2;
+        
+        // Audio / midi ?
+        portType = [NSString stringWithCString:jack_port_type(port) encoding:NSUTF8StringEncoding];
+        
+        if ([((NSString*)([[portType componentsSeparatedByString:@" "] lastObject])) compare:@"audio"] == NSOrderedSame) audioMidi = 1;
+        else if ([((NSString*)([[portType componentsSeparatedByString:@" "] lastObject])) compare:@"midi"] == NSOrderedSame) audioMidi = 2;
+        
+        // Add port
+        JackViewPort* jackViewPort = [[JackViewPort alloc] init];
+        jackViewPort.name = [[NSString alloc] initWithCString:ports[i] encoding:NSUTF8StringEncoding];
+        jackViewPort.inputOutput = inputOutput;
+        jackViewPort.audioMidi = audioMidi;
+        
+        // Put the corresponding button in the right scroll view
+        if (inputOutput == 2 && audioMidi == 1 && jackViewClient.audioInputButton == nil && [_currentClientName compare:jackViewClient.name] != NSOrderedSame)
+        {
+            JackViewButton* button = [[JackViewButton alloc] initWithFrame:CGRectMake([[_audioInputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins) + kJackViewIconMargins,
+                                                                                kJackViewIconMargins,
+                                                                                kJackViewButtonWidth,
+                                                                                kJackViewButtonHeight)];
+            jackViewClient.audioInputButton = button;
+            button.jackViewClient = jackViewClient;
+            button.jackView = self;
+            button.audioMidi = 1;
+            button.inputOutput = 1;
+            [_audioInputsScrollView addSubview:jackViewClient.audioInputButton];
+        }
+        else if (inputOutput == 1 && audioMidi == 1 && jackViewClient.audioOutputButton == nil && [_currentClientName compare:jackViewClient.name] != NSOrderedSame)
+        {
+            JackViewButton* button = [[JackViewButton alloc] initWithFrame:CGRectMake([[_audioOutputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins) + kJackViewIconMargins,
+                                                                                kJackViewIconMargins,
+                                                                                kJackViewButtonWidth,
+                                                                                kJackViewButtonHeight)];
+            jackViewClient.audioOutputButton = button;
+            button.jackViewClient = jackViewClient;
+            button.jackView = self;
+            button.audioMidi = 1;
+            button.inputOutput = 2;
+            [_audioOutputsScrollView addSubview:jackViewClient.audioOutputButton];
+        }
+        else if (inputOutput == 2 && audioMidi == 2 && jackViewClient.midiInputButton == nil && [_currentClientName compare:jackViewClient.name] != NSOrderedSame)
+        {
+            JackViewButton* button = [[JackViewButton alloc] initWithFrame:CGRectMake([[_midiInputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins) + kJackViewIconMargins,
+                                                                                kJackViewIconMargins,
+                                                                                kJackViewButtonWidth,
+                                                                                kJackViewButtonHeight)];
+            jackViewClient.midiInputButton = button;
+            button.jackViewClient = jackViewClient;
+            button.jackView = self;
+            button.audioMidi = 2;
+            button.inputOutput = 1;
+            [_midiInputsScrollView addSubview:jackViewClient.midiInputButton];
+        }
+        else if (inputOutput == 1 && audioMidi == 2 && jackViewClient.midiOutputButton == nil && [_currentClientName compare:jackViewClient.name] != NSOrderedSame)
+        {
+            JackViewButton* button = [[JackViewButton alloc] initWithFrame:CGRectMake([[_midiOutputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins) + kJackViewIconMargins,
+                                                                                kJackViewIconMargins,
+                                                                                kJackViewButtonWidth,
+                                                                                kJackViewButtonHeight)];
+            jackViewClient.midiOutputButton = button;
+            button.jackViewClient = jackViewClient;
+            button.jackView = self;
+            button.audioMidi = 2;
+            button.inputOutput = 2;
+            [_midiOutputsScrollView addSubview:jackViewClient.midiOutputButton];
+        }
+        
+        [jackViewClient.ports addObject:jackViewPort];
+        
+        // Add client
+        if (![self doesClientExist:clientName])
+        {
+            [_clients addObject:jackViewClient];
+        }
+	}
+    
+    [_audioInputsScrollView setContentSize:CGSizeMake([[_audioInputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins),
+                                                      _audioInputsScrollView.frame.size.height)];
+    [_audioOutputsScrollView setContentSize:CGSizeMake([[_audioOutputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins),
+                                                       _audioOutputsScrollView.frame.size.height)];
+    [_midiInputsScrollView setContentSize:CGSizeMake([[_midiInputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins),
+                                                     _midiInputsScrollView.frame.size.height)];
+    [_midiOutputsScrollView setContentSize:CGSizeMake([[_midiOutputsScrollView subviews] count] * (kJackViewButtonWidth + kJackViewIconMargins),
+                                                      _midiOutputsScrollView.frame.size.height)];
+    
+    [self makeButtonsSymetric];
+    
+    // Add current app icon
+    JackViewButton* button = [[JackViewButton alloc] initWithFrame:CGRectMake(self.frame.size.width / 2. - kJackViewButtonWidth / 2.,
+                                                                              kJackViewExtTopVMargins + kJackViewIconMargins,
+                                                                              kJackViewButtonWidth,
+                                                                              self.frame.size.height - 2. * kJackViewExtBottomVMargins - 2. * kJackViewIconMargins)];
+    button.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
+    button.jackViewClient = [self clientWithName:_currentClientName];
+    button.jackView = self;
+    self.currentClientButton = button;
+    [self addSubview:button];
+    
+    // Deactivate uncomaptible buttons and select connected buttons
+    NSArray* buttons = nil;
+    BOOL compatible = NO;
+    BOOL selected = NO;
+    
+    buttons = [_audioInputsScrollView subviews];
+    compatible = [self hasCurrentClientCompatiblePortWithInputOutput:1 audioMidi:1];
+
+    for (i = 0; i < [buttons count]; ++i)
+    {
+        ((JackViewButton*)([buttons objectAtIndex:i])).enabled = compatible;
+        
+        selected = [self isClient:((JackViewButton*)([buttons objectAtIndex:i])).jackViewClient connectedToCurrentClientInputOutput:1 audioMidi:1];
+        ((JackViewButton*)([buttons objectAtIndex:i])).selected = selected;
+    }
+    
+    buttons = [_audioOutputsScrollView subviews];
+    compatible = [self hasCurrentClientCompatiblePortWithInputOutput:2 audioMidi:1];
+    for (i = 0; i < [buttons count]; ++i)
+    {
+        ((JackViewButton*)([buttons objectAtIndex:i])).enabled = compatible;
+        
+        selected = [self isClient:((JackViewButton*)([buttons objectAtIndex:i])).jackViewClient connectedToCurrentClientInputOutput:2 audioMidi:1];
+        ((JackViewButton*)([buttons objectAtIndex:i])).selected = selected;
+    }
+    
+    buttons = [_midiInputsScrollView subviews];
+    compatible = [self hasCurrentClientCompatiblePortWithInputOutput:1 audioMidi:2];
+    for (i = 0; i < [buttons count]; ++i)
+    {
+        ((JackViewButton*)([buttons objectAtIndex:i])).enabled = compatible;
+        
+        selected = [self isClient:((JackViewButton*)([buttons objectAtIndex:i])).jackViewClient connectedToCurrentClientInputOutput:1 audioMidi:2];
+        ((JackViewButton*)([buttons objectAtIndex:i])).selected = selected;
+    }
+    
+    buttons = [_midiOutputsScrollView subviews];
+    compatible = [self hasCurrentClientCompatiblePortWithInputOutput:2 audioMidi:2];
+    for (i = 0; i < [buttons count]; ++i)
+    {
+        ((JackViewButton*)([buttons objectAtIndex:i])).enabled = compatible;
+        
+        selected = [self isClient:((JackViewButton*)([buttons objectAtIndex:i])).jackViewClient connectedToCurrentClientInputOutput:2 audioMidi:2];
+        ((JackViewButton*)([buttons objectAtIndex:i])).selected = selected;
+    }
+    
+    [self showHideScrollViews];
+    
+    // Free memory
+    jack_free(ports);
+    free(aliases[0]);
+    free(aliases[1]);
+}
+
+- (jack_client_t*)jackClient
+{
+    return _jackClient;
+}
+
+- (BOOL)doesClientExist:(NSString*)clientName
+{
+    int i = 0;
+    int nbClients = [_clients count];
+    
+    for (i = 0; i < nbClients; ++i)
+    {
+        if ([((JackViewClient*)[_clients objectAtIndex:i]).name compare:clientName] == NSOrderedSame)
+        {
+            return YES;
+        }
+    }
+    
+    return NO;
+}
+
+
+- (JackViewClient*)clientWithName:(NSString*)clientName
+{
+    int i = 0;
+    int nbClients = [_clients count];
+    
+    for (i = 0; i < nbClients; ++i)
+    {
+        if ([((JackViewClient*)[_clients objectAtIndex:i]).name compare:clientName] == NSOrderedSame)
+        {
+            return ((JackViewClient*)[_clients objectAtIndex:i]);
+        }
+    }
+    
+    return nil;
+}
+
+- (JackViewPort*)portWithName:(NSString*)portName
+{
+    int i = 0;
+    NSString* clientName = [[portName componentsSeparatedByString:@":"] objectAtIndex:0];
+    JackViewClient* client = [self clientWithName:clientName];
+    int nbPorts = [client.ports count];
+    JackViewPort* port = nil;
+    
+    for (i = 0; i < nbPorts; ++i)
+    {
+        port = (JackViewPort*)[client.ports objectAtIndex:i];
+        if ([port.name compare:portName] == NSOrderedSame)
+        {
+            return port;
+        }
+    }
+
+    return nil;
+}
+
+- (void)makeButtonsSymetric
+{
+    int i = 0;
+    float offset = 0.;
+    
+    // Re-organize audio output scroll view icons
+    if (_audioOutputsScrollView.contentSize.width < _audioOutputsScrollView.frame.size.width)
+    {
+        offset = _audioOutputsScrollView.frame.size.width - _audioOutputsScrollView.contentSize.width;
+        
+        for (i = 0; i < [[_audioOutputsScrollView subviews] count]; ++i)
+        {
+            JackViewButton* button = ((JackViewButton*)[[_audioOutputsScrollView subviews] objectAtIndex:i]);
+            [button setFrame:CGRectMake(i * kJackViewButtonWidth + offset,
+                                        button.frame.origin.y,
+                                        button.frame.size.width,
+                                        button.frame.size.height)];
+        }
+    }
+    
+    // Re-organize midi output scroll view icons
+    if (_midiOutputsScrollView.contentSize.width < _midiOutputsScrollView.frame.size.width)
+    {
+        offset = _midiOutputsScrollView.frame.size.width - _midiOutputsScrollView.contentSize.width;
+        
+        for (i = 0; i < [[_midiOutputsScrollView subviews] count]; ++i)
+        {
+            JackViewButton* button = ((JackViewButton*)[[_midiOutputsScrollView subviews] objectAtIndex:i]);
+            [button setFrame:CGRectMake(i * kJackViewButtonWidth + offset,
+                                        button.frame.origin.y,
+                                        button.frame.size.width,
+                                        button.frame.size.height)];
+        }
+    }
+}
+
+- (BOOL)hasCurrentClientCompatiblePortWithInputOutput:(int)inputOutput audioMidi:(int)audioMidi
+{
+    JackViewClient* currentClient = [self clientWithName:_currentClientName];
+    JackViewPort* port = nil;
+    int nbPorts = [currentClient.ports count];
+    int i = 0;
+    
+    for (i = 0; i < nbPorts; ++i)
+    {
+        port = [currentClient.ports objectAtIndex:i];
+        
+        if (port.inputOutput == inputOutput
+            && port.audioMidi == audioMidi)
+        {
+            return YES;
+        }
+    }
+    
+    return NO;
+}
+
+- (BOOL)isClient:(JackViewClient*)client connectedToCurrentClientInputOutput:(int)inputOutput audioMidi:(int)audioMidi
+{
+    JackViewClient* jackViewAppClient = [self clientWithName:_currentClientName];
+    int nbAppClientPorts = [jackViewAppClient.ports count];
+    int i = 0;
+    int j = 0;
+    JackViewPort* port = nil;
+    const char **connections;
+    NSString* connection = nil;
+    NSString* connectedClient = nil;
+        
+    // Find app client ports connected to client
+    for (i = 0; i < nbAppClientPorts; ++i)
+    {
+        port = [jackViewAppClient.ports objectAtIndex:i];
+                
+        if (port.audioMidi == audioMidi
+            && port.inputOutput == inputOutput)
+        {
+            if ((connections = jack_port_get_all_connections(_jackClient,
+                                                             jack_port_by_name(_jackClient,
+                                                                               [port.name cStringUsingEncoding:NSUTF8StringEncoding]))) != 0)
+            {
+				for (j = 0; connections[j]; j++)
+                {
+                    connection = [NSString stringWithCString:connections[j] encoding:NSUTF8StringEncoding];
+                    connectedClient = [[connection componentsSeparatedByString:@":"] objectAtIndex:0];
+                                        
+                    if ([connectedClient compare:client.name] == NSOrderedSame)
+                    {
+                        jack_free (connections);
+                        return YES;
+                    }
+				}
+				jack_free (connections);
+			}
+        }
+    }
+    
+    return NO;
+}
+
+- (BOOL)isPort:(JackViewPort*)port connectedToCurrentClientInputOutput:(int)inputOutput audioMidi:(int)audioMidi
+{
+    const char **connections;
+    NSString* connection = nil;
+    NSString* connectedClient = nil;
+    int i = 0;
+        
+    if ((connections = jack_port_get_all_connections(_jackClient,
+                                                     jack_port_by_name(_jackClient,
+                                                                       [port.name cStringUsingEncoding:NSUTF8StringEncoding]))) != 0)
+    {
+        for (i = 0; connections[i]; i++)
+        {
+            connection = [NSString stringWithCString:connections[i] encoding:NSUTF8StringEncoding];
+            connectedClient = [[connection componentsSeparatedByString:@":"] objectAtIndex:0];
+                        
+            if ([connectedClient compare:_currentClientName] == NSOrderedSame)
+            {
+                jack_free (connections);
+                return YES;
+            }
+        }
+        jack_free (connections);
+    }
+    
+    return NO;
+}
+
+- (BOOL)isPort:(NSString*)portName1
+connectedWithPort:(NSString*)portName2
+{
+    const char **connections;
+    NSString* connection = nil;
+    int i = 0;
+    
+    if ((connections = jack_port_get_all_connections(_jackClient,
+                                                     jack_port_by_name(_jackClient,
+                                                                       [portName1 cStringUsingEncoding:NSUTF8StringEncoding]))) != 0)
+    {
+        for (i = 0; connections[i]; i++)
+        {
+            connection = [NSString stringWithCString:connections[i] encoding:NSUTF8StringEncoding];
+            
+            if ([connection compare:portName2] == NSOrderedSame)
+            {
+                jack_free (connections);
+                return YES;
+            }
+        }
+        jack_free (connections);
+    }
+    
+    return NO;
+}
+
+- (NSArray*)getCurrentClientPortConnectedTo:(NSString*)portName
+{
+    const char **connections;
+    NSString* connection = nil;
+    NSString* connectedClient = nil;
+    int i = 0;
+    NSMutableArray* array = [NSMutableArray arrayWithCapacity:0];
+    
+    if ((connections = jack_port_get_all_connections(_jackClient,
+                                                     jack_port_by_name(_jackClient,
+                                                                       [portName cStringUsingEncoding:NSUTF8StringEncoding]))) != 0)
+    {
+        for (i = 0; connections[i]; i++)
+        {
+            connection = [NSString stringWithCString:connections[i] encoding:NSUTF8StringEncoding];
+            connectedClient = [[connection componentsSeparatedByString:@":"] objectAtIndex:0];
+            
+            if ([connectedClient compare:_currentClientName] == NSOrderedSame)
+            {
+                [array addObject:connection];
+            }
+        }
+        jack_free (connections);
+    }
+    
+    return array;
+}
+
+// Returns YES if software was able to connect, NO otherwise
+- (BOOL)quicklyConnectAppToClient:(NSString*)clientName
+                      inputOutput:(int)inputOutput
+                        audioMidi:(int)audioMidi
+{
+    JackViewClient* jackViewAppClient = [self clientWithName:_currentClientName];
+    int nbAppClientPorts = [jackViewAppClient.ports count];
+    
+    JackViewClient* jackViewClient = [self clientWithName:clientName];
+    int nbClientPorts = [jackViewClient.ports count];
+    
+    int i = 0;
+    JackViewPort* port = nil;
+    
+    NSMutableArray* jackViewAppClientAvailablePorts = [NSMutableArray arrayWithCapacity:0];
+    NSMutableArray* jackViewClientAvailablePorts = [NSMutableArray arrayWithCapacity:0];
+    
+    // Find connectable ports for app client
+    for (i = 0; i < nbAppClientPorts; ++i)
+    {
+        port = [jackViewAppClient.ports objectAtIndex:i];
+        
+        if (port.audioMidi == audioMidi
+            && port.inputOutput == inputOutput)
+        {
+            [jackViewAppClientAvailablePorts addObject:port];
+        }
+    }
+    
+    // Find connectable ports for client
+    for (i = 0; i < nbClientPorts; ++i)
+    {
+        port = [jackViewClient.ports objectAtIndex:i];
+        
+        if (port.audioMidi == audioMidi
+            && ((inputOutput == 1 && port.inputOutput == 2)
+                || (inputOutput == 2 && port.inputOutput == 1)))
+        {
+            [jackViewClientAvailablePorts addObject:port];
+        }
+    }
+    
+    if ([jackViewAppClientAvailablePorts count] == 0
+        || [jackViewClientAvailablePorts count] == 0)
+    {
+        return NO;
+    }
+    
+    // Connect rules
+    // Audio
+    if (audioMidi == 1)
+    {
+        // Input or output, Same number of inputs for app client and client
+        if ([jackViewAppClientAvailablePorts count] == [jackViewClientAvailablePorts count])
+        {
+            for (i = 0; i < [jackViewAppClientAvailablePorts count]; ++i)
+            {
+                if (inputOutput == 1)
+                {
+                    jack_connect(_jackClient,
+                                 [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:i])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                                 [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:i])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+                }
+                else if (inputOutput == 2)
+                {
+                    jack_connect(_jackClient,
+                                 [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:i])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                                 [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:i])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+                }
+            }
+        }
+        
+        // Input, 2 inputs for app client, 1 output for client
+        else if (inputOutput == 1
+            && [jackViewAppClientAvailablePorts count] == 2
+            && [jackViewClientAvailablePorts count] == 1)
+        {
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:1])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+        }
+        
+        // Input, 1 input for app client, 2 outputs for client
+        else if (inputOutput == 1
+                 && [jackViewAppClientAvailablePorts count] == 1
+                 && [jackViewClientAvailablePorts count] == 2)
+        {
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:1])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+        }
+        
+        // Other input cases
+        else if (inputOutput == 1)
+        {
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+        }
+        
+        // Other output cases
+        else
+        {
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+        }
+    }
+    
+    // Midi
+    else if (audioMidi == 2)
+    {
+        // Input cases
+        if (inputOutput == 1)
+        {
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+        }
+        
+        // Output cases
+        else
+        {
+            
+            jack_connect(_jackClient,
+                         [((JackViewPort*)([jackViewAppClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding],
+                         [((JackViewPort*)([jackViewClientAvailablePorts objectAtIndex:0])).name cStringUsingEncoding:NSUTF8StringEncoding]);
+        }
+    }
+    
+    return YES;
+}
+
+// Returns YES if software was able to disconnect, NO otherwise
+- (BOOL)quicklyDisconnectAppToClient:(NSString*)clientName
+                         inputOutput:(int)inputOutput
+                           audioMidi:(int)audioMidi
+{
+    JackViewClient* jackViewAppClient = [self clientWithName:_currentClientName];
+    int nbAppClientPorts = [jackViewAppClient.ports count];
+    int i = 0;
+    int j = 0;
+    JackViewPort* port = nil;
+    const char **connections;
+    NSString* connection = nil;
+    NSString* client = nil;
+    
+    // Find app client ports connected to client
+    for (i = 0; i < nbAppClientPorts; ++i)
+    {
+        port = [jackViewAppClient.ports objectAtIndex:i];
+        
+        if (port.audioMidi == audioMidi
+            && port.inputOutput == inputOutput)
+        {            
+            if ((connections = jack_port_get_all_connections(_jackClient,
+                                                             jack_port_by_name(_jackClient,
+                                                                               [port.name cStringUsingEncoding:NSUTF8StringEncoding]))) != 0)
+            {
+				for (j = 0; connections[j]; j++)
+                {
+                    connection = [NSString stringWithCString:connections[j] encoding:NSUTF8StringEncoding];
+                    client = [[connection componentsSeparatedByString:@":"] objectAtIndex:0];
+                                        
+                    if ([client compare:_currentClientName])
+                    {
+                        if (inputOutput == 1)
+                        {
+                            jack_disconnect(_jackClient,
+                                            connections[j],
+                                            [port.name cStringUsingEncoding:NSUTF8StringEncoding]);
+                        }
+                        else if (inputOutput == 2)
+                        {
+                            jack_disconnect(_jackClient,
+                                            [port.name cStringUsingEncoding:NSUTF8StringEncoding],
+                                            connections[j]);
+                        }
+                    }
+				}
+				jack_free (connections);
+			}
+        }
+    }
+    
+    return YES;
+}
+
+- (void)connectPort:(NSString*)inputPort
+           withPort:(NSString*)outputPort
+{    
+    jack_connect(_jackClient,
+                 [inputPort cStringUsingEncoding:NSUTF8StringEncoding],
+                 [outputPort cStringUsingEncoding:NSUTF8StringEncoding]);
+}
+
+- (void)disconnectPort:(NSString*)inputPort
+              withPort:(NSString*)outputPort
+{
+    jack_disconnect(_jackClient,
+                    [inputPort cStringUsingEncoding:NSUTF8StringEncoding],
+                    [outputPort cStringUsingEncoding:NSUTF8StringEncoding]);
+}
+
+- (BOOL)isPointInsideCurrentAppIcon:(CGPoint)pt
+{
+    return (pt.x >= self.currentClientButton.frame.origin.x
+            && pt.x <= self.currentClientButton.frame.origin.x + self.currentClientButton.frame.size.width
+            && pt.y >= self.currentClientButton.frame.origin.y
+            && pt.y <= self.currentClientButton.frame.origin.y + self.currentClientButton.frame.size.height);
+}
+
+- (BOOL)isPointInsideView:(CGPoint)pt
+{
+    return (pt.x >= 0
+            && pt.x <= self.frame.size.width
+            && pt.y >= 0
+            && pt.y <= self.frame.size.height);
+}
+
+
+// Refresh view
+- (void)drawRect:(CGRect)rect
+{
+    UIBezierPath* path = [UIBezierPath bezierPath];
+    CGPoint pt;
+    UIFont* font = [UIFont systemFontOfSize:11.0f];
+    NSString* str = nil;
+    
+    [[UIColor colorWithWhite:0.8 alpha:0.95] set];
+    
+    [path moveToPoint:CGPointMake(rect.origin.x, rect.origin.y)];
+    [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y)];
+    [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height)];
+    [path addLineToPoint:CGPointMake(rect.origin.x, rect.origin.y + rect.size.height)];
+    [path closePath];
+    [path fillWithBlendMode:kCGBlendModeNormal alpha:1.];
+    
+    // In / Out
+    [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jackview-in" ofType:@"png"]] drawAtPoint:CGPointMake(kJackViewExtHMargins, 0)];
+    [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jackview-out" ofType:@"png"]] drawAtPoint:CGPointMake(rect.origin.x + rect.size.width - 75 - kJackViewExtHMargins, 0)];
+    
+    // Left section
+    //   Input(s)
+    if (!_audioInputsScrollView.hidden
+        || !_midiInputsScrollView.hidden)
+    {
+        [path removeAllPoints];
+        [[UIColor colorWithWhite:0. alpha:0.6] set];
+        [path moveToPoint:CGPointMake(0, kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins)];
+        [path addLineToPoint:CGPointMake(rect.size.width / 2., kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins)];
+        [path stroke];
+        
+        [[UIColor blackColor] set];
+        pt = CGPointMake(currentClientButton.frame.origin.x,
+                         kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins);
+        [path removeAllPoints];
+        [path moveToPoint:CGPointMake(pt.x - 8, pt.y - 2.5)];
+        [path addLineToPoint:CGPointMake(pt.x + 2, pt.y)];
+        [path addLineToPoint:CGPointMake(pt.x - 8, pt.y + 2.5)];
+        [path closePath];
+        [path fill];
+    }
+    
+    //   No input
+    else
+    {
+        if (self.audioButton.selected) str = @"no audio input";
+        else str = @"no midi input";
+        pt = CGPointMake((float)kJackViewExtHMargins,
+                         (float)(kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins));
+        [[UIColor blackColor] set];
+        [str drawAtPoint:pt
+                withFont:font];
+    }
+    
+    
+    // Right section
+    //   Output(s)
+    if (!_audioInputsScrollView.hidden
+        || !_midiInputsScrollView.hidden)
+    {
+        [path removeAllPoints];
+        [[UIColor colorWithWhite:0. alpha:0.6] set];
+        [path moveToPoint:CGPointMake(rect.size.width / 2., kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins)];
+        [path addLineToPoint:CGPointMake(rect.size.width, kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins)];
+        [path stroke];
+        
+        [[UIColor blackColor] set];
+        pt = CGPointMake(currentClientButton.frame.origin.x + currentClientButton.frame.size.width + 10,
+                         kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins);
+        [path removeAllPoints];
+        [path moveToPoint:CGPointMake(pt.x - 11, pt.y - 2.5)];
+        [path addLineToPoint:CGPointMake(pt.x - 1, pt.y)];
+        [path addLineToPoint:CGPointMake(pt.x - 11, pt.y + 2.5)];
+        [path closePath];
+        [path fill];
+    }
+    
+    //   No output
+    else
+    {
+        if (self.audioButton.selected) str = @"no audio output";
+        else str = @"no midi output";
+        CGSize stringBoundingBox = [str sizeWithFont:font];
+        pt = CGPointMake(self.frame.size.width - stringBoundingBox.width - kJackViewExtHMargins,
+                         kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins);
+        [[UIColor blackColor] set];
+        [str drawAtPoint:pt
+                withFont:font];
+    }
+    
+    // Right section
+    
+    /*[path removeAllPoints];
+    [path moveToPoint:CGPointMake(0, kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins)];
+    [path addLineToPoint:CGPointMake(rect.size.width, kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins)];
+    [path stroke];
+
+    [[UIColor blackColor] set];
+    
+    pt = CGPointMake(currentClientButton.frame.origin.x,
+                     kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins);
+    [path removeAllPoints];
+    [path moveToPoint:CGPointMake(pt.x - 8, pt.y - 2.5)];
+    [path addLineToPoint:CGPointMake(pt.x + 2, pt.y)];
+    [path addLineToPoint:CGPointMake(pt.x - 8, pt.y + 2.5)];
+    [path closePath];
+    [path fill];
+    
+    pt = CGPointMake(currentClientButton.frame.origin.x + currentClientButton.frame.size.width + 10,
+                     kJackViewExtTopVMargins + kJackViewButtonWidth / 2. + kJackViewIconMargins);
+    [path removeAllPoints];
+    [path moveToPoint:CGPointMake(pt.x - 11, pt.y - 2.5)];
+    [path addLineToPoint:CGPointMake(pt.x - 1, pt.y)];
+    [path addLineToPoint:CGPointMake(pt.x - 11, pt.y + 2.5)];
+    [path closePath];
+    [path fill];*/
+}
+
+- (int)numberOfCurrentAppPortsWithInputOutput:(int)inputOutput
+                                    audioMidi:(int)audioMidi
+{
+    JackViewClient* client = [self clientWithName:_currentClientName];
+    JackViewPort* port = nil;
+    int nbPorts = [client.ports count];
+    int i = 0;
+    int cpt = 0;
+    
+    // Find ports to display
+    for (i = 0; i < nbPorts; ++i)
+    {
+        port = [client.ports objectAtIndex:i];
+        
+        if (((port.inputOutput == 1 && inputOutput == 2) || (port.inputOutput == 2 && inputOutput == 1))
+            && port.audioMidi == audioMidi)
+        {
+            cpt++;
+        }
+    }
+    
+    return cpt;
+}
+
+- (void)displayCurrentAppPortsWithInputOutput:(int)inputOutput audioMidi:(int)audioMidi
+{
+    JackViewClient* client = [self clientWithName:_currentClientName];
+    JackViewPort* port = nil;
+    int nbPorts = [client.ports count];
+    int i = 0;
+    NSMutableArray* portsArray = [NSMutableArray arrayWithCapacity:0];
+    
+    // Find ports to display
+    for (i = 0; i < nbPorts; ++i)
+    {
+        port = [client.ports objectAtIndex:i];
+        
+        if (((port.inputOutput == 1 && inputOutput == 2) || (port.inputOutput == 2 && inputOutput == 1))
+            && port.audioMidi == audioMidi)
+        {
+            [portsArray addObject:port];
+        }
+    }
+
+    for (i = 0; i < [portsArray count]; ++i)
+    {
+        JackViewPortsViewItem* item = [[JackViewPortsViewItem alloc] initWithFrame:CGRectMake(self.portsView.currentAppX, i * kPortsViewItemHeight, kPortsViewItemWidth, kPortsViewItemHeight)];
+        
+        item.longName = ((JackViewPort*)([portsArray objectAtIndex:i])).name;
+        item.selected = [self isPort:((JackViewPort*)([portsArray objectAtIndex:i]))
+     connectedToCurrentClientInputOutput:((JackViewPort*)([portsArray objectAtIndex:i])).inputOutput
+                               audioMidi:((JackViewPort*)([portsArray objectAtIndex:i])).audioMidi];
+        
+        [self.portsView addItem:item];
+    }
+}
+
+- (void)viewClicked
+{
+    [self dismissPortsView];
+}
+
+- (void)dismissPortsView
+{
+    if (portsView)
+    {
+        [portsView removeFromSuperview];
+        [portsView release];
+        portsView = nil;
+        [self.superview setNeedsDisplay];
+        
+        // Fade in
+        CATransition *animation = [CATransition animation];
+        [animation setDuration:0.3];
+        [animation setType:kCATransitionFade];
+        [animation setSubtype:kCATransitionFromLeft];
+        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+        
+        [[self.window layer] addAnimation:animation forKey:@"DismissPortsView"];
+    }
+}
+
+- (void)fsToClient
+{    
+    if (!self.portsView) return;
+    
+    NSString* clientName = self.portsView.clientButton.jackViewClient.name;
+    
+    // Switch to Jack server
+    if ([clientName compare:@"system"] == NSOrderedSame
+        || [clientName compare:@"system_midi"] == NSOrderedSame)
+    {
+        jack_gui_switch_to_client([self jackClient], "jack");
+    }
+    
+    // Switch to other client
+    else
+    {
+        jack_gui_switch_to_client([self jackClient], [clientName cStringUsingEncoding:NSUTF8StringEncoding]);
+    }
+}
+
+- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
+{
+    [self dismissPortsView];
+}
+
+- (void)showHideScrollViews
+{
+    if (self.audioButton.selected)
+    {
+        _audioInputsScrollView.hidden = ![self hasCurrentClientCompatiblePortWithInputOutput:1 audioMidi:1];
+        _audioOutputsScrollView.hidden = ![self hasCurrentClientCompatiblePortWithInputOutput:2 audioMidi:1];
+        _midiInputsScrollView.hidden = YES;
+        _midiOutputsScrollView.hidden = YES;
+    }
+    else if (self.midiButton.selected)
+    {
+        _audioInputsScrollView.hidden = YES;
+        _audioOutputsScrollView.hidden = YES;
+        _midiInputsScrollView.hidden = ![self hasCurrentClientCompatiblePortWithInputOutput:1 audioMidi:2];
+        _midiOutputsScrollView.hidden = ![self hasCurrentClientCompatiblePortWithInputOutput:2 audioMidi:2];
+    }
+}
+
+ at end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/architecture/iOS/iOS/JackViewPortsView.h b/architecture/iOS/iOS/JackViewPortsView.h
new file mode 100644
index 0000000..dc3b370
--- /dev/null
+++ b/architecture/iOS/iOS/JackViewPortsView.h
@@ -0,0 +1,73 @@
+//
+//  JackViewPortsView.h
+//  iOS
+//
+//  Created by Olivier Guillerminet on 29/04/13.
+//
+//
+
+#import <UIKit/UIKit.h>
+
+#define kPortsViewItemWidth 100
+#define kPortsViewItemHeight 50
+#define kPortsViewArrowHeight 30
+#define kPortsViewArrowWidth 30
+#define kPortsViewMinXBetweenItems 120
+#define kPortsViewFSButtonWidth 30
+#define kPortsViewFSButtonHeight 30
+#define kPortsViewMaxHeight 150
+
+#import "JackViewPortsViewBackgroundView.h"
+
+ at class JackViewButton;
+
+ at interface JackViewPortsViewItem : UIControl
+
+ at property (assign, nonatomic) NSString* longName;
+ at property (assign, nonatomic) NSString* alias;
+ at property (assign, nonatomic) BOOL touching;
+
+ at end
+
+
+ at interface JackViewPortsLink : NSObject
+
+ at property (assign, nonatomic) CGPoint srcPt;
+ at property (assign, nonatomic) CGPoint dstPt;
+ at property (assign, nonatomic) NSString* srcName;
+ at property (assign, nonatomic) NSString* dstName;
+ at property (assign, nonatomic) BOOL selected;
+
+ at end
+
+
+ at interface JackViewPortsView : UIView
+{
+    UIScrollView*           _scrollView;
+    UITapGestureRecognizer* _tapRecognizer;
+}
+
+ at property (assign, nonatomic) JackViewButton* clientButton;
+ at property (assign, nonatomic) UIButton* fsButton;
+ at property (assign, nonatomic) float clientX;
+ at property (assign, nonatomic) float currentAppX;
+ at property (assign, nonatomic) BOOL linking;
+ at property (assign, nonatomic) BOOL dontDrawLinking;
+ at property (assign, readwrite) CGPoint srcPt;
+ at property (assign, readwrite) CGPoint dstPt;
+ at property (assign, readwrite) JackViewPortsViewBackgroundView* backgroundView;
+ at property (assign, readwrite) NSMutableArray* links;
+ at property (assign, readwrite) UIButton* deleteButton;
+
+- (void)refreshLinks;
+- (void)deleteSelectedLink;
+- (JackViewPortsViewItem*)itemAtPoint:(CGPoint)pt;
+- (void)singleTap:(UIGestureRecognizer *)gestureRecognizer;
+- (float)computeXOffsetWithXItems:(float)xItems xIcon:(float)xIcon;
+- (void)setUtilHeight:(float)h;
+- (void)addItem:(JackViewPortsViewItem*)item;
+- (void)refreshScrollViewOffset:(float)y;
+- (NSArray*)portsItems;
+- (void)connectIfTouchingTwoItems;
+
+ at end
diff --git a/architecture/iOS/iOS/JackViewPortsView.mm b/architecture/iOS/iOS/JackViewPortsView.mm
new file mode 100644
index 0000000..649ac57
--- /dev/null
+++ b/architecture/iOS/iOS/JackViewPortsView.mm
@@ -0,0 +1,616 @@
+//
+//  JackViewPortsView.m
+//  iOS
+//
+//  Created by Olivier Guillerminet on 29/04/13.
+//
+//
+
+#import "JackViewPortsView.h"
+#import "JackView.h"
+
+
+ at implementation JackViewPortsViewItem
+
+ at synthesize longName;
+ at synthesize touching;
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+        self.backgroundColor = [UIColor clearColor];
+        self.longName = nil;
+        self.touching = NO;
+    }
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect
+{
+    self.backgroundColor = [UIColor clearColor];
+
+    // Draw selection
+    //if (self.selected)
+    {
+        UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(rect.origin.x + 1.,
+                                                                                rect.origin.y + 5.,
+                                                                                rect.size.width - 2.,
+                                                                                rect.size.height - 10.)
+                                                        cornerRadius:10.];
+        path.lineWidth = 1.5;
+        
+        /*[path moveToPoint:CGPointMake(rect.origin.x, rect.origin.y + 1)];
+        [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + 1)];
+        [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - 1)];
+        [path addLineToPoint:CGPointMake(rect.origin.x, rect.origin.y + rect.size.height - 1)];
+        [path closePath];*/
+        
+        [[UIColor colorWithWhite:0.8 alpha:1.] set];
+        [path fillWithBlendMode:kCGBlendModeNormal alpha:1.];
+        
+        [[UIColor blackColor] set];
+        [path strokeWithBlendMode:kCGBlendModeNormal alpha:1.];
+    }
+    
+    if (self.longName)
+    {
+        UIFont* font = [UIFont systemFontOfSize:16.0f];
+        NSString* str = [[self.longName componentsSeparatedByString:@":"] objectAtIndex:1];
+        CGSize stringBoundingBox = [str sizeWithFont:font];
+        [[UIColor blackColor] set];
+        
+        [str drawAtPoint:CGPointMake((rect.size.width - stringBoundingBox.width) / 2., 14.f)
+                withFont:font];
+    }
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    JackViewPortsView* portsView = (JackViewPortsView*)(self.superview.superview);
+    NSEnumerator* enumerator = [touches objectEnumerator];
+    UITouch* touch;
+    
+    if ([touches count] == 1)
+    {
+        portsView.dontDrawLinking = NO;
+    }
+    
+    portsView.linking = NO;
+    self.touching = YES;
+    
+    [portsView connectIfTouchingTwoItems];
+    
+    while ((touch = (UITouch*)[enumerator nextObject]))
+    {
+        if (self.frame.origin.x == fminf(portsView.clientX, portsView.currentAppX))
+        {
+            portsView.srcPt = CGPointMake(self.frame.origin.x + self.frame.size.width, self.frame.origin.y + self.frame.size.height / 2.);
+        }
+        else
+        {
+            portsView.srcPt = CGPointMake(self.frame.origin.x, self.frame.origin.y + self.frame.size.height / 2.);
+        }
+    }
+    
+    [portsView setNeedsDisplay];
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    JackViewPortsView* portsView = (JackViewPortsView*)(self.superview.superview);
+        
+    NSEnumerator* enumerator = [touches objectEnumerator];
+    UITouch* touch;
+    
+    self.touching = YES;
+    
+    while ((touch = (UITouch*)[enumerator nextObject]))
+    {
+        if ([touch locationInView:self].x < self.frame.origin.x
+            || [touch locationInView:self].x > self.frame.origin.x + self.frame.size.width
+            || [touch locationInView:self].y < self.frame.origin.y
+            || [touch locationInView:self].y > self.frame.origin.y + self.frame.size.height)
+        {
+            portsView.linking = YES;
+            portsView.dstPt = CGPointMake([touch locationInView:portsView.backgroundView].x, [touch locationInView:portsView.backgroundView].y);
+            [portsView refreshScrollViewOffset:[touch locationInView:portsView.backgroundView].y];
+        }
+    }
+
+    [portsView setNeedsDisplay];
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    JackViewPortsView* portsView = (JackViewPortsView*)(self.superview.superview);
+    JackView* jackView = portsView.clientButton.jackView;
+    
+    [jackView setNeedsDisplay];
+    
+    NSEnumerator* enumerator = [touches objectEnumerator];
+    UITouch* touch;
+    NSString* dstAppPortName = nil;
+    if ([touches count] == 1)
+    {
+        self.touching = NO;
+    }
+    
+    while ((touch = (UITouch*)[enumerator nextObject]))
+    {
+        JackViewPortsViewItem* item = [portsView itemAtPoint:CGPointMake([touch locationInView:portsView.backgroundView].x,
+                                                                         [touch locationInView:portsView.backgroundView].y)];
+
+        if (item && [item isKindOfClass:[JackViewPortsViewItem class]])
+        {
+            // Connect new link
+            dstAppPortName = item.longName;
+            
+            [jackView connectPort:self.longName withPort:dstAppPortName];
+            [jackView connectPort:dstAppPortName withPort:self.longName];
+            
+            self.selected = YES;
+            [self setNeedsDisplay];
+            
+            portsView.clientButton.selected = YES;
+        }            
+    }
+    
+    portsView.linking = NO;
+    [portsView refreshLinks];
+    [portsView setNeedsDisplay];
+    [jackView setNeedsDisplay];
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+    JackViewPortsView* portsView = (JackViewPortsView*)(self.superview.superview);
+    
+    portsView.linking = NO;
+    self.touching = NO;
+    
+    [portsView refreshLinks];
+    [portsView setNeedsDisplay];
+}
+
+ at end
+
+
+ at implementation JackViewPortsLink
+
+ at synthesize srcPt;
+ at synthesize dstPt;
+ at synthesize srcName;
+ at synthesize dstName;
+ at synthesize selected;
+
+- (id)init
+{
+    self = [super init];
+    if (self)
+    {
+        self.srcPt = CGPointMake(0., 0.);
+        self.dstPt = CGPointMake(0., 0.);
+        self.srcName = nil;
+        self.dstName = nil;
+        self.selected = NO;
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    [self.srcName release];
+    [self.dstName release];
+    [super dealloc];
+}
+
+ at end
+
+
+
+ at implementation JackViewPortsView
+
+ at synthesize clientButton;
+ at synthesize clientX;
+ at synthesize currentAppX;
+ at synthesize linking;
+ at synthesize srcPt;
+ at synthesize dstPt;
+ at synthesize backgroundView;
+ at synthesize links;
+ at synthesize deleteButton;
+ at synthesize dontDrawLinking;
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+        // Add scroll view
+        _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,
+                                                                     0,
+                                                                     frame.size.width,
+                                                                     frame.size.height - kPortsViewFSButtonHeight - kPortsViewArrowHeight)];
+        [self addSubview:_scrollView];
+        
+        // Add background view in scroll view
+        self.backgroundView = [[JackViewPortsViewBackgroundView alloc] initWithFrame:_scrollView.frame];
+        [_scrollView addSubview:self.backgroundView];
+        
+        self.backgroundColor = [UIColor clearColor];
+        self.clientButton = nil;
+        self.clientX = 0.;
+        self.currentAppX = 0.;
+        self.linking = NO;
+        self.dontDrawLinking = NO;
+        self.links = [[NSMutableArray alloc] initWithCapacity:0];
+        _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
+        _tapRecognizer.numberOfTapsRequired = 1;
+        [self addGestureRecognizer:_tapRecognizer];
+        self.deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
+        //[self.deleteButton setTitle:@"X" forState:UIControlStateNormal];
+        [self.deleteButton setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon-Delete" ofType:@"png"]] forState:UIControlStateNormal];
+        [self.deleteButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
+        [self.deleteButton setFrame:CGRectMake(0, 0, 20, 20)];
+        self.deleteButton.showsTouchWhenHighlighted = YES;
+        self.deleteButton.hidden = YES;
+        [self.deleteButton addTarget:self action:@selector(deleteSelectedLink) forControlEvents:UIControlEventTouchUpInside];
+        [_scrollView addSubview:self.deleteButton];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    [self.links release];
+    [_scrollView release];
+    [super dealloc];
+}
+
+- (float)computeXOffsetWithXItems:(float)xItems xIcon:(float)xIcon
+{
+    float xOffset = 0.;
+    
+    if (xItems + kPortsViewItemWidth <= xIcon)                          xOffset = kPortsViewItemWidth - kPortsViewArrowWidth;
+    else if (xItems <= xIcon && xItems + kPortsViewItemWidth >= xIcon)  xOffset = xIcon - xItems;
+    else if (xItems == xIcon)                                       xOffset = 0;
+    
+    return xOffset;
+}
+
+- (void)drawRect:(CGRect)rect
+{
+    int i = 0;
+    JackView* jackView = self.clientButton.jackView;
+    float xItems = 0.;
+    float xIcon = 0.;
+    float xOffset = 0.;
+    CGContextRef context;
+    UIBezierPath* path = [UIBezierPath bezierPath];
+
+    // Background
+    self.backgroundColor = [UIColor clearColor];
+        
+    [[UIColor colorWithWhite:0.8 alpha:0.95] set];
+    
+    [path moveToPoint:CGPointMake(rect.origin.x, rect.origin.y)];
+    [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y)];
+    [path addLineToPoint:CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - kPortsViewArrowHeight)];
+    [path addLineToPoint:CGPointMake(rect.origin.x, rect.origin.y + rect.size.height - kPortsViewArrowHeight)];
+    [path closePath];
+    [path fillWithBlendMode:kCGBlendModeNormal alpha:1.];
+        
+    // Ports
+    for (i = 0; i < [[self subviews] count]; ++i)
+    {
+        [[[self subviews] objectAtIndex:i] setNeedsDisplay];
+    }
+        
+    // Client arrow
+    xItems = clientX;
+    xIcon = [clientButton convertPoint:CGPointMake(0, 0) toView:self].x;
+    
+    xOffset = [self computeXOffsetWithXItems:xItems xIcon:xIcon];
+    
+    context = UIGraphicsGetCurrentContext();
+    CGContextBeginPath(context);
+    CGContextMoveToPoint(context,
+                         clientX + xOffset,
+                         self.frame.size.height - kPortsViewArrowHeight);
+    CGContextAddLineToPoint(context,
+                            fmin(clientX + kPortsViewArrowWidth + xOffset, clientX + kPortsViewItemWidth),
+                            self.frame.size.height - kPortsViewArrowHeight);
+    CGContextAddLineToPoint(context,
+                            [clientButton convertPoint:CGPointMake(0, 0) toView:self].x + kPortsViewArrowWidth / 2.,
+                            self.frame.size.height);
+    CGContextClosePath(context);
+    
+    CGContextFillPath(context);
+    
+    // Current app arrow
+    xItems = currentAppX;
+    xIcon = jackView.currentClientButton.frame.origin.x;
+    
+    xOffset = [self computeXOffsetWithXItems:xItems xIcon:xIcon];
+    
+    CGContextBeginPath(context);
+    CGContextMoveToPoint(context,
+                         currentAppX + xOffset,
+                         self.frame.size.height - kPortsViewArrowHeight);
+    CGContextAddLineToPoint(context,
+                            fmin(currentAppX + kPortsViewArrowWidth + xOffset, currentAppX + kPortsViewItemWidth),
+                            self.frame.size.height - kPortsViewArrowHeight);
+    CGContextAddLineToPoint(context,
+                            jackView.currentClientButton.frame.origin.x + kPortsViewArrowWidth / 2.,
+                            self.frame.size.height);
+    CGContextClosePath(context);
+    
+    CGContextFillPath(context);
+        
+    // Links
+    [self.backgroundView setNeedsDisplay];
+}
+
+- (void)refreshLinks
+{
+    // Links
+    int i = 0;
+    int j = 0;
+    int k = 0;
+    NSArray* buttons = [_scrollView subviews];
+    JackViewPortsViewItem* srcItem = nil;
+    JackViewPortsViewItem* dstItem = nil;
+    JackView* jackView = self.clientButton.jackView;
+    CGPoint tmpSrcPt;
+    CGPoint tmpDstPt;
+    NSString* srcName = nil;
+    NSString* dstName = nil;
+    NSArray* dstArray = nil;
+    
+    [self.links removeAllObjects];
+    self.deleteButton.hidden = YES;
+    
+    for (i = 0; i < [buttons count]; ++i)
+    {
+        srcItem = ((JackViewPortsViewItem*)([buttons objectAtIndex:i]));
+        if ([srcItem isKindOfClass:[JackViewPortsViewItem class]] && srcItem.frame.origin.x == clientX)
+        {
+            if ([jackView isPort:[jackView portWithName:srcItem.longName] connectedToCurrentClientInputOutput:self.clientButton.inputOutput audioMidi:self.clientButton.audioMidi])
+            {
+                srcName = srcItem.longName;
+                
+                if (srcItem.frame.origin.x == fminf(self.clientX, self.currentAppX))
+                {
+                    tmpSrcPt = CGPointMake(srcItem.frame.origin.x + srcItem.frame.size.width,
+                                           srcItem.frame.origin.y + srcItem.frame.size.height / 2.);
+                }
+                else
+                {
+                    tmpSrcPt = CGPointMake(srcItem.frame.origin.x,
+                                           srcItem.frame.origin.y + srcItem.frame.size.height / 2.);
+                }
+                
+                dstArray = [jackView getCurrentClientPortConnectedTo:srcName];
+                
+                for (j = 0; j < [buttons count]; ++j)
+                {
+                    dstItem = (JackViewPortsViewItem*)[buttons objectAtIndex:j];
+                    
+                    if ([dstItem isKindOfClass:[JackViewPortsViewItem class]] && dstItem.frame.origin.x == currentAppX)
+                    {
+                        for (k = 0; k < [dstArray count]; ++k)
+                        {
+                            dstName = [[NSString alloc] initWithFormat:@"%@", (NSString*)[dstArray objectAtIndex:k]];
+                            
+                            if ([dstItem.longName compare:dstName] == NSOrderedSame)
+                            {
+                                if (dstItem.frame.origin.x == fminf(self.clientX, self.currentAppX))
+                                {
+                                    tmpDstPt = CGPointMake(dstItem.frame.origin.x + dstItem.frame.size.width,
+                                                           dstItem.frame.origin.y + dstItem.frame.size.height / 2.);
+                                }
+                                else
+                                {
+                                    tmpDstPt = CGPointMake(dstItem.frame.origin.x,
+                                                           dstItem.frame.origin.y + dstItem.frame.size.height / 2.);
+                                }
+                                
+                                JackViewPortsLink* link = [[JackViewPortsLink alloc] init];
+                                link.srcPt = CGPointMake(tmpSrcPt.x, tmpSrcPt.y);
+                                link.dstPt = CGPointMake(tmpDstPt.x, tmpDstPt.y);
+                                link.srcName = srcName;
+                                link.dstName = dstName;
+                                [self.links addObject:link];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+- (void)deleteSelectedLink
+{
+    int i = 0;
+    JackViewPortsLink* link = nil;
+    JackView* jackView = self.clientButton.jackView;
+    
+    for (i = 0; i < [self.links count]; ++i)
+    {
+        link = [self.links objectAtIndex:i];
+
+        if (link.selected)
+        {
+            [clientButton.jackView disconnectPort:link.srcName withPort:link.dstName];
+            [clientButton.jackView disconnectPort:link.dstName withPort:link.srcName];
+            
+            clientButton.selected = [jackView isClient:clientButton.jackViewClient connectedToCurrentClientInputOutput:clientButton.inputOutput audioMidi:clientButton.audioMidi];
+        }
+    }
+    
+    self.deleteButton.hidden = YES;
+    [self refreshLinks];
+    [self setNeedsDisplay];
+}
+
+- (JackViewPortsViewItem*)itemAtPoint:(CGPoint)pt
+{
+    NSArray* items = [_scrollView subviews];
+    JackViewPortsViewItem* item = nil;
+    int i = 0;
+    
+    pt.y = pt.y;
+    
+    for (i = 0; i < [items count]; ++i)
+    {
+        item = (JackViewPortsViewItem*)[items objectAtIndex:i];
+        if ([item isKindOfClass:[JackViewPortsViewItem class]]
+            && pt.x >= item.frame.origin.x
+            && pt.x <= item.frame.origin.x +item.frame.size.width
+            && pt.y >= item.frame.origin.y
+            && pt.y <= item.frame.origin.y +item.frame.size.height)
+        {
+            return item;
+        }
+    }
+    
+    return nil;
+}
+
+- (void)singleTap:(UIGestureRecognizer *)gestureRecognizer
+{
+    CGPoint pt = [gestureRecognizer locationInView:self.backgroundView];
+    float a = 0.f;
+    float b = 0.f;
+    float c = 0.f;
+    float m = 0.f;
+    float p = 0.f;
+    JackViewPortsLink* link = nil;
+    int i = 0;
+    int minLinkIndex = -1;
+    float dist = 0.;
+    float minDist = 100000.;
+    
+    self.deleteButton.hidden = YES;
+    
+    // Look for nearest link
+    for (i = 0; i < [self.links count]; ++i)
+    {
+        link = [self.links objectAtIndex:i];
+        link.selected = NO;
+        
+        if (pt.x > fminf(link.srcPt.x, link.dstPt.x)
+            && pt.x < fmaxf(link.srcPt.x, link.dstPt.x))
+        {
+            // Compute link equation : y = mx + p
+            m = (link.dstPt.y - link.srcPt.y) / (link.dstPt.x - link.srcPt.x);
+            p = link.srcPt.y - m * link.srcPt.x;
+            
+            // Convert link equation to ax + by + c = 0
+            b = 1.;
+            a = -m;
+            c = -p;
+            
+            // Compute distance from pt to line
+            dist = fabsf(a * pt.x + b * pt.y + c) / sqrt(a * a + b * b);
+            
+            if (dist <= 10)
+            {
+                // Compare distance with min distance
+                minDist = fminf(minDist, dist);
+                
+                // If this current link is the nearest, keep its index
+                if (minDist == dist)
+                {
+                    minLinkIndex = i;
+                }
+            }
+        }
+    }
+    
+    if (minLinkIndex != -1)
+    {
+        float x = 0.f;
+        float y = 0.f;
+        
+        link = [self.links objectAtIndex:minLinkIndex];
+        link.selected = YES;
+        
+        x = fmaxf(link.dstPt.x, link.srcPt.x);
+        if (x == link.dstPt.x) y = link.dstPt.y;
+        else y = link.srcPt.y;
+        
+        [self.deleteButton setFrame:CGRectMake(x - 30,
+                                               (y - 20) * 0.8 + (y - 20) * 0.2,
+                                               20,
+                                               20)];
+    }
+    
+    [self setNeedsDisplay];
+}
+
+- (void)setUtilHeight:(float)h
+{
+    [backgroundView setFrame:CGRectMake(0, 0, self.frame.size.width, h)];
+    [_scrollView setContentSize:CGSizeMake(self.frame.size.width, h)];
+}
+
+- (void)addItem:(JackViewPortsViewItem*)item
+{
+    [_scrollView addSubview:item];
+}
+
+- (void)refreshScrollViewOffset:(float)y
+{
+    [_scrollView scrollRectToVisible:CGRectMake(0, y, 1, 1) animated:NO];
+}
+
+- (NSArray*)portsItems
+{
+    return [_scrollView subviews];
+}
+
+- (void)connectIfTouchingTwoItems
+{
+    JackViewPortsViewItem* item = nil;
+    JackViewPortsViewItem* item1 = nil;
+    JackViewPortsViewItem* item2 = nil;
+    int i = 0;
+    NSArray* items = [_scrollView subviews];
+    JackView* jackView = self.clientButton.jackView;
+    
+    for (i = 0; i < [items count]; ++i)
+    {
+        item = ((JackViewPortsViewItem*)[items objectAtIndex:i]);
+        if (item && [item isKindOfClass:[JackViewPortsViewItem class]] && item.touching)
+        {
+            if (!item1) item1 = item;
+            else if (!item2) item2 = item;
+        }
+    }
+    
+    if (item1 && item2)
+    {
+        if ([jackView isPort:item1.longName
+            connectedWithPort:item2.longName])
+        {
+            [jackView disconnectPort:item1.longName withPort:item2.longName];
+            [jackView disconnectPort:item2.longName withPort:item1.longName];
+        }
+        else
+        {
+            [jackView connectPort:item1.longName withPort:item2.longName];
+            [jackView connectPort:item2.longName withPort:item1.longName];
+        }
+        
+        self.linking = NO;
+        self.dontDrawLinking = YES;
+        
+        [self setNeedsDisplay];
+    }
+}
+
+ at end
diff --git a/architecture/iOS/iOS/JackViewPortsViewBackgroundView.h b/architecture/iOS/iOS/JackViewPortsViewBackgroundView.h
new file mode 100644
index 0000000..43d9103
--- /dev/null
+++ b/architecture/iOS/iOS/JackViewPortsViewBackgroundView.h
@@ -0,0 +1,13 @@
+//
+//  JackViewPortsViewBackgroundView.h
+//  iOS
+//
+//  Created by Olivier Guillerminet on 13/06/13.
+//
+//
+
+#import <UIKit/UIKit.h>
+
+ at interface JackViewPortsViewBackgroundView : UIView
+
+ at end
diff --git a/architecture/iOS/iOS/JackViewPortsViewBackgroundView.mm b/architecture/iOS/iOS/JackViewPortsViewBackgroundView.mm
new file mode 100644
index 0000000..5f4432f
--- /dev/null
+++ b/architecture/iOS/iOS/JackViewPortsViewBackgroundView.mm
@@ -0,0 +1,99 @@
+//
+//  JackViewPortsViewBackgroundView.m
+//  iOS
+//
+//  Created by Olivier Guillerminet on 13/06/13.
+//
+//
+
+#import "JackViewPortsViewBackgroundView.h"
+#import "JackViewPortsView.h"
+
+ at implementation JackViewPortsViewBackgroundView
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+        self.backgroundColor = [UIColor clearColor];
+    }
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect
+{
+    int i = 0;
+    JackViewPortsView* portsView = (JackViewPortsView*)self.superview.superview;
+    JackViewPortsLink* link = nil;
+    UIBezierPath* path = [UIBezierPath bezierPath];
+    CGPoint pt;
+    
+    path.lineWidth = 1.5;
+    path.lineCapStyle = kCGLineCapSquare;
+    
+    // Background
+    self.backgroundColor = [UIColor clearColor];
+    
+    float cst = 0.4;
+    
+    // Links
+    for (i = 0; i < [portsView.links count]; ++i)
+    {
+        link = [portsView.links objectAtIndex:i];
+        
+        if (portsView.linking) link.selected = NO;
+                
+        if (link.selected)
+        {
+            [[UIColor blueColor] set];
+            portsView.deleteButton.hidden = NO;
+        }
+        else [[UIColor blackColor] set];
+        
+        [path removeAllPoints];
+        [path moveToPoint:CGPointMake(link.srcPt.x - 5, link.srcPt.y)];
+        [path addCurveToPoint:CGPointMake(link.dstPt.x - 5, link.dstPt.y)
+                controlPoint1:CGPointMake((link.srcPt.x * cst + link.dstPt.x * (1. - cst)), link.srcPt.y)
+                controlPoint2:CGPointMake((link.srcPt.x * (1. - cst) + link.dstPt.x * cst), link.dstPt.y)];
+        [path stroke];
+        
+        // Arrow
+        if (link.srcPt.x < link.dstPt.x) pt = CGPointMake(link.dstPt.x, link.dstPt.y);
+        else pt = CGPointMake(link.srcPt.x, link.srcPt.y);
+        [path removeAllPoints];
+        [path moveToPoint:CGPointMake(pt.x - 10, pt.y - 2.5)];
+        [path addLineToPoint:CGPointMake(pt.x, pt.y)];
+        [path addLineToPoint:CGPointMake(pt.x - 10, pt.y + 2.5)];
+        [path closePath];
+        [path fill];
+    }
+    
+    if (portsView.linking
+        && !portsView.dontDrawLinking)
+    {
+        portsView.deleteButton.hidden = YES;
+                
+        [[UIColor blackColor] set];
+        
+        [path removeAllPoints];
+        [path moveToPoint:CGPointMake(portsView.srcPt.x - 5, portsView.srcPt.y)];
+        [path addCurveToPoint:CGPointMake(portsView.dstPt.x - 5, portsView.dstPt.y)
+                controlPoint1:CGPointMake((portsView.srcPt.x * cst + portsView.dstPt.x * (1. - cst)), portsView.srcPt.y)
+                controlPoint2:CGPointMake((portsView.srcPt.x * (1. - cst) + portsView.dstPt.x * cst), portsView.dstPt.y)];
+        [path stroke];
+        
+        // Arrow
+        if (portsView.srcPt.x < portsView.dstPt.x) pt = CGPointMake(portsView.dstPt.x, portsView.dstPt.y);
+        else pt = CGPointMake(portsView.srcPt.x, portsView.srcPt.y);
+        [path removeAllPoints];
+        [path moveToPoint:CGPointMake(pt.x - 10, pt.y - 2.5)];
+        [path addLineToPoint:CGPointMake(pt.x, pt.y)];
+        [path addLineToPoint:CGPointMake(pt.x - 10, pt.y + 2.5)];
+        [path closePath];
+        [path fill];
+    }
+}
+
+
+ at end
diff --git a/architecture/iOS/iOS/close.png b/architecture/iOS/iOS/close.png
new file mode 100644
index 0000000..b5dbe3c
Binary files /dev/null and b/architecture/iOS/iOS/close.png differ
diff --git a/architecture/iOS/iOS/close at 2x.png b/architecture/iOS/iOS/close at 2x.png
new file mode 100644
index 0000000..879039c
Binary files /dev/null and b/architecture/iOS/iOS/close at 2x.png differ
diff --git a/architecture/iOS/iOS/en.lproj/InfoPlist.strings b/architecture/iOS/iOS/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/architecture/iOS/iOS/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/architecture/iOS/iOS/en.lproj/MainStoryboard_iPad.storyboard b/architecture/iOS/iOS/en.lproj/MainStoryboard_iPad.storyboard
new file mode 100644
index 0000000..c31b112
--- /dev/null
+++ b/architecture/iOS/iOS/en.lproj/MainStoryboard_iPad.storyboard
@@ -0,0 +1,382 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5056" systemVersion="12F45" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="2">
+    <dependencies>
+        <deployment defaultVersion="1280" identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
+    </dependencies>
+    <scenes>
+        <!--Main View Controller-->
+        <scene sceneID="4">
+            <objects>
+                <viewController id="2" customClass="FIMainViewController" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="8">
+                        <rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="DYz-Ul-ted" customClass="FIScrollView">
+                                <rect key="frame" x="0.0" y="44" width="768" height="980"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <subviews>
+                                    <view contentMode="scaleToFill" id="doz-xe-PRv">
+                                        <rect key="frame" x="-1" y="0.0" width="768" height="980"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                                    </view>
+                                </subviews>
+                                <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/>
+                            </scrollView>
+                            <navigationBar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="black" id="13">
+                                <rect key="frame" x="0.0" y="1" width="768" height="44"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <items>
+                                    <navigationItem title="Title" id="14">
+                                        <barButtonItem key="rightBarButtonItem" title="Info" id="15">
+                                            <connections>
+                                                <action selector="togglePopover:" destination="2" id="23"/>
+                                            </connections>
+                                        </barButtonItem>
+                                    </navigationItem>
+                                </items>
+                            </navigationBar>
+                            <view contentMode="scaleToFill" id="Mgn-p8-mCp" userLabel="Widget Preferences View">
+                                <rect key="frame" x="0.0" y="728" width="768" height="552"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                                <subviews>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="Pvr-Li-09S">
+                                        <rect key="frame" x="18" y="20" width="415" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="Run-yt-9bc">
+                                        <rect key="frame" x="18" y="78" width="415" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                        <segments>
+                                            <segment title="None"/>
+                                            <segment title="X"/>
+                                            <segment title="Y"/>
+                                            <segment title="Z"/>
+                                            <segment title="Shake"/>
+                                            <segment title="Compass"/>
+                                        </segments>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="ygl-R2-JBg"/>
+                                        </connections>
+                                    </segmentedControl>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Assignation" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="epA-8C-RMd">
+                                        <rect key="frame" x="18" y="49" width="415" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="WJX-8A-ivY">
+                                        <rect key="frame" x="82" y="129" width="51" height="31"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="ccK-Dh-aui"/>
+                                        </connections>
+                                    </switch>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Inverted" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="MNy-AK-j5v">
+                                        <rect key="frame" x="18" y="129" width="90" height="27"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="HeD-Hx-0Qp">
+                                        <rect key="frame" x="721" y="20" width="30" height="30"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                        <state key="normal" image="close.png">
+                                            <color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
+                                            <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                        <state key="highlighted">
+                                            <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                        <connections>
+                                            <action selector="dismissWidgetPreferencesView:" destination="2" eventType="touchUpInside" id="bKU-sX-2T2"/>
+                                        </connections>
+                                    </button>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.20000000298023224" maxValue="3" id="3bk-nE-3by">
+                                        <rect key="frame" x="16" y="193" width="419" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="REC-GD-F7R"/>
+                                        </connections>
+                                    </slider>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Sensibility" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="YxN-9B-ZAG">
+                                        <rect key="frame" x="18" y="164" width="127" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="1." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="euO-NB-r62">
+                                        <rect key="frame" x="393" y="164" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="Gc8-ji-ACM">
+                                        <rect key="frame" x="18" y="239" width="733" height="37"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                        <state key="normal" title="Reset parameters">
+                                            <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                            <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                        <state key="highlighted" title="Reset parameters">
+                                            <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                        </state>
+                                        <connections>
+                                            <action selector="resetWidgetPreferences:" destination="2" eventType="touchUpInside" id="h5u-c1-nZ0"/>
+                                        </connections>
+                                    </button>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="zVh-z1-hcY">
+                                        <rect key="frame" x="476" y="72" width="229" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="NjE-04-Tlh"/>
+                                        </connections>
+                                    </slider>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="DUk-k7-wpD">
+                                        <rect key="frame" x="476" y="129" width="229" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="rjq-oD-MNu"/>
+                                        </connections>
+                                    </slider>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="U29-wJ-Vqy">
+                                        <rect key="frame" x="476" y="187" width="229" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="gji-jY-Wbm"/>
+                                        </connections>
+                                    </slider>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="G" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="zFp-SI-iQf">
+                                        <rect key="frame" x="450" y="136" width="20" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="R" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="tGb-KT-GwV">
+                                        <rect key="frame" x="450" y="78" width="20" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="B" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="bnp-tE-l6R">
+                                        <rect key="frame" x="450" y="194" width="20" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="92N-N8-vs5">
+                                        <rect key="frame" x="711" y="135" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="2hb-uW-6R7">
+                                        <rect key="frame" x="711" y="78" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="vRe-p1-nia">
+                                        <rect key="frame" x="711" y="193" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Color" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="mzI-i5-3FF">
+                                        <rect key="frame" x="450" y="44" width="301" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="jPy-h5-RhB">
+                                        <rect key="frame" x="246" y="129" width="51" height="31"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="pPJ-QT-Kfw"/>
+                                        </connections>
+                                    </switch>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Filtered" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="rey-Sy-gI5">
+                                        <rect key="frame" x="186" y="129" width="90" height="27"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.75" colorSpace="calibratedRGB"/>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" white="0.25" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                    <simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
+                    <connections>
+                        <outlet property="_bLabel" destination="bnp-tE-l6R" id="nJQ-WG-HHo"/>
+                        <outlet property="_colorBLabel" destination="vRe-p1-nia" id="T75-ZS-wBV"/>
+                        <outlet property="_colorBSlider" destination="U29-wJ-Vqy" id="GVS-ZH-Khf"/>
+                        <outlet property="_colorGLabel" destination="92N-N8-vs5" id="HO9-wP-Sqb"/>
+                        <outlet property="_colorGSlider" destination="DUk-k7-wpD" id="puC-Ft-eD2"/>
+                        <outlet property="_colorLabel" destination="mzI-i5-3FF" id="t36-Cw-u89"/>
+                        <outlet property="_colorRLabel" destination="2hb-uW-6R7" id="Hiy-eb-Q2D"/>
+                        <outlet property="_colorRSlider" destination="zVh-z1-hcY" id="dMX-wB-D0t"/>
+                        <outlet property="_dspScrollView" destination="DYz-Ul-ted" id="PsL-1u-45q"/>
+                        <outlet property="_dspView" destination="doz-xe-PRv" id="hey-J9-4L0"/>
+                        <outlet property="_gLabel" destination="zFp-SI-iQf" id="PXU-NI-jpI"/>
+                        <outlet property="_gyroAxisSegmentedControl" destination="Run-yt-9bc" id="VuE-Q7-yT1"/>
+                        <outlet property="_gyroFilteredSwitch" destination="jPy-h5-RhB" id="nRE-YQ-44z"/>
+                        <outlet property="_gyroInvertedSwitch" destination="WJX-8A-ivY" id="ahf-N3-EsY"/>
+                        <outlet property="_gyroInvertedTitleLabel" destination="MNy-AK-j5v" id="4cV-rD-hqg"/>
+                        <outlet property="_gyroSensibilityLabel" destination="euO-NB-r62" id="F5h-nM-CT6"/>
+                        <outlet property="_gyroSensibilitySlider" destination="3bk-nE-3by" id="eYZ-ZC-v7B"/>
+                        <outlet property="_gyroSensibilityTitleLabel" destination="YxN-9B-ZAG" id="hqN-uZ-dUy"/>
+                        <outlet property="_rLabel" destination="tGb-KT-GwV" id="E0I-jM-SWW"/>
+                        <outlet property="_titleNavigationItem" destination="14" id="cHE-VL-RhB"/>
+                        <outlet property="_widgetPreferencesTitleLabel" destination="Pvr-Li-09S" id="px2-eg-iG9"/>
+                        <outlet property="_widgetPreferencesView" destination="Mgn-p8-mCp" id="4fj-Nt-mFP"/>
+                        <outlet property="view" destination="8" id="oQM-4B-TUr"/>
+                        <segue destination="5" kind="popover" identifier="showAlternate" popoverAnchorBarButtonItem="15" id="22">
+                            <popoverArrowDirection key="popoverArrowDirection" up="YES" down="YES" left="YES" right="YES"/>
+                        </segue>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="3" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="-286" y="15"/>
+        </scene>
+        <!--Flipside View Controller-->
+        <scene sceneID="7">
+            <objects>
+                <viewController id="5" customClass="FIFlipsideViewController" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="9">
+                        <rect key="frame" x="0.0" y="0.0" width="320" height="852"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <navigationBar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="black" id="17">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <items>
+                                    <navigationItem title="Preferences" id="18">
+                                        <barButtonItem key="leftBarButtonItem" systemItem="done" id="19">
+                                            <connections>
+                                                <action selector="done:" destination="5" id="21"/>
+                                            </connections>
+                                        </barButtonItem>
+                                    </navigationItem>
+                                </items>
+                            </navigationBar>
+                            <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="6" id="Kds-Fy-egu">
+                                <rect key="frame" x="18" y="101" width="284" height="29"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <connections>
+                                    <action selector="sampleRateSliderMoved:" destination="5" eventType="valueChanged" id="xa0-bW-uL8"/>
+                                </connections>
+                            </slider>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" id="Zoc-vZ-s98">
+                                <rect key="frame" x="169" y="71" width="131" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Sample rate" lineBreakMode="tailTruncation" minimumFontSize="10" id="xzD-Qg-dA6">
+                                <rect key="frame" x="20" y="71" width="98" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="7" id="dan-b9-bmY">
+                                <rect key="frame" x="18" y="198" width="284" height="29"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <connections>
+                                    <action selector="bufferSizeSliderMoved:" destination="5" eventType="valueChanged" id="Otb-fB-bes"/>
+                                </connections>
+                            </slider>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" id="m0z-XB-fbo">
+                                <rect key="frame" x="169" y="168" width="131" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Buffer size" lineBreakMode="tailTruncation" minimumFontSize="10" id="MLn-cX-JGW">
+                                <rect key="frame" x="20" y="168" width="98" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Open widget panel" lineBreakMode="tailTruncation" minimumFontSize="10" id="YUX-0g-vlP">
+                                <rect key="frame" x="20" y="273" width="184" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="qyE-R8-8ri">
+                                <rect key="frame" x="223" y="279" width="51" height="31"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <connections>
+                                    <action selector="openWidgetPanelSwitchMoved:" destination="5" eventType="valueChanged" id="8ac-H0-Qwl"/>
+                                </connections>
+                            </switch>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="on long press" lineBreakMode="tailTruncation" minimumFontSize="10" id="d9Q-47-hve">
+                                <rect key="frame" x="20" y="292" width="184" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="1pd-bf-BVD">
+                                <rect key="frame" x="20" y="789" width="280" height="44"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                                <state key="normal" title="Reset parameters">
+                                    <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                    <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+                                </state>
+                                <connections>
+                                    <action selector="deleteAssignationsButtonClicked:" destination="5" eventType="touchUpInside" id="90c-dR-M2x"/>
+                                </connections>
+                            </button>
+                        </subviews>
+                        <color key="backgroundColor" white="0.25" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                    <splitViewMasterSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+                    <connections>
+                        <outlet property="_bufferSizeLabel" destination="m0z-XB-fbo" id="Uqm-Jo-cfT"/>
+                        <outlet property="_bufferSizeSlider" destination="dan-b9-bmY" id="4FT-Yu-Xy6"/>
+                        <outlet property="_openWidgetPanelSwitch" destination="qyE-R8-8ri" id="LEv-sS-iXx"/>
+                        <outlet property="_sampleRateLabel" destination="Zoc-vZ-s98" id="LTR-c4-d0c"/>
+                        <outlet property="_sampleRateSlider" destination="Kds-Fy-egu" id="PbM-MO-KiP"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="6" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="836" y="101"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="close.png" width="30" height="30"/>
+    </resources>
+    <simulatedMetricsContainer key="defaultSimulatedMetrics">
+        <simulatedStatusBarMetrics key="statusBar"/>
+        <simulatedOrientationMetrics key="orientation"/>
+        <simulatedScreenMetrics key="destination"/>
+    </simulatedMetricsContainer>
+</document>
diff --git a/architecture/iOS/iOS/en.lproj/MainStoryboard_iPhone.storyboard b/architecture/iOS/iOS/en.lproj/MainStoryboard_iPhone.storyboard
new file mode 100644
index 0000000..f767d58
--- /dev/null
+++ b/architecture/iOS/iOS/en.lproj/MainStoryboard_iPhone.storyboard
@@ -0,0 +1,398 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5056" systemVersion="12F45" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="2">
+    <dependencies>
+        <deployment defaultVersion="1280" identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
+    </dependencies>
+    <scenes>
+        <!--Main View Controller-->
+        <scene sceneID="5">
+            <objects>
+                <viewController id="2" customClass="FIMainViewController" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="3">
+                        <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                        <subviews>
+                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="fZt-lk-p4g" customClass="FIScrollView">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="434"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <subviews>
+                                    <view contentMode="scaleToFill" id="aVQ-bg-Kex">
+                                        <rect key="frame" x="0.0" y="0.0" width="320" height="434"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                                    </view>
+                                </subviews>
+                            </scrollView>
+                            <button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="infoLight" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="10">
+                                <rect key="frame" x="278" y="438" width="22" height="22"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                <fontDescription key="fontDescription" name="Helvetica-Bold" family="Helvetica" pointSize="15"/>
+                                <state key="normal">
+                                    <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
+                                    <color key="titleShadowColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
+                                </state>
+                                <state key="highlighted">
+                                    <color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                </state>
+                                <connections>
+                                    <segue destination="6" kind="modal" identifier="showAlternate" modalTransitionStyle="flipHorizontal" id="11"/>
+                                </connections>
+                            </button>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="" lineBreakMode="tailTruncation" minimumFontSize="10" id="d0p-QQ-rUB">
+                                <rect key="frame" x="20" y="442" width="254" height="21"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" id="DUJ-Ab-spl" userLabel="WidgetPreferencesView">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <subviews>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="bwQ-lC-BmZ">
+                                        <rect key="frame" x="286" y="4" width="30" height="30"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" size="button"/>
+                                        <state key="normal" image="close.png">
+                                            <color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
+                                            <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                        <state key="highlighted">
+                                            <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                        <connections>
+                                            <action selector="dismissWidgetPreferencesView:" destination="2" eventType="touchUpInside" id="B9a-Wd-Clg"/>
+                                        </connections>
+                                    </button>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Assignation" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="vna-qX-amq">
+                                        <rect key="frame" x="16" y="38" width="127" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="MHD-KX-YrV">
+                                        <rect key="frame" x="75" y="136" width="51" height="31"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="kv9-6s-4t2"/>
+                                        </connections>
+                                    </switch>
+                                    <segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="oyc-qf-yU0">
+                                        <rect key="frame" x="15" y="67" width="284" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <segments>
+                                            <segment title="None"/>
+                                            <segment title="X"/>
+                                            <segment title="Y"/>
+                                            <segment title="Z"/>
+                                            <segment title="Shk"/>
+                                            <segment title="Cmp"/>
+                                        </segments>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="xK1-ad-oY1"/>
+                                        </connections>
+                                    </segmentedControl>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Inverted" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="6KO-3L-jmo">
+                                        <rect key="frame" x="15" y="139" width="59" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="9SF-kE-5Rs" userLabel="Title Label">
+                                        <rect key="frame" x="15" y="12" width="247" height="13"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.20000000000000001" maxValue="3" id="iyb-fe-vwf">
+                                        <rect key="frame" x="14" y="219" width="288" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="GDr-3Q-IcL"/>
+                                        </connections>
+                                    </slider>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Sensibility" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="AY8-gB-Tic">
+                                        <rect key="frame" x="16" y="190" width="127" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="1." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="apq-xS-CIn">
+                                        <rect key="frame" x="260" y="190" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="lmO-gX-8hS">
+                                        <rect key="frame" x="16" y="429" width="284" height="37"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                                        <color key="backgroundColor" red="1" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
+                                        <color key="tintColor" cocoaTouchSystemColor="darkTextColor"/>
+                                        <state key="normal" title="Reset parameters">
+                                            <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                            <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                        <state key="selected">
+                                            <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                        </state>
+                                        <state key="highlighted" title="Reset parameters">
+                                            <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                        </state>
+                                        <connections>
+                                            <action selector="resetWidgetPreferences:" destination="2" eventType="touchUpInside" id="o5b-zz-og5"/>
+                                        </connections>
+                                    </button>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="wuh-th-T8n">
+                                        <rect key="frame" x="41" y="311" width="223" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="RtE-yy-w7c"/>
+                                        </connections>
+                                    </slider>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="ZlL-eL-z5q">
+                                        <rect key="frame" x="41" y="341" width="223" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="Lyn-c0-ZfK"/>
+                                        </connections>
+                                    </slider>
+                                    <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="gL4-Rz-j3r">
+                                        <rect key="frame" x="41" y="371" width="223" height="29"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="OjV-s7-Tzz"/>
+                                        </connections>
+                                    </slider>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="G" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="4pG-uw-ehd">
+                                        <rect key="frame" x="15" y="341" width="20" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="R" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="XES-4z-RJX">
+                                        <rect key="frame" x="15" y="311" width="20" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="B" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="yUT-Xd-fbB">
+                                        <rect key="frame" x="15" y="371" width="20" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="Vuz-Tj-k9N">
+                                        <rect key="frame" x="259" y="341" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="xTV-Pv-w7h">
+                                        <rect key="frame" x="260" y="311" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="NLf-bE-hY3">
+                                        <rect key="frame" x="259" y="371" width="40" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Color" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="zCY-BJ-uzg">
+                                        <rect key="frame" x="15" y="282" width="92" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="PM6-kf-OgL">
+                                        <rect key="frame" x="223" y="136" width="51" height="31"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <connections>
+                                            <action selector="widgetPreferencesChanged:" destination="2" eventType="valueChanged" id="zcx-4w-SaN"/>
+                                        </connections>
+                                    </switch>
+                                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Filtered" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="N9a-CT-YBM">
+                                        <rect key="frame" x="168" y="139" width="54" height="21"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.75" colorSpace="calibratedRGB"/>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/>
+                    </view>
+                    <simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="blackOpaque"/>
+                    <simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
+                    <connections>
+                        <outlet property="_bLabel" destination="yUT-Xd-fbB" id="DlN-HS-T4v"/>
+                        <outlet property="_colorBLabel" destination="NLf-bE-hY3" id="JSD-5u-iz0"/>
+                        <outlet property="_colorBSlider" destination="gL4-Rz-j3r" id="FtP-Yv-E0P"/>
+                        <outlet property="_colorGLabel" destination="Vuz-Tj-k9N" id="pq8-t0-r9i"/>
+                        <outlet property="_colorGSlider" destination="ZlL-eL-z5q" id="bA8-J1-Ti5"/>
+                        <outlet property="_colorLabel" destination="zCY-BJ-uzg" id="3LT-kF-NF3"/>
+                        <outlet property="_colorRLabel" destination="xTV-Pv-w7h" id="mhd-IP-c4f"/>
+                        <outlet property="_colorRSlider" destination="wuh-th-T8n" id="XHu-AY-zjl"/>
+                        <outlet property="_dspScrollView" destination="fZt-lk-p4g" id="4pS-iH-fVQ"/>
+                        <outlet property="_dspView" destination="aVQ-bg-Kex" id="cJ8-2W-mdT"/>
+                        <outlet property="_gLabel" destination="4pG-uw-ehd" id="UzE-Hf-mHu"/>
+                        <outlet property="_gyroAxisSegmentedControl" destination="oyc-qf-yU0" id="gRv-5r-Ug8"/>
+                        <outlet property="_gyroFilteredSwitch" destination="PM6-kf-OgL" id="oGz-h3-Ay3"/>
+                        <outlet property="_gyroInvertedSwitch" destination="MHD-KX-YrV" id="MxV-he-KaP"/>
+                        <outlet property="_gyroInvertedTitleLabel" destination="6KO-3L-jmo" id="i3t-nd-dhI"/>
+                        <outlet property="_gyroSensibilityLabel" destination="apq-xS-CIn" id="YNN-AL-V0z"/>
+                        <outlet property="_gyroSensibilitySlider" destination="iyb-fe-vwf" id="LfQ-i3-jcc"/>
+                        <outlet property="_gyroSensibilityTitleLabel" destination="AY8-gB-Tic" id="Da6-D3-tb0"/>
+                        <outlet property="_rLabel" destination="XES-4z-RJX" id="kpH-b4-Vas"/>
+                        <outlet property="_titleLabel" destination="d0p-QQ-rUB" id="MHx-ti-iZN"/>
+                        <outlet property="_widgetPreferencesTitleLabel" destination="9SF-kE-5Rs" id="f4i-BX-JGS"/>
+                        <outlet property="_widgetPreferencesView" destination="DUJ-Ab-spl" id="gdd-2l-fIR"/>
+                        <outlet property="view" destination="3" id="I0f-qd-cZb"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="4" sceneMemberID="firstResponder"/>
+                <view contentMode="scaleToFill" id="eDr-Z1-lL3">
+                    <rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
+                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                </view>
+            </objects>
+            <point key="canvasLocation" x="-51" y="182"/>
+        </scene>
+        <!--Flipside View Controller-->
+        <scene sceneID="9">
+            <objects>
+                <viewController id="6" customClass="FIFlipsideViewController" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="7">
+                        <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                        <subviews>
+                            <navigationBar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="black" id="12">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <items>
+                                    <navigationItem title="Preferences" id="13">
+                                        <barButtonItem key="leftBarButtonItem" systemItem="done" id="14">
+                                            <connections>
+                                                <action selector="done:" destination="6" id="16"/>
+                                            </connections>
+                                        </barButtonItem>
+                                    </navigationItem>
+                                </items>
+                            </navigationBar>
+                            <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="6" id="1Y5-CG-5xs">
+                                <rect key="frame" x="18" y="107" width="284" height="29"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <connections>
+                                    <action selector="sampleRateSliderMoved:" destination="6" eventType="valueChanged" id="b3e-GR-tJA"/>
+                                </connections>
+                            </slider>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" id="U5Y-mi-YMk">
+                                <rect key="frame" x="169" y="78" width="131" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Sample rate" lineBreakMode="tailTruncation" minimumFontSize="10" id="nck-eO-QEa">
+                                <rect key="frame" x="20" y="78" width="98" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="7" id="gDC-YP-Hzz">
+                                <rect key="frame" x="18" y="188" width="284" height="29"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <connections>
+                                    <action selector="bufferSizeSliderMoved:" destination="6" eventType="valueChanged" id="P4Q-Wd-fei"/>
+                                </connections>
+                            </slider>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" id="9wB-mL-QeI">
+                                <rect key="frame" x="169" y="175" width="131" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Buffer size" lineBreakMode="tailTruncation" minimumFontSize="10" id="3Cu-7y-dC8">
+                                <rect key="frame" x="20" y="159" width="98" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Open widget panel" lineBreakMode="tailTruncation" minimumFontSize="10" id="QHj-Ev-ZRr">
+                                <rect key="frame" x="20" y="245" width="184" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="0tq-fl-CWV">
+                                <rect key="frame" x="251" y="251" width="51" height="31"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                <connections>
+                                    <action selector="openWidgetPanelSwitchMoved:" destination="6" eventType="valueChanged" id="qim-6k-Qi3"/>
+                                </connections>
+                            </switch>
+                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="on long press" lineBreakMode="tailTruncation" minimumFontSize="10" id="MCl-8J-e1e">
+                                <rect key="frame" x="20" y="264" width="184" height="21"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="Ca2-EY-o9G">
+                                <rect key="frame" x="20" y="424" width="280" height="37"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                                <state key="normal" title="Reset parameters">
+                                    <color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                    <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
+                                </state>
+                                <connections>
+                                    <action selector="deleteAssignationsButtonClicked:" destination="6" eventType="touchUpInside" id="fgT-bQ-u5J"/>
+                                </connections>
+                            </button>
+                        </subviews>
+                        <color key="backgroundColor" white="0.25" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                    <connections>
+                        <outlet property="_bufferSizeLabel" destination="9wB-mL-QeI" id="8c8-pu-tF8"/>
+                        <outlet property="_bufferSizeSlider" destination="gDC-YP-Hzz" id="tGk-M5-y3n"/>
+                        <outlet property="_openWidgetPanelSwitch" destination="0tq-fl-CWV" id="c3B-yb-Vnl"/>
+                        <outlet property="_sampleRateLabel" destination="U5Y-mi-YMk" id="mw6-2F-q56"/>
+                        <outlet property="_sampleRateSlider" destination="1Y5-CG-5xs" id="wSl-lW-BS3"/>
+                        <outlet property="delegate" destination="2" id="15"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="8" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="424" y="182"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="close.png" width="30" height="30"/>
+    </resources>
+    <simulatedMetricsContainer key="defaultSimulatedMetrics">
+        <simulatedStatusBarMetrics key="statusBar"/>
+        <simulatedOrientationMetrics key="orientation"/>
+        <simulatedScreenMetrics key="destination"/>
+    </simulatedMetricsContainer>
+</document>
diff --git a/architecture/iOS/iOS/iOS-Info.plist b/architecture/iOS/iOS/iOS-Info.plist
new file mode 100644
index 0000000..37fafe9
--- /dev/null
+++ b/architecture/iOS/iOS/iOS-Info.plist
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFiles</key>
+	<array>
+		<string>Icon.png</string>
+		<string>Icon at 2x.png</string>
+		<string>Icon-72.png</string>
+		<string>Icon-72 at 2x.png</string>
+	</array>
+	<key>CFBundleIcons</key>
+	<dict>
+		<key>CFBundlePrimaryIcon</key>
+		<dict>
+			<key>CFBundleIconFiles</key>
+			<array>
+				<string>Icon.png</string>
+				<string>Icon at 2x.png</string>
+				<string>Icon-72.png</string>
+				<string>Icon-72 at 2x.png</string>
+			</array>
+			<key>UIPrerenderedIcon</key>
+			<false/>
+		</dict>
+	</dict>
+	<key>CFBundleIdentifier</key>
+	<string>fr.grame.iGrame.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.00</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleURLName</key>
+			<string>fr.grame.${PRODUCT_NAME}</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>${PRODUCT_NAME}</string>
+			</array>
+		</dict>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>1.00</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>audio</string>
+	</array>
+	<key>UIMainStoryboardFile</key>
+	<string>MainStoryboard_iPhone</string>
+	<key>UIMainStoryboardFile~ipad</key>
+	<string>MainStoryboard_iPad</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UIStatusBarHidden</key>
+	<true/>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+</dict>
+</plist>
diff --git a/architecture/iOS/iOS/iOS-Prefix.pch b/architecture/iOS/iOS/iOS-Prefix.pch
new file mode 100644
index 0000000..d85e708
--- /dev/null
+++ b/architecture/iOS/iOS/iOS-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'iOS' target in the 'iOS' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_5_0
+#warning "This project uses features only available in iOS SDK 5.0 and later."
+#endif
+
+#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+    #import <Foundation/Foundation.h>
+#endif
diff --git a/architecture/iOS/iOS/main.m b/architecture/iOS/iOS/main.m
new file mode 100644
index 0000000..b5e7aa3
--- /dev/null
+++ b/architecture/iOS/iOS/main.m
@@ -0,0 +1,28 @@
+/************************************************************************
+ ************************************************************************
+ FAUST Architecture File
+ Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ 
+ This is sample code. This file is provided as an example of minimal
+ FAUST architecture file. Redistribution and use in source and binary
+ forms, with or without modification, in part or in full are permitted.
+ In particular you can create a derived work of this FAUST architecture
+ and distribute that work under terms of your choice.
+ 
+ This sample code 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.
+ ************************************************************************
+ ************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#import "FIAppDelegate.h"
+
+int main(int argc, char *argv[])
+{
+    @autoreleasepool {
+        return UIApplicationMain(argc, argv, nil, NSStringFromClass([FIAppDelegate class]));
+    }
+}
diff --git a/architecture/iOS/iOSTests/en.lproj/InfoPlist.strings b/architecture/iOS/iOSTests/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/architecture/iOS/iOSTests/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/architecture/iOS/iOSTests/iOSTests-Info.plist b/architecture/iOS/iOSTests/iOSTests-Info.plist
new file mode 100644
index 0000000..43c9b30
--- /dev/null
+++ b/architecture/iOS/iOSTests/iOSTests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIdentifier</key>
+	<string>fr.grame.iGrame.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>
diff --git a/architecture/iOS/iOSTests/iOSTests.h b/architecture/iOS/iOSTests/iOSTests.h
new file mode 100644
index 0000000..cf3db85
--- /dev/null
+++ b/architecture/iOS/iOSTests/iOSTests.h
@@ -0,0 +1,13 @@
+//
+//  iOSTests.h
+//  iOSTests
+//
+//  Created by Olivier Guillerminet on 02/02/12.
+//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+
+ at interface iOSTests : SenTestCase
+
+ at end
diff --git a/architecture/iOS/iOSTests/iOSTests.m b/architecture/iOS/iOSTests/iOSTests.m
new file mode 100644
index 0000000..fa53e16
--- /dev/null
+++ b/architecture/iOS/iOSTests/iOSTests.m
@@ -0,0 +1,32 @@
+//
+//  iOSTests.m
+//  iOSTests
+//
+//  Created by Olivier Guillerminet on 02/02/12.
+//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import "iOSTests.h"
+
+ at implementation iOSTests
+
+- (void)setUp
+{
+    [super setUp];
+    
+    // Set-up code here.
+}
+
+- (void)tearDown
+{
+    // Tear-down code here.
+    
+    [super tearDown];
+}
+
+- (void)testExample
+{
+    STFail(@"Unit tests are not implemented yet in iOSTests");
+}
+
+ at end
diff --git a/architecture/iOS/icon-72.png b/architecture/iOS/icon-72.png
new file mode 100644
index 0000000..db81178
Binary files /dev/null and b/architecture/iOS/icon-72.png differ
diff --git a/architecture/iOS/icon.png b/architecture/iOS/icon.png
new file mode 100644
index 0000000..bf4fdf5
Binary files /dev/null and b/architecture/iOS/icon.png differ
diff --git a/architecture/iOS/pix/Icon-Analyzer.png b/architecture/iOS/pix/Icon-Analyzer.png
new file mode 100644
index 0000000..e54d7d0
Binary files /dev/null and b/architecture/iOS/pix/Icon-Analyzer.png differ
diff --git a/architecture/iOS/pix/Icon-Analyzer136.png b/architecture/iOS/pix/Icon-Analyzer136.png
new file mode 100644
index 0000000..065327e
Binary files /dev/null and b/architecture/iOS/pix/Icon-Analyzer136.png differ
diff --git a/architecture/iOS/pix/Icon-Analyzer at 2x.png b/architecture/iOS/pix/Icon-Analyzer at 2x.png
new file mode 100644
index 0000000..6c63fc2
Binary files /dev/null and b/architecture/iOS/pix/Icon-Analyzer at 2x.png differ
diff --git a/architecture/iOS/pix/Icon-Delete.png b/architecture/iOS/pix/Icon-Delete.png
new file mode 100644
index 0000000..f6b0583
Binary files /dev/null and b/architecture/iOS/pix/Icon-Delete.png differ
diff --git a/architecture/iOS/pix/Icon-Delete at 2x.png b/architecture/iOS/pix/Icon-Delete at 2x.png
new file mode 100644
index 0000000..40aa5d3
Binary files /dev/null and b/architecture/iOS/pix/Icon-Delete at 2x.png differ
diff --git a/architecture/iOS/pix/Icon-Expand.png b/architecture/iOS/pix/Icon-Expand.png
new file mode 100644
index 0000000..3ff91af
Binary files /dev/null and b/architecture/iOS/pix/Icon-Expand.png differ
diff --git a/architecture/iOS/pix/Icon-Expand at 2x.png b/architecture/iOS/pix/Icon-Expand at 2x.png
new file mode 100644
index 0000000..c9fc3e5
Binary files /dev/null and b/architecture/iOS/pix/Icon-Expand at 2x.png differ
diff --git a/architecture/iOS/pix/Icon-Fx.png b/architecture/iOS/pix/Icon-Fx.png
new file mode 100644
index 0000000..de206a5
Binary files /dev/null and b/architecture/iOS/pix/Icon-Fx.png differ
diff --git a/architecture/iOS/pix/Icon-Fx136.png b/architecture/iOS/pix/Icon-Fx136.png
new file mode 100644
index 0000000..ecf2635
Binary files /dev/null and b/architecture/iOS/pix/Icon-Fx136.png differ
diff --git a/architecture/iOS/pix/Icon-Fx at 2x.png b/architecture/iOS/pix/Icon-Fx at 2x.png
new file mode 100644
index 0000000..3358363
Binary files /dev/null and b/architecture/iOS/pix/Icon-Fx at 2x.png differ
diff --git a/architecture/iOS/pix/Icon-Jack.png b/architecture/iOS/pix/Icon-Jack.png
new file mode 100644
index 0000000..cfaf8b5
Binary files /dev/null and b/architecture/iOS/pix/Icon-Jack.png differ
diff --git a/architecture/iOS/pix/Icon-Jack at 2x.png b/architecture/iOS/pix/Icon-Jack at 2x.png
new file mode 100644
index 0000000..742ca34
Binary files /dev/null and b/architecture/iOS/pix/Icon-Jack at 2x.png differ
diff --git a/architecture/iOS/pix/Icon-Output.png b/architecture/iOS/pix/Icon-Output.png
new file mode 100644
index 0000000..17ed5e8
Binary files /dev/null and b/architecture/iOS/pix/Icon-Output.png differ
diff --git a/architecture/iOS/pix/Icon-Output1024.png b/architecture/iOS/pix/Icon-Output1024.png
new file mode 100644
index 0000000..01d7f62
Binary files /dev/null and b/architecture/iOS/pix/Icon-Output1024.png differ
diff --git a/architecture/iOS/pix/Icon-Output136.png b/architecture/iOS/pix/Icon-Output136.png
new file mode 100644
index 0000000..9e9a155
Binary files /dev/null and b/architecture/iOS/pix/Icon-Output136.png differ
diff --git a/architecture/iOS/pix/Icon-Output at 2x.png b/architecture/iOS/pix/Icon-Output at 2x.png
new file mode 100644
index 0000000..adf0652
Binary files /dev/null and b/architecture/iOS/pix/Icon-Output at 2x.png differ
diff --git a/architecture/iOS/pix/Icon_Apple.png b/architecture/iOS/pix/Icon_Apple.png
new file mode 100644
index 0000000..fd43bd2
Binary files /dev/null and b/architecture/iOS/pix/Icon_Apple.png differ
diff --git a/architecture/iOS/pix/Icon_Apple at 2x.png b/architecture/iOS/pix/Icon_Apple at 2x.png
new file mode 100644
index 0000000..71119ea
Binary files /dev/null and b/architecture/iOS/pix/Icon_Apple at 2x.png differ
diff --git a/architecture/iOS/pix/jackview-audio-off.png b/architecture/iOS/pix/jackview-audio-off.png
new file mode 100644
index 0000000..ae71fed
Binary files /dev/null and b/architecture/iOS/pix/jackview-audio-off.png differ
diff --git a/architecture/iOS/pix/jackview-audio-off at 2x.png b/architecture/iOS/pix/jackview-audio-off at 2x.png
new file mode 100644
index 0000000..5201f5e
Binary files /dev/null and b/architecture/iOS/pix/jackview-audio-off at 2x.png differ
diff --git a/architecture/iOS/pix/jackview-audio-on.png b/architecture/iOS/pix/jackview-audio-on.png
new file mode 100644
index 0000000..d950b96
Binary files /dev/null and b/architecture/iOS/pix/jackview-audio-on.png differ
diff --git a/architecture/iOS/pix/jackview-audio-on at 2x.png b/architecture/iOS/pix/jackview-audio-on at 2x.png
new file mode 100644
index 0000000..d21f690
Binary files /dev/null and b/architecture/iOS/pix/jackview-audio-on at 2x.png differ
diff --git a/architecture/iOS/pix/jackview-in.png b/architecture/iOS/pix/jackview-in.png
new file mode 100644
index 0000000..f44e911
Binary files /dev/null and b/architecture/iOS/pix/jackview-in.png differ
diff --git a/architecture/iOS/pix/jackview-in at 2x.png b/architecture/iOS/pix/jackview-in at 2x.png
new file mode 100644
index 0000000..4c62f3e
Binary files /dev/null and b/architecture/iOS/pix/jackview-in at 2x.png differ
diff --git a/architecture/iOS/pix/jackview-midi-off.png b/architecture/iOS/pix/jackview-midi-off.png
new file mode 100644
index 0000000..b283d44
Binary files /dev/null and b/architecture/iOS/pix/jackview-midi-off.png differ
diff --git a/architecture/iOS/pix/jackview-midi-off at 2x.png b/architecture/iOS/pix/jackview-midi-off at 2x.png
new file mode 100644
index 0000000..0b8193e
Binary files /dev/null and b/architecture/iOS/pix/jackview-midi-off at 2x.png differ
diff --git a/architecture/iOS/pix/jackview-midi-on.png b/architecture/iOS/pix/jackview-midi-on.png
new file mode 100644
index 0000000..0e3119c
Binary files /dev/null and b/architecture/iOS/pix/jackview-midi-on.png differ
diff --git a/architecture/iOS/pix/jackview-midi-on at 2x.png b/architecture/iOS/pix/jackview-midi-on at 2x.png
new file mode 100644
index 0000000..1e865b9
Binary files /dev/null and b/architecture/iOS/pix/jackview-midi-on at 2x.png differ
diff --git a/architecture/iOS/pix/jackview-out.png b/architecture/iOS/pix/jackview-out.png
new file mode 100644
index 0000000..4717b01
Binary files /dev/null and b/architecture/iOS/pix/jackview-out.png differ
diff --git a/architecture/iOS/pix/jackview-out at 2x.png b/architecture/iOS/pix/jackview-out at 2x.png
new file mode 100644
index 0000000..f1f22dc
Binary files /dev/null and b/architecture/iOS/pix/jackview-out at 2x.png differ
diff --git a/architecture/iPhone/CocoaUI.h b/architecture/iPhone/CocoaUI.h
index 775f3b6..8dd0c6c 100644
--- a/architecture/iPhone/CocoaUI.h
+++ b/architecture/iPhone/CocoaUI.h
@@ -37,7 +37,7 @@
 #import <UIKit/UIKit.h>
 #import "iPhoneViewController.h"
 
-#include "misc.h"
+#include "faust/misc.h"
 
 #include <list>
 #include <map>
diff --git a/architecture/iPhone/iPhone.xcodeproj/project.pbxproj b/architecture/iPhone/iPhone.xcodeproj/project.pbxproj
old mode 100755
new mode 100644
index 0e8884a..685a488
--- a/architecture/iPhone/iPhone.xcodeproj/project.pbxproj
+++ b/architecture/iPhone/iPhone.xcodeproj/project.pbxproj
@@ -17,7 +17,7 @@
 		4B4BE15D113724BF00866BE1 /* iPhone-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4B4BE15C113724BF00866BE1 /* iPhone-Info.plist */; };
 		4BC3718C1137C53100BDEDEB /* iPhoneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3718B1137C53100BDEDEB /* iPhoneViewController.m */; };
 		4BC3718E1137C53500BDEDEB /* iPhoneAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3718D1137C53500BDEDEB /* iPhoneAppDelegate.mm */; };
-		4BCB3798112D633F008C7BC1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCB3797112D633F008C7BC1 /* AudioToolbox.framework */; };
+		6556A86614D970690068591C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6556A86514D970690068591C /* AudioToolbox.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -28,8 +28,8 @@
 		28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
 		4B425F671136BB83008FDC7D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		4B425FE11136C16E008FDC7D /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = SOURCE_ROOT; };
-		4B4BE15A113724B700866BE1 /* iPhoneViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = iPhoneViewController.xib; path = ../../iPhoneViewController.xib; sourceTree = BUILT_PRODUCTS_DIR; };
-		4B4BE15C113724BF00866BE1 /* iPhone-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "iPhone-Info.plist"; path = "../../iPhone-Info.plist"; sourceTree = BUILT_PRODUCTS_DIR; };
+		4B4BE15A113724B700866BE1 /* iPhoneViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = iPhoneViewController.xib; path = DerivedData/iPhone/Build/iPhoneViewController.xib; sourceTree = "<group>"; };
+		4B4BE15C113724BF00866BE1 /* iPhone-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; name = "iPhone-Info.plist"; path = "DerivedData/iPhone/Build/iPhone-Info.plist"; sourceTree = "<group>"; };
 		4BC371841137C50200BDEDEB /* CocoaUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CocoaUI.h; sourceTree = "<group>"; };
 		4BC371861137C50200BDEDEB /* iphone-faust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "iphone-faust.h"; sourceTree = "<group>"; };
 		4BC371871137C50200BDEDEB /* iPhoneAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneAppDelegate.h; sourceTree = "<group>"; };
@@ -37,7 +37,7 @@
 		4BC371891137C50200BDEDEB /* iPhone_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhone_Prefix.pch; sourceTree = "<group>"; };
 		4BC3718B1137C53100BDEDEB /* iPhoneViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iPhoneViewController.m; sourceTree = SOURCE_ROOT; };
 		4BC3718D1137C53500BDEDEB /* iPhoneAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iPhoneAppDelegate.mm; sourceTree = SOURCE_ROOT; };
-		4BCB3797112D633F008C7BC1 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.3.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
+		6556A86514D970690068591C /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -45,10 +45,10 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				6556A86614D970690068591C /* AudioToolbox.framework in Frameworks */,
 				1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
 				1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
 				288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
-				4BCB3798112D633F008C7BC1 /* AudioToolbox.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -95,7 +95,7 @@
 		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
-				4BCB3797112D633F008C7BC1 /* AudioToolbox.framework */,
+				6556A86514D970690068591C /* AudioToolbox.framework */,
 				1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
 				1D30AB110D05D00D00671497 /* Foundation.framework */,
 				288765A40DF7441C002DB57D /* CoreGraphics.framework */,
@@ -208,13 +208,15 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-				"CODE_SIGN_IDENTITY[sdk=iphonesimulator3.1.3]" = "iPhone Developer";
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos5.0]" = "iPhone Developer";
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				PREBINDING = NO;
-				"PROVISIONING_PROFILE[sdk=iphonesimulator3.1.3]" = "";
-				SDKROOT = iphonesimulator3.1.3;
+				PROVISIONING_PROFILE = "";
+				"PROVISIONING_PROFILE[sdk=iphoneos5.0]" = "";
+				SDKROOT = iphoneos;
 				USER_HEADER_SEARCH_PATHS = "/usr/local/lib/faust/**";
 			};
 			name = Debug;
@@ -223,13 +225,15 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-				"CODE_SIGN_IDENTITY[sdk=iphonesimulator3.1.3]" = "iPhone Developer";
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos5.0]" = "iPhone Developer";
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				PREBINDING = NO;
-				"PROVISIONING_PROFILE[sdk=iphonesimulator3.1.3]" = "";
-				SDKROOT = iphonesimulator3.1.3;
+				PROVISIONING_PROFILE = "";
+				"PROVISIONING_PROFILE[sdk=iphoneos5.0]" = "";
+				SDKROOT = iphoneos;
 				USER_HEADER_SEARCH_PATHS = "/usr/local/lib/faust/**";
 			};
 			name = Release;
diff --git a/architecture/iPhone/iPhone.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/architecture/iPhone/iPhone.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1e7dfa8
--- /dev/null
+++ b/architecture/iPhone/iPhone.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:iPhone.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/architecture/iPhone/iPhone.xcodeproj/project.xcworkspace/xcuserdata/olivierguillerminet.xcuserdatad/UserInterfaceState.xcuserstate b/architecture/iPhone/iPhone.xcodeproj/project.xcworkspace/xcuserdata/olivierguillerminet.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..067a2cb
Binary files /dev/null and b/architecture/iPhone/iPhone.xcodeproj/project.xcworkspace/xcuserdata/olivierguillerminet.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/architecture/iPhone/iPhoneViewController.m b/architecture/iPhone/iPhoneViewController.m
index cabb44d..8bfd055 100644
--- a/architecture/iPhone/iPhoneViewController.m
+++ b/architecture/iPhone/iPhoneViewController.m
@@ -54,6 +54,12 @@
 }
 */
 
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+    return YES;
+}
+
+
 - (void)didReceiveMemoryWarning {
 	// Releases the view if it doesn't have a superview.
     [super didReceiveMemoryWarning];
diff --git a/architecture/instrument.lib b/architecture/instrument.lib
new file mode 100644
index 0000000..215ff45
--- /dev/null
+++ b/architecture/instrument.lib
@@ -0,0 +1,287 @@
+//instrument.lib - Faust function of various types usefull for building physical model instruments
+
+declare name "Faust-STK Tools Library";
+declare author "Romain Michon (rmichon at ccrma.stanford.edu)";
+declare copyright "Romain Michon";
+declare version "1.0";
+declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
+
+import("math.lib");
+import("filter.lib");
+import("effect.lib");
+
+//========================= ENVELOPE GENERATORS ===============================
+
+//----------------------- VIBRATO ENVELOPE ----------------------------
+// 4 phases envelope to control vibrato gain
+//
+// USAGE:
+//   _ : *(envVibrato(b,a,s,r,t)) : _
+// where
+//   b = beginning duration (silence) in seconds
+//   a = attack duration in seconds
+//   s = sustain as a percentage of the amplitude to be modified
+//   r = release duration in seconds
+//   t = trigger signal
+
+envVibrato(b,a,s,r,t) = env ~ (_,_,_) : (!,!,_) // the 3 'state' signals are fed back
+with {
+    env (p2,cnt,y) =
+        (t>0) & (p2|(y>=1)),
+		(cnt + 1)*(t>0), // counter for the first step "b"
+        (y + p1*p3*u*(s/100) - p4*w*y)*((p4==0)|(y>=eps))	// y  = envelop signal
+		//*(y>=eps) // cut off tails to prevent denormals
+    with {
+	p1 = (p2==0) & (t>0) & (y<1) & (cnt>(b*SR)); // p1 = attack phase
+	p3 = 1-(cnt<(nb)); // p3 = beginning phase
+	p4 = (t<=0) & (y>0);  // p4 = release phase
+	// #samples in attack, release, must be >0
+	nb = SR*b+(b==0.0) ; na = SR*a+(a==0.0); nr = SR*r+(r==0.0);
+	// attack and (-60dB) release rates
+	z = s+(s==0.0)*db2linear(-60);
+	u = 1/na; w = 1-1/pow(z*db2linear(60), 1/nr);
+	// values below this threshold are considered zero in the release phase
+	eps = db2linear(-120);
+    };
+};
+
+//----------------------- ATTACK - SUSTAIN - RELEASE ----------------------------
+// Attack - Sustain - Release envelope
+//
+// USAGE:
+//   _ : *(asr(a,s,r,t)) : _
+// where
+//   a = attack duration in seconds
+//   s = sustain as a percentage of the amplitude to be modified
+//   r = release duration in seconds
+//   t = trigger signal
+
+asr(a,s,r,t) = env ~ (_,_) : (!,_) // the 2 'state' signals are fed back
+with {
+    env (p2,y) =
+        (t>0) & (p2|(y>=1)),
+        (y + p1*u*(s/100) - p3*w*y)	// y  = envelop signal
+	*((p3==0)|(y>=eps)) // cut off tails to prevent denormals
+    with {
+	p1 = (p2==0) & (t>0) & (y<1); // p1 = attack phase
+	p3 = (t<=0) & (y>0); // p3 = release phase
+	// #samples in attack, release, must be >0
+	na = SR*a+(a==0.0); nr = SR*r+(r==0.0);
+	// correct zero sustain level
+	z = s+(s==0.0)*db2linear(-60);
+	// attack and (-60dB) release rates
+	u = 1/na; w = 1-1/pow(z*db2linear(60), 1/nr);
+	// values below this threshold are considered zero in the release phase
+	eps = db2linear(-120);
+    };
+};
+
+//----------------------- ASYMPT60 ----------------------------
+// Envelope generator which asymptotically approaches a target value.
+//
+// USAGE:
+//   asympT60(value,trgt,T60,trig) : _
+// where
+//   value = starting value
+//   trgt = target value
+//   T60 = ramping time
+//   trig = trigger signal
+
+asympT60(value,trgt,T60,trig) = (_*factor + constant)~_
+	with{
+		cntSample = *(trig) + 1~_ : -(1);
+		attDur = float(2);
+		cndFirst = ((cntSample < attDur) & (trig > 0));
+		target = value*cndFirst + trgt*(cndFirst < 1);
+		factorAtt = exp(-7/attDur);
+		factorT60 = exp(-7/(T60*float(SR)));
+		factor = factorAtt*((cntSample < attDur) & (trig > 0)) +
+		       ((cntSample >= attDur) | (trig < 1))*factorT60;
+		constant = (1 - factor)*target;
+	};
+
+//========================= TABLES ===============================
+
+//----------------------- CLIPPING FUNCTION ----------------------------
+// Positive and negative clipping functions.
+//
+// USAGE:
+//   _ : saturationPos : _
+//   _ : saturationNeg : _
+//   _ : saturationPos : saturationNeg : _
+
+saturationPos(x) = x <: (_>1),(_<=1 : *(x)) :> +;
+saturationNeg(x) = x <: (_<-1),(_>=-1 : *(x)) :> *(-1) + _;
+
+//----------------------- BOW TABLE ----------------------------
+// Simple bow table.
+//
+// USAGE:
+//   index : bow(offset,slope) : _
+// where
+//   0 <= index <= 1
+
+bow(offset,slope) = pow(abs(sample) + 0.75, -4) : saturationPos
+	with{
+	sample(y) = (y + offset)*slope;
+	};
+
+//----------------------- REED TABLE ----------------------------
+// Simple reed table to be used with waveguide models of clanrinet, saxophone, etc.
+//
+// USAGE:
+//   _ : reed(offset,slope) : _
+// where
+//   offset = offset between 0 and 1
+//   slope = slope between 0 and 1
+// REFERENCE:
+//   https://ccrma.stanford.edu/~jos/pasp/View_Single_Reed_Oscillation.html
+
+reed(offset,slope) = reedTable : saturationPos : saturationNeg
+	with{
+	reedTable = offset + (slope*_);
+	};
+
+//========================= FILTERS ===============================
+
+//----------------------- ONE POLE ----------------------------
+
+onePole(b0,a1,x) = (b0*x - a1*_)~_;
+
+//----------------------- ONE POLE SWEPT ----------------------------
+
+onePoleSwep(a1,x) = (1 + a1)*x - a1*x';
+
+//----------------------- POLE ZERO ----------------------------
+
+poleZero(b0,b1,a1,x) = (b0*x + b1*x' - a1*_)~_;
+
+//----------------------- ONE ZEROS ----------------------------
+// Simple One zero and One zero recursive filters
+//
+// USAGE:
+//   _ : oneZero0(b0,b1) : _
+//   _ : oneZero1(b0,b1) : _
+// REFERENCE:
+//   https://ccrma.stanford.edu/~jos/fp2/One_Zero.html
+
+oneZero0(b0,b1,x) = (*(b1) + x*b0)~_;
+oneZero1(b0,b1,x) = (x'*b1 + x*b0);
+
+//----------------------- BANDPASS FILTER WITH CONSTANT UNITY PEAK GAIN BASED ON A BIQUAD ----------------------------
+
+bandPass(resonance,radius) = TF2(b0,b1,b2,a1,a2)
+	with{
+		a2 = radius*radius;
+		a1 = -2*radius*cos(PI*2*resonance/SR);
+		b0 = 0.5-0.5*a2;
+		b1 = 0;
+		b2 = -b0;
+	};
+
+//----------------------- BANDPASS FILTER BASED ON A BIQUAD ----------------------------
+// Band pass filter using a biquad (TF2 is declared in filter.lib)
+//
+// USAGE:
+//   _ : bandPassH(resonance,radius) : _
+// where
+//   resonance = center frequency
+//   radius = radius
+
+bandPassH(resonance,radius) = TF2(b0,b1,b2,a1,a2)
+	with{
+		a2 = radius*radius;
+		a1 = -2*radius*cos(PI*2*resonance/SR);
+		b0 = 1;
+		b1 = 0;
+		b2 = 0;
+	};
+
+//----------------------- FLUE JET NON-LINEAR FUNCTION ----------------------------
+// Jet Table: flue jet non-linear function, computed by a polynomial calculation
+
+jetTable(x) = x <: _*(_*_-1) : saturationPos : saturationNeg;
+
+//----------------------- NON LINEAR MODULATOR ----------------------------
+// nonLinearModulator adapts the function allpassnn from filter.lib for using it with waveguide instruments
+//
+// USAGE:
+//   _ : nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) : _
+// where
+//   nonlinearity = nonlinearity coefficient between 0 and 1
+//   env = input to connect any kind of envelope
+//   freq = current tone frequency
+//   typeMod = if 0: theta is modulated by the incoming signal;
+//	       if 1: theta is modulated by the averaged incoming signal;
+//	       if 2: theta is modulated by the squared incoming signal;
+//	       if 3: theta is modulated by a sine wave of frequency freqMod;
+//	       if 4: theta is modulated by a sine wave of frequency freq;
+//   freqMod = frequency of the sine wave modulation
+//   order = order of the filter
+
+nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) =
+	//theta is modulated by a sine wave
+	_ <: nonLinearFilterOsc*(typeMod >= 3),
+	//theta is modulated by the incoming signal
+	     (_ <: nonLinearFilterSig*nonlinearity,_*(1 - nonlinearity) :> +)*(typeMod < 3)
+	:> +
+	with{
+		//which frequency to use for the sine wave oscillator?
+		freqOscMod = (typeMod == 4)*freq + (typeMod != 4)*freqMod;
+
+		//the incoming signal is scaled and the envelope is applied
+		tsignorm(x) = nonlinearity*PI*x*env;
+		tsigsquared(x) = nonlinearity*PI*x*x*env; //incoming signal is squared
+		tsigav(x) = nonlinearity*PI*((x + x')/2)*env; //incoming signal is averaged with its previous sample
+
+		//select which version of the incoming signal of theta to use
+		tsig(x) = tsignorm(x)*(typeMod == 0) + tsigav(x)*(typeMod == 1)
+			  + tsigsquared(x)*(typeMod == 2);
+
+		//theta is modulated by a sine wave generator
+		tosc = nonlinearity*PI*osc(freqOscMod)*env;
+
+		//incoming signal is sent to the nonlinear passive allpass ladder filter
+		nonLinearFilterSig(x) = x <: allpassnn(order,(par(i,order,tsig(x))));
+		nonLinearFilterOsc = _ <: allpassnn(order,(par(i,order,tosc)));
+	};
+
+//========================= TOOLS ===============================
+
+//----------------------- STEREOIZER ----------------------------
+// This function takes a mono input signal and spacialize it in stereo
+// in function of the period duration of the tone being played.
+//
+// USAGE:
+//   _ : stereo(periodDuration) : _,_
+// where
+//   periodDuration = period duration of the tone being played in number of samples
+// ACKNOWLEDGMENT
+//   Formulation initiated by Julius O. Smith in https://ccrma.stanford.edu/realsimple/faust_strings/
+
+stereoizer(periodDuration) = _ <: _,widthdelay : stereopanner
+	   with{
+		W = hslider("v:Spat/spatial width", 0.5, 0, 1, 0.01);
+		A = hslider("v:Spat/pan angle", 0.6, 0, 1, 0.01);
+		widthdelay = delay(4096,W*periodDuration/2);
+		stereopanner = _,_ : *(1.0-A), *(A);
+	   };
+
+//----------------------- INSTRREVERB ----------------------------
+// GUI for zita_rev1_stereo from effect.lib
+//
+// USAGE:
+//  _,_ : instrRerveb
+
+instrReverb = _,_ <: *(reverbGain),*(reverbGain),*(1 - reverbGain),*(1 - reverbGain) :
+zita_rev1_stereo(rdel,f1,f2,t60dc,t60m,fsmax),_,_ <: _,!,_,!,!,_,!,_ : +,+
+       with{
+       reverbGain = hslider("v:Reverb/reverbGain",0.137,0,1,0.01) : smooth(0.999);
+       roomSize = hslider("v:Reverb/roomSize",0.72,0.01,2,0.01);
+       rdel = 20;
+       f1 = 200;
+       f2 = 6000;
+       t60dc = roomSize*3;
+       t60m = roomSize*2;
+       fsmax = 48000;
+       };
diff --git a/architecture/ios-coreaudio-api.cpp b/architecture/ios-coreaudio-api.cpp
new file mode 100644
index 0000000..ec4b967
--- /dev/null
+++ b/architecture/ios-coreaudio-api.cpp
@@ -0,0 +1,291 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/meta.h"
+#include "faust/gui/jsonfaustui.h"
+#include "faust/gui/JSONUI.h"
+#include "faust/gui/MapUI.h"
+
+//**************************************************************
+// Intrinsic
+//**************************************************************
+
+<<includeIntrinsic>>
+	
+//**************************************************************
+// Class
+//**************************************************************
+
+<<includeclass>>
+	
+//**************************************************************
+// Polyphony
+//**************************************************************
+
+#include "faust/dsp/poly-dsp.h"
+
+//**************************************************************
+// IOS Coreaudio
+//**************************************************************
+
+#include "faust/audio/coreaudio-ios-dsp.h"
+
+//**************************************************************
+// Interface
+//**************************************************************
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+class dsp_faust {
+
+private:
+
+    int polyMax;
+    int inChanNumb;
+    int outChanNumb;
+    bool on;
+    
+    TiPhoneCoreAudioRenderer fAudioDevice;
+    mydsp DSP;
+    mydsp_poly *DSPpoly;
+    MapUI mapUI;
+    JSONUI json;
+    string jsonString;
+    
+public:
+
+    dsp_faust() : json(DSP.getNumInputs(), DSP.getNumOutputs()),DSPpoly(0),on(false) {}
+    virtual ~dsp_faust() { delete DSPpoly; }
+    
+    /*
+     * init(samplingRate, bufferFrames)
+     * Initializes the Audio engine and the DSP code
+     * with samplingRate and bufferFrames.
+     * This method also looks for the [style:poly]
+     * metadata in the Faust code and initializes a
+     * polyphonic object or not based on that. init
+     * should be called before start.
+     */
+    bool init(int samplingRate, int bufferSize) {
+        DSP.init(samplingRate);
+        inChanNumb = DSP.getNumInputs();
+        outChanNumb = DSP.getNumOutputs();
+        
+        // configuring the UI
+        DSP.buildUserInterface(&mapUI);
+        DSP.buildUserInterface(&json);
+        
+        jsonString = json.JSON();
+        
+        if (jsonString.find("keyboard") != std::string::npos ||
+           jsonString.find("poly") != std::string::npos){
+            polyMax = 4;
+            DSPpoly = new mydsp_poly(polyMax, true);
+            DSPpoly->init(samplingRate);
+        } else {
+            polyMax = 0;
+        }
+        
+        return (fAudioDevice.Open(((polyMax > 0) ? DSPpoly : &DSP), inChanNumb, outChanNumb, bufferSize, samplingRate) == 0);
+    }
+    
+    /*
+     * start()
+     * Begins the processing and return 1 if the connection
+     * with the audio device was successful and 0 if not.
+     * On Android it also creates the native thread where the
+     * DSP tasks will be computed.
+     */
+    bool start() {
+        on = true;
+        return (fAudioDevice.Start() == 0);
+    }
+    
+    /*
+     * stop()
+     * Stops the processing, closes the audio engine and terminates
+     * the native thread on Android.
+     */
+    void stop() {
+        on = false;
+        fAudioDevice.Stop();
+    }
+    
+    /*
+     * isRunning()
+     * returns true if the DSP frames are being computed and
+     * false if not.
+     */
+    bool isRunning() {
+        return on;
+    }
+    
+    /*
+     * keyOn(pitch, velocity)
+     * Instantiates a new polyphonic voice where velocity
+     * and pitch are MIDI numbers (0-127). keyOn can only
+     * be used if the [style:poly] metadata is used in the
+     * Faust code. keyOn will return 0 if the object is not
+     * polyphonic and 1 otherwise.
+     */
+    int keyOn(int pitch, int velocity) {
+        if (polyMax > 0) {
+            DSPpoly->keyOn(0, pitch, velocity);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    /*
+     * keyOff(pitch)
+     * De-instantiates a polyphonic voice where pitch is the
+     * MIDI number of the note (0-127). keyOff can only be
+     * used if the [style:poly] metadata is used in the Faust
+     * code. keyOn will return 0 if the object is not polyphonic
+     * and 1 otherwise.
+     */
+    int keyOff(int pitch) {
+        if (polyMax > 0) {
+            DSPpoly->keyOff(0, pitch);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    /*
+     * pitchBend(refPitch, pitch)
+     * Replaces refPitch in the voice associated with it with pitch.
+     * pitch is a MIDI number expressed as a decimal number.
+     * pitchBend can only be used if the [style:poly] metadata
+     * is used in the Faust code. pitchBend will return 0
+     * if the object is not polyphonic and 1 otherwise.
+     */
+    int pitchBend(int refPitch, float pitch) {
+        if (polyMax > 0) {
+            DSPpoly->pitchBend(0, refPitch, pitch);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    /*
+     * getJSON()
+     * Returns a string containing a JSON description of the
+     * UI of the Faust object.
+     */
+    const char* getJSON() {
+        return jsonString.c_str();
+    }
+    
+    /*
+     * getParamsCount()
+     * Returns the number of parameters of the Faust object.
+     */
+    int getParamsCount() {
+        return mapUI.getParamsCount();
+    }
+    
+    /*
+     * getParam(address)
+     * Takes the address of a parameter and returns its current
+     * value.
+     */
+    float getParam(const char* address) {
+        return (polyMax == 0) ? mapUI.getValue(address) : DSPpoly->getValue(address);
+     }
+    
+    /*
+     * setParam(address,value)
+     * Sets the value of the parameter associated with address.
+     */
+    void setParam(const char* address, float value) {
+        if (polyMax == 0) {
+            mapUI.setValue(address, value);
+        } else {
+            DSPpoly->setValue(address, value);
+        }
+    }
+    
+    /*
+     * setVoiceParam(address,pitch,value)
+     * Sets the value of the parameter associated with address for
+     * the voice associated with pitch. setVoiceParam can only be
+     * used if the [style:poly] metadata is used in the Faust code.
+     * setVoiceParam will return 0 if the object is not polyphonic
+     * and 1 otherwise.
+     */
+    int setVoiceParam(const char* address, int pitch, float value) {
+        if (polyMax > 0) {
+            DSPpoly->setValue(address, pitch, value);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    /*
+     * setVoiceGain(pitch,gain)
+     * Sets the gain (0-1) of the voice associated with pitch.
+     * setVoiceGain can only be used if the [style:poly] metadata
+     * is used in the Faust code. setVoiceGain will return 0 if the
+     * object is not polyphonic and 1 otherwise.
+     */
+    int setVoiceGain(int pitch, float gain) {
+        if (polyMax > 0) {
+            setVoiceParam(DSPpoly->fGainLabel.c_str(), pitch, gain);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
+    /*
+     * getParamAddress(id)
+     * Returns the address of a parameter in function of its "id".
+     */
+    const char* getParamAddress(int id) {
+        return mapUI.getParamPath(id).c_str();
+    }  
+};
diff --git a/architecture/ios-coreaudio-jack.cpp b/architecture/ios-coreaudio-jack.cpp
new file mode 100644
index 0000000..b3288de
--- /dev/null
+++ b/architecture/ios-coreaudio-jack.cpp
@@ -0,0 +1,77 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#define JACK_IOS 1
+
+#import "FICocoaUI.h"
+#include "faust/audio/jack-dsp.h"
+#include "faust/audio/coreaudio-ios-dsp.h"
+#include "faust/misc.h"
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/******************************************************************************
+*******************************************************************************
+
+								USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+
+/********************END ARCHITECTURE SECTION (part 1/2)****************/
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+mydsp DSP;
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
diff --git a/architecture/ios-coreaudio.cpp b/architecture/ios-coreaudio.cpp
new file mode 100644
index 0000000..2c725a7
--- /dev/null
+++ b/architecture/ios-coreaudio.cpp
@@ -0,0 +1,73 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#import "FICocoaUI.h"
+#include "faust/audio/coreaudio-ios-dsp.h"
+#include "faust/misc.h"
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/******************************************************************************
+*******************************************************************************
+
+								USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+/********************END ARCHITECTURE SECTION (part 1/2)****************/
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+mydsp DSP;
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
diff --git a/architecture/jack-console.cpp b/architecture/jack-console.cpp
index 4da8d08..aeb4ccb 100644
--- a/architecture/jack-console.cpp
+++ b/architecture/jack-console.cpp
@@ -37,17 +37,22 @@
 #include <libgen.h>
 #include <math.h>
 #include <iostream>
+#include <list>
+#include <vector>
 
-#include "gui/console.h"
-#include "misc.h"
-#include "audio/jack-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/GUI.h"
+#include "faust/gui/console.h"
+#include "faust/audio/jack-dsp.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
 #endif
 
-using namespace std;
-
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
 
 /******************************************************************************
 *******************************************************************************
@@ -59,13 +64,6 @@ using namespace std;
 
 <<includeIntrinsic>>
 
-/******************************************************************************
-*******************************************************************************
-
-								USER INTERFACE
-
-*******************************************************************************
-/**************************BEGIN USER SECTION **************************/
 		
 <<includeclass>>
 
@@ -73,36 +71,63 @@ using namespace std;
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 					
-mydsp		DSP;
-list<GUI*>	GUI::fGuiList;
-	
+mydsp DSP;
+std::list<GUI*>     GUI::fGuiList;
+
 //-------------------------------------------------------------------------
 // 									MAIN
 //-------------------------------------------------------------------------
 int main(int argc, char *argv[] )
 {
-	char	jackname[256];
-	snprintf(jackname, 255, "%s", basename(argv[0]));
+	char appname[256];
+    char rcfilename[256];
+    char* home = getenv("HOME");
+    
+	snprintf(appname, 255, "%s", basename(argv[0]));
+    snprintf(rcfilename, 255, "%s/.%src", home, appname);
 
 	CMDUI* interface = new CMDUI(argc, argv);
+    FUI* finterface	= new FUI();
 	DSP.buildUserInterface(interface);
+	DSP.buildUserInterface(finterface);
 
 #ifdef OSCCTRL
-	GUI*	oscinterface = new OSCUI(jackname, argc, argv);
+	GUI* oscinterface = new OSCUI(appname, argc, argv);
 	DSP.buildUserInterface(oscinterface);
 #endif
 
+#ifdef HTTPCTRL
+	httpdUI* httpdinterface = new httpdUI(appname, DSP.getNumInputs(), DSP.getNumOutputs(), argc, argv);
+	DSP.buildUserInterface(httpdinterface);
+ #endif
+
 	jackaudio audio;
-	audio.init(jackname, &DSP);
+	audio.init(appname, &DSP);
 	interface->process_command();
 	audio.start();
-		
+
+#ifdef HTTPCTRL
+	httpdinterface->run();
+#endif	
+	
 #ifdef OSCCTRL
 	oscinterface->run();
 #endif
 	interface->run();
 	
 	audio.stop();
+    finterface->saveState(rcfilename);
+    
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
 	return 0;
 } 
 
diff --git a/architecture/jack-gtk-ros.cpp b/architecture/jack-gtk-ros.cpp
new file mode 100644
index 0000000..2e38190
--- /dev/null
+++ b/architecture/jack-gtk-ros.cpp
@@ -0,0 +1,150 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections : 
+	the ARCHITECTURE section (in two parts) and the USER section. Each section 
+	is governed by its own copyright and license. Please check individually 
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2014-2015 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work 
+	that contains this FAUST architecture section and distribute  
+	that work under terms of your choice, so long as this FAUST 
+	architecture section is not modified. 
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "faust/misc.h"
+#include "faust/gui/faustgtk.h"
+#include "faust/audio/jack-dsp.h"
+#include "faust/gui/RosUI.h"
+
+#include <ros/ros.h>
+
+#ifdef OSCCTRL
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+/**************************BEGIN USER SECTION **************************/
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+					
+mydsp*	DSP;
+
+std::list<GUI*>               GUI::fGuiList;
+
+//-------------------------------------------------------------------------
+// 									MAIN
+//-------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+    
+	char	appname[256];
+	char* 	home = getenv("HOME");
+	
+	snprintf(appname, 255, "%s", basename(argv[0]));
+	
+	// create DSP object
+	DSP = new mydsp();
+	if (DSP==0) 
+	{
+        ROS_ERROR("Unable to allocate Faust DSP object" );
+		exit(1);
+	}
+
+	// Get name from file name to name the namespace.
+	ros::init(argc, argv, (std::string)appname);
+	ros::NodeHandle n;
+		
+	// create and build graphic and ROS interfaces
+	GUI* interface 	= new GTKUI (appname, &argc, &argv);
+	RosUI* rosinterface = new RosUI (n, (std::string)appname);
+	
+	DSP->buildUserInterface(rosinterface);
+	DSP->buildUserInterface(interface);
+	
+	// Is there any declared ROS metadata ?
+	bool meta = rosinterface->isTrue();
+
+	if (meta) // If there is any, then we subscribe to the specific subscriber(s)
+	{
+		RosCallbacks* subscriber = new RosCallbacks(n); 
+	
+		std::vector<FAUSTFLOAT*> my_zones = rosinterface->getZones();
+		subscriber->subscribe(my_zones);
+	}
+	
+	// Launching jack audio API
+	jackaudio audio;
+	audio.init(appname, DSP);
+	
+	audio.start();
+
+
+	// ROS Callbacks are called by AsyncSpinner spinner
+	ros::AsyncSpinner spinner(rosinterface->getParamsCount());
+	spinner.start();
+	
+	// GTK interface is launched
+	interface->run();
+	
+	// Once the user clicks on the red cross of the window, everything stops	
+	interface->stop();
+    
+	audio.stop();
+	
+    
+    // desallocation
+    delete interface;
+    delete rosinterface;
+    
+
+
+  	return 0;
+}
+
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/jack-gtk.cpp b/architecture/jack-gtk.cpp
index 21a2910..51300b9 100644
--- a/architecture/jack-gtk.cpp
+++ b/architecture/jack-gtk.cpp
@@ -37,14 +37,24 @@
 #include <libgen.h>
 #include <stdlib.h>
 #include <iostream>
+#include <list>
 
-#include "gui/FUI.h"
-#include "misc.h"
-#include "gui/faustgtk.h"
-#include "audio/jack-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/gui/PrintUI.h"
+#include "faust/misc.h"
+#include "faust/gui/faustgtk.h"
+#include "faust/audio/jack-dsp.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+#ifdef OCVCTRL
+#include "faust/gui/OCVUI.h"
 #endif
 
 /**************************BEGIN USER SECTION **************************/
@@ -66,50 +76,80 @@
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 					
-mydsp*	DSP;
-
-list<GUI*>                   GUI::fGuiList;
+mydsp		DSP;
+std::list<GUI*>	GUI::fGuiList;
 
 //-------------------------------------------------------------------------
 // 									MAIN
 //-------------------------------------------------------------------------
 int main(int argc, char *argv[])
 {
-	char	appname[256];
-	char  	rcfilename[256];
-	char* 	home = getenv("HOME");
+	char appname[256];
+	char rcfilename[256];
+	char* home = getenv("HOME");
 	
 	snprintf(appname, 255, "%s", basename(argv[0]));
 	snprintf(rcfilename, 255, "%s/.%src", home, appname);
 
-	DSP = new mydsp();
-	if (DSP==0) {
-		cerr << "Unable to allocate Faust DSP object" << endl;
-		exit(1);
-	}
 	GUI* interface 	= new GTKUI (appname, &argc, &argv);
 	FUI* finterface	= new FUI();
-	DSP->buildUserInterface(interface);
-	DSP->buildUserInterface(finterface);
+	DSP.buildUserInterface(interface);
+	DSP.buildUserInterface(finterface);
+    DSP.buildUserInterface(new PrintUI());
+
+#ifdef HTTPCTRL
+	httpdUI* httpdinterface = new httpdUI(appname, DSP.getNumInputs(), DSP.getNumOutputs(), argc, argv);
+	DSP.buildUserInterface(httpdinterface);
+ 	std::cout << "HTTPD is on" << std::endl;
+#endif
 
 #ifdef OSCCTRL
-	GUI*	oscinterface = new OSCUI(appname, argc, argv);
-	DSP->buildUserInterface(oscinterface);
+	GUI* oscinterface = new OSCUI(appname, argc, argv);
+	DSP.buildUserInterface(oscinterface);
+#endif
+
+#ifdef OCVCTRL
+	std::cout<<"OCVCTRL defined"<<std::endl;
+	OCVUI* ocvinterface = new OCVUI();
+	DSP.buildUserInterface(ocvinterface);
 #endif
 
 	jackaudio audio;
-	audio.init(appname, DSP);
+	audio.init(appname, &DSP);
 	finterface->recallState(rcfilename);	
 	audio.start();
 	
+#ifdef HTTPCTRL
+	httpdinterface->run();
+#endif
+
 #ifdef OSCCTRL
 	oscinterface->run();
 #endif
+
+#ifdef OCVCTRL
+	ocvinterface->run();
+#endif
+
 	interface->run();
 	
 	audio.stop();
 	finterface->saveState(rcfilename);
-	delete DSP;
+    
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
+#ifdef OCVCTRL
+	 delete ocvinterface;
+#endif
+
   	return 0;
 }
 
diff --git a/architecture/jack-internal.cpp b/architecture/jack-internal.cpp
index 0df7fd0..e364f70 100644
--- a/architecture/jack-internal.cpp
+++ b/architecture/jack-internal.cpp
@@ -74,8 +74,6 @@ struct Meta : map<const char*, const char*>
     void declare (const char* key, const char* value) { (*this)[key]=value; }
 };
 
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
 
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
diff --git a/architecture/jack-qt.cpp b/architecture/jack-qt.cpp
index 7ed7f7e..3c73933 100644
--- a/architecture/jack-qt.cpp
+++ b/architecture/jack-qt.cpp
@@ -37,14 +37,25 @@
 #include <libgen.h>
 #include <stdlib.h>
 #include <iostream>
+#include <list>
 
-#include "gui/FUI.h"
-#include "misc.h"
-#include "gui/faustqt.h"
-#include "audio/jack-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/faustqt.h"
+#include "faust/audio/jack-dsp.h"
+#include "faust/midi/midi.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+#if MIDICTRL
+#include "faust/midi/rt-midi.h"
+#include "faust/gui/MidiUI.h"
 #endif
 
 /**************************BEGIN USER SECTION **************************/
@@ -59,54 +70,124 @@
 
 <<includeIntrinsic>>
 
-
 <<includeclass>>
 
+#ifdef POLY
+#include "faust/dsp/poly-dsp.h"
+mydsp_poly*	DSP;
+#else
+mydsp* DSP;
+#endif 
+
 /***************************END USER SECTION ***************************/
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 					
-mydsp	DSP;
+std::list<GUI*> GUI::fGuiList;
 
-list<GUI*>               GUI::fGuiList;
+/******************************************************************************
+*******************************************************************************
+
+                                MAIN PLAY THREAD
+
+*******************************************************************************
+*******************************************************************************/
 
-//-------------------------------------------------------------------------
-// 									MAIN
-//-------------------------------------------------------------------------
 int main(int argc, char *argv[])
 {
-	char	appname[256];
-	char	rcfilename[256];
-	char* 	home = getenv("HOME");
-
-	snprintf(appname, 255, "%s", basename(argv[0]));
-	snprintf(rcfilename, 255, "%s/.%src", home, appname);
+ 	char name[256];
+	char rcfilename[256];
+	char* home = getenv("HOME");
+
+	snprintf(name, 255, "%s", basename(argv[0]));
+	snprintf(rcfilename, 255, "%s/.%src", home, name);
+    
+    int poly = lopt(argv, "--poly", 4);
+    
+#if MIDICTRL
+    rtmidi midi(name);
+#endif
+	
+#ifdef POLY
+#if MIDICTRL
+    DSP = new mydsp_poly(poly, true);
+    midi.addMidiIn(DSP);
+#else
+    DSP = new mydsp_poly(poly);
+#endif
+#else
+    DSP = new mydsp();
+#endif
+    if (DSP == 0) {
+        std::cerr << "Unable to allocate Faust DSP object" << std::endl;
+        exit(1);
+    }
+
+    QApplication myApp(argc, argv);
+    
+    QTGUI interface;
+    FUI finterface;
+    DSP->buildUserInterface(&interface);
+    DSP->buildUserInterface(&finterface);
+    
+#ifdef MIDICTRL
+    MidiUI midiinterface(name);
+    DSP->buildUserInterface(&midiinterface);
+    std::cout << "MIDI is on" << std::endl;
+#endif
 
-	GUI* interface = new QTGUI(argc, argv);
-	FUI* finterface	= new FUI();
-	DSP.buildUserInterface(interface);
-	DSP.buildUserInterface(finterface);
+#ifdef HTTPCTRL
+	httpdUI httpdinterface(name, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
+	DSP->buildUserInterface(&httpdinterface);
+    std::cout << "HTTPD is on" << std::endl;
+#endif
 
 #ifdef OSCCTRL
-	GUI*	oscinterface = new OSCUI(appname, argc, argv);
-	DSP.buildUserInterface(oscinterface);
+    OSCUI oscinterface(name, argc, argv);
+    DSP->buildUserInterface(&oscinterface);
+    std::cout << "OSC is on" << std::endl;
 #endif
 	
 	jackaudio audio;
-	audio.init(appname, &DSP);
-	finterface->recallState(rcfilename);	
+	audio.init(name, DSP);
+	finterface.recallState(rcfilename);	
 	audio.start();
+    
+    printf("ins %d\n", audio.get_num_inputs());
+    printf("outs %d\n", audio.get_num_outputs());
+    
+#if MIDICTRL
+    midi.start();
+#endif
+	
+#ifdef HTTPCTRL
+	httpdinterface.run();
+#ifdef QRCODECTRL
+    interface.displayQRCode(httpdinterface.getTCPPort());
+#endif
+#endif
 	
 #ifdef OSCCTRL
-	oscinterface->run();
+	oscinterface.run();
 #endif
-	interface->run();
+#ifdef MIDICTRL
+	midiinterface.run();
+#endif
+	interface.run();
 	
+    myApp.setStyleSheet(interface.styleSheet());
+    myApp.exec();
+    interface.stop();
+    
 	audio.stop();
-	finterface->saveState(rcfilename);
+	finterface.saveState(rcfilename);
+    
+#if MIDICTRL
+    midi.stop();
+#endif
+    
   	return 0;
 }
 
-
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
 
diff --git a/architecture/jack-ros.cpp b/architecture/jack-ros.cpp
new file mode 100644
index 0000000..0bd1755
--- /dev/null
+++ b/architecture/jack-ros.cpp
@@ -0,0 +1,134 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections : 
+	the ARCHITECTURE section (in two parts) and the USER section. Each section 
+	is governed by its own copyright and license. Please check individually 
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2014-2015 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work 
+	that contains this FAUST architecture section and distribute  
+	that work under terms of your choice, so long as this FAUST 
+	architecture section is not modified. 
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "faust/misc.h"
+#include "faust/audio/jack-dsp.h"
+#include "faust/gui/RosUI.h"
+
+#include <ros/ros.h>
+
+#ifdef OSCCTRL
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+/**************************BEGIN USER SECTION **************************/
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+					
+mydsp*	DSP;
+
+//-------------------------------------------------------------------------
+// 									MAIN
+//-------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+    
+	char	appname[256];
+	
+	snprintf(appname, 255, "%s", basename(argv[0]));
+	
+	// Create DSP Object
+	DSP = new mydsp();
+	if (DSP==0) {
+        ROS_ERROR("Unable to allocate Faust DSP object" );
+		exit(1);
+	}
+
+	// Get name from file name to name the namespace
+		//This is a lot of names !
+	ros::init(argc, argv, (std::string)appname);
+	ros::NodeHandle n;
+	
+	// Create and build ROS interface
+	RosUI* interface = new RosUI(n, (std::string)appname);
+	DSP->buildUserInterface(interface);
+	
+	// Is there any declared ROS metadata ?
+	bool meta = interface->isTrue();
+	
+	if (meta) // If there is any, then we subscribe to the specific subscriber(s)
+	{
+		RosCallbacks* subscriber = new RosCallbacks(n); 
+	
+		std::vector<FAUSTFLOAT*> my_zones = interface->getZones();
+		subscriber->subscribe(my_zones);
+	}
+	
+	// Launching jack audio API
+	jackaudio audio;
+	audio.init(appname, DSP);
+
+	audio.start();
+	
+		
+	// Call ROS Callbacks
+	ros::spin();
+	
+	// Once Ctrl + C, everything stops
+	audio.stop();
+	
+    // desallocation
+    delete interface;
+
+
+  	return 0;
+}
+
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/ladspa.cpp b/architecture/ladspa.cpp
index d98becc..79bf536 100644
--- a/architecture/ladspa.cpp
+++ b/architecture/ladspa.cpp
@@ -45,23 +45,9 @@
 #include <map>
 
 #include "ladspa.h"
-#include "gui/GUI.h"
-#include "misc.h"
-#include "audio/dsp.h"
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #warning *** ladspa.cpp: NO SSE FLAG (denormals may slow things down) ***
-    #define AVOIDDENORMALS
-#endif
+#include "faust/gui/GUI.h"
+#include "faust/misc.h"
+#include "faust/audio/dsp.h"
 
 #define sym(name) xsym(name)
 #define xsym(name) #name
@@ -137,16 +123,16 @@ class portCollector : public UI
 	const char* 			fPortNames[MAXPORT];		// table of port names to be used in a LADSPA_Descriptor
 	LADSPA_PortRangeHint 	fPortHints[MAXPORT];		// table of port hints to be used in a LADSPA_Descriptor
 
-	string					fPluginName;				// toplevel prefix used as plugin name
-	stack<string>			fPrefix;					// current prefix for controls name
+    std::string					fPluginName;				// toplevel prefix used as plugin name
+    std::stack<std::string>			fPrefix;					// current prefix for controls name
 
 
 	//--------------------------------------------------------------------------------------
-	string simplify(const string& src)
+    std::string simplify(const std::string& src)
 	{
 		int		i=0;
 		int		level=2;
-		string	dst;
+        std::string	dst;
 
 		while (src[i] ) {
 
@@ -209,7 +195,7 @@ class portCollector : public UI
 
 	void addPortDescr(int type, const char* label, int hint, float min=0.0, float max=0.0)
 	{
-		string fullname = simplify(fPrefix.top() + "-" + label);
+        std::string fullname = simplify(fPrefix.top() + "-" + label);
 		char * str = strdup(fullname.c_str());
 
 		fPortDescs[fInsCount + fOutsCount + fCtrlCount] = type;
@@ -228,7 +214,7 @@ class portCollector : public UI
 			fPrefix.push(label);
 
 		} else {
-			string s;
+            std::string s;
 			if (label && label[0]) {
 				s = fPrefix.top() + "-" + label;
 			} else {
diff --git a/architecture/lv2.cpp b/architecture/lv2.cpp
new file mode 100644
index 0000000..94bdade
--- /dev/null
+++ b/architecture/lv2.cpp
@@ -0,0 +1,1048 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+    Copyright (C) 2009-2011 Albert Graef <Dr.Graef at t-online.de>
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.
+ ************************************************************************
+ ************************************************************************/
+
+/* LV2 architecture for Faust. */
+
+#include <stdlib.h>
+#include <math.h>
+#include <list>
+#include <map>
+
+using namespace std;
+
+// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
+// flags to avoid costly denormals
+#ifdef __SSE__
+    #include <xmmintrin.h>
+    #ifdef __SSE2__
+        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+    #else
+        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+    #endif
+#else
+  #define AVOIDDENORMALS
+#endif
+
+typedef pair<const char*,const char*> strpair;
+
+struct Meta
+{
+  list< strpair > data;
+  void declare (const char* key, const char* value)
+  { data.push_back(strpair(key, value)); }
+};
+
+//-------------------------------------------------------------------
+// Generic min and max using c++ inline
+//-------------------------------------------------------------------
+
+inline int 	max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
+inline int 	max (int a, int b)		{ return (a>b) ? a : b; }
+
+inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
+inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
+inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
+
+inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
+inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
+inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
+inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
+inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
+
+inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
+inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
+inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
+inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
+inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
+inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
+inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
+
+
+inline int	min (int a, int b)		{ return (a<b) ? a : b; }
+
+inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
+inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
+inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
+
+inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
+inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
+inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
+inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
+inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
+
+inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
+inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
+inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
+inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
+inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
+inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
+inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
+
+// abs is now predefined
+//template<typename T> T abs (T a)		{ return (a<T(0)) ? -a : a; }
+
+inline int	lsr (int x, int n)		{ return int(((unsigned int)x) >> n); }
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
+//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
+
+<<includeIntrinsic>>
+
+/******************************************************************************
+*******************************************************************************
+
+			ABSTRACT USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+class UI
+{
+  bool	fStopped;
+public:
+
+  UI() : fStopped(false) {}
+  virtual ~UI() {}
+
+  virtual void addButton(const char* label, float* zone) = 0;
+  virtual void addCheckButton(const char* label, float* zone) = 0;
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
+
+  virtual void openTabBox(const char* label) = 0;
+  virtual void openHorizontalBox(const char* label) = 0;
+  virtual void openVerticalBox(const char* label) = 0;
+  virtual void closeBox() = 0;
+
+  virtual void run() = 0;
+
+  void stop() { fStopped = true; }
+  bool stopped() { return fStopped; }
+
+  virtual void declare(float* zone, const char* key, const char* value) {}
+};
+
+/***************************************************************************
+   LV2 UI interface
+ ***************************************************************************/
+
+enum ui_elem_type_t {
+  UI_BUTTON, UI_CHECK_BUTTON,
+  UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
+  UI_V_BARGRAPH, UI_H_BARGRAPH,
+  UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
+};
+
+struct ui_elem_t {
+  ui_elem_type_t type;
+  const char *label;
+  int port;
+  float *zone;
+  void *ref;
+  float init, min, max, step;
+};
+
+class LV2UI : public UI
+{
+public:
+  int nelems, nports;
+  ui_elem_t *elems;
+  map< int, list<strpair> > metadata;
+
+  LV2UI();
+  virtual ~LV2UI();
+
+protected:
+  void add_elem(ui_elem_type_t type, const char *label = NULL);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float init, float min, float max, float step);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float min, float max);
+
+public:
+  virtual void addButton(const char* label, float* zone);
+  virtual void addCheckButton(const char* label, float* zone);
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+
+  virtual void openTabBox(const char* label);
+  virtual void openHorizontalBox(const char* label);
+  virtual void openVerticalBox(const char* label);
+  virtual void closeBox();
+
+  virtual void run();
+
+  virtual void declare(float* zone, const char* key, const char* value);
+};
+
+LV2UI::LV2UI()
+{
+  nelems = nports = 0;
+  elems = NULL;
+}
+
+LV2UI::~LV2UI()
+{
+  if (elems) free(elems);
+}
+
+void LV2UI::declare(float* zone, const char* key, const char* value)
+{
+  map< int, list<strpair> >::iterator it = metadata.find(nelems);
+  if (it != metadata.end())
+    it->second.push_back(strpair(key, value));
+  else
+    metadata[nelems] = list<strpair>(1, strpair(key, value));
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = -1;
+  elems[nelems].zone = NULL;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = nports++;
+  elems[nelems].zone = zone;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			     float init, float min, float max, float step)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = nports++;
+  elems[nelems].zone = zone;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = init;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = step;
+  nelems++;
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			     float min, float max)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = nports++;
+  elems[nelems].zone = zone;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+void LV2UI::addButton(const char* label, float* zone)
+{ add_elem(UI_BUTTON, label, zone); }
+void LV2UI::addCheckButton(const char* label, float* zone)
+{ add_elem(UI_CHECK_BUTTON, label, zone); }
+void LV2UI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
+void LV2UI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
+void LV2UI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
+
+void LV2UI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_H_BARGRAPH, label, zone, min, max); }
+void LV2UI::addVerticalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_V_BARGRAPH, label, zone, min, max); }
+
+void LV2UI::openTabBox(const char* label)
+{ add_elem(UI_T_GROUP, label); }
+void LV2UI::openHorizontalBox(const char* label)
+{ add_elem(UI_H_GROUP, label); }
+void LV2UI::openVerticalBox(const char* label)
+{ add_elem(UI_V_GROUP, label); }
+void LV2UI::closeBox()
+{ add_elem(UI_END_GROUP); }
+
+void LV2UI::run() {}
+
+/******************************************************************************
+*******************************************************************************
+
+			    FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------
+//  abstract definition of a signal processor
+//----------------------------------------------------------------
+
+class dsp {
+ protected:
+  int fSamplingFreq;
+ public:
+  // internal freelist for custom voice allocation
+  dsp *prev, *next;
+  dsp() {}
+  virtual ~dsp() {}
+  virtual int getNumInputs() = 0;
+  virtual int getNumOutputs() = 0;
+  virtual void buildUserInterface(UI* interface) = 0;
+  virtual void init(int samplingRate) = 0;
+  virtual void compute(int len, float** inputs, float** outputs) = 0;
+};
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+
+<<includeclass>>
+
+//----------------------------------------------------------------------------
+//  LV2 interface
+//----------------------------------------------------------------------------
+
+//#line 391 "lv2.cpp"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* This enables automatic MIDI controller mapping based on the midi:ctrl
+   attributes in the Faust source. We have this enabled by default, but you
+   may have to disable it if the custom controller mapping gets in the way of
+   the automation facilities that the host provides. (But then again if the
+   host wants to do its own controller mapping then it probably won't, or at
+   least shouldn't, send us the MIDI controllers in the first place.) */
+#ifndef FAUST_MIDICC
+#define FAUST_MIDICC 1
+#endif
+
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+#include <lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h>
+#if FAUST_MIDICC
+#include <lv2/lv2plug.in/ns/ext/atom/util.h>
+#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
+#define MIDI_EVENT_URI "http://lv2plug.in/ns/ext/midi#MidiEvent"
+#endif
+
+#ifndef URI_PREFIX
+#define URI_PREFIX "http://faust-lv2.googlecode.com"
+#endif
+
+#ifndef PLUGIN_URI
+#define PLUGIN_URI URI_PREFIX "/mydsp"
+#endif
+
+/* This allows various manifest data to be generated from the corresponding
+   metadata (author, name, description, license) in the Faust source. */
+#ifndef FAUST_META
+#define FAUST_META 1
+#endif
+
+// You can define these for various debugging output items.
+//#define DEBUG_META 1 // recognized MIDI controller metadata
+//#define DEBUG_MIDI 1 // incoming MIDI messages
+//#define DEBUG_MIDICC 1 // controller messages
+
+struct LV2Plugin {
+  bool active;		// activation status
+  int rate;		// sampling rate
+  mydsp *dsp;		// the dsp
+  LV2UI *ui;		// its Faust interface description
+  int n_in, n_out;	// number of input and output control ports
+  int *ctrls;		// Faust ui elements (indices into ui->elems)
+  float **ports;	// corresponding LV2 data
+  float *portvals;	// cached port data from the last run
+  int *inctrls, *outctrls;	// indices for active and passive controls
+  float **inputs, **outputs;	// audio buffers
+#if FAUST_MIDICC
+  LV2_Atom_Sequence* event_port; // midi input
+  std::map<uint8_t,int> ctrlmap; // MIDI controller map
+  // Needed host features.
+  LV2_URID_Map* map;	// the urid extension
+  LV2_URID midi_event;	// midi event uri
+#endif
+
+  LV2Plugin() {
+    active = false;
+    rate = 44100;
+    n_in = n_out = 0;
+    dsp = NULL;
+    ui = NULL;
+    ctrls = inctrls = outctrls = NULL;
+    ports = inputs = outputs = NULL;
+    portvals = NULL;
+#if FAUST_MIDICC
+    map = NULL;
+    midi_event = -1;
+    event_port = NULL;
+#endif
+  }
+};
+
+static LV2_Handle
+instantiate(const LV2_Descriptor*     descriptor,
+            double                    rate,
+            const char*               bundle_path,
+            const LV2_Feature* const* features)
+{
+  LV2Plugin* plugin = new LV2Plugin;
+#if FAUST_MIDICC
+  // Scan host features for URID map.
+  for (int i = 0; features[i]; i++) {
+    if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) {
+      plugin->map = (LV2_URID_Map*)features[i]->data;
+      plugin->midi_event =
+	plugin->map->map(plugin->map->handle, MIDI_EVENT_URI);
+    }
+  }
+  if (!plugin->map) {
+    fprintf
+      (stderr, "%s: host doesn't support urid:map, giving up\n",
+       PLUGIN_URI);
+    delete plugin;
+    return 0;
+  }
+#endif
+  plugin->rate = rate;
+  plugin->dsp = new mydsp();
+  plugin->ui = new LV2UI();
+  plugin->dsp->init(plugin->rate);
+  plugin->dsp->buildUserInterface(plugin->ui);
+  // The LV2 ports are numbered as follows: 0..k-1 are the control ports, then
+  // come the n audio input ports, finally the m audio output ports (and
+  // possibly a MIDI input port).
+  int k = plugin->ui->nports, p = 0, q = 0;
+  int n = plugin->dsp->getNumInputs(), m = plugin->dsp->getNumOutputs();
+  // Allocate tables for the control elements and their LV2 ports.
+  plugin->ctrls = (int*)calloc(k, sizeof(int));
+  plugin->inctrls = (int*)calloc(k, sizeof(int));
+  plugin->outctrls = (int*)calloc(k, sizeof(int));
+  plugin->ports = (float**)calloc(k, sizeof(float*));
+  plugin->portvals = (float*)calloc(k, sizeof(float));
+  assert(k == 0 || (plugin->ctrls && plugin->inctrls && plugin->outctrls &&
+		    plugin->ports && plugin->portvals));
+  // Scan the Faust UI for active and passive controls which become the
+  // input and output control ports of the LV2 plugin, respectively.
+  for (int i = 0, j = 0; i < plugin->ui->nelems; i++) {
+    switch (plugin->ui->elems[i].type) {
+    case UI_T_GROUP: case UI_H_GROUP: case UI_V_GROUP: case UI_END_GROUP:
+      // control groups
+      break;
+    case UI_H_BARGRAPH: case UI_V_BARGRAPH:
+      // passive controls (output ports)
+      plugin->ctrls[j++] = i;
+      plugin->outctrls[q++] = i;
+      break;
+    default:
+      // active controls (input ports)
+#if FAUST_MIDICC
+      {
+	std::map< int, list<strpair> >::iterator it =
+	  plugin->ui->metadata.find(i);
+	if (it != plugin->ui->metadata.end()) {
+	  // Scan for controller mappings.
+	  for (std::list<strpair>::iterator jt = it->second.begin();
+	       jt != it->second.end(); jt++) {
+	    const char *key = jt->first, *val = jt->second;
+#if DEBUG_META
+	    fprintf(stderr, "ctrl '%s' meta: '%s' -> '%s'\n",
+		    plugin->ui->elems[i].label, key, val);
+#endif
+	    if (strcmp(key, "midi")) continue;
+	    unsigned num;
+	    if (sscanf(val, "ctrl %u", &num) < 1) continue;
+#if 0 // enable this to get feedback about controller assignments
+	    fprintf(stderr, "%s: cc %d -> %s\n", PLUGIN_URI, num,
+		    plugin->ui->elems[i].label);
+#endif
+	    plugin->ctrlmap.insert(std::pair<uint8_t,int>(num, p));
+	  }
+	}
+      }
+#endif
+      plugin->ctrls[j++] = i;
+      plugin->inctrls[p++] = i;
+      int p = plugin->ui->elems[i].port;
+      float val = plugin->ui->elems[i].init;
+      plugin->portvals[p] = val;
+      break;
+    }
+  }
+  // Realloc the inctrls and outctrls vectors to their appropriate sizes.
+  plugin->inctrls = (int*)realloc(plugin->inctrls, p*sizeof(int));
+  assert(p == 0 || plugin->inctrls);
+  plugin->outctrls = (int*)realloc(plugin->outctrls, q*sizeof(int));
+  assert(q == 0 || plugin->outctrls);
+  plugin->n_in = p; plugin->n_out = q;
+  // Allocate vectors for the audio input and output ports. Like
+  // plugin->ports, these will be initialized in the connect_port callback.
+  plugin->inputs = (float**)calloc(n, sizeof(float*));
+  assert(n == 0 || plugin->inputs);
+  plugin->outputs = (float**)calloc(m, sizeof(float*));
+  assert(m == 0 || plugin->outputs);
+  return (LV2_Handle)plugin;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+  LV2Plugin* plugin = (LV2Plugin*)instance;
+  delete plugin->dsp;
+  delete plugin->ui;
+  free(plugin->ctrls);
+  free(plugin->inctrls);
+  free(plugin->outctrls);
+  free(plugin->ports);
+  free(plugin->portvals);
+  free(plugin->inputs);
+  free(plugin->outputs);
+  delete plugin;
+}
+
+static void
+connect_port(LV2_Handle instance,
+             uint32_t   port,
+             void*      data)
+{
+  LV2Plugin* plugin = (LV2Plugin*)instance;
+  int i = port, k = plugin->ui->nports;
+  int n = plugin->dsp->getNumInputs(), m = plugin->dsp->getNumOutputs();
+  if (i < k)
+    plugin->ports[i] = (float*)data;
+  else {
+    i -= k;
+    if (i < n)
+      plugin->inputs[i] = (float*)data;
+    else {
+      i -= n;
+      if (i < m)
+	plugin->outputs[i] = (float*)data;
+#if FAUST_MIDICC
+      else if (i == m)
+	plugin->event_port = (LV2_Atom_Sequence*)data;
+#endif
+      else
+	fprintf(stderr, "%s: bad port number %u\n", PLUGIN_URI, port);
+    }
+  }
+}
+
+#if FAUST_MIDICC
+static float ctrlval(const ui_elem_t &el, uint8_t v)
+{
+  // Translate the given MIDI controller value to the range and stepsize
+  // indicated by the Faust control.
+  switch (el.type) {
+  case UI_BUTTON: case UI_CHECK_BUTTON:
+    return (float)(v>=64);
+  default:
+    /* Continuous controllers. The problem here is that the range 0..127 is
+       not symmetric. We'd like to map 64 to the center of the range
+       (max-min)/2 and at the same time retain the full control range
+       min..max. So let's just pretend that there are 128 controller values
+       and map value 127 to the max value anyway. */
+    if (v==127)
+      return el.max;
+    else
+      // XXXFIXME: We might want to add proper quantization according to
+      // el.step here.
+      return el.min+(el.max-el.min)*v/128;
+  }
+}
+#endif
+
+static void
+run(LV2_Handle instance, uint32_t n_samples)
+{
+  LV2Plugin* plugin = (LV2Plugin*)instance;
+  int n = plugin->dsp->getNumInputs(), m = plugin->dsp->getNumOutputs();
+  AVOIDDENORMALS;
+  if (!plugin->active) {
+    if (n == m) {
+      // copy inputs to outputs
+      for (int i = 0; i < m; i++)
+	for (unsigned j = 0; j < n_samples; j++)
+	  plugin->outputs[i][j] = plugin->inputs[i][j];
+    } else {
+      // silence
+      for (int i = 0; i < m; i++)
+	for (unsigned j = 0; j < n_samples; j++)
+	  plugin->outputs[i][j] = 0.0f;
+    }
+    return;
+  }
+#if FAUST_MIDICC
+  if (!plugin->ctrlmap.empty() && plugin->event_port) {
+    // Process incoming MIDI events.
+    LV2_Atom_Event* i;
+    LV2_ATOM_SEQUENCE_FOREACH(plugin->event_port, ev) {
+      if (ev->body.type == plugin->midi_event) {
+	uint8_t *data = (uint8_t*)(ev+1);
+#if DEBUG_MIDI
+	fprintf(stderr, "midi ev (%u bytes):", ev->body.size);
+	for (unsigned i = 0; i < ev->body.size; i++)
+	  fprintf(stderr, " 0x%0x", data[i]);
+	fprintf(stderr, "\n");
+#endif
+	uint8_t status = data[0] & 0xf0, chan = data[0] & 0x0f;
+	if (status == 0xb0) {
+	  // interpret all other controller changes according to the MIDI
+	  // controller map defined in the Faust plugin itself
+	  std::map<uint8_t,int>::iterator it = plugin->ctrlmap.find(data[1]);
+	  if (it != plugin->ctrlmap.end()) {
+	    // defined MIDI controller
+	    int j = plugin->inctrls[it->second];
+#if DEBUG_MIDICC
+	    fprintf(stderr, "ctrl-change chan %d, ctrl %d, val %d\n", chan+1,
+		    data[1], data[2]);
+#endif
+	    *plugin->ui->elems[j].zone = ctrlval(plugin->ui->elems[j], data[2]);
+	  }
+	}
+      } else {
+	fprintf(stderr, "%s: unknown event type %d\n", PLUGIN_URI, ev->body.type);
+      }
+    }
+  }
+#endif
+  // Only update the controls if the port value actually changed. This is
+  // necessary to preserve the MIDI controller changes (see above). Also note
+  // that we do this *after* processing the MIDI controller data so that
+  // manual inputs can override these.
+  for (int i = 0; i < plugin->n_in; i++) {
+    int j = plugin->inctrls[i], k = plugin->ui->elems[j].port;
+    float &oldval = plugin->portvals[k], newval = *plugin->ports[k];
+    if (newval != oldval)
+      *plugin->ui->elems[j].zone = oldval = newval;
+  }
+  // Let Faust do all the hard work.
+  plugin->dsp->compute(n_samples, plugin->inputs, plugin->outputs);
+  // Finally grab the passive controls and write them back to the
+  // corresponding LV2 ports.
+  for (int i = 0; i < plugin->n_out; i++) {
+    int j = plugin->outctrls[i], k = plugin->ui->elems[j].port;
+    float *z = plugin->ui->elems[j].zone;
+    *plugin->ports[k] = *z;
+  }
+}
+
+static void
+activate(LV2_Handle instance)
+{
+  LV2Plugin* plugin = (LV2Plugin*)instance;
+  plugin->dsp->init(plugin->rate);
+  for (int i = 0, j = 0; i < plugin->ui->nelems; i++) {
+    int p = plugin->ui->elems[i].port;
+    if (p >= 0) {
+      float val = plugin->ui->elems[i].init;
+      plugin->portvals[p] = val;
+    }
+  }
+  plugin->active = true;
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+  LV2Plugin* plugin = (LV2Plugin*)instance;
+  plugin->active = false;
+}
+
+const void*
+extension_data(const char* uri)
+{
+  return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+  PLUGIN_URI,
+  instantiate,
+  connect_port,
+  activate,
+  run,
+  deactivate,
+  cleanup,
+  extension_data
+};
+
+extern "C"
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+  switch (index) {
+  case 0:
+    return &descriptor;
+  default:
+    return NULL;
+  }
+}
+
+//----------------------------------------------------------------------------
+//  Dynamic manifest
+//----------------------------------------------------------------------------
+
+// NOTE: If your LV2 host doesn't offer this extension then you'll have to
+// create a static ttl file with the descriptions of the ports yourself. You
+// can also do this by compiling this code to a standalone executable while
+// defining the __MAIN__ symbol. Running the executable then prints the
+// manifest on stdout.
+
+extern "C"
+LV2_SYMBOL_EXPORT
+int lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle *handle,
+			  const LV2_Feature *const *features)
+{
+  LV2Plugin* plugin = new LV2Plugin;
+  plugin->dsp = new mydsp();
+  plugin->ui = new LV2UI();
+  plugin->dsp->init(48000);
+  plugin->dsp->buildUserInterface(plugin->ui);
+  int k = plugin->ui->nports;
+  plugin->ctrls = (int*)calloc(k, sizeof(int));
+  assert(k == 0 || plugin->ctrls);
+  for (int i = 0, j = 0; i < plugin->ui->nelems; i++) {
+    switch (plugin->ui->elems[i].type) {
+    case UI_T_GROUP: case UI_H_GROUP: case UI_V_GROUP: case UI_END_GROUP:
+      // control groups
+      break;
+    case UI_H_BARGRAPH: case UI_V_BARGRAPH:
+      // passive controls (output ports)
+      plugin->ctrls[j++] = i;
+      break;
+    default:
+      // active controls (input ports)
+      plugin->ctrls[j++] = i;
+      break;
+    }
+  }
+  *handle = (LV2_Dyn_Manifest_Handle)plugin;
+  return 0;
+}
+
+extern "C"
+LV2_SYMBOL_EXPORT
+int lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,
+				  FILE *fp)
+{
+  fprintf(fp, "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n\
+<%s> a lv2:Plugin .\n", PLUGIN_URI);
+  return 0;
+}
+
+#include <string>
+#include <ctype.h>
+
+static string mangle(const string &s)
+{
+  string t = s;
+  size_t n = s.size();
+  for (size_t i = 0; i < n; i++)
+    if ((i == 0 && !isalpha(t[i]) && t[i] != '_') ||
+	(!isalnum(t[i]) && t[i] != '_'))
+      t[i] = '_';
+  return t;
+}
+
+#if FAUST_META
+static bool is_xmlstring(const char *s)
+{
+  // This is just a basic sanity check. The string must not contain any
+  // (unescaped) newlines, carriage returns or double quotes.
+  return !strchr(s, '\n') && !strchr(s, '\r') && !strchr(s, '"');
+}
+#endif
+
+extern "C"
+LV2_SYMBOL_EXPORT
+int lv2_dyn_manifest_get_data(LV2_Dyn_Manifest_Handle handle,
+			      FILE *fp,
+			      const char *uri)
+{
+  LV2Plugin* plugin = (LV2Plugin*)handle;
+  int k = plugin->ui->nports;
+  int n = plugin->dsp->getNumInputs(), m = plugin->dsp->getNumOutputs();
+  // Scan the global metadata for plugin name, description, license etc.
+  const char *plugin_name = NULL, *plugin_author = NULL, *plugin_descr = NULL,
+    *plugin_license = NULL;
+#if FAUST_META
+  Meta meta;
+  plugin->dsp->metadata(&meta);
+  for (std::list<strpair>::iterator it = meta.data.begin();
+       it != meta.data.end(); it++) {
+    const char *key = it->first, *val = it->second;
+    if (!val || !is_xmlstring(val)) continue;
+    if (!strcmp(key, "name")) {
+      if (!plugin_name)
+	plugin_name = val;
+    } else if (!strcmp(key, "description")) {
+      if (!plugin_descr)
+	plugin_descr = val;
+    } else if (!strcmp(key, "author")) {
+      if (!plugin_author)
+	plugin_author = val;
+    } else if (!strcmp(key, "license")) {
+      if (!plugin_license)
+	plugin_license = val;
+    }
+  }
+#endif
+  if (!plugin_name) plugin_name = "mydsp";
+  fprintf(fp, "@prefix doap:  <http://usefulinc.com/ns/doap#> .\n\
+ at prefix foaf:  <http://xmlns.com/foaf/0.1/> .\n\
+ at prefix lv2:   <http://lv2plug.in/ns/lv2core#> .\n\
+ at prefix epp:   <http://lv2plug.in/ns/ext/port-props#> .\n\
+ at prefix atom:  <http://lv2plug.in/ns/ext/atom#> .\n\
+ at prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
+ at prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .\n\
+ at prefix units: <http://lv2plug.in/ns/extensions/units#> .\n\
+<%s>\n\
+       a lv2:Plugin ;\n\
+       doap:name \"%s\" ;\n\
+       lv2:binary <mydsp.so> ;\n\
+       lv2:optionalFeature epp:supportsStrictBounds ;\n\
+       lv2:optionalFeature lv2:hardRtCapable ;\n", PLUGIN_URI, plugin_name);
+  if (plugin_author)
+    fprintf(fp, "\
+       doap:maintainer [ foaf:name \"%s\" ] ;\n", plugin_author);
+  if (plugin_descr)
+    fprintf(fp, "\
+       doap:description \"%s\" ;\n", plugin_descr);
+  if (plugin_license)
+    fprintf(fp, "\
+       doap:license \"%s\" ;\n", plugin_license);
+  int idx = 0;
+  bool have_midi = false;
+  // control ports
+  for (int i = 0; i < k; i++, idx++) {
+    int j = plugin->ctrls[i];
+    assert(idx == plugin->ui->elems[j].port);
+    fprintf(fp, "%s [\n", idx==0?"    lv2:port":" ,");
+    const char *label = plugin->ui->elems[j].label;
+    assert(label);
+    string sym = mangle(plugin->ui->elems[j].label);
+    switch (plugin->ui->elems[j].type) {
+    // active controls (input ports)
+    case UI_BUTTON: case UI_CHECK_BUTTON:
+    fprintf(fp, "\
+	a lv2:ControlPort ;\n\
+	a lv2:InputPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"%s\" ;\n\
+	lv2:name \"%s\" ;\n\
+        lv2:portProperty epp:hasStrictBounds ;\n\
+        lv2:portProperty lv2:toggled ;\n\
+	lv2:default 0.00000 ;\n\
+	lv2:minimum 0.00000 ;\n\
+	lv2:maximum 1.00000 ;\n", idx, sym.c_str(), label);
+      break;
+    case UI_NUM_ENTRY: case UI_H_SLIDER: case UI_V_SLIDER:
+    fprintf(fp, "\
+	a lv2:ControlPort ;\n\
+	a lv2:InputPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"%s\" ;\n\
+	lv2:name \"%s\" ;\n\
+	lv2:default %g ;\n\
+	lv2:minimum %g ;\n\
+	lv2:maximum %g ;\n", idx, sym.c_str(), label,
+	    plugin->ui->elems[j].init,
+	    plugin->ui->elems[j].min,
+	    plugin->ui->elems[j].max);
+      break;
+    // passive controls (output ports)
+    case UI_H_BARGRAPH: case UI_V_BARGRAPH:
+    fprintf(fp, "\
+	a lv2:ControlPort ;\n\
+	a lv2:OutputPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"%s\" ;\n\
+	lv2:name \"%s\" ;\n\
+	lv2:default %g ;\n\
+	lv2:minimum %g ;\n\
+	lv2:maximum %g ;\n", idx, sym.c_str(), label,
+	    plugin->ui->elems[j].min,
+	    plugin->ui->elems[j].min,
+	    plugin->ui->elems[j].max);
+      break;
+    default:
+      assert(0 && "this can't happen");
+      break;
+    }
+    // Scan for Faust control metadata we understand and add corresponding
+    // hints to the LV2 description of the port.
+    std::map< int, list<strpair> >::iterator it =
+      plugin->ui->metadata.find(j);
+    if (it != plugin->ui->metadata.end()) {
+      for (std::list<strpair>::iterator jt = it->second.begin();
+	   jt != it->second.end(); jt++) {
+	const char *key = jt->first, *val = jt->second;
+#if FAUST_MIDICC
+	unsigned num;
+	if (!strcmp(key, "midi") && sscanf(val, "ctrl %u", &num) == 1)
+	  have_midi = true;
+#endif
+	if (!strcmp(key, "unit"))
+	  fprintf(fp, "\
+	units:unit [\n\
+            a            units:Unit ;\n\
+            units:name   \"%s\" ;\n\
+            units:symbol \"%s\" ;\n\
+            units:render \"%%f %s\"\n\
+	] ;\n", val, val, val);
+	if (strcmp(key, "lv2")) continue;
+	if (!strcmp(val, "integer"))
+	  fprintf(fp, "\
+	lv2:portProperty lv2:integer ;\n");
+	else if (!strcmp(val, "hidden") || !strcmp(val, "notOnGUI"))
+	  fprintf(fp, "\
+	lv2:portProperty epp:notOnGUI ;\n");
+	else if (!strncmp(val, "scalepoint", 10) ||
+		 !strncmp(val, "scalePoint", 10)) {
+	  val += 10;
+	  if (!isspace(*val)) continue;
+	  char *label = (char*)malloc(strlen(val)+1);
+	  float point;
+	  int pos;
+	  while (sscanf(val, "%s %g%n", label, &point, &pos) == 2) {
+	    fprintf(fp, "\
+	lv2:scalePoint [ rdfs:label \"%s\"; rdf:value %g ] ;\n",
+		    label, point);
+	    val += pos;
+	  }
+	  free(label);
+	} else
+	  fprintf(stderr, "%s: bad port property '%s:%s'\n", PLUGIN_URI,
+		  key, val);
+      }
+    }
+    fprintf(fp, "    ]");
+  }
+  // audio inputs
+  for (int i = 0; i < n; i++, idx++)
+    fprintf(fp, "%s [\n\
+	a lv2:AudioPort ;\n\
+	a lv2:InputPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"in%d\" ;\n\
+	lv2:name \"in%d\" ;\n\
+    ]", idx==0?"    lv2:port":" ,", idx, i, i);
+  // audio outputs
+  for (int i = 0; i < m; i++, idx++)
+    fprintf(fp, "%s [\n\
+	a lv2:AudioPort ;\n\
+	a lv2:OutputPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"out%d\" ;\n\
+	lv2:name \"out%d\" ;\n\
+    ]", idx==0?"    lv2:port":" ,", idx, i, i);
+  if (have_midi) {
+    // midi input
+    fprintf(fp, "%s [\n\
+	a lv2:InputPort ;\n\
+	a atom:AtomPort ;\n\
+	atom:bufferType atom:Sequence ;\n\
+	atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"midiin\" ;\n\
+	lv2:name \"midiin\"\n\
+    ]", idx==0?"    lv2:port":" ,", idx);
+    idx++;
+  }
+  fprintf(fp, "\n.\n");
+  return 0;
+}
+
+extern "C"
+LV2_SYMBOL_EXPORT
+void lv2_dyn_manifest_close(LV2_Dyn_Manifest_Handle handle)
+{
+  LV2Plugin* plugin = (LV2Plugin*)handle;
+  delete plugin->dsp;
+  delete plugin->ui;
+  delete plugin;
+}
+
+int main()
+{
+  LV2_Dyn_Manifest_Handle handle;
+  LV2_Feature **features = { NULL };
+  int res = lv2_dyn_manifest_open(&handle, features);
+  if (res) return res;
+  res = lv2_dyn_manifest_get_data(handle, stdout, PLUGIN_URI);
+  return res;
+}
diff --git a/architecture/lv2synth.cpp b/architecture/lv2synth.cpp
new file mode 100644
index 0000000..572706f
--- /dev/null
+++ b/architecture/lv2synth.cpp
@@ -0,0 +1,1750 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+    Copyright (C) 2009-2011 Albert Graef <Dr.Graef at t-online.de>
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.
+ ************************************************************************
+ ************************************************************************/
+
+/* LV2 architecture for Faust synths. */
+
+/* NOTE: This requires one of the Boost headers (boost/circular_buffer.hpp),
+   so to compile Faust programs created with this architecture you need to
+   have at least the Boost headers installed somewhere on your include path
+   (the Boost libraries aren't needed). */
+
+#include <stdlib.h>
+#include <math.h>
+#include <list>
+#include <map>
+
+using namespace std;
+
+// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
+// flags to avoid costly denormals
+#ifdef __SSE__
+    #include <xmmintrin.h>
+    #ifdef __SSE2__
+        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+    #else
+        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+    #endif
+#else
+  #define AVOIDDENORMALS
+#endif
+
+typedef pair<const char*,const char*> strpair;
+
+struct Meta
+{
+  list< strpair > data;
+  void declare (const char* key, const char* value)
+  { data.push_back(strpair(key, value)); }
+};
+
+//-------------------------------------------------------------------
+// Generic min and max using c++ inline
+//-------------------------------------------------------------------
+
+inline int 	max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
+inline int 	max (int a, int b)		{ return (a>b) ? a : b; }
+
+inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
+inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
+inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
+
+inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
+inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
+inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
+inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
+inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
+
+inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
+inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
+inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
+inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
+inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
+inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
+inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
+
+
+inline int	min (int a, int b)		{ return (a<b) ? a : b; }
+
+inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
+inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
+inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
+
+inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
+inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
+inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
+inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
+inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
+
+inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
+inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
+inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
+inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
+inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
+inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
+inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
+
+// abs is now predefined
+//template<typename T> T abs (T a)		{ return (a<T(0)) ? -a : a; }
+
+inline int	lsr (int x, int n)		{ return int(((unsigned int)x) >> n); }
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
+//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
+
+<<includeIntrinsic>>
+
+/******************************************************************************
+*******************************************************************************
+
+			ABSTRACT USER INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+
+class UI
+{
+  bool	fStopped;
+public:
+
+  UI() : fStopped(false) {}
+  virtual ~UI() {}
+
+  virtual void addButton(const char* label, float* zone) = 0;
+  virtual void addCheckButton(const char* label, float* zone) = 0;
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
+
+  virtual void openTabBox(const char* label) = 0;
+  virtual void openHorizontalBox(const char* label) = 0;
+  virtual void openVerticalBox(const char* label) = 0;
+  virtual void closeBox() = 0;
+
+  virtual void run() = 0;
+
+  void stop() { fStopped = true; }
+  bool stopped() { return fStopped; }
+
+  virtual void declare(float* zone, const char* key, const char* value) {}
+};
+
+/***************************************************************************
+   LV2 UI interface
+ ***************************************************************************/
+
+enum ui_elem_type_t {
+  UI_BUTTON, UI_CHECK_BUTTON,
+  UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
+  UI_V_BARGRAPH, UI_H_BARGRAPH,
+  UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
+};
+
+struct ui_elem_t {
+  ui_elem_type_t type;
+  const char *label;
+  int port;
+  float *zone;
+  void *ref;
+  float init, min, max, step;
+};
+
+class LV2UI : public UI
+{
+public:
+  int nelems, nports;
+  ui_elem_t *elems;
+  map< int, list<strpair> > metadata;
+
+  LV2UI();
+  virtual ~LV2UI();
+
+protected:
+  void add_elem(ui_elem_type_t type, const char *label = NULL);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float init, float min, float max, float step);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float min, float max);
+
+public:
+  virtual void addButton(const char* label, float* zone);
+  virtual void addCheckButton(const char* label, float* zone);
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+
+  virtual void openTabBox(const char* label);
+  virtual void openHorizontalBox(const char* label);
+  virtual void openVerticalBox(const char* label);
+  virtual void closeBox();
+
+  virtual void run();
+
+  virtual void declare(float* zone, const char* key, const char* value);
+};
+
+LV2UI::LV2UI()
+{
+  nelems = nports = 0;
+  elems = NULL;
+}
+
+LV2UI::~LV2UI()
+{
+  if (elems) free(elems);
+}
+
+void LV2UI::declare(float* zone, const char* key, const char* value)
+{
+  map< int, list<strpair> >::iterator it = metadata.find(nelems);
+  if (it != metadata.end())
+    it->second.push_back(strpair(key, value));
+  else
+    metadata[nelems] = list<strpair>(1, strpair(key, value));
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = -1;
+  elems[nelems].zone = NULL;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+static bool is_voice_ctrl(const char *label);
+
+#define portno(label) (is_voice_ctrl(label)?-1:nports++)
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = portno(label);
+  elems[nelems].zone = zone;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			     float init, float min, float max, float step)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = portno(label);
+  elems[nelems].zone = zone;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = init;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = step;
+  nelems++;
+}
+
+inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			     float min, float max)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  elems[nelems].type = type;
+  elems[nelems].label = label;
+  elems[nelems].port = portno(label);
+  elems[nelems].zone = zone;
+  elems[nelems].ref = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+void LV2UI::addButton(const char* label, float* zone)
+{ add_elem(UI_BUTTON, label, zone); }
+void LV2UI::addCheckButton(const char* label, float* zone)
+{ add_elem(UI_CHECK_BUTTON, label, zone); }
+void LV2UI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
+void LV2UI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
+void LV2UI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
+
+void LV2UI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_H_BARGRAPH, label, zone, min, max); }
+void LV2UI::addVerticalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_V_BARGRAPH, label, zone, min, max); }
+
+void LV2UI::openTabBox(const char* label)
+{ add_elem(UI_T_GROUP, label); }
+void LV2UI::openHorizontalBox(const char* label)
+{ add_elem(UI_H_GROUP, label); }
+void LV2UI::openVerticalBox(const char* label)
+{ add_elem(UI_V_GROUP, label); }
+void LV2UI::closeBox()
+{ add_elem(UI_END_GROUP); }
+
+void LV2UI::run() {}
+
+/******************************************************************************
+*******************************************************************************
+
+			    FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------
+//  abstract definition of a signal processor
+//----------------------------------------------------------------
+
+class dsp {
+ protected:
+  int fSamplingFreq;
+ public:
+  // internal freelist for custom voice allocation
+  dsp *prev, *next;
+  dsp() {}
+  virtual ~dsp() {}
+  virtual int getNumInputs() = 0;
+  virtual int getNumOutputs() = 0;
+  virtual void buildUserInterface(UI* interface) = 0;
+  virtual void init(int samplingRate) = 0;
+  virtual void compute(int len, float** inputs, float** outputs) = 0;
+};
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+
+<<includeclass>>
+
+//----------------------------------------------------------------------------
+//  LV2 interface
+//----------------------------------------------------------------------------
+
+//#line 400 "lv2synth.cpp"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <bitset>
+#include <boost/circular_buffer.hpp>
+
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+#include <lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h>
+#include <lv2/lv2plug.in/ns/ext/atom/util.h>
+#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
+
+#ifndef URI_PREFIX
+#define URI_PREFIX "http://faust-lv2.googlecode.com"
+#endif
+
+#ifndef PLUGIN_URI
+#define PLUGIN_URI URI_PREFIX "/mydsp"
+#endif
+
+#define MIDI_EVENT_URI "http://lv2plug.in/ns/ext/midi#MidiEvent"
+
+#ifndef NVOICES
+#define NVOICES 16
+#endif
+
+/* This allows various manifest data to be generated from the corresponding
+   metadata (author, name, description, license) in the Faust source. */
+#ifndef FAUST_META
+#define FAUST_META 1
+#endif
+
+/* This enables automatic MIDI controller mapping based on the midi:ctrl
+   attributes in the Faust source. We have this enabled by default, but you
+   may have to disable it if the custom controller mapping gets in the way of
+   the automation facilities that the host provides. (But then again if the
+   host wants to do its own controller mapping then it probably won't, or at
+   least shouldn't, send us the MIDI controllers in the first place.) */
+#ifndef FAUST_MIDICC
+#define FAUST_MIDICC 1
+#endif
+
+// You can define these for various debugging output items.
+//#define DEBUG_META 1 // recognized MIDI controller metadata
+//#define DEBUG_VOICES 1 // triggering of synth voices
+//#define DEBUG_VOICE_ALLOC 1 // voice allocation
+//#define DEBUG_MIDI 1 // incoming MIDI messages
+//#define DEBUG_NOTES 1 // note messages
+//#define DEBUG_MIDICC 1 // controller messages
+//#define DEBUG_RPN 1 // RPN messages (pitch bend range, master tuning)
+//#define DEBUG_MTS 1 // MTS messages (octave/scale tuning)
+
+static bool is_voice_ctrl(const char *label)
+{
+  return !strcmp(label, "freq") || !strcmp(label, "gain") ||
+    !strcmp(label, "gate");
+}
+
+struct LV2SynthPlugin {
+  bool active;		// activation status
+  int rate;		// sampling rate
+  int nvoices;		// current number of voices (polyphony; <= NVOICES)
+  mydsp *dsp[NVOICES];	// the dsps
+  LV2UI *ui[NVOICES];	// their Faust interface descriptions
+  int n_in, n_out;	// number of input and output control ports
+  int *ctrls;		// Faust ui elements (indices into ui->elems)
+  float **ports;	// corresponding LV2 data
+  float *portvals;	// cached port data from the last run
+  float *midivals[16];	// per-midi channel data
+  int *inctrls, *outctrls;	// indices for active and passive controls
+  float **inputs, **outputs;	// audio buffers
+  int freq, gain, gate;	// indices of voice controls
+  unsigned n_samples;	// current block size
+  float **outbuf;	// audio buffers for mixing down the voices
+  float **inbuf;	// dummy input buffer
+  LV2_Atom_Sequence* event_port; // midi input
+  float *poly;		// polyphony port
+  std::map<uint8_t,int> ctrlmap; // MIDI controller map
+  // Needed host features.
+  LV2_URID_Map* map;	// the urid extension
+  LV2_URID midi_event;	// midi event uri
+  // Octave tunings (offsets in semitones) per MIDI channel.
+  float tuning[16][12];
+  // Allocated voices per MIDI channel and note.
+  int8_t notes[16][128];
+  // Free and used voices.
+  int n_free, n_used;
+  boost::circular_buffer<int> free_voices;
+  boost::circular_buffer<int> used_voices;
+  struct {
+    uint8_t ch;
+    int8_t note;
+  } note_info[NVOICES];
+  // Voices queued for note-offs (zero-length notes).
+  int n_queued;
+  bitset<NVOICES> queued;
+  // Last gate value during run() for each voice. We need to keep track of
+  // these so that we can force the Faust synth to retrigger a note when
+  // needed.
+  float lastgate[NVOICES];
+  // Current pitch bend and pitch bend range on each MIDI channel, in semitones.
+  float bend[16], range[16];
+  // Current coarse, fine and total master tuning on each MIDI channel (tuning
+  // offset relative to A4 = 440 Hz, in semitones).
+  float coarse[16], fine[16], tune[16];
+  // Current RPN MSB and LSB numbers, as set with controllers 101 and 100.
+  uint8_t rpn_msb[16], rpn_lsb[16];
+  // Current data entry MSB and LSB numbers, as set with controllers 6 and 38.
+  uint8_t data_msb[16], data_lsb[16];
+
+  LV2SynthPlugin() : free_voices(NVOICES), used_voices(NVOICES) {
+    active = false;
+    rate = 44100;
+    nvoices = NVOICES;
+    n_in = n_out = 0;
+    map = NULL;
+    midi_event = -1;
+    event_port = NULL;
+    poly = NULL;
+    freq = gain = gate = -1;
+    n_free = NVOICES;
+    for (int i = 0; i < NVOICES; i++) {
+      free_voices.push_back(i);
+      lastgate[i] = 0.0f;
+    }
+    for (int i = 0; i < 16; i++) {
+      bend[i] = 0.0f;
+      range[i] = 2.0f;
+      coarse[i] = fine[i] = tune[i] = 0.0f;
+      rpn_msb[i] = rpn_lsb[i] = 0x7f;
+      data_msb[i] = data_lsb[i] = 0;
+      for (int j = 0; j < 12; j++)
+	tuning[i][j] = 0.0f;
+    }
+    n_used = 0;
+    n_queued = 0;
+    n_samples = 0;
+    memset(dsp, 0, sizeof(dsp));
+    memset(ui, 0, sizeof(ui));
+    memset(notes, 0xff, sizeof(notes));
+    ctrls = inctrls = outctrls = NULL;
+    ports = inputs = outputs = inbuf = outbuf = NULL;
+    portvals = NULL;
+    memset(midivals, 0, sizeof(midivals));
+  }
+
+  // Voice allocation.
+
+#if DEBUG_VOICE_ALLOC
+  void print_voices(const char *msg)
+  {
+    fprintf(stderr, "%s: notes =", msg);
+    for (uint8_t ch = 0; ch < 16; ch++)
+      for (int note = 0; note < 128; note++)
+	if (notes[ch][note] >= 0)
+	  fprintf(stderr, " [%d] %d(#%d)", ch, note, notes[ch][note]);
+    fprintf(stderr, "\nqueued (%d):", n_queued);
+    for (int i = 0; i < nvoices; i++)
+      if (queued[i]) fprintf(stderr, " #%d", i);
+    fprintf(stderr, "\nused (%d):", n_used);
+    for (boost::circular_buffer<int>::iterator it = used_voices.begin();
+	 it != used_voices.end(); it++)
+      fprintf(stderr, " #%d->%d", *it, note_info[*it].note);
+    fprintf(stderr, "\nfree (%d):", n_free);
+    for (boost::circular_buffer<int>::iterator it = free_voices.begin();
+	 it != free_voices.end(); it++)
+      fprintf(stderr, " #%d", *it);
+    fprintf(stderr, "\n");
+  }
+#endif
+
+  int alloc_voice(uint8_t ch, int8_t note, int8_t vel)
+  {
+    int i = notes[ch][note];
+    if (i >= 0) {
+      // note already playing on same channel, retrigger it
+      voice_off(i);
+      voice_on(i, note, vel, ch);
+      // move this voice to the end of the used list
+      for (boost::circular_buffer<int>::iterator it = used_voices.begin();
+	   it != used_voices.end(); it++) {
+	if (*it == i) {
+	  used_voices.erase(it);
+	  used_voices.push_back(i);
+	  break;
+	}
+      }
+#if DEBUG_VOICE_ALLOC
+      print_voices("retrigger");
+#endif
+      return i;
+    } else if (n_free > 0) {
+      // take voice from free list
+      int i = free_voices.front();
+      free_voices.pop_front();
+      n_free--;
+      used_voices.push_back(i);
+      note_info[i].ch = ch;
+      note_info[i].note = note;
+      n_used++;
+      voice_on(i, note, vel, ch);
+      notes[ch][note] = i;
+#if DEBUG_VOICE_ALLOC
+      print_voices("alloc");
+#endif
+      return i;
+    } else {
+      // steal a voice
+      assert(n_used > 0);
+      // FIXME: Maybe we should look for the oldest note on the *current*
+      // channel here, but this is faster.
+      int i = used_voices.front();
+      int oldch = note_info[i].ch;
+      int oldnote = note_info[i].note;
+      voice_off(i);
+      notes[oldch][oldnote] = -1;
+      if (queued[i]) {
+	queued[i] = false;
+	n_queued--;
+      }
+      used_voices.pop_front();
+      used_voices.push_back(i);
+      note_info[i].ch = ch;
+      note_info[i].note = note;
+      voice_on(i, note, vel, ch);
+      notes[ch][note] = i;
+#if DEBUG_VOICE_ALLOC
+      print_voices("steal");
+#endif
+      return i;
+    }
+  }
+
+  int dealloc_voice(uint8_t ch, int8_t note, int8_t vel)
+  {
+    int i = notes[ch][note];
+    if (i >= 0) {
+      if (lastgate[i] == 0.0f && gate >= 0) {
+	// zero-length note, queued for later
+	if (!queued[i]) {
+	  queued[i] = true;
+	  n_queued++;
+	  notes[ch][note] = -1;
+	}
+#if DEBUG_VOICE_ALLOC
+	print_voices("dealloc (queued)");
+#endif
+	return i;
+      }
+      assert(n_free < nvoices);
+      free_voices.push_back(i);
+      n_free++;
+      voice_off(i);
+      notes[ch][note] = -1;
+      // erase this voice from the used list
+      for (boost::circular_buffer<int>::iterator it = used_voices.begin();
+	   it != used_voices.end(); it++) {
+	if (*it == i) {
+	  used_voices.erase(it);
+	  n_used--;
+	  break;
+	}
+      }
+#if DEBUG_VOICE_ALLOC
+      print_voices("dealloc");
+#endif
+      return i;
+    }
+    return -1;
+  }
+
+
+  float midicps(int8_t note, uint8_t chan)
+  {
+    float pitch = note + tune[chan] + tuning[chan][note%12] + bend[chan];
+    return 440.0*pow(2, (pitch-69.0)/12.0);
+  }
+
+  void voice_on(int i, int8_t note, int8_t vel, uint8_t ch)
+  {
+    if (lastgate[i] == 1.0f && gate >= 0) {
+      // Make sure that the synth sees the 0.0f gate so that the voice is
+      // properly retriggered.
+      *ui[i]->elems[gate].zone = 0.0f;
+      dsp[i]->compute(1, inbuf, outbuf);
+    }
+#if DEBUG_VOICES
+    fprintf(stderr, "voice on: %d %d (%g Hz) %d (%g)\n", i,
+	    note, midicps(note, ch), vel, vel/127.0);
+#endif
+    if (freq >= 0)
+      *ui[i]->elems[freq].zone = midicps(note, ch);
+    if (gate >= 0)
+      *ui[i]->elems[gate].zone = 1.0f;
+    if (gain >= 0)
+      *ui[i]->elems[gain].zone = vel/127.0;
+    // reinitialize the per-channel control data for this voice
+    for (int idx = 0; idx < n_in; idx++) {
+      int j = inctrls[idx], k = ui[0]->elems[j].port;
+      *ui[i]->elems[j].zone = midivals[ch][k];
+    }
+  }
+
+  void voice_off(int i)
+  {
+#if DEBUG_VOICES
+    fprintf(stderr, "voice off: %d\n", i);
+#endif
+    if (gate >= 0)
+      *ui[i]->elems[gate].zone = 0.0f;
+  }
+
+  void update_voices(uint8_t chan)
+  {
+    // update running voices on the given channel after tuning or pitch bend
+    // changes
+    for (boost::circular_buffer<int>::iterator it = used_voices.begin();
+	 it != used_voices.end(); it++) {
+      int i = *it;
+      if (note_info[i].ch == chan && freq >= 0) {
+	int note = note_info[i].note;
+	*ui[i]->elems[freq].zone = midicps(note, chan);
+      }
+    }
+  }
+
+  void all_notes_off()
+  {
+    for (int i = 0; i < nvoices; i++)
+      voice_off(i);
+    for (int i = 0; i < 16; i++)
+      bend[i] = 0.0f;
+    memset(notes, 0xff, sizeof(notes));
+    free_voices.clear();
+    n_free = nvoices;
+    for (int i = 0; i < nvoices; i++)
+      free_voices.push_back(i);
+    queued.reset();
+    n_queued = 0;
+    used_voices.clear();
+    n_used = 0;
+  }
+
+  void all_notes_off(uint8_t chan)
+  {
+    for (boost::circular_buffer<int>::iterator it = used_voices.begin();
+	 it != used_voices.end(); ) {
+      int i = *it;
+      if (note_info[i].ch == chan) {
+	assert(n_free < nvoices);
+	free_voices.push_back(i);
+	n_free++;
+	voice_off(i);
+	notes[note_info[i].ch][note_info[i].note] = -1;
+	if (queued[i]) {
+	  queued[i] = false;
+	  n_queued--;
+	}
+	// erase this voice from the used list
+	it = used_voices.erase(it);
+	n_used--;
+#if DEBUG_VOICE_ALLOC
+	print_voices("dealloc (all-notes-off)");
+#endif
+      } else
+	it++;
+    }
+    bend[chan] = 0.0f;
+  }
+
+  void queued_notes_off()
+  {
+    if (n_queued == 0) return;
+    for (int i = 0; i < nvoices; i++)
+      if (queued[i]) {
+	assert(n_free < nvoices);
+	free_voices.push_back(i);
+	n_free++;
+	voice_off(i);
+	notes[note_info[i].ch][note_info[i].note] = -1;
+	queued[i] = false;
+	n_queued--;
+	// erase this voice from the used list
+	for (boost::circular_buffer<int>::iterator it = used_voices.begin();
+	     it != used_voices.end(); it++) {
+	  if (*it == i) {
+	    used_voices.erase(it);
+	    n_used--;
+	    break;
+	  }
+	}
+#if DEBUG_VOICE_ALLOC
+	print_voices("dealloc (unqueued)");
+#endif
+      }
+  }
+};
+
+static LV2_Handle
+instantiate(const LV2_Descriptor*     descriptor,
+            double                    rate,
+            const char*               bundle_path,
+            const LV2_Feature* const* features)
+{
+  LV2SynthPlugin* plugin = new LV2SynthPlugin;
+  // Scan host features for URID map.
+  for (int i = 0; features[i]; i++) {
+    if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) {
+      plugin->map = (LV2_URID_Map*)features[i]->data;
+      plugin->midi_event =
+	plugin->map->map(plugin->map->handle, MIDI_EVENT_URI);
+    }
+  }
+  if (!plugin->map) {
+    fprintf
+      (stderr, "%s: host doesn't support urid:map, giving up\n",
+       PLUGIN_URI);
+    delete plugin;
+    return 0;
+  }
+  plugin->rate = rate;
+  for (int i = 0; i < NVOICES; i++) {
+    plugin->dsp[i] = new mydsp();
+    plugin->ui[i] = new LV2UI();
+    plugin->dsp[i]->init(plugin->rate);
+    plugin->dsp[i]->buildUserInterface(plugin->ui[i]);
+  }
+  // The LV2 ports are numbered as follows: 0..k-1 are the control ports, then
+  // come the n audio input ports, then the m audio output ports, and finally
+  // the midi input port and the polyphony control.
+  int k = plugin->ui[0]->nports, p = 0, q = 0;
+  int n = plugin->dsp[0]->getNumInputs(), m = plugin->dsp[0]->getNumOutputs();
+  // Allocate tables for the control elements and their LV2 ports.
+  plugin->ctrls = (int*)calloc(k, sizeof(int));
+  plugin->inctrls = (int*)calloc(k, sizeof(int));
+  plugin->outctrls = (int*)calloc(k, sizeof(int));
+  plugin->ports = (float**)calloc(k, sizeof(float*));
+  plugin->portvals = (float*)calloc(k, sizeof(float));
+  assert(k == 0 || (plugin->ctrls && plugin->inctrls && plugin->outctrls &&
+		    plugin->ports && plugin->portvals));
+  for (int ch = 0; ch < 16; ch++) {
+    plugin->midivals[ch] = (float*)calloc(k, sizeof(float));
+    assert(k == 0 || plugin->midivals[ch]);
+  }
+  // Scan the Faust UI for active and passive controls which become the
+  // input and output control ports of the LV2 plugin, respectively.
+  for (int i = 0, j = 0; i < plugin->ui[0]->nelems; i++) {
+    switch (plugin->ui[0]->elems[i].type) {
+    case UI_T_GROUP: case UI_H_GROUP: case UI_V_GROUP: case UI_END_GROUP:
+      // control groups
+      break;
+    case UI_H_BARGRAPH: case UI_V_BARGRAPH:
+      // passive controls (output ports)
+      plugin->ctrls[j++] = i;
+      plugin->outctrls[q++] = i;
+      break;
+    default:
+      // active controls (input ports)
+      if (plugin->freq == -1 &&
+	  !strcmp(plugin->ui[0]->elems[i].label, "freq"))
+	plugin->freq = i;
+      else if (plugin->gain == -1 &&
+	       !strcmp(plugin->ui[0]->elems[i].label, "gain"))
+	plugin->gain = i;
+      else if (plugin->gate == -1 &&
+	       !strcmp(plugin->ui[0]->elems[i].label, "gate"))
+	plugin->gate = i;
+      else {
+#if FAUST_MIDICC
+	std::map< int, list<strpair> >::iterator it =
+	  plugin->ui[0]->metadata.find(i);
+	if (it != plugin->ui[0]->metadata.end()) {
+	  // Scan for controller mappings.
+	  for (std::list<strpair>::iterator jt = it->second.begin();
+	       jt != it->second.end(); jt++) {
+	    const char *key = jt->first, *val = jt->second;
+#if DEBUG_META
+	    fprintf(stderr, "ctrl '%s' meta: '%s' -> '%s'\n",
+		    plugin->ui[0]->elems[i].label, key, val);
+#endif
+	    if (strcmp(key, "midi")) continue;
+	    unsigned num;
+	    if (sscanf(val, "ctrl %u", &num) < 1) continue;
+#if 0 // enable this to get feedback about controller assignments
+	    fprintf(stderr, "%s: cc %d -> %s\n", PLUGIN_URI, num,
+		    plugin->ui[0]->elems[i].label);
+#endif
+	    plugin->ctrlmap.insert(std::pair<uint8_t,int>(num, p));
+	  }
+	}
+#endif
+	plugin->ctrls[j++] = i;
+	plugin->inctrls[p++] = i;
+	int p = plugin->ui[0]->elems[i].port;
+	float val = plugin->ui[0]->elems[i].init;
+	plugin->portvals[p] = val;
+	for (int ch = 0; ch < 16; ch++)
+	  plugin->midivals[ch][p] = val;
+      }
+      break;
+    }
+  }
+  // Realloc the inctrls and outctrls vectors to their appropriate sizes.
+  plugin->inctrls = (int*)realloc(plugin->inctrls, p*sizeof(int));
+  assert(p == 0 || plugin->inctrls);
+  plugin->outctrls = (int*)realloc(plugin->outctrls, q*sizeof(int));
+  assert(q == 0 || plugin->outctrls);
+  plugin->n_in = p; plugin->n_out = q;
+  // Allocate vectors for the audio input and output ports. Like
+  // plugin->ports, these will be initialized in the connect_port callback.
+  plugin->inputs = (float**)calloc(n, sizeof(float*));
+  assert(n == 0 || plugin->inputs);
+  plugin->outputs = (float**)calloc(m, sizeof(float*));
+  assert(m == 0 || plugin->outputs);
+  // Initialize the mixdown buffer.
+  plugin->outbuf = (float**)calloc(m, sizeof(float*));
+  assert(m == 0 || plugin->outbuf);
+  // We start out with a blocksize of 512 samples here. Hopefully this is
+  // enough for most realtime hosts so that we can avoid reallocations in the
+  // event loop where we know what the actual blocksize is.
+  plugin->n_samples = 512;
+  for (int i = 0; i < m; i++) {
+    plugin->outbuf[i] = (float*)malloc(plugin->n_samples*sizeof(float));
+    assert(plugin->outbuf[i]);
+  }
+  // Initialize a 1-sample dummy input buffer used for retriggering notes.
+  plugin->inbuf = (float**)calloc(n, sizeof(float*));
+  assert(n == 0 || plugin->inbuf);
+  for (int i = 0; i < m; i++) {
+    plugin->inbuf[i] = (float*)malloc(sizeof(float));
+    assert(plugin->inbuf[i]);
+    *plugin->inbuf[i] = 0.0f;
+  }
+  return (LV2_Handle)plugin;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)instance;
+  int m = plugin->dsp[0]->getNumOutputs();
+  for (int i = 0; i < NVOICES; i++) {
+    delete plugin->dsp[i];
+    delete plugin->ui[i];
+  }
+  free(plugin->ctrls);
+  free(plugin->inctrls);
+  free(plugin->outctrls);
+  free(plugin->ports);
+  free(plugin->portvals);
+  free(plugin->inputs);
+  free(plugin->outputs);
+  for (int ch = 0; ch < 16; ch++)
+    free(plugin->midivals[ch]);
+  for (int i = 0; i < m; i++)
+    free(plugin->outbuf[i]);
+  free(plugin->outbuf);
+  delete plugin;
+}
+
+static void
+connect_port(LV2_Handle instance,
+             uint32_t   port,
+             void*      data)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)instance;
+  int i = port, k = plugin->ui[0]->nports;
+  int n = plugin->dsp[0]->getNumInputs(), m = plugin->dsp[0]->getNumOutputs();
+  if (i < k)
+    plugin->ports[i] = (float*)data;
+  else {
+    i -= k;
+    if (i < n)
+      plugin->inputs[i] = (float*)data;
+    else {
+      i -= n;
+      if (i < m)
+	plugin->outputs[i] = (float*)data;
+      else if (i == m)
+	plugin->event_port = (LV2_Atom_Sequence*)data;
+      else if (i == m+1)
+	plugin->poly = (float*)data;
+      else
+	fprintf(stderr, "%s: bad port number %u\n", PLUGIN_URI, port);
+    }
+  }
+}
+
+#if FAUST_MIDICC
+static float ctrlval(const ui_elem_t &el, uint8_t v)
+{
+  // Translate the given MIDI controller value to the range and stepsize
+  // indicated by the Faust control.
+  switch (el.type) {
+  case UI_BUTTON: case UI_CHECK_BUTTON:
+    return (float)(v>=64);
+  default:
+    /* Continuous controllers. The problem here is that the range 0..127 is
+       not symmetric. We'd like to map 64 to the center of the range
+       (max-min)/2 and at the same time retain the full control range
+       min..max. So let's just pretend that there are 128 controller values
+       and map value 127 to the max value anyway. */
+    if (v==127)
+      return el.max;
+    else
+      // XXXFIXME: We might want to add proper quantization according to
+      // el.step here.
+      return el.min+(el.max-el.min)*v/128;
+  }
+}
+#endif
+
+static void
+run(LV2_Handle instance, uint32_t n_samples)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)instance;
+  int n = plugin->dsp[0]->getNumInputs(), m = plugin->dsp[0]->getNumOutputs();
+  AVOIDDENORMALS;
+  plugin->queued_notes_off();
+  if (!plugin->active) {
+    if (n == m) {
+      // copy inputs to outputs
+      for (int i = 0; i < m; i++)
+	for (unsigned j = 0; j < n_samples; j++)
+	  plugin->outputs[i][j] = plugin->inputs[i][j];
+    } else {
+      // silence
+      for (int i = 0; i < m; i++)
+	for (unsigned j = 0; j < n_samples; j++)
+	  plugin->outputs[i][j] = 0.0f;
+    }
+    return;
+  }
+  // Handle changes in the polyphony control.
+  if (plugin->poly) {
+    int nvoices = *plugin->poly;
+    if (plugin->nvoices != nvoices && nvoices > 0 && nvoices <= NVOICES) {
+      for (int i = 0; i < plugin->nvoices; i++)
+	plugin->voice_off(i);
+      plugin->nvoices = nvoices;
+      // Reset the voice allocation.
+      memset(plugin->notes, 0xff, sizeof(plugin->notes));
+      plugin->free_voices.clear();
+      plugin->n_free = nvoices;
+      for (int i = 0; i < nvoices; i++)
+	plugin->free_voices.push_back(i);
+      plugin->used_voices.clear();
+      plugin->n_used = 0;
+    } else
+      *plugin->poly = plugin->nvoices;
+  }
+  int nvoices = plugin->nvoices;
+  // Process incoming MIDI events.
+  if (plugin->event_port) {
+    LV2_Atom_Event* i;
+    LV2_ATOM_SEQUENCE_FOREACH(plugin->event_port, ev) {
+      if (ev->body.type == plugin->midi_event) {
+	uint8_t *data = (uint8_t*)(ev+1);
+#if 0
+	// FIXME: Consider doing sample-accurate note onsets here. LV2 keeps
+	// track of the exact onset in the frames and subframes fields
+	// (http://lv2plug.in/ns/doc/html/structLV2__Atom__Event.html), but we
+	// can't use that information at present, since our gate parameter is
+	// a control variable which can only change at block boundaries. In
+	// the future, the gate could be implemented as an audio signal to get
+	// sample-accurate note onsets.
+	uint32_t frames = ev->body.frames;
+#endif
+#if DEBUG_MIDI
+	fprintf(stderr, "midi ev (%u bytes):", ev->body.size);
+	for (unsigned i = 0; i < ev->body.size; i++)
+	  fprintf(stderr, " 0x%0x", data[i]);
+	fprintf(stderr, "\n");
+#endif
+	uint8_t status = data[0] & 0xf0, chan = data[0] & 0x0f;
+	switch (status) {
+	case 0x90: {
+	  // note on
+#if DEBUG_NOTES
+	  fprintf(stderr, "note-on  chan %d, note %d, vel %d\n", chan+1,
+		  data[1], data[2]);
+#endif
+	  // LV2 actually forbids zero velocities here, but we never know how
+	  // broken the host is, so we handle this case anyway to be on the safe
+	  // side.
+	  if (data[2] == 0) goto note_off;
+	  plugin->alloc_voice(chan, data[1], data[2]);
+	  break;
+	}
+	case 0x80: {
+	  // note off
+#if DEBUG_NOTES
+	  fprintf(stderr, "note-off chan %d, note %d, vel %d\n", chan+1,
+		  data[1], data[2]);
+#endif
+	  note_off:
+	  plugin->dealloc_voice(chan, data[1], data[2]);
+	  break;
+	}
+	case 0xe0: {
+	  // pitch bend
+	  // data[1] is LSB, data[2] MSB, range is 0..0x3fff (which maps to
+	  // -2..+2 semitones by default), center point is 0x2000 = 8192
+	  int val = data[1] | (data[2]<<7);
+	  plugin->bend[chan] = (val-0x2000)/8192.0f*plugin->range[chan];
+#if DEBUG_MIDICC
+	  fprintf(stderr, "pitch-bend (chan %d): %g cent\n", chan+1,
+		  plugin->bend[chan]*100.0);
+#endif
+	  plugin->update_voices(chan);
+	  break;
+	}
+	case 0xb0: {
+	  // controller change
+	  switch (data[1]) {
+	  case 120: case 123:
+	    // all-sound-off and all-notes-off controllers (these are treated
+	    // the same in the current implementation)
+	    plugin->all_notes_off(chan);
+#if DEBUG_MIDICC
+	    fprintf(stderr, "all-notes-off (chan %d)\n", chan+1);
+#endif
+	    break;
+	  case 121:
+	    // all-controllers-off (in the current implementation, this just
+	    // resets the RPN-related controllers)
+	    plugin->data_msb[chan] = plugin->data_lsb[chan] = 0;
+	    plugin->rpn_msb[chan] = plugin->rpn_lsb[chan] = 0x7f;
+#if DEBUG_MIDICC
+	    fprintf(stderr, "all-controllers-off (chan %d)\n", chan+1);
+#endif
+	    break;
+	  case 101: case 100:
+	    // RPN MSB/LSB
+	    if (data[1] == 101)
+	      plugin->rpn_msb[chan] = data[2];
+	    else
+	      plugin->rpn_lsb[chan] = data[2];
+	    break;
+	  case 6: case 38:
+	    // data entry coarse/fine
+	    if (data[1] == 6)
+	      plugin->data_msb[chan] = data[2];
+	    else
+	      plugin->data_lsb[chan] = data[2];
+	    goto rpn;
+	  case 96: case 97:
+	    // data increment/decrement
+	    /* NOTE: The specification of these controllers is a complete
+	       mess. Originally, the MIDI specification didn't have anything
+	       to say about their exact behaviour at all. Nowadays, the
+	       behaviour depends on which RPN or NRPN is being modified, which
+	       is also rather confusing. Fortunately, as we only handle RPNs
+	       0..2 here anyway, it's sufficient to assume the MSB for RPN #2
+	       (channel coarse tuning) and the LSB otherwise. */
+	    if (plugin->rpn_msb[chan] == 0 && plugin->rpn_lsb[chan] == 2) {
+	      // modify the MSB
+	      if (data[1] == 96 && plugin->data_msb[chan] < 0x7f)
+		plugin->data_msb[chan]++;
+	      else if (data[1] == 97 && plugin->data_msb[chan] > 0)
+		plugin->data_msb[chan]--;
+	    } else {
+	      // modify the LSB
+	      if (data[1] == 96 && plugin->data_lsb[chan] < 0x7f)
+		plugin->data_lsb[chan]++;
+	      else if (data[1] == 97 && plugin->data_lsb[chan] > 0)
+		plugin->data_lsb[chan]--;
+	    }
+	  rpn:
+	    if (plugin->rpn_msb[chan] == 0) {
+	      switch (plugin->rpn_lsb[chan]) {
+	      case 0:
+		// pitch bend range, coarse value is in semitones, fine value
+		// in cents
+		plugin->range[chan] = plugin->data_msb[chan]+
+		  plugin->data_lsb[chan]/100.0;
+#if DEBUG_RPN
+		fprintf(stderr, "pitch-bend-range (chan %d): %g cent\n", chan+1,
+			plugin->range[chan]*100.0);
+#endif
+		break;
+	      case 1:
+		{
+		  // channel fine tuning (14 bit value, range -100..+100 cents)
+		  int value = (plugin->data_msb[chan]<<7) |
+		    plugin->data_lsb[chan];
+		  plugin->fine[chan] = (value-8192)/8192.0f;
+		}
+		goto master_tune;
+	      case 2:
+		// channel coarse tuning (only msb is used, range -64..+63
+		// semitones)
+		plugin->coarse[chan] = plugin->data_msb[chan]-64;
+	      master_tune:
+		plugin->tune[chan] = plugin->coarse[chan]+plugin->fine[chan];
+#if DEBUG_RPN
+		fprintf(stderr, "master-tuning (chan %d): %g cent\n", chan+1,
+			plugin->tune[chan]*100.0);
+#endif
+		plugin->update_voices(chan);
+		break;
+	      default:
+		break;
+	      }
+	    }
+	    break;
+	  default: {
+#if FAUST_MIDICC
+	    // interpret all other controller changes according to the MIDI
+	    // controller map defined in the Faust plugin itself
+	    std::map<uint8_t,int>::iterator it = plugin->ctrlmap.find(data[1]);
+	    if (it != plugin->ctrlmap.end()) {
+	      // defined MIDI controller
+	      int j = plugin->inctrls[it->second],
+		k = plugin->ui[0]->elems[j].port;
+	      float val = ctrlval(plugin->ui[0]->elems[j], data[2]);
+	      plugin->midivals[chan][k] = val;
+	      // update running voices on this channel
+	      for (boost::circular_buffer<int>::iterator it =
+		     plugin->used_voices.begin();
+		   it != plugin->used_voices.end(); it++) {
+		int i = *it;
+		if (plugin->note_info[i].ch == chan)
+		  *plugin->ui[i]->elems[j].zone = val;
+	      }
+#if DEBUG_MIDICC
+	      fprintf(stderr, "ctrl-change chan %d, ctrl %d, val %d\n", chan+1,
+		      data[1], data[2]);
+#endif
+	    }
+#endif
+	    break;
+	  }
+	  }
+	  break;
+	}
+	case 0xf0:
+	  if (data[0] == 0xf0 && data[ev->body.size-1] == 0xf7) {
+	    // sysex
+	    if ((data[1] == 0x7e || data[1] == 0x7f) && data[3] == 8) {
+	      // MIDI tuning standard
+	      bool realtime = data[1] == 0x7f;
+	      if ((ev->body.size == 21 && data[4] == 8) ||
+		  (ev->body.size == 33 && data[4] == 9)) {
+		// MTS scale/octave tuning 1- or 2-byte form
+		bool onebyte = data[4] == 8;
+		unsigned chanmsk = (data[5]<<14) | (data[6]<<7) | data[7];
+		for (int i = 0; i < 12; i++) {
+		  float t;
+		  if (onebyte)
+		    t = (data[i+8]-64)/100.0;
+		  else
+		    t = (((data[2*i+8]<<7)|data[2*i+9])-8192)/8192.0;
+		  for (uint8_t ch = 0; ch < 16; ch++)
+		    if (chanmsk & (1<<ch))
+		      plugin->tuning[ch][i] = t;
+		}
+		if (realtime) {
+		  for (uint8_t ch = 0; ch < 16; ch++)
+		    if (chanmsk & (1<<ch)) {
+		      // update running voices on this channel
+		      plugin->update_voices(ch);
+		    }
+		}
+#if DEBUG_MTS
+		fprintf(stderr, "octave-tuning-%s (chan ",
+			realtime?"realtime":"non-realtime");
+		bool first = true;
+		for (uint8_t i = 0; i < 16; )
+		  if (chanmsk & (1<<i)) {
+		    uint8_t j;
+		    for (j = i+1; j < 16 && (chanmsk&(1<<j)); )
+		      j++;
+		    if (first)
+		      first = false;
+		    else
+		      fprintf(stderr, ",");
+		    if (j > i+1)
+		      fprintf(stderr, "%u-%u", i+1, j);
+		    else
+		      fprintf(stderr, "%u", i+1);
+		    i = j;
+		  } else
+		    i++;
+		fprintf(stderr, "):");
+		if (onebyte) {
+		  for (int i = 8; i < 20; i++) {
+		    int val = data[i];
+		    fprintf(stderr, " %d", val-64);
+		  }
+		} else {
+		  for (int i = 8; i < 32; i++) {
+		    int val = data[i++] << 7;
+		    val |= data[i];
+		    fprintf(stderr, " %g", ((double)val-8192.0)/8192.0*100.0);
+		  }
+		}
+		fprintf(stderr, "\n");
+#endif
+	      }
+	    }
+	  }
+	  break;
+	default:
+	  break;
+	}
+      } else {
+	fprintf(stderr, "%s: unknown event type %d\n", PLUGIN_URI, ev->body.type);
+      }
+    }
+  }
+  // Only update the controls (of all voices simultaneously) if the port value
+  // actually changed. This is necessary to allow MIDI controllers to modify
+  // the values for individual MIDI channels (see above). Also note that we do
+  // this *after* processing the MIDI controller data so that manual inputs
+  // can override these.
+  for (int i = 0; i < plugin->n_in; i++) {
+    int j = plugin->inctrls[i], k = plugin->ui[0]->elems[j].port;
+    float &oldval = plugin->portvals[k], newval = *plugin->ports[k];
+    if (newval != oldval) {
+      // update running voices
+      for (boost::circular_buffer<int>::iterator it =
+	     plugin->used_voices.begin();
+	   it != plugin->used_voices.end(); it++) {
+	int i = *it;
+	*plugin->ui[i]->elems[j].zone = newval;
+      }
+      // also update the MIDI controller data for all channels (manual control
+      // input is always omni)
+      for (int ch = 0; ch < 16; ch++)
+	plugin->midivals[ch][k] = newval;
+      // record the new value
+      oldval = newval;
+    }
+  }
+  // Initialize the output buffers.
+  if (plugin->n_samples < n_samples) {
+    // We need to enlarge the buffers. We're not officially allowed to do this
+    // here (presumably in the realtime thread), but since we can't know the
+    // hosts's block size beforehand, there's really nothing else that we can
+    // do. Let's just hope that doing this once suffices, then hopefully
+    // noone will notice.
+    for (int i = 0; i < m; i++) {
+      plugin->outbuf[i] = (float*)realloc(plugin->outbuf[i],
+					  n_samples*sizeof(float));
+      assert(plugin->outbuf[i]);
+    }
+    plugin->n_samples = n_samples;
+  }
+  for (int i = 0; i < m; i++)
+    for (unsigned j = 0; j < n_samples; j++)
+      plugin->outputs[i][j] = 0.0f;
+  // Mix the voices down to one signal.
+  for (int l = 0; l < nvoices; l++) {
+    // Let Faust do all the hard work.
+    plugin->dsp[l]->compute(n_samples, plugin->inputs, plugin->outbuf);
+    for (int i = 0; i < m; i++)
+      for (unsigned j = 0; j < n_samples; j++)
+	plugin->outputs[i][j] += plugin->outbuf[i][j];
+  }
+  // Finally grab the passive controls and write them back to the
+  // corresponding LV2 ports. FIXME: It's not clear how to aggregate the data
+  // of the different voices. We compute the maximum of each control for now.
+  for (int i = 0; i < plugin->n_out; i++) {
+    int j = plugin->outctrls[i], k = plugin->ui[0]->elems[j].port;
+    float *z = plugin->ui[0]->elems[j].zone;
+    *plugin->ports[k] = *z;
+    for (int l = 1; l < nvoices; l++) {
+      float *z = plugin->ui[l]->elems[j].zone;
+      if (*plugin->ports[k] < *z)
+	*plugin->ports[k] = *z;
+    }
+  }
+  // Keep track of the last gates set for each voice, so that voices can be
+  // forcibly retriggered if needed.
+  if (plugin->gate >= 0)
+    for (int i = 0; i < nvoices; i++)
+      plugin->lastgate[i] = *plugin->ui[i]->elems[plugin->gate].zone;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)instance;
+  for (int i = 0; i < NVOICES; i++)
+    plugin->dsp[i]->init(plugin->rate);
+  for (int i = 0, j = 0; i < plugin->ui[0]->nelems; i++) {
+    int p = plugin->ui[0]->elems[i].port;
+    if (p >= 0) {
+      float val = plugin->ui[0]->elems[i].init;
+      plugin->portvals[p] = val;
+    }
+  }
+  plugin->active = true;
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)instance;
+  plugin->active = false;
+  plugin->all_notes_off();
+}
+
+const void*
+extension_data(const char* uri)
+{
+  return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+  PLUGIN_URI,
+  instantiate,
+  connect_port,
+  activate,
+  run,
+  deactivate,
+  cleanup,
+  extension_data
+};
+
+extern "C"
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+  switch (index) {
+  case 0:
+    return &descriptor;
+  default:
+    return NULL;
+  }
+}
+
+//----------------------------------------------------------------------------
+//  Dynamic manifest
+//----------------------------------------------------------------------------
+
+// NOTE: If your LV2 host doesn't offer this extension then you'll have to
+// create a static ttl file with the descriptions of the ports yourself. You
+// can also do this by compiling this code to a standalone executable while
+// defining the __MAIN__ symbol. Running the executable then prints the
+// manifest on stdout.
+
+extern "C"
+LV2_SYMBOL_EXPORT
+int lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle *handle,
+			  const LV2_Feature *const *features)
+{
+  LV2SynthPlugin* plugin = new LV2SynthPlugin;
+  plugin->dsp[0] = new mydsp();
+  plugin->ui[0] = new LV2UI();
+  plugin->dsp[0]->init(48000);
+  plugin->dsp[0]->buildUserInterface(plugin->ui[0]);
+  int k = plugin->ui[0]->nports;
+  plugin->ctrls = (int*)calloc(k, sizeof(int));
+  assert(k == 0 || plugin->ctrls);
+  plugin->freq = plugin->gain = plugin->gate = -1;
+  for (int i = 0, j = 0; i < plugin->ui[0]->nelems; i++) {
+    switch (plugin->ui[0]->elems[i].type) {
+    case UI_T_GROUP: case UI_H_GROUP: case UI_V_GROUP: case UI_END_GROUP:
+      // control groups
+      break;
+    case UI_H_BARGRAPH: case UI_V_BARGRAPH:
+      // passive controls (output ports)
+      plugin->ctrls[j++] = i;
+      break;
+    default:
+      // active controls (input ports)
+      if (plugin->freq == -1 &&
+	  !strcmp(plugin->ui[0]->elems[i].label, "freq"))
+	plugin->freq = i;
+      else if (plugin->gain == -1 &&
+	       !strcmp(plugin->ui[0]->elems[i].label, "gain"))
+	plugin->gain = i;
+      else if (plugin->gate == -1 &&
+	       !strcmp(plugin->ui[0]->elems[i].label, "gate"))
+	plugin->gate = i;
+      else
+	plugin->ctrls[j++] = i;
+      break;
+    }
+  }
+  *handle = (LV2_Dyn_Manifest_Handle)plugin;
+  return 0;
+}
+
+extern "C"
+LV2_SYMBOL_EXPORT
+int lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,
+				  FILE *fp)
+{
+  fprintf(fp, "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n\
+<%s> a lv2:Plugin .\n", PLUGIN_URI);
+  return 0;
+}
+
+#include <string>
+#include <ctype.h>
+
+static string mangle(const string &s)
+{
+  string t = s;
+  size_t n = s.size();
+  for (size_t i = 0; i < n; i++)
+    if ((i == 0 && !isalpha(t[i]) && t[i] != '_') ||
+	(!isalnum(t[i]) && t[i] != '_'))
+      t[i] = '_';
+  return t;
+}
+
+static unsigned steps(float min, float max, float step)
+{
+  if (step == 0.0) return 1;
+  int n = (max-min)/step;
+  if (n < 0) n = -n;
+  if (n == 0) n = 1;
+  return n;
+}
+
+#if FAUST_META
+static bool is_xmlstring(const char *s)
+{
+  // This is just a basic sanity check. The string must not contain any
+  // (unescaped) newlines, carriage returns or double quotes.
+  return !strchr(s, '\n') && !strchr(s, '\r') && !strchr(s, '"');
+}
+#endif
+
+extern "C"
+LV2_SYMBOL_EXPORT
+int lv2_dyn_manifest_get_data(LV2_Dyn_Manifest_Handle handle,
+			      FILE *fp,
+			      const char *uri)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)handle;
+  int k = plugin->ui[0]->nports;
+  int n = plugin->dsp[0]->getNumInputs(), m = plugin->dsp[0]->getNumOutputs();
+  // Scan the global metadata for plugin name, description, license etc.
+  const char *plugin_name = NULL, *plugin_author = NULL, *plugin_descr = NULL,
+    *plugin_license = NULL;
+#if FAUST_META
+  Meta meta;
+  plugin->dsp[0]->metadata(&meta);
+  for (std::list<strpair>::iterator it = meta.data.begin();
+       it != meta.data.end(); it++) {
+    const char *key = it->first, *val = it->second;
+    if (!val || !is_xmlstring(val)) continue;
+    if (!strcmp(key, "name")) {
+      if (!plugin_name)
+	plugin_name = val;
+    } else if (!strcmp(key, "description")) {
+      if (!plugin_descr)
+	plugin_descr = val;
+    } else if (!strcmp(key, "author")) {
+      if (!plugin_author)
+	plugin_author = val;
+    } else if (!strcmp(key, "license")) {
+      if (!plugin_license)
+	plugin_license = val;
+    }
+  }
+#endif
+  if (!plugin_name) plugin_name = "mydsp";
+  fprintf(fp, "@prefix doap:  <http://usefulinc.com/ns/doap#> .\n\
+ at prefix foaf:  <http://xmlns.com/foaf/0.1/> .\n\
+ at prefix lv2:   <http://lv2plug.in/ns/lv2core#> .\n\
+ at prefix epp:   <http://lv2plug.in/ns/ext/port-props#> .\n\
+ at prefix atom:  <http://lv2plug.in/ns/ext/atom#> .\n\
+ at prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
+ at prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .\n\
+ at prefix units: <http://lv2plug.in/ns/extensions/units#> .\n\
+<%s>\n\
+       a lv2:Plugin, lv2:InstrumentPlugin ;\n\
+       doap:name \"%s\" ;\n\
+       lv2:binary <mydsp.so> ;\n\
+       lv2:optionalFeature epp:supportsStrictBounds ;\n\
+       lv2:optionalFeature lv2:hardRtCapable ;\n", PLUGIN_URI, plugin_name);
+  if (plugin_author)
+    fprintf(fp, "\
+       doap:maintainer [ foaf:name \"%s\" ] ;\n", plugin_author);
+  if (plugin_descr)
+    fprintf(fp, "\
+       doap:description \"%s\" ;\n", plugin_descr);
+  if (plugin_license)
+    fprintf(fp, "\
+       doap:license \"%s\" ;\n", plugin_license);
+  int idx = 0;
+  // control ports
+  for (int i = 0; i < k; i++, idx++) {
+    int j = plugin->ctrls[i];
+    assert(idx == plugin->ui[0]->elems[j].port);
+    fprintf(fp, "%s [\n", idx==0?"    lv2:port":" ,");
+    const char *label = plugin->ui[0]->elems[j].label;
+    assert(label);
+    string sym = mangle(plugin->ui[0]->elems[j].label);
+    switch (plugin->ui[0]->elems[j].type) {
+    // active controls (input ports)
+    case UI_BUTTON: case UI_CHECK_BUTTON:
+    fprintf(fp, "\
+	a lv2:InputPort ;\n\
+	a lv2:ControlPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"%s\" ;\n\
+	lv2:name \"%s\" ;\n\
+        lv2:portProperty epp:hasStrictBounds ;\n\
+        lv2:portProperty lv2:toggled ;\n\
+	lv2:default 0.00000 ;\n\
+	lv2:minimum 0.00000 ;\n\
+	lv2:maximum 1.00000 ;\n", idx, sym.c_str(), label);
+      break;
+    case UI_NUM_ENTRY: case UI_H_SLIDER: case UI_V_SLIDER:
+    fprintf(fp, "\
+	a lv2:InputPort ;\n\
+	a lv2:ControlPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"%s\" ;\n\
+	lv2:name \"%s\" ;\n\
+        lv2:portProperty epp:hasStrictBounds ;\n\
+        epp:rangeSteps %u ;\n\
+	lv2:default %g ;\n\
+	lv2:minimum %g ;\n\
+	lv2:maximum %g ;\n", idx, sym.c_str(), label,
+	    steps(plugin->ui[0]->elems[j].min,
+		  plugin->ui[0]->elems[j].max,
+		  plugin->ui[0]->elems[j].step),
+	    plugin->ui[0]->elems[j].init,
+	    plugin->ui[0]->elems[j].min,
+	    plugin->ui[0]->elems[j].max);
+      break;
+    // passive controls (output ports)
+    case UI_H_BARGRAPH: case UI_V_BARGRAPH:
+    fprintf(fp, "\
+	a lv2:OutputPort ;\n\
+	a lv2:ControlPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"%s\" ;\n\
+	lv2:name \"%s\" ;\n\
+	lv2:default %g ;\n\
+	lv2:minimum %g ;\n\
+	lv2:maximum %g ;\n", idx, sym.c_str(), label,
+	    plugin->ui[0]->elems[j].min,
+	    plugin->ui[0]->elems[j].min,
+	    plugin->ui[0]->elems[j].max);
+      break;
+    default:
+      assert(0 && "this can't happen");
+      break;
+    }
+    // Scan for Faust control metadata we understand and add corresponding
+    // hints to the LV2 description of the port.
+    std::map< int, list<strpair> >::iterator it =
+      plugin->ui[0]->metadata.find(j);
+    if (it != plugin->ui[0]->metadata.end()) {
+      for (std::list<strpair>::iterator jt = it->second.begin();
+	   jt != it->second.end(); jt++) {
+	const char *key = jt->first, *val = jt->second;
+	if (!strcmp(key, "unit"))
+	  fprintf(fp, "\
+	units:unit [\n\
+            a            units:Unit ;\n\
+            units:name   \"%s\" ;\n\
+            units:symbol \"%s\" ;\n\
+            units:render \"%%f %s\"\n\
+	] ;\n", val, val, val);
+	if (strcmp(key, "lv2")) continue;
+	if (!strcmp(val, "integer"))
+	  fprintf(fp, "\
+	lv2:portProperty lv2:integer ;\n");
+	else if (!strcmp(val, "hidden") || !strcmp(val, "notOnGUI"))
+	  fprintf(fp, "\
+	lv2:portProperty epp:notOnGUI ;\n");
+	else if (!strncmp(val, "scalepoint", 10) ||
+		 !strncmp(val, "scalePoint", 10)) {
+	  val += 10;
+	  if (!isspace(*val)) continue;
+	  char *label = (char*)malloc(strlen(val)+1);
+	  float point;
+	  int pos;
+	  while (sscanf(val, "%s %g%n", label, &point, &pos) == 2) {
+	    fprintf(fp, "\
+	lv2:scalePoint [ rdfs:label \"%s\"; rdf:value %g ] ;\n",
+		    label, point);
+	    val += pos;
+	  }
+	  free(label);
+	} else
+	  fprintf(stderr, "%s: bad port property '%s:%s'\n", PLUGIN_URI,
+		  key, val);
+      }
+    }
+    fprintf(fp, "    ]");
+  }
+  // audio inputs
+  for (int i = 0; i < n; i++, idx++)
+    fprintf(fp, "%s [\n\
+	a lv2:InputPort ;\n\
+	a lv2:AudioPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"in%d\" ;\n\
+	lv2:name \"in%d\" ;\n\
+    ]", idx==0?"    lv2:port":" ,", idx, i, i);
+  // audio outputs
+  for (int i = 0; i < m; i++, idx++)
+    fprintf(fp, "%s [\n\
+	a lv2:OutputPort ;\n\
+	a lv2:AudioPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"out%d\" ;\n\
+	lv2:name \"out%d\" ;\n\
+    ]", idx==0?"    lv2:port":" ,", idx, i, i);
+  // midi input
+  fprintf(fp, "%s [\n\
+	a lv2:InputPort ;\n\
+	a atom:AtomPort ;\n\
+	atom:bufferType atom:Sequence ;\n\
+	atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"midiin\" ;\n\
+	lv2:name \"midiin\"\n\
+    ]", idx==0?"    lv2:port":" ,", idx);
+  idx++;
+  // polyphony control
+  fprintf(fp, "%s [\n\
+	a lv2:InputPort ;\n\
+	a lv2:ControlPort ;\n\
+	lv2:index %d ;\n\
+	lv2:symbol \"nvoices\" ;\n\
+	lv2:name \"Polyphony\" ;\n\
+        lv2:portProperty epp:hasStrictBounds ;\n\
+#       lv2:portProperty epp:expensive ;\n\
+        lv2:portProperty lv2:integer ;\n\
+        epp:rangeSteps %d ;\n\
+	lv2:default %d ;\n\
+	lv2:minimum 1 ;\n\
+	lv2:maximum %d ;\n\
+    ]", idx==0?"    lv2:port":" ,", idx, NVOICES,
+	  NVOICES>1?NVOICES/2:1,
+	  NVOICES);
+  idx++;
+  fprintf(fp, "\n.\n");
+  return 0;
+}
+
+extern "C"
+LV2_SYMBOL_EXPORT
+void lv2_dyn_manifest_close(LV2_Dyn_Manifest_Handle handle)
+{
+  LV2SynthPlugin* plugin = (LV2SynthPlugin*)handle;
+  delete plugin->dsp[0];
+  delete plugin->ui[0];
+  delete plugin;
+}
+
+int main()
+{
+  LV2_Dyn_Manifest_Handle handle;
+  LV2_Feature **features = { NULL };
+  int res = lv2_dyn_manifest_open(&handle, features);
+  if (res) return res;
+  res = lv2_dyn_manifest_get_data(handle, stdout, PLUGIN_URI);
+  return res;
+}
diff --git a/architecture/math.lib b/architecture/math.lib
index 759bba6..c98f5f6 100644
--- a/architecture/math.lib
+++ b/architecture/math.lib
@@ -1,11 +1,11 @@
 /************************************************************************
  ************************************************************************
   	FAUST library file
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
+	Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
+    ----------------------------------------------------------------------
     This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as 
-	published by the Free Software Foundation; either version 2.1 of the 
+    it under the terms of the GNU Lesser General Public License as
+	published by the Free Software Foundation; either version 2.1 of the
 	License, or (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -16,7 +16,18 @@
     You should have received a copy of the GNU Lesser General Public
  	License along with the GNU C Library; if not, write to the Free
   	Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-  	02111-1307 USA. 
+  	02111-1307 USA.
+
+  	EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
+  	larger FAUST program which directly or indirectly imports this library
+  	file and still distribute the compiled code generated by the FAUST
+  	compiler, or a modified version of this compiled code, under your own
+  	copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
+  	grants you the right to freely choose the license for the resulting
+  	compiled code. In particular the resulting compiled code has no obligation
+  	to be LGPL or GPL. For example you are free to choose a commercial or
+  	closed source license or any other license if you decide so.
+
  ************************************************************************
  ************************************************************************/
 
@@ -24,161 +35,539 @@ declare name "Math Library";
 declare author "GRAME";
 declare copyright "GRAME";
 declare version "1.0";
-declare license "LGPL"; 
-
-//--------------------------------------------------------------------------------
-// 						Mathematic library for Faust
+declare license "LGPL with exception";
 
-// Implementation of the math.h file as Faust foreign functions
+//----------------------Mathematic library for Faust----------------------------
+//
+// Implementation as Faust foreign functions of math.h functions that are not
+// part of Faust's primitives. Defines also various constants and several utilities
+//
+// ### History
+// + 07/08/2015	[YO]	documentation comments
+// + 20/06/2014	[SL]	added FTZ function
+// + 20/06/2014	[SL]	added FTZ function
+// + 22/06/2013	[YO]	added float|double|quad variants of some foreign functions
+// + 28/06/2005	[YO]	postfixed functions with 'f' to force float version instead of double
+// + 28/06/2005	[YO]	removed 'modf' because it requires a pointer as argument
+//------------------------------------------------------------------------------
+
+
+//--------------------------------- SR ---------------------------------------
+// Current sampling rate (between 1Hz and 192000Hz). Constant during
+// program execution.
 //
-// History
-// ----------
-// 28/06/2005	[YO]	postfixed functions with 'f' to force float version
-//						instead of double
-//			  	[YO]	removed 'modf' because it requires a pointer as argument
-//---------------------------------------------------------------------------------
+// ### Usage:
+//    `SR:_`
+//-----------------------------------------------------------------------------
+SR 			= min(192000, max(1, fconstant(int fSamplingFreq, <math.h>)));
 
-// -- Utilities and constants
 
-SR 			= min(192000, max(1, fconstant(int fSamplingFreq, <math.h>)));
+//--------------------------------- BS ---------------------------------------
+// Current block-size. Can change during the execution
+//
+// ### Usage:
+//    `BS:_`
+//-----------------------------------------------------------------------------
 BS          = fvariable(int count, <math.h>);
 
+
+//--------------------------------- PI ---------------------------------------
+// Constant PI in double precision
+//
+// ### Usage:
+//    `PI:_`
+//-----------------------------------------------------------------------------
 PI          = 3.1415926535897932385;
 
-// -- neg and inv functions
 
+//--------------------------------- FTZ ---------------------------------------
+// Flush to zero : force samples under the "maximum subnormal number"
+// to be zero. Usually not needed in C++ because the architecture
+// file take care of this, but can be useful in javascript for instance.
+//
+// ### Usage:
+//    `_:ftz:_`
+//
+// see : <http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html>
+//-----------------------------------------------------------------------------
+FTZ(x)      = x * (abs(x) > 1.17549435e-38);
+
+
+//--------------------------------- neg ---------------------------------------
+// Invert the sign (-x) of a signal.
+//
+// ### Usage:
+//    `_:neg:_`
+//
+//-----------------------------------------------------------------------------
 neg(x)      = -x;
+
+
+//--------------------------------- inv ---------------------------------------
+// Compute the inverse (1/x) of the input signal
+//
+// ### Usage:
+//    `_:inv:_`
+//
+//-----------------------------------------------------------------------------
 inv(x)      = 1/x;
 
-// -- Trigonometric Functions
 
-//acos		= ffunction(float acosf (float), <math.h>, "");
-//asin		= ffunction(float asinf (float), <math.h>, "");
-//atan		= ffunction(float atanf (float), <math.h>, "");
-//atan2		= ffunction(float atan2f (float, float), <math.h>, "");
+//--------------------------------- cbrt --------------------------------------
+// Computes the cube root of of the input signal.
+//
+// ### Usage:
+//    `_:cbrt:_`
+//-----------------------------------------------------------------------------
+cbrt 		= ffunction(float cbrtf|cbrt|cbrtl (float), <math.h>,"");
+
+
+//--------------------------------- hypot(x,y) -------------------------------------
+// Computes the euclidian distance of the two input signals
+// sqrt(x*x+y*y) without undue overflow or underflow.
+//
+// ### Usage:
+//    `hypot(x,y):_`
+//    `_,_:hypot:_`
+//-----------------------------------------------------------------------------
+hypot 		= ffunction(float hypotf|hypot|hypotl (float, float), <math.h>,"");
+
 
-//sin			= ffunction(float sinf (float), <math.h>, "");
-//cos			= ffunction(float cosf (float), <math.h>, "");
-//tan			= ffunction(float tanf (float), <math.h>,"");
+//--------------------------------- ldexp -------------------------------------
+// Takes two input signals: x and n, and multiplies x by 2 to the power n.
+//
+// ### Usage:
+//    `_,_:ldexp:_`
+//-----------------------------------------------------------------------------
+ldexp 		= ffunction(float ldexpf|ldexp|ldexpl (float, int), <math.h>,"");
 
-// -- Exponential Functions
 
-//exp 		= ffunction(float expf (float), <math.h>,"");
-//log 		= ffunction(float logf (float), <math.h>,"");
-//log10 	= ffunction(float log10f (float), <math.h>,"");
-//pow 		= ffunction(float powf (float, float), <math.h>,"");
-//sqrt 		= ffunction(float sqrtf (float), <math.h>,"");
-cbrt 		= ffunction(float cbrtf (float), <math.h>,"");
-hypot 		= ffunction(float hypotf (float, float), <math.h>,"");
-ldexp 		= ffunction(float ldexpf (float, int), <math.h>,"");
-scalb 		= ffunction(float scalbf (float, float), <math.h>,"");
-log1p 		= ffunction(float log1pf (float), <math.h>,"");
-logb 		= ffunction(float logbf (float), <math.h>,"");
-ilogb 		= ffunction(int ilogbf (float), <math.h>,"");
-expm1 		= ffunction(float expm1f (float), <math.h>,"");
+//--------------------------------- scalb -------------------------------------
+// Takes two input signals: x and n, and multiplies x by 2 to the power n.
+//
+// ### Usage:
+//    `_,_:scalb:_`
+//-----------------------------------------------------------------------------
+scalb 		= ffunction(float scalbnf|scalbn|scalbnl (float, int), <math.h>,"");
 
-// -- Hyperbolic Functions
 
-acosh		= ffunction(float acoshf (float), <math.h>, "");
-asinh		= ffunction(float asinhf (float), <math.h>, "");
-atanh		= ffunction(float atanhf (float), <math.h>, "");
+//--------------------------------- log1p(x) ----------------------------------
+// Computes log(1 + x) without undue loss of accuracy when x is nearly zero.
+//
+// ### Usage:
+// +  `log1p(x):_`
+// +  `_:log1p:_`
+//-----------------------------------------------------------------------------
+log1p 		= ffunction(float log1pf|log1p|log1pl (float), <math.h>,"");
 
-sinh		= ffunction(float sinhf (float), <math.h>, "");
-cosh		= ffunction(float coshf (float), <math.h>, "");
-tanh		= ffunction(float tanhf (float), <math.h>,"");
 
-// -- Remainder Functions
+//--------------------------------- logb ---------------------------------------
+// Return exponent of the input signal as a floating-point number
+//
+// ### Usage:
+//    `_:logb:_`
+//-----------------------------------------------------------------------------
+logb 		= ffunction(float logbf|logb|logbl (float), <math.h>,"");
 
-//fmod 		= ffunction(float fmodf (float, float),<math.h>,"");
-//remainder 	= ffunction(float remainderf (float, float),<math.h>,"");
 
-// -- Nearest Integer Functions
+//--------------------------------- ilogb -------------------------------------
+// Return exponent of the input signal as an integer number
+//
+// ### Usage:
+//    `_:ilogb:_`
+//-----------------------------------------------------------------------------
+ilogb 		= ffunction(int ilogbf|ilogb|ilogbl (float), <math.h>,"");
 
-//floor 		= ffunction(float floorf (float), <math.h>,"");
-//ceil 		= ffunction(float ceilf (float), <math.h>,"");
-//rint 		= ffunction(float rintf (float), <math.h>,"");
 
-// -- Special Functions
+//--------------------------------- expm1 -------------------------------------
+// Return exponent of the input signal minus 1 with better precision.
+//
+// ### Usage:
+//    `_:expm1:_`
+//-----------------------------------------------------------------------------
+expm1 		= ffunction(float expm1f|expm1|expm1l (float), <math.h>,"");
 
-erf			= ffunction(float erff(float), <math.h>,"");
-erfc		= ffunction(float erfcf(float), <math.h>,"");
-gamma		= ffunction(float gammaf(float), <math.h>,"");
-J0			= ffunction(float j0f(float), <math.h>,"");
-J1			= ffunction(float j1f(float), <math.h>,"");
-Jn			= ffunction(float jnf(int, float), <math.h>,"");
-lgamma		= ffunction(float lgammaf(float), <math.h>,"");
-Y0			= ffunction(float y0f(float), <math.h>,"");
-Y1			= ffunction(float y1f(float), <math.h>,"");
-Yn			= ffunction(float ynf(int, float), <math.h>,"");
 
+//--------------------------------- acosh -------------------------------------
+// Computes the principle value of the inverse hyperbolic cosine
+// of the input signal.
+//
+// ### Usage:
+//    `_:acosh:_`
+//-----------------------------------------------------------------------------
+acosh		= ffunction(float acoshf|acosh|acoshl (float), <math.h>, "");
+
+
+//-------------------------------- asinh(x) -----------------------------------
+// Computes the inverse hyperbolic sine of the input signal.
+//
+// ### Usage:
+//    `_:asinh:_`
+//-----------------------------------------------------------------------------
+asinh		= ffunction(float asinhf|asinh|asinhl (float), <math.h>, "");
+
+
+//-------------------------------- atanh(x) -----------------------------------
+// Computes the inverse hyperbolic tangent of the input signal.
+//
+// ### Usage:
+//    `_:atanh:_`
+//-----------------------------------------------------------------------------
+atanh		= ffunction(float atanhf|atanh|atanhl (float), <math.h>, "");
+
+
+//--------------------------------- sinh ---------------------------------------
+// Computes the hyperbolic sine of the input signal.
+//
+// ### Usage:
+//    `_:sinh:_`
+//-----------------------------------------------------------------------------
+sinh		= ffunction(float sinhf|sinh|sinhl (float), <math.h>, "");
+
+
+//--------------------------------- cosh --------------------------------------
+// Computes the hyperbolic cosine of the input signal.
+//
+// ### Usage:
+//    `_:cosh:_`
+//-----------------------------------------------------------------------------
+cosh		= ffunction(float coshf|cosh|coshl (float), <math.h>, "");
+
+
+//--------------------------------- tanh --------------------------------------
+// Computes the hyperbolic tangent of the input signal.
+//
+// ### Usage:
+//    `_:tanh:_`
+//-----------------------------------------------------------------------------
+tanh		= ffunction(float tanhf|tanh|tanhl (float), <math.h>,"");
+
+
+//--------------------------------- erf ---------------------------------------
+// Computes the error function of the input signal.
+//
+// ### Usage:
+//    `_:erf:_`
+//-----------------------------------------------------------------------------
+erf			= ffunction(float erff|erf|erfl(float), <math.h>,"");
+
+
+//--------------------------------- erf ---------------------------------------
+// Computes the complementary error function of the input signal.
+//
+// ### Usage:
+//    `_:erfc:_`
+//-----------------------------------------------------------------------------
+erfc		= ffunction(float erfcf|erfc|erfcl(float), <math.h>,"");
+
+
+//--------------------------------- gamma -------------------------------------
+// Computes the gamma function of the input signal.
+//
+// ### Usage:
+//    `_:gamma:_`
+//-----------------------------------------------------------------------------
+gamma		= ffunction(float tgammaf|tgamma|tgammal(float), <math.h>,"");
+
+
+//--------------------------------- lgamma ------------------------------------
+// Calculates the natural logorithm of the absolute value of
+// the gamma function of the input signal.
+//
+// ### Usage:
+//    `_:lgamma:_`
+//-----------------------------------------------------------------------------
+lgamma		= ffunction(float lgammaf|lgamma|lgammal(float), <math.h>,"");
+
+
+//---------------------------------- J0 ---------------------------------------
+// Computes the Bessel function of the first kind of order 0
+// of the input signal.
+//
+// ### Usage:
+//    `_:J0:_`
+//-----------------------------------------------------------------------------
+J0			= ffunction(float j0(float), <math.h>,"");
+
+//---------------------------------- J1 ---------------------------------------
+// Computes the Bessel function of the first kind of order 1
+// of the input signal.
+//
+// ### Usage:
+//    `_:J1:_`
+//-----------------------------------------------------------------------------
+J1			= ffunction(float j1(float), <math.h>,"");
+
+//---------------------------------- Jn ---------------------------------------
+// Computes the Bessel function of the first kind of order n
+// (first input signal) of the second input signal.
+//
+// ### Usage:
+//    `_,_:Jn:_`
+//-----------------------------------------------------------------------------
+Jn			= ffunction(float jn(int, float), <math.h>,"");
 
-// -- Miscellaneous Functions
 
-//fabs 		= ffunction(float fabsf (float), <math.h>,"");
-//fmax 		= ffunction(float max (float, float),<math.h>,"");
-//fmin 		= ffunction(float min (float, float),<math.h>,"");
+//---------------------------------- Y0 ---------------------------------------
+// Computes the linearly independent Bessel function of the second kind
+// of order 0 of the input signal.
+//
+// ### Usage:
+//    `_:Y0:_`
+//-----------------------------------------------------------------------------
+Y0			= ffunction(float y0(float), <math.h>,"");
+
+//---------------------------------- Y1 ---------------------------------------
+// Computes the linearly independent Bessel function of the second kind
+// of order 1 of the input signal.
+//
+// ### Usage:
+//    `_:Y0:_`
+//-----------------------------------------------------------------------------
+Y1			= ffunction(float y1(float), <math.h>,"");
+
+//---------------------------------- Yn ---------------------------------------
+// Computes the linearly independent Bessel function of the second kind
+// of order n (first input signal) of the second input signal.
+//
+// ### Usage:
+//    `_,_:Yn:_`
+//-----------------------------------------------------------------------------
+Yn			= ffunction(float yn(int, float), <math.h>,"");
+
+
+// -- Miscellaneous Functions
 
 fabs = abs;
 fmax = max;
 fmin = min;
 
+//--------------- isnan(x) ----------------
+// return non-zero if and only if x is a NaN,
+//
+// ### Usage:
+//    `_:isnan:_`
+//
+// #### Where:
+// + x = signal to analyse
+//
+//------------------------------------------
 isnan 		= ffunction(int isnan (float),<math.h>,"");
 nextafter	= ffunction(float nextafter(float, float),<math.h>,"");
 
-// Pattern matching functions to count and access the elements of a list
-// USAGE : 	count ((10,20,30,40)) 	-> 4  
-//			take  (3,(10,20,30,40)) -> 30
-// 
 
+//--------------------------------- count(l) ---------------------------------
+// Count the number of elements of list l
+//
+// ### Usage:
+//    `count ((10,20,30,40)) 	-> 4`
+//
+// #### Where:
+// + l = list of elements
+//
+//-----------------------------------------------------------------------------
 count ((xs, xxs)) = 1 + count(xxs);
 count (xx) = 1;
 
+
+//------------------------------- take(e,l) -----------------------------------
+// Take an element from a list
+//
+// ### Usage:
+//    `take  (3,(10,20,30,40)) -> 30`
+//
+// #### Where:
+// + p = position (starting at 1)
+// + l = list of elements
+//
+//-----------------------------------------------------------------------------
 take (1, (xs, xxs)) 	= xs;
 take (1, xs) 			= xs;
 take (nn, (xs, xxs)) 	= take (nn-1, xxs);
 
-// linear interpolation between two signals 
-interpolate(i) = *(1.0-i),*(i) : +; 
 
-// if-then-else implemented with a select2. 
+//---------------------------- subseq(l, p, n) --------------------------------
+// Extract a part of a list
+//
+// ### Usage:
+// +  `subseq((10,20,30,40,50,60), 1, 3) -> (20,30,40)`
+// +  `subseq((10,20,30,40,50,60), 4, 1) -> 50`
+//
+// #### Where:
+// + l = list
+// + p = start point (0: begin of list)
+// + n = number of elements
+//
+// #### Note:
+// Faust doesn't have proper lists. Lists are simulated with parallel
+// compositions and there is no empty list
+//
+//-----------------------------------------------------------------------------
+subseq((head, tail), 0, 1)      = head;
+subseq((head, tail), 0, n)      = head, subseq(tail, 0, n-1);
+subseq((head, tail), p, n)      = subseq(tail, p-1, n);
+subseq(head, 0, n)              = head;
+
+
+//----------------------------- interpolate(i) -------------------------------
+// linear interpolation between two signals
+//
+// ### Usage:
+//    `_,_:interpolate(i):_`
+//
+// #### Where:
+// + i = interpolation control between 0 and 1 (0: first input; 1: second input)
+//
+//-----------------------------------------------------------------------------
+interpolate(i) = *(1.0-i),*(i) : +;
+
+
+//----------------------------- if(c,t,e)) -----------------------------------
+// if-then-else implemented with a select2
+//
+// ### Usage:
+// +   `if(c, then, else):_`
+// +   `_,_:if(c):_`
+//
+// #### Where:
+// + c = condition
+// + t = signal selected while c is true
+// + e = signal selected while c is false
+//
+//-----------------------------------------------------------------------------
 if(cond,thn,els) = select2(cond,els,thn);
 
 
-//-----------------------------------------------------------------
-// countdown(count,trig) 
-// start counting down from count, count-1,...,0 when trig > 0
-//-----------------------------------------------------------------
+//---------------------------- countdown(n,trig) ------------------------------
+// Starts counting down from n included to 0. While trig is 1 the output is n.
+// The countdown starts with the transition of trig from 1 to 0. At the end
+// of the countdown the output value will remain at 0 until the next trig.
+//
+// ### Usage:
+// + `countdown(n,trig):_`
+// + `_:countdown(n):_`
+// + `_,_:countdown:_`
+//
+// #### Where
+// + n : the starting point of the countdown
+// + trig : the trigger signal (1: start at n; 0: decrease until 0)
+//-----------------------------------------------------------------------------
 countdown(count, trig)	= \(c).(if(trig>0, count, max(0, c-1))) ~_;
 
-//-----------------------------------------------------------------
-// countup(count,trig) 
-// start counting down from 0, 1, ... count-1, count when trig > 0
-//-----------------------------------------------------------------
+
+//---------------------------- countup(n,trig) --------------------------------
+// Starts counting up from 0 to n included. While trig is 1 the output is 0.
+// The countup starts with the transition of trig from 1 to 0. At the end
+// of the countup the output value will remain at n until the next trig.
+//
+// ### Usage:
+// + `countup(n,trig):_`
+// + `_:countup(n):_`
+// + `_,_:countup:_`
+//
+// #### Where
+// + n : the starting point of the countup
+// + trig : the trigger signal (1: start at 0; 0: increase until n)
+//-----------------------------------------------------------------------------
 countup(count, trig)	= \(c).(if(trig>0, 0, min(count, c+1))) ~_;
 
-/******************************************************************
- *  Hadamard matrix function
- *  Implementation contributed by Remy Muller
- *****************************************************************/
 
-// bus(n) : n parallel cables
+//-------------------------------- bus(n) -------------------------------------
+// n parallel cables
+//
+// ### Usage:
+//    `bus(4) -> _,_,_,_`
+//
+// #### Where:
+// + n = is an integer known at compile time that indicates the number of parallel cables.
+//
+//-----------------------------------------------------------------------------
 bus(2) = _,_; // avoids a lot of "bus(1)" labels in block diagrams
 bus(n) = par(i, n, _);
 
-// selector(i,n) : select ith cable among n
+
+//----------------------------- selector(i,n) ---------------------------------
+// Selects the ith input among n
+//
+// ### Usage:
+// `_,_,_,_:selector(2,4):_`  selects the 3rd input among 4
+//
+// #### Where:
+// + i = input to select (int, numbered from 0, known at compile time)
+// + n = number of inputs (int, known at compile time, n > i)
+//
+//-----------------------------------------------------------------------------
 selector(i,n) = par(j, n, S(i, j))    with { S(i,i) = _; S(i,j) = !; };
 
-// interleave(m,n) : interleave m*n cables : x(0), x(m), x(2m), ..., x(1),x(1+m), x(1+2m)...
-//interleave(m,n) = bus(m*n) <: par(i, m, par(j, n, selector(i+j*m,m*n))); 
 
-// interleave(row,col) : interleave row*col cables from column order to row order.
+//-------------------------- interleave(row,col) ------------------------------
+// interleave row*col cables from column order to row order.
 // input : x(0), x(1), x(2) ..., x(row*col-1)
 // output: x(0+0*row), x(0+1*row), x(0+2*row), ..., x(1+0*row), x(1+1*row), x(1+2*row), ...
-interleave(row,col) = bus(row*col) <: par(r, row, par(c, col, selector(r+c*row,row*col))); 
+//
+// ### Usage:
+//    `_,_,_,_,_,_:interleave(3,2):_,_,_,_,_,_`
+//
+// #### Where:
+// + row = the number of row (int, known at compile time)
+// + column = the number of column (int, known at compile time)
+//
+//-----------------------------------------------------------------------------
+interleave(row,col) = bus(row*col) <: par(r, row, par(c, col, selector(r+c*row,row*col)));
+
 
-// butterfly(n) : addition then substraction of interleaved signals : 
+//------------------------------- butterfly(n) --------------------------------
+// Addition (first half) then substraction (second half) of interleaved signals.
+//
+// ### Usage:
+//    `_,_,_,_:butterfly(4):_,_,_,_`
+//
+// #### Where:
+// + n = size of the butterfly (n is int, even and known at compile time)
+//
+//-----------------------------------------------------------------------------
 butterfly(n) = bus(n) <: interleave(n/2,2), interleave(n/2,2) : par(i, n/2, +), par(i, n/2, -);
 
-// hadamard(n) : hadamard matrix function of size n = 2^k
+
+//------------------------------ hadamard(n) ----------------------------------
+// hadamard matrix function of size n = 2^k
+//
+// ### Usage:
+//    `_,_,_,_:hadamard(4):_,_,_,_`
+//
+// #### Where:
+// + n = 2^k, size of the matrix (int, must be known at compile time)
+//
+// #### Note:
+// Implementation contributed by Remy Muller.
+//
+//-----------------------------------------------------------------------------
 hadamard(2) = butterfly(2);
 hadamard(n) = butterfly(n) : (hadamard(n/2) , hadamard(n/2));
+
+
+//------------------------------- dot(n) --------------------------------------
+// Dot product for two vectors of size n
+//
+// ### Usage:
+//    `_,_,_,_,_,_:dot(3):_`
+//
+// #### Where:
+// + n = size of the vectors (int, must be known at compile time)
+//
+//-----------------------------------------------------------------------------
+dot(n) = interleave(n,2) : par(i,n,*) :> _;
+
+
+//-------------------------------- cross(n) -----------------------------------
+// cross n signals : (x1,x2,..,xn) -> (xn,..,x2,x1)
+//
+// ### Usage:
+//    `_,_,_:cross(3):_,_,_`
+//
+// #### Where:
+// + n = number of signals (int, must be known at compile time)
+//
+//-----------------------------------------------------------------------------
+// cross n cables : (x1,x2,..,xn) -> (xn,..,x2,x1)
+cross(n) = bus(n) <: par(i,n,selector(n-i-1,n));
diff --git a/architecture/matlabplot.cpp b/architecture/matlabplot.cpp
index 8830082..cb12a8f 100644
--- a/architecture/matlabplot.cpp
+++ b/architecture/matlabplot.cpp
@@ -21,6 +21,7 @@
  ************************************************************************/
 
 /* matlabplot.cpp = simple variation of plot.cpp */
+#include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -47,53 +48,6 @@ struct Meta : map<const char*, const char*>
 };
 
 
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-
-
 
 inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
 
@@ -398,6 +352,8 @@ public:
 
     channels(int nframes, int nchannels)
     {
+		assert(nchannels < 256);
+		
         fNumFrames		= nframes;
         fNumChannels 	= nchannels;
 
@@ -407,6 +363,27 @@ public:
         }
     }
 
+    void zero()
+    {
+        // allocate audio  channels
+        for (int i = 0; i < fNumChannels; i++) {
+			for (int f = 0; f < fNumFrames; f++) {
+				fBuffers[i][f] = 0.0;
+			}
+        }
+    }
+
+    void impulse()
+    {
+        // allocate audio  channels
+        for (int i = 0; i < fNumChannels; i++) {
+			fBuffers[i][0] = 1.0;
+			for (int f = 1; f < fNumFrames; f++) {
+				fBuffers[i][f] = 0.0;
+			}
+        }
+    }
+
     ~channels()
     {
         // free separate input channels
@@ -426,6 +403,7 @@ int main(int argc, char *argv[] )
 {
     float			fStartAtSample;
 	float			fnbsamples;
+    float 			srate;
 
 
     CMDUI* interface = new CMDUI(argc, argv);
@@ -433,21 +411,28 @@ int main(int argc, char *argv[] )
 	
     interface->addOption("-s", &fStartAtSample, 0, 0.0, 100000000.0);
 	interface->addOption("-n", &fnbsamples, 16, 0.0, 100000000.0);
+    interface->addOption("-r", &srate, 44100.0, 1.0, 100000000.0);
 
-    if (DSP.getNumInputs() > 0) {
-        fprintf(stderr,
-                "*** input signals not supported by architecture file matlab.cpp\n");
-        exit(1);
-    }
+//     if (DSP.getNumInputs() > 0) {
+//         fprintf(stderr,
+//                 "*** input signals not supported by architecture file matlab.cpp\n");
+//         exit(1);
+//     }
 
     // init signal processor and the user interface values:
-    DSP.init(44100);
+    DSP.init(int(srate));
 
     // modify the UI values according to the command-line options:
     interface->process_command();
 
+	// prepare input channels (if any) with an impulse
+    int nins = DSP.getNumInputs();
+    channels inchan (kFrames, nins);
+	inchan.impulse(); // after each compute we will zero them
+
+	// prepare output channels
     int nouts = DSP.getNumOutputs();
-    channels chan (kFrames, nouts);
+    channels outchan (kFrames, nouts);
 
     // print usage info:
     printf("%% Usage: octave --persist thisfile.m\n\n");
@@ -459,11 +444,12 @@ int main(int argc, char *argv[] )
 	// skip <start> samples
 	int start = int(fStartAtSample);
 	while (start > kFrames) {
-		DSP.compute(kFrames, 0, chan.buffers());
+		DSP.compute(kFrames, inchan.buffers(), outchan.buffers());
+		inchan.zero();
 		start -= kFrames;
 	}
 	if (start > 0) {
-		DSP.compute(start, 0, chan.buffers());
+		DSP.compute(start, inchan.buffers(), outchan.buffers());
 	}
 	// end skip
 	
@@ -471,11 +457,11 @@ int main(int argc, char *argv[] )
 	int nbsamples = int(fnbsamples);
     while (nbsamples > kFrames) {
 
-        DSP.compute(kFrames, 0, chan.buffers());
-
+        DSP.compute(kFrames, inchan.buffers(), outchan.buffers());
+		inchan.zero();
         for (int i = 0; i < kFrames; i++) {
             for (int c = 0; c < nouts; c++) {
-                printf(" %g", chan.buffers()[c][i]);
+                printf(" %g", outchan.buffers()[c][i]);
             }
             if (i < kFrames-1) {
                 printf("; ...\n");
@@ -488,11 +474,11 @@ int main(int argc, char *argv[] )
 
     if (nbsamples) { // Write out partial-chunk buffer:
 
-        DSP.compute(nbsamples, 0, chan.buffers());
-
+        DSP.compute(nbsamples, inchan.buffers(), outchan.buffers());
+		inchan.zero();
         for (int i = 0; i < nbsamples; i++) {
             for (int c = 0; c < nouts; c++) {
-                printf(" %g", chan.buffers()[c][i]);
+                printf(" %g", outchan.buffers()[c][i]);
             }
             printf("; ...\n");
         }
diff --git a/architecture/max-msp.cpp b/architecture/max-msp.cpp
deleted file mode 100644
index 21edbec..0000000
--- a/architecture/max-msp.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections :
-	the ARCHITECTURE section (in two parts) and the USER section. Each section
-	is governed by its own copyright and license. Please check individually
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2004-2011 GRAME, Centre National de Creation Musicale
-    ---------------------------------------------------------------------
-    This Architecture section is free software; you can redistribute it
-    and/or modify it under the terms of the GNU Lesser General Public
-	License as published by the Free Software Foundation; either version 3
-	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 Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-	along with this program; If not, see <http://www.gnu.org/licenses/>.
-
-	EXCEPTION : As a special exception, you may create a larger work
-	that contains this FAUST architecture section and distribute
-	that work under terms of your choice, so long as this FAUST
-	architecture section is not modified.
-
-	MAX MSP SDK : in order to compile a MaxMSP external with this
-	architecture file you will need the official MaxMSP SDK from
-	cycling'74. Please check the corresponding license.
-
- ************************************************************************
- ************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <math.h>
-#include <errno.h>
-#include <time.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <string>
-#include <vector>
-#include <map>
-#include <math.h>
-
-#ifdef __APPLE__
-#include <Carbon/Carbon.h>
-#include <unistd.h>
-#endif
-
-#include "gui/GUI.h"
-#include "audio/dsp.h"
-#include "misc.h"
-
-using namespace std ;
-
-// There is a bug with powf() when cross compiling with mingw
-// the following macro avoid the problem
-#ifdef WIN32
-#define powf(x,y) pow(x,y)
-#define expf(x) exp(x)
-#endif
-
-#ifdef __GNUC__
-
-//-------------------------------------------------------------------
-// Generic min and max using gcc extensions
-//-------------------------------------------------------------------
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-#else
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max(unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max(int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max(long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max(int a, long b)          { return (a>b) ? a : b; }
-inline long 	max(long a, int b)          { return (a>b) ? a : b; }
-
-inline float 	max(float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max(int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max(float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max(long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max(float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max(double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max(int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max(double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max(long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max(double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max(float a, double b)      { return (a>b) ? a : b; }
-inline double 	max(double a, float b)      { return (a>b) ? a : b; }
-
-
-inline int 		min(int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min(long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min(int a, long b)          { return (a<b) ? a : b; }
-inline long 	min(long a, int b)          { return (a<b) ? a : b; }
-
-inline float 	min(float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min(int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min(float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min(long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min(float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min(double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min(int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min(double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min(long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min(double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min(float a, double b)      { return (a<b) ? a : b; }
-inline double 	min(double a, float b)      { return (a<b) ? a : b; }
-
-#endif
-
-/******************************************************************************
-*******************************************************************************
-
-							       VECTOR INTRINSICS
-
-*******************************************************************************
-*******************************************************************************/
-
-<<includeIntrinsic>>
-
-/********************END ARCHITECTURE SECTION (part 1/2)****************/
-
-/**************************BEGIN USER SECTION **************************/
-
-<<includeclass>>
-
-/***************************END USER SECTION ***************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
-
-
-/* Faust code wrapper ------- */
-
-#include "ext.h"
-#include "z_dsp.h"
-#include <string.h>
-
-#define ASSIST_INLET 	1  		/* should be defined somewhere ?? */
-#define ASSIST_OUTLET 	2		/* should be defined somewhere ?? */
-
-class mspUI;
-
-/*--------------------------------------------------------------------------*/
-typedef struct faust
-{
-	t_pxobject m_ob;
-	t_atom *m_seen,*m_want;
-	short m_where;
-	void** args;
-	mspUI* dspUI;
-	mydsp* dsp;
-} t_faust;
-
-void *faust_class;
-
-/*--------------------------------------------------------------------------*/
-class mspUIObject {
-
-	protected:
-
-		string fLabel;
-		float* fZone;
-
-		float range(float min, float max, float val) {return (val < min) ? min : (val > max) ? max : val;}
-
-	public:
-
-		mspUIObject(const char* label, float* zone):fLabel(label),fZone(zone) {}
-		virtual ~mspUIObject() {}
-
-		virtual void SetValue(double f) {*fZone = range(0.0,1.0,f);}
-		virtual void toString(char* buffer) {}
-		virtual string GetName() {return fLabel;}
-};
-
-/*--------------------------------------------------------------------------*/
-class mspToggleButton : public mspUIObject {
-
-	public:
-
-		mspToggleButton(const char* label, float* zone):mspUIObject(label,zone) {}
-		virtual ~mspToggleButton() {}
-
-		void toString(char* buffer)
-		{
-		#ifdef WIN32
-            sprintf(buffer, "ToggleButton(float): %s", fLabel.c_str());
-		#else
-			std::sprintf(buffer, "ToggleButton(float): %s", fLabel.c_str());
-		#endif
-		}
-};
-
-/*--------------------------------------------------------------------------*/
-class mspCheckButton : public mspUIObject {
-
-	public:
-
-		mspCheckButton(const char* label, float* zone):mspUIObject(label,zone) {}
-		virtual ~mspCheckButton() {}
-
-		void toString(char* buffer)
-		{
-		#ifdef WIN32
-            sprintf(buffer, "CheckButton(float): %s", fLabel.c_str());
-		#else
-			std::sprintf(buffer, "CheckButton(float): %s", fLabel.c_str());
-		#endif
-		}
-};
-
-/*--------------------------------------------------------------------------*/
-class mspButton : public mspUIObject {
-
-	public:
-
-		mspButton(const char* label, float* zone):mspUIObject(label,zone) {}
-		virtual ~mspButton() {}
-
-		void toString(char* buffer)
-		{
-		#ifdef WIN32
-            sprintf(buffer, "Button(float): %s", fLabel.c_str());
-		#else
-			std::sprintf(buffer, "Button(float): %s", fLabel.c_str());
-		#endif
-		}
-};
-
-/*--------------------------------------------------------------------------*/
-class mspSlider : public mspUIObject{
-
-	private:
-
-		float fInit;
-		float fMin;
-		float fMax;
-		float fStep;
-
-	public:
-
-		mspSlider(const char* label, float* zone, float init, float min, float max, float step)
-			:mspUIObject(label,zone),fInit(init),fMin(min),fMax(max),fStep(step) {}
-		virtual ~mspSlider() {}
-
-		void toString(char* buffer)
-		{
-		#ifdef WIN32
-            sprintf(buffer, "Slider(float): %s [%.1f:%.1f:%.1f]", fLabel.c_str(), fMin, fInit, fMax);
-		#else
-			std::sprintf(buffer, "Slider(float): %s [%.1f:%.1f:%.1f]", fLabel.c_str(), fMin, fInit, fMax);
-		#endif
-		}
-
-		void SetValue(double f) {*fZone = range(fMin,fMax,f);}
-};
-
-/*--------------------------------------------------------------------------*/
-class mspUI : public UI
-{
-	private:
-
-		map<string,mspUIObject*> fUITable;
-
-	public:
-		typedef map<string,mspUIObject*>::iterator iterator;
-
-		mspUI(){}
-		virtual ~mspUI()
-		{
-			for (iterator iter = fUITable.begin(); iter != fUITable.end(); iter++)
-				delete (iter->second);
-   		}
-
-		void addButton(const char* label, float* zone) {fUITable[string(label)] = new mspButton(label, zone);}
-
-		void addToggleButton(const char* label, float* zone) {fUITable[string(label)] = new mspToggleButton(label, zone);}
-
-		void addCheckButton(const char* label, float* zone) {fUITable[string(label)] = new mspCheckButton(label, zone);}
-
-		void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-		{
-			fUITable[string(label)] = new mspSlider(label, zone, init, min, max, step);
-		}
-
-		void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-		{
-			fUITable[string(label)] = new mspSlider(label, zone, init, min, max, step);
-		}
-
-		void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-		{
-			fUITable[string(label)] = new mspSlider(label, zone, init, min, max, step);
-		}
-
-		void openFrameBox(const char* label) {}
-		void openTabBox(const char* label) {}
-		void openHorizontalBox(const char* label) {}
-		void openVerticalBox(const char* label) {}
-		void closeBox() {}
-
-		void SetValue(string name, double f)
-		{
-			if(fUITable.count(name))
-				fUITable[name]->SetValue(f);
-		}
-		iterator begin()	{return fUITable.begin();}
-		iterator end()		{return fUITable.end();}
-
-		// To be implemented
-		void addNumDisplay(const char* label, float* zone, int precision) {}
-		void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) {}
-        void addHorizontalBargraph(const char* label, float* zone, float min, float max) {}
-		void addVerticalBargraph(const char* label, float* zone, float min, float max) {}
-};
-
-//--------------------------------------------------------------------------
-void faust_method(t_faust *obj, t_symbol *s, short ac, t_atom *at)
-{
-	if(ac < 0) return;
-    if(at[0].a_type != A_FLOAT) return;
-
-    string name = string( (s)->s_name );
-    float value = at[0].a_w.w_float;
-
-    // lookup du nom dans une std::map<string,mspUIObject *>
-    // ou une std::map<string,float *>
-    // et affectation de value;
-	obj->dspUI->SetValue(name,value); // doesn't have any effect if name is unknown
-}
-
-/*--------------------------------------------------------------------------*/
-void *faust_new(t_symbol *s, short ac, t_atom *av)
-{
-	t_faust *x = (t_faust *)newobject(faust_class);
-
-	x->dsp = new mydsp();
-	x->dspUI= new mspUI();
-
-	x->dsp->init(long(sys_getsr()));
-	x->dsp->buildUserInterface(x->dspUI);
-
-	x->args = (void**)calloc((x->dsp->getNumInputs()+x->dsp->getNumOutputs())+2, sizeof(void*));
-
-	/* Multi in */
-	dsp_setup((t_pxobject *)x, x->dsp->getNumInputs());
-
-	/* Multi out */
-	for (int i = 0; i< x->dsp->getNumOutputs(); i++)
-		outlet_new((t_pxobject *)x, (char*)"signal");
-
-	((t_pxobject *)x)->z_misc = Z_NO_INPLACE; // To assure input and output buffers are actually different
-	return x;
-}
-
-/*--------------------------------------------------------------------------*/
-void faust_assist(t_faust *x, void *b, long msg, long a, char *dst)
-{
-    if (msg == ASSIST_INLET) {
-        if (a == 0) {
-            if (x->dsp->getNumInputs() == 0) {
-			#ifdef WIN32
-                sprintf(dst, "(signal) : Unused Input");
-			#else
-				std::sprintf(dst, "(signal) : Unused Input");
-			#endif
-            } else {
-			#ifdef WIN32
-                sprintf(dst, "(signal) : Audio Input %ld", (a+1));
-			#else
-				std::sprintf(dst, "(signal) : Audio Input %ld", (a+1));
-			#endif
-			}
-			post((char*)"------------------");
-			for (mspUI::iterator it = x->dspUI->begin(); it != x->dspUI->end(); ++it) {
-				char param[64];
-				it->second->toString(param);
-				post(param);
-			}
-        } else if (a < x->dsp->getNumInputs()) {
-		#ifdef WIN32
-            sprintf(dst, "(signal) : Audio Input %ld", (a+1));
-		#else
-			std::sprintf(dst, "(signal) : Audio Input %ld", (a+1));
-		#endif
-        }
-    } else if (msg == ASSIST_OUTLET) {
-	#ifdef WIN32
-        sprintf(dst, "(signal) : Audio Output %ld", (a+1));
-	#else
-		std::sprintf(dst, "(signal) : Audio Output %ld", (a+1));
-	#endif
-    }
-}
-
-/*--------------------------------------------------------------------------*/
-void faust_free(t_faust *x)
-{
-	dsp_free((t_pxobject *)x);
-	if (x->dsp) delete x->dsp;
-	if (x->dspUI) delete x->dspUI;
-	if (x->args)free(x->args);
-}
-
-/*--------------------------------------------------------------------------*/
-t_int *faust_perform(t_int *w)
-{
-	t_faust* x = (t_faust*) (w[1]);
-	long n = w[2];
-	int offset = 3;
-	AVOIDDENORMALS;
-	x->dsp->compute(n, ((float**)&w[offset]), ((float**)&w[offset+x->dsp->getNumInputs()]));
-	return (w + (x->dsp->getNumInputs()+x->dsp->getNumOutputs())+2+1);
-}
-
-/*--------------------------------------------------------------------------*/
-void  faust_dsp(t_faust *x, t_signal **sp, short *count)
-{
-	x->args[0] = x;
-	x->args[1] = (void*)sp[0]->s_n;
-	for (int i = 0; i<(x->dsp->getNumInputs()+x->dsp->getNumOutputs()); i++)
-		x->args[i+2] = sp[i]->s_vec;
-	dsp_addv(faust_perform, (x->dsp->getNumInputs()+x->dsp->getNumOutputs())+2, x->args);
-}
-
-/*--------------------------------------------------------------------------*/
-int main()
-{
-	setup((t_messlist **)&faust_class, (method)faust_new, (method)faust_free,
-		(short)sizeof(t_faust), 0L, A_DEFFLOAT, 0);
-
-	dsp *thedsp = new mydsp();
-	mspUI *dspUI= new mspUI();
-	thedsp->buildUserInterface(dspUI);
-
-	// Add the same method for every parameters and use the symbol as a selector
-	// inside thid method
-	for (mspUI::iterator it = dspUI->begin(); it != dspUI->end(); ++it) {
-		char *name = const_cast<char *>(it->second->GetName().c_str());
-		addmess((method)faust_method, name, A_GIMME, 0);
-	}
-
-	addmess((method)faust_dsp, (char*)"dsp", A_CANT, 0);
-	addmess((method)faust_assist, (char*)"assist", A_CANT, 0);
-	dsp_initclass();
-
-    delete(dspUI);
-    delete(thedsp);
-	post((char*)"Faust DSP object");
-	return 0;
-}
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
-
-
-
diff --git a/architecture/max-msp/max-msp.cpp b/architecture/max-msp/max-msp.cpp
new file mode 100644
index 0000000..d8437c8
--- /dev/null
+++ b/architecture/max-msp/max-msp.cpp
@@ -0,0 +1,731 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2004-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser General Public
+	License as published by the Free Software Foundation; either version 3
+	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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+	along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+	MAX MSP SDK : in order to compile a MaxMSP external with this
+	architecture file you will need the official MaxMSP SDK from
+	cycling'74. Please check the corresponding license.
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <math.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#ifdef __APPLE__
+#include <Carbon/Carbon.h>
+#include <unistd.h>
+#endif
+
+#ifdef WIN32
+#ifndef NAN
+    static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
+    #define NAN (*(const float *) __nan)
+#endif
+#endif
+
+#include "faust/gui/UI.h"
+#include "faust/gui/JSONUI.h"
+#include "faust/audio/dsp.h"
+#include "faust/misc.h"
+
+using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/********************END ARCHITECTURE SECTION (part 1/2)****************/
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+
+/* Faust code wrapper ------- */
+
+#include "ext.h"
+#include "ext_obex.h"
+#include "z_dsp.h"
+#include "jpatcher_api.h"
+#include <string.h>
+
+#define ASSIST_INLET 	1  		/* should be defined somewhere ?? */
+#define ASSIST_OUTLET 	2		/* should be defined somewhere ?? */
+
+#define EXTERNAL_VERSION "0.55"
+
+class mspUI;
+
+struct Max_Meta1 : Meta
+{
+    int fCount;
+    
+    Max_Meta1():fCount(0)
+    {}
+     
+    void declare(const char* key, const char* value)
+    {
+        if ((strcmp("name", key) == 0) || (strcmp("author", key) == 0)) {
+            fCount++;
+        }
+    }
+};
+
+struct Max_Meta2 : Meta
+{
+    void declare(const char* key, const char* value)
+    {
+        if ((strcmp("name", key) == 0) || (strcmp("author", key) == 0)) {
+            post("%s : %s", key, value);
+        }
+    }
+};
+
+
+/*--------------------------------------------------------------------------*/
+typedef struct faust
+{
+    t_pxobject m_ob;
+    t_atom *m_seen, *m_want;
+    map<string, t_object*> m_output_table;
+    short m_where;
+    bool m_mute;
+    void** args;
+    mspUI* dspUI;
+    mydsp* dsp;
+    char* m_json;                
+} t_faust;
+
+void *faust_class;
+
+/*--------------------------------------------------------------------------*/
+class mspUIObject {
+    
+protected:
+    
+    string fLabel;
+    FAUSTFLOAT* fZone;
+    
+    FAUSTFLOAT range(FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT val) {return (val < min) ? min : (val > max) ? max : val;}
+    
+public:
+    
+    mspUIObject(const string& label, FAUSTFLOAT* zone):fLabel(label),fZone(zone) {}
+    virtual ~mspUIObject() {}
+    
+    virtual void setValue(FAUSTFLOAT f) {*fZone = range(0.0, 1.0, f);}
+    virtual FAUSTFLOAT getValue() { return *fZone; }
+    virtual void toString(char* buffer) {}
+    virtual string getName() {return fLabel;}
+  
+};
+
+/*--------------------------------------------------------------------------*/
+class mspCheckButton : public mspUIObject {
+    
+    public:
+        
+        mspCheckButton(const string& label, FAUSTFLOAT* zone):mspUIObject(label,zone) {}
+        virtual ~mspCheckButton() {}
+        
+        void toString(char* buffer)
+        {
+            snprintf(buffer, 256, "CheckButton(float): %s", fLabel.c_str());
+        }
+};
+
+/*--------------------------------------------------------------------------*/
+class mspButton : public mspUIObject {
+    
+    public:
+        
+        mspButton(const string& label, FAUSTFLOAT* zone):mspUIObject(label, zone) {}
+        virtual ~mspButton() {}
+        
+        void toString(char* buffer)
+        {
+            snprintf(buffer, 256, "Button(float): %s", fLabel.c_str());
+        }
+};
+
+/*--------------------------------------------------------------------------*/
+class mspSlider : public mspUIObject {
+    
+    private:
+        
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        
+    public:
+        
+        mspSlider(const string& label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        :mspUIObject(label,zone),fInit(init),fMin(min),fMax(max),fStep(step) {}
+        virtual ~mspSlider() {}
+        
+        void toString(char* buffer)
+        {
+            stringstream s; 
+            s << "Slider(float): " << fLabel << " [init=" << fInit << ":min=" << fMin << ":max=" << fMax << ":step=" << fStep << ":cur=" << *fZone << "]";
+            strcpy(buffer, s.str().c_str());
+        }
+        
+        void setValue(FAUSTFLOAT f) {*fZone = range(fMin, fMax, f);}
+};
+
+/*--------------------------------------------------------------------------*/
+class mspBargraph : public mspUIObject {
+    
+    private:
+        
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fCurrent;
+        
+    public:
+        
+        mspBargraph(const string& label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        :mspUIObject(label,zone),fMin(min),fMax(max),fCurrent(*zone) {}
+        virtual ~mspBargraph() {}
+        
+        void toString(char* buffer)
+        {
+            stringstream s; 
+            s << "Bargraph(float): " << fLabel << " [min=" << fMin << ":max=" << fMax << ":cur=" << *fZone << "]";
+            strcpy(buffer, s.str().c_str());
+        }
+        
+        virtual FAUSTFLOAT getValue() 
+        { 
+            if (*fZone != fCurrent) {
+                fCurrent = *fZone;
+                return fCurrent;
+            } else {
+                return NAN; 
+            }
+        }
+};
+
+/*--------------------------------------------------------------------------*/
+class mspUI : public UI
+{
+
+    private:
+        
+        map<string, mspUIObject*> fUITable1;       // Table using labels
+        map<string, mspUIObject*> fUITable2;       // Table using complete path
+        map<string, mspUIObject*> fUITable3;       // Table containing bargraph
+         
+        map<const char*, const char*> fDeclareTable;
+        std::vector<std::string> fControlsLevel;
+        
+        std::string buildPath(const std::string& label) 
+        {
+            std::string res = "/";
+            for (size_t i = 0; i < fControlsLevel.size(); i++) {
+                res += fControlsLevel[i];
+                res += "/";
+            }
+            res += label;
+            replace(res.begin(), res.end(), ' ', '_');
+            return res;
+        }
+    
+        string createLabel(const char* label)
+        {
+            map<const char*, const char*>::reverse_iterator it;
+            if (fDeclareTable.size() > 0) {
+                unsigned int i = 0;
+                string res = string(label);
+                char sep = '[';
+                for (it = fDeclareTable.rbegin(); it != fDeclareTable.rend(); it++, i++) {
+                    res = res + sep + (*it).first + ":" + (*it).second;
+                    sep = ',';
+                }
+                res += ']';
+                fDeclareTable.clear();
+                return res;
+            } else {
+                return string(label);
+            }
+        }
+        
+    public:
+        
+        typedef map<string, mspUIObject*>::iterator iterator;
+        
+        mspUI() {}
+        virtual ~mspUI()
+        {
+            clear();
+        }
+        
+        void addButton(const char* label, FAUSTFLOAT* zone) 
+        {
+            mspUIObject* obj = new mspButton(createLabel(label), zone);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj;
+        }
+        
+        void addCheckButton(const char* label, FAUSTFLOAT* zone) 
+        {
+            mspUIObject* obj = new mspCheckButton(createLabel(label), zone);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj; 
+        }
+        
+        void addSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            mspUIObject* obj = new mspSlider(createLabel(label), zone, init, min, max, step);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj; 
+        }
+        
+        void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addSlider(label, zone, init, min, max, step);
+        }
+        
+        void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addSlider(label, zone, init, min, max, step);
+        }
+        
+        void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            mspUIObject* obj = new mspSlider(createLabel(label), zone, init, min, max, step);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj;
+        }
+        
+        void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {   
+            fUITable3[buildPath(label)] = new mspBargraph(createLabel(label), zone, min, max);
+            fDeclareTable.clear();
+        }
+        void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            fUITable3[buildPath(label)] = new mspBargraph(createLabel(label), zone, min, max);
+            fDeclareTable.clear();
+        }
+    
+        void openTabBox(const char* label) {fControlsLevel.push_back(label); fDeclareTable.clear();}
+        void openHorizontalBox(const char* label) {fControlsLevel.push_back(label); fDeclareTable.clear();}
+        void openVerticalBox(const char* label) {fControlsLevel.push_back(label); fDeclareTable.clear();}
+        void closeBox() {fControlsLevel.pop_back(); fDeclareTable.clear();}
+        
+        virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {
+            fDeclareTable[key] = val;
+        }
+       
+        bool isValue(string name) 
+        {
+            return (fUITable1.count(name) || fUITable2.count(name));
+        }
+        bool isOutputValue(string name) 
+        {
+            return fUITable3.count(name);
+        }
+        bool isInputValue(string name) 
+        {
+            return fUITable2.count(name);
+        }
+        bool setValue(string name, FAUSTFLOAT f)
+        {
+            if (fUITable1.count(name)) {
+                fUITable1[name]->setValue(f);
+                return true;
+            } else if (fUITable2.count(name)) {
+                fUITable2[name]->setValue(f);
+                return true;
+            } else {
+                return false;
+            }
+        }
+        
+        FAUSTFLOAT getOutputValue(string name) { return fUITable3[name]->getValue(); }
+          
+        iterator begin1()	{ return fUITable1.begin(); }
+        iterator end1()		{ return fUITable1.end(); }
+        
+        iterator begin2()	{ return fUITable2.begin(); }
+        iterator end2()		{ return fUITable2.end(); }
+        
+        int itemsCount() { return fUITable1.size(); }
+        void clear() 
+        { 
+            iterator it;
+            for (it = begin1(); it != end1(); it++) {
+                delete (*it).second;
+            }
+            fUITable1.clear(); 
+            fUITable2.clear(); 
+        }
+    
+};
+
+//--------------------------------------------------------------------------
+static bool check_digit(const string& name)
+{
+    for (int i = name.size() - 1; i >= 0; i--) {
+        if (isdigit(name[i])) return true;
+    }
+    return false;
+}
+
+static int count_digit(const string& name)
+{
+    int count = 0;
+    for (int i = name.size() - 1; i >= 0; i--) {
+        if (isdigit(name[i])) count++;
+    }
+    return count;
+}
+
+void faust_anything(t_faust* obj, t_symbol* s, short ac, t_atom* av)
+{
+    bool res = false;
+    string name = string((s)->s_name);
+     
+    if (ac < 0) return;
+    
+    // Check if no argument is there, consider it is a toggle message for a button
+    if (ac == 0 && obj->dspUI->isValue(name)) {
+        
+        string name = string((s)->s_name);
+        float off = 0.0f;
+        float on = 1.0f;
+        obj->dspUI->setValue(name, off);
+        obj->dspUI->setValue(name, on);
+        
+        av[0].a_type = A_FLOAT;
+        av[0].a_w.w_float = off;
+        faust_anything(obj, s, 1, av);
+        
+        return;
+    }
+    
+    // List of values
+    if (check_digit(name)) {
+        
+        int ndigit = 0;
+        int pos;
+        
+        for (pos = name.size() - 1; pos >= 0; pos--) {
+            if (isdigit(name[pos]) || name[pos] == ' ') {
+                ndigit++;
+            } else {
+                break;
+            }
+        }
+        pos++;
+        
+        string prefix = name.substr(0, pos);
+        string num_base = name.substr(pos);
+        int num = atoi(num_base.c_str());
+        
+        int i;
+        t_atom* ap;
+       
+        // Increment ap each time to get to the next atom
+        for (i = 0, ap = av; i < ac; i++, ap++) {
+            float value;
+            switch (atom_gettype(ap)) {
+                case A_LONG: {
+                    value = (float)ap[0].a_w.w_long;
+                    break;
+                }
+                case A_FLOAT:
+                    value = ap[0].a_w.w_float;
+                    break;
+                    
+                default:
+                    post("Invalid argument in parameter setting"); 
+                    return;         
+            }
+            
+            stringstream num_val;
+            num_val << num + i;
+            char param_name[256];
+            
+            switch (ndigit - count_digit(num_val.str())) {
+                case 0: 
+                    sprintf(param_name, "%s%s", prefix.c_str(), num_val.str().c_str());
+                    break;
+                case 1: 
+                    sprintf(param_name, "%s %s", prefix.c_str(), num_val.str().c_str());
+                    break;
+                case 2: 
+                    sprintf(param_name, "%s  %s", prefix.c_str(), num_val.str().c_str());
+                    break;
+            }
+            
+            // Try special naming scheme for list of parameters
+            res = obj->dspUI->setValue(param_name, value); 
+            
+            // Otherwise try standard name
+            if (!res) {
+                res = obj->dspUI->setValue(name, value);
+            }
+            
+            if (!res) {
+                post("Unknown parameter : %s", (s)->s_name);
+            }
+        }
+    } else {
+        // Standard parameter name
+        float value = (av[0].a_type == A_LONG) ? (float)av[0].a_w.w_long : av[0].a_w.w_float;
+        res = obj->dspUI->setValue(name, value); 
+    }
+    
+    if (!res) {
+        post("Unknown parameter : %s", (s)->s_name);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_create_jsui(t_faust* x)
+{
+    t_object *patcher, *box, *obj;
+    object_obex_lookup((t_object*)x, gensym("#P"), &patcher);
+    
+    for (box = jpatcher_get_firstobject(patcher); box; box = jbox_get_nextobject(box)) {
+        obj = jbox_get_object(box);
+        // Notify JSON
+        if (obj && strcmp(object_classname(obj)->s_name, "js") == 0) {
+            t_atom json;
+            atom_setsym(&json, gensym(x->m_json));
+            object_method_typed(obj, gensym("anything"), 1, &json, 0);
+            post("Generate UI from JSON...");
+        }
+    }
+        
+    // Keep all outputs
+    x->m_output_table.clear();
+    for (box = jpatcher_get_firstobject(patcher); box; box = jbox_get_nextobject(box)) {
+        obj = jbox_get_object(box);
+        t_symbol *scriptingname = jbox_get_varname(obj); // scripting name
+        if (scriptingname && x->dspUI->isOutputValue(scriptingname->s_name)) {
+            x->m_output_table[scriptingname->s_name] = obj;
+        }
+    }
+}
+
+void faust_update_outputs(t_faust* x)
+{
+    map<string, t_object*>::iterator it;
+    for (it =  x->m_output_table.begin(); it != x->m_output_table.end(); it++) {
+        FAUSTFLOAT value = x->dspUI->isOutputValue((*it).first);
+        if (value != NAN) {
+            t_atom at_value;
+            atom_setfloat(&at_value, value);
+            object_method_typed((*it).second, gensym("float"), 1, &at_value, 0);
+        }
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void* faust_new(t_symbol* s, short ac, t_atom* av)
+{
+    t_faust* x = (t_faust*)newobject(faust_class);
+
+    x->m_mute = false;
+
+    x->dsp = new mydsp();
+    x->dspUI = new mspUI();
+
+    x->dsp->init(long(sys_getsr()));
+    x->dsp->buildUserInterface(x->dspUI);
+    
+    // Prepare JSON
+    
+    JSONUI builder(x->dsp->getNumInputs(), x->dsp->getNumOutputs());
+    x->dsp->metadata(&builder);
+    x->dsp->buildUserInterface(&builder);
+    x->m_json = strdup(builder.JSON().c_str());
+    
+    x->args = (void**)calloc((x->dsp->getNumInputs()+x->dsp->getNumOutputs())+2, sizeof(void*));
+
+    /* Multi in */
+    dsp_setup((t_pxobject*)x, x->dsp->getNumInputs());
+
+    /* Multi out */
+    for (int i = 0; i< x->dsp->getNumOutputs(); i++) {
+        outlet_new((t_pxobject*)x, (char*)"signal");
+    }
+
+    ((t_pxobject*)x)->z_misc = Z_NO_INPLACE; // To assure input and output buffers are actually different
+    
+    // send JSON to JS script
+    faust_create_jsui(x);
+    return x;
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_assist(t_faust* x, void* b, long msg, long a, char* dst)
+{
+    if (msg == ASSIST_INLET) {
+        if (a == 0) {
+            if (x->dsp->getNumInputs() == 0) {
+                sprintf(dst, "(signal) : Unused Input");
+            } else {
+                sprintf(dst, "(signal) : Audio Input %ld", (a+1));
+			}
+			post((char*)"------------------");
+			for (mspUI::iterator it = x->dspUI->begin1(); it != x->dspUI->end1(); ++it) {
+				char param[256];
+				it->second->toString(param);
+				post(param);
+			}
+        } else if (a < x->dsp->getNumInputs()) {
+            sprintf(dst, "(signal) : Audio Input %ld", (a+1));
+        }
+    } else if (msg == ASSIST_OUTLET) {
+        sprintf(dst, "(signal) : Audio Output %ld", (a+1));
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_mute(t_faust* obj, t_symbol* s, short ac, t_atom* at)
+{
+    if (atom_gettype(at) == A_LONG) {
+        obj->m_mute = atom_getlong(at);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_free(t_faust* x)
+{
+	dsp_free((t_pxobject*)x);
+	if (x->dsp) delete x->dsp;
+	if (x->dspUI) delete x->dspUI;
+	if (x->args) free(x->args);
+    if (x->m_json) free(x->m_json);
+}
+
+/*--------------------------------------------------------------------------*/
+t_int *faust_perform(t_int *w)
+{
+	t_faust* x = (t_faust*) (w[1]);
+	long n = w[2];
+	int offset = 3;
+	AVOIDDENORMALS;
+    if (x->m_mute) {
+        float** outputs = ((float**)&w[offset+x->dsp->getNumInputs()]);
+        // Write null buffers to outs
+        for (int i = 0; i < x->dsp->getNumOutputs(); i++) {
+             memset(outputs[i], 0, sizeof(float) * n);
+        }
+    } else {
+        x->dsp->compute(n, ((float**)&w[offset]), ((float**)&w[offset+x->dsp->getNumInputs()]));
+        faust_update_outputs(x);
+    }
+	return (w + (x->dsp->getNumInputs()+x->dsp->getNumOutputs()) + 2 + 1);
+}
+
+/*--------------------------------------------------------------------------*/
+void  faust_dsp(t_faust* x, t_signal **sp, short* count)
+{
+	x->args[0] = x;
+	x->args[1] = (void*)sp[0]->s_n;
+	for (int i = 0; i<(x->dsp->getNumInputs()+x->dsp->getNumOutputs()); i++) {
+		x->args[i + 2] = sp[i]->s_vec;
+    }
+	dsp_addv(faust_perform, (x->dsp->getNumInputs()+x->dsp->getNumOutputs()) + 2, x->args);
+}
+
+/*--------------------------------------------------------------------------*/
+extern "C" int main(void)
+{
+	setup((t_messlist**)&faust_class, (method)faust_new, (method)faust_free,
+		(short)sizeof(t_faust), 0L, A_DEFFLOAT, 0);
+
+	dsp* thedsp = new mydsp();
+	mspUI dspUI;
+ 	thedsp->buildUserInterface(&dspUI);
+   
+    // 03/11/14 : use 'anything' to handle all parameter changes
+    addmess((method)faust_anything, (char*)"anything", A_GIMME, 0);
+
+	addmess((method)faust_dsp, (char*)"dsp", A_CANT, 0);
+	addmess((method)faust_assist, (char*)"assist", A_CANT, 0);
+    addmess((method)faust_mute, (char*)"mute", A_GIMME, 0);
+	dsp_initclass();
+    
+    post((char*)"Faust DSP object v%s (sample = 32 bits code = 32 bits)" , EXTERNAL_VERSION);
+    post((char*)"Copyright (c) 2012-2015 Grame");
+    Max_Meta1 meta1;
+    mydsp::metadata(&meta1);
+    if (meta1.fCount > 0) {
+        Max_Meta2 meta2;
+        post("------------------------------");
+        mydsp::metadata(&meta2);
+        post("------------------------------");
+    }
+
+    delete(thedsp);
+	return 0;
+}
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
+
+
diff --git a/architecture/max-msp/max-msp64.cpp b/architecture/max-msp/max-msp64.cpp
new file mode 100644
index 0000000..d56ac46
--- /dev/null
+++ b/architecture/max-msp/max-msp64.cpp
@@ -0,0 +1,772 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2004-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser General Public
+	License as published by the Free Software Foundation; either version 3
+	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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+	along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+	MAX MSP SDK : in order to compile a MaxMSP external with this
+	architecture file you will need the official MaxMSP SDK from
+	cycling'74. Please check the corresponding license.
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <math.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#ifdef __APPLE__
+#include <Carbon/Carbon.h>
+#include <unistd.h>
+#endif
+
+#ifdef WIN32
+#ifndef NAN
+    static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
+    #define NAN (*(const float *) __nan)
+#endif
+#endif
+
+#define FAUSTFLOAT double
+
+#include "faust/gui/UI.h"
+#include "faust/gui/JSONUI.h"
+#include "faust/audio/dsp.h"
+#include "faust/misc.h"
+
+using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/********************END ARCHITECTURE SECTION (part 1/2)****************/
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+
+/* Faust code wrapper ------- */
+
+#include "ext.h"
+#include "ext_obex.h"
+#include "z_dsp.h"
+#include "jpatcher_api.h"
+#include <string.h>
+
+#define ASSIST_INLET 	1  		/* should be defined somewhere ?? */
+#define ASSIST_OUTLET 	2		/* should be defined somewhere ?? */
+
+#define EXTERNAL_VERSION "0.55"
+
+static const char* getCodeSize()
+{
+    int tmp;
+    return (sizeof(&tmp) == 8) ? "64 bits" : "32 bits";
+}
+
+class mspUI;
+
+struct Max_Meta1 : Meta
+{
+    int fCount;
+    
+    Max_Meta1():fCount(0)
+    {}
+     
+    void declare(const char* key, const char* value)
+    {
+        if ((strcmp("name", key) == 0) || (strcmp("author", key) == 0)) {
+            fCount++;
+        }
+    }
+};
+
+struct Max_Meta2 : Meta
+{
+    void declare(const char* key, const char* value)
+    {
+        if ((strcmp("name", key) == 0) || (strcmp("author", key) == 0)) {
+            post("%s : %s", key, value);
+        }
+    }
+};
+
+
+/*--------------------------------------------------------------------------*/
+typedef struct faust
+{
+    t_pxobject m_ob;
+    t_atom *m_seen, *m_want;
+    map<string, t_object*> m_output_table;
+    short m_where;
+    bool m_mute;
+    void** args;
+    mspUI* dspUI;
+    mydsp* dsp;
+    char* m_json;
+} t_faust;
+
+void *faust_class;
+
+/*--------------------------------------------------------------------------*/
+class mspUIObject {
+
+	protected:
+
+		string fLabel;
+		FAUSTFLOAT* fZone;
+
+		FAUSTFLOAT range(FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT val) {return (val < min) ? min : (val > max) ? max : val;}
+
+	public:
+
+		mspUIObject(const string& label, FAUSTFLOAT* zone):fLabel(label),fZone(zone) {}
+		virtual ~mspUIObject() {}
+
+		virtual void setValue(FAUSTFLOAT f) {*fZone = range(0.0,1.0,f);}
+        virtual FAUSTFLOAT getValue() { return *fZone; }
+		virtual void toString(char* buffer) {}
+		virtual string getName() {return fLabel;}
+};
+
+/*--------------------------------------------------------------------------*/
+class mspCheckButton : public mspUIObject {
+
+	public:
+
+		mspCheckButton(const string& label, FAUSTFLOAT* zone):mspUIObject(label,zone) {}
+		virtual ~mspCheckButton() {}
+
+		void toString(char* buffer)
+		{
+            sprintf(buffer, "CheckButton(double): %s", fLabel.c_str());
+		}
+};
+
+/*--------------------------------------------------------------------------*/
+class mspButton : public mspUIObject {
+
+	public:
+
+		mspButton(const string& label, FAUSTFLOAT* zone):mspUIObject(label,zone) {}
+		virtual ~mspButton() {}
+
+		void toString(char* buffer)
+		{
+            sprintf(buffer, "Button(double): %s", fLabel.c_str());
+		}
+};
+
+/*--------------------------------------------------------------------------*/
+class mspSlider : public mspUIObject {
+
+	private:
+
+		FAUSTFLOAT fInit;
+		FAUSTFLOAT fMin;
+		FAUSTFLOAT fMax;
+		FAUSTFLOAT fStep;
+
+	public:
+
+		mspSlider(const string& label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+			:mspUIObject(label,zone),fInit(init),fMin(min),fMax(max),fStep(step) {}
+		virtual ~mspSlider() {}
+
+		void toString(char* buffer)
+		{
+            stringstream s; 
+            s << "Slider(double): " << fLabel << " [init=" << fInit << ":min=" << fMin << ":max=" << fMax << ":step=" << fStep << ":cur=" << *fZone << "]";
+            strcpy(buffer, s.str().c_str());
+		}
+
+		void setValue(FAUSTFLOAT f) {*fZone = range(fMin,fMax,f);}
+};
+
+/*--------------------------------------------------------------------------*/
+class mspBargraph : public mspUIObject {
+    
+    private:
+        
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fCurrent;
+        
+    public:
+        
+        mspBargraph(const string& label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        :mspUIObject(label,zone),fMin(min),fMax(max),fCurrent(*zone) {}
+        virtual ~mspBargraph() {}
+        
+        void toString(char* buffer)
+        {
+            stringstream s; 
+            s << "Bargraph(float): " << fLabel << " [min=" << fMin << ":max=" << fMax << ":cur=" << *fZone << "]";
+            strcpy(buffer, s.str().c_str());
+        }
+        
+        virtual FAUSTFLOAT getValue() 
+        { 
+            if (*fZone != fCurrent) {
+                fCurrent = *fZone;
+                return fCurrent;
+            } else {
+                return NAN; 
+            }
+        }
+};
+
+/*--------------------------------------------------------------------------*/
+
+#define MULTI_SIZE  256
+
+class mspUI : public UI
+{
+	private:
+
+        map<string, mspUIObject*> fUITable1;       // Table using labels
+        map<string, mspUIObject*> fUITable2;       // Table using complete path
+        map<string, mspUIObject*> fUITable3;       // Table containing bargraph
+       
+        map<const char*, const char*> fDeclareTable;
+        std::vector<std::string> fControlsLevel;
+        
+        FAUSTFLOAT* fMultiTable[MULTI_SIZE];
+        int fMultiIndex;
+        int fMultiControl;
+        
+        std::string buildPath(const std::string& label) 
+        {
+            std::string res = "/";
+            for (size_t i = 0; i < fControlsLevel.size(); i++) {
+                res += fControlsLevel[i];
+                res += "/";
+            }
+            res += label;
+            replace(res.begin(), res.end(), ' ', '_');
+            return res;
+        }
+    
+        string createLabel(const char* label)
+        {
+            map<const char*, const char*>::reverse_iterator it;
+            if (fDeclareTable.size() > 0) {
+                unsigned int i = 0;
+                string res = string(label);
+                char sep = '[';
+                for (it = fDeclareTable.rbegin(); it != fDeclareTable.rend(); it++, i++) {
+                    res = res + sep + (*it).first + ":" + (*it).second;
+                    sep = ',';
+                }
+                res += ']';
+                fDeclareTable.clear();
+                return res;
+            } else {
+                return string(label);
+            }
+        }
+
+	public:
+    
+		typedef map<string,mspUIObject*>::iterator iterator;
+
+		mspUI() 
+        {
+     		for (int i = 0; i < MULTI_SIZE; i++) {
+                fMultiTable[i] = 0;
+            }
+            fMultiIndex = fMultiControl = 0;
+        }
+		virtual ~mspUI()
+		{
+            clear();
+   		}
+      
+		void addButton(const char* label, FAUSTFLOAT* zone) 
+        {
+            mspUIObject* obj = new mspButton(createLabel(label), zone);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj;
+        }
+        
+        void addCheckButton(const char* label, FAUSTFLOAT* zone) 
+        {
+            mspUIObject* obj = new mspCheckButton(createLabel(label), zone);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj; 
+        }
+        
+        void addSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            mspUIObject* obj = new mspSlider(createLabel(label), zone, init, min, max, step);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj; 
+        }
+        
+        void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addSlider(label, zone, init, min, max, step);
+        }
+        
+        void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addSlider(label, zone, init, min, max, step);
+        }
+        
+        void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            mspUIObject* obj = new mspSlider(createLabel(label), zone, init, min, max, step);
+            fUITable1[string(label)] = obj;
+            fUITable2[buildPath(label)] = obj;
+        }
+        
+        void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {   
+            fUITable3[buildPath(label)] = new mspBargraph(createLabel(label), zone, min, max);
+            fDeclareTable.clear();
+        }
+        void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) 
+        {
+            fUITable3[buildPath(label)] = new mspBargraph(createLabel(label), zone, min, max);
+            fDeclareTable.clear();
+        }
+    
+        void openTabBox(const char* label) {fControlsLevel.push_back(label); fDeclareTable.clear();}
+        void openHorizontalBox(const char* label) {fControlsLevel.push_back(label); fDeclareTable.clear();}
+        void openVerticalBox(const char* label) {fControlsLevel.push_back(label); fDeclareTable.clear();}
+        void closeBox() {fControlsLevel.pop_back(); fDeclareTable.clear();}
+
+        virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+        {
+            if (strcmp(key,"multi") == 0) {
+                int index = atoi(val);
+                if (index >= 0 && index < MULTI_SIZE) {
+                    fMultiTable[index] = zone;
+                    fMultiControl++;
+                } else {
+                    post("Invalid multi index = %d", index);
+                }
+            }
+            
+            fDeclareTable[key] = val;
+        }
+        
+        void setMultiValues(FAUSTFLOAT* multi, int buffer_size)
+		{
+            for (int read = 0; read < buffer_size; read++) {
+                int write = (fMultiIndex + read) & (MULTI_SIZE - 1);
+                if (fMultiTable[write]) {
+                    *fMultiTable[write] = multi[read];
+                }
+            }
+            fMultiIndex += buffer_size;
+		}
+        
+        bool isMulti() { return fMultiControl > 0; }
+    
+        bool isValue(string name) 
+        {
+            return (fUITable1.count(name) || fUITable2.count(name));
+        }
+        bool isOutputValue(string name) 
+        {
+            return fUITable3.count(name);
+        }
+        bool isInputValue(string name) 
+        {
+            return fUITable2.count(name);
+        }
+        bool setValue(string name, FAUSTFLOAT f)
+        {
+            if (fUITable1.count(name)) {
+                fUITable1[name]->setValue(f);
+                return true;
+            } else if (fUITable2.count(name)) {
+                fUITable2[name]->setValue(f);
+                return true;
+            } else {
+                return false;
+            }
+        }
+		FAUSTFLOAT getOutputValue(string name) { return fUITable3[name]->getValue(); }
+          
+        iterator begin1()	{ return fUITable1.begin(); }
+        iterator end1()		{ return fUITable1.end(); }
+        
+        iterator begin2()	{ return fUITable2.begin(); }
+        iterator end2()		{ return fUITable2.end(); }
+
+        int itemsCount() { return fUITable1.size(); }
+        void clear() 
+        { 
+            iterator it;
+            for (it = begin1(); it != end1(); it++) {
+                delete (*it).second;
+            }
+            fUITable1.clear(); 
+            fUITable2.clear(); 
+        }
+};
+
+//--------------------------------------------------------------------------
+static bool check_digit(const string& name)
+{
+    for (int i = name.size() - 1; i >= 0; i--) {
+        if (isdigit(name[i])) return true;
+    }
+    return false;
+}
+
+static int count_digit(const string& name)
+{
+    int count = 0;
+    for (int i = name.size() - 1; i >= 0; i--) {
+        if (isdigit(name[i])) count++;
+    }
+    return count;
+}
+
+void faust_anything(t_faust* obj, t_symbol* s, short ac, t_atom* av)
+{
+    bool res = false;
+    string name = string((s)->s_name);
+     
+    if (ac < 0) return;
+    
+    // Check if no argument is there, consider it is a toggle message for a button
+    if (ac == 0 && obj->dspUI->isValue(name)) {
+        
+        string name = string((s)->s_name);
+        float off = 0.0f;
+        float on = 1.0f;
+        obj->dspUI->setValue(name, off);
+        obj->dspUI->setValue(name, on);
+        
+        av[0].a_type = A_FLOAT;
+        av[0].a_w.w_float = off;
+        faust_anything(obj, s, 1, av);
+        
+        return;
+    }
+    
+    // List of values
+    if (check_digit(name)) {
+        
+        int ndigit = 0;
+        int pos;
+        
+        for (pos = name.size() - 1; pos >= 0; pos--) {
+            if (isdigit(name[pos]) || name[pos] == ' ') {
+                ndigit++;
+            } else {
+                break;
+            }
+        }
+        pos++;
+        
+        string prefix = name.substr(0, pos);
+        string num_base = name.substr(pos);
+        int num = atoi(num_base.c_str());
+        
+        int i;
+        t_atom* ap;
+       
+        // Increment ap each time to get to the next atom
+        for (i = 0, ap = av; i < ac; i++, ap++) {
+            float value;
+            switch (atom_gettype(ap)) {
+                case A_LONG: {
+                    value = (float)ap[0].a_w.w_long;
+                    break;
+                }
+                case A_FLOAT:
+                    value = ap[0].a_w.w_float;
+                    break;
+                    
+                default:
+                    post("Invalid argument in parameter setting"); 
+                    return;         
+            }
+            
+            stringstream num_val;
+            num_val << num + i;
+            char param_name[256];
+            
+            switch (ndigit - count_digit(num_val.str())) {
+                case 0: 
+                    sprintf(param_name, "%s%s", prefix.c_str(), num_val.str().c_str());
+                    break;
+                case 1: 
+                    sprintf(param_name, "%s %s", prefix.c_str(), num_val.str().c_str());
+                    break;
+                case 2: 
+                    sprintf(param_name, "%s  %s", prefix.c_str(), num_val.str().c_str());
+                    break;
+            }
+            
+            // Try special naming scheme for list of parameters
+            res = obj->dspUI->setValue(param_name, value); 
+            
+            // Otherwise try standard name
+            if (!res) {
+                res = obj->dspUI->setValue(name, value);
+            }
+            
+            if (!res) {
+                post("Unknown parameter : %s", (s)->s_name);
+            }
+        }
+    } else {
+        // Standard parameter name
+        float value = (av[0].a_type == A_LONG) ? (float)av[0].a_w.w_long : av[0].a_w.w_float;
+        res = obj->dspUI->setValue(name, value);
+    }
+    
+    if (!res) {
+        post("Unknown parameter : %s", (s)->s_name);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_create_jsui(t_faust* x)
+{
+    t_object *patcher, *box, *obj;
+    object_obex_lookup((t_object*)x, gensym("#P"), &patcher);
+    
+    for (box = jpatcher_get_firstobject(patcher); box; box = jbox_get_nextobject(box)) {
+        obj = jbox_get_object(box);
+        // Notify JSON
+        if (obj && strcmp(object_classname(obj)->s_name, "js") == 0) {
+            t_atom json;
+            atom_setsym(&json, gensym(x->m_json));
+            object_method_typed(obj, gensym("anything"), 1, &json, 0);
+            post("Generate UI from JSON...");
+        }
+    }
+        
+    // Keep all outputs
+    x->m_output_table.clear();
+    for (box = jpatcher_get_firstobject(patcher); box; box = jbox_get_nextobject(box)) {
+        obj = jbox_get_object(box);
+        t_symbol *scriptingname = jbox_get_varname(obj); // scripting name
+        if (scriptingname && x->dspUI->isOutputValue(scriptingname->s_name)) {
+            x->m_output_table[scriptingname->s_name] = obj;
+        }
+    }
+}
+
+void faust_update_outputs(t_faust* x)
+{
+    map<string, t_object*>::iterator it;
+    for (it =  x->m_output_table.begin(); it != x->m_output_table.end(); it++) {
+        FAUSTFLOAT value = x->dspUI->isOutputValue((*it).first);
+        if (value != NAN) {
+            t_atom at_value;
+            atom_setfloat(&at_value, value);
+            object_method_typed((*it).second, gensym("float"), 1, &at_value, 0);
+        }
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void* faust_new(t_symbol* s, short ac, t_atom* av)
+{
+    t_faust* x = (t_faust*)newobject(faust_class);
+
+    x->m_mute = false;
+
+    x->dsp = new mydsp();
+    x->dspUI = new mspUI();
+
+    x->dsp->init(long(sys_getsr()));
+    x->dsp->buildUserInterface(x->dspUI);
+    
+    // Prepare JSON
+    JSONUI builder(x->dsp->getNumInputs(), x->dsp->getNumOutputs());
+    x->dsp->metadata(&builder);
+    x->dsp->buildUserInterface(&builder);
+    x->m_json = strdup(builder.JSON().c_str());
+    
+    int num_input;
+    
+    if (x->dspUI->isMulti()) {
+        num_input = x->dsp->getNumInputs() + 1;
+    } else {
+        num_input = x->dsp->getNumInputs();
+    }
+    
+    x->args = (void**)calloc((num_input + x->dsp->getNumOutputs()) + 2, sizeof(void*));
+    /* Multi in */
+    dsp_setup((t_pxobject*)x, num_input);
+
+    /* Multi out */
+    for (int i = 0; i< x->dsp->getNumOutputs(); i++) {
+        outlet_new((t_pxobject*)x, (char*)"signal");
+    }
+
+    ((t_pxobject*)x)->z_misc = Z_NO_INPLACE; // To assure input and output buffers are actually different
+    
+    // send JSON to JS script
+    faust_create_jsui(x);
+    return x;
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_assist(t_faust* x, void* b, long msg, long a, char* dst)
+{
+    if (msg == ASSIST_INLET) {
+        if (a == 0) {
+            if (x->dsp->getNumInputs() == 0) {
+                sprintf(dst, "(signal) : Unused Input");
+            } else {
+                sprintf(dst, "(signal) : Audio Input %ld", (a+1));
+			}
+			post((char*)"------------------");
+			for (mspUI::iterator it = x->dspUI->begin1(); it != x->dspUI->end1(); ++it) {
+				char param[256];
+				it->second->toString(param);
+				post(param);
+			}
+        } else if (a < x->dsp->getNumInputs()) {
+            sprintf(dst, "(signal) : Audio Input %ld", (a+1));
+        }
+    } else if (msg == ASSIST_OUTLET) {
+        sprintf(dst, "(signal) : Audio Output %ld", (a+1));
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_mute(t_faust* obj, t_symbol* s, short ac, t_atom* at)
+{
+    if (atom_gettype(at) == A_LONG) {
+        obj->m_mute = atom_getlong(at);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_free(t_faust* x)
+{
+	dsp_free((t_pxobject*)x);
+	if (x->dsp) delete x->dsp;
+	if (x->dspUI) delete x->dspUI;
+	if (x->args) free(x->args);
+    if (x->m_json) free(x->m_json);
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_perform64(t_faust* x, t_object* dsp64, double** ins, long numins, double** outs, long numouts, long sampleframes, long flags, void* userparam)
+{
+    AVOIDDENORMALS;
+    if (x->m_mute) {
+        // Write null buffers to outs
+        for (int i = 0; i < numouts; i++) {
+             memset(outs[i], 0, sizeof(double) * sampleframes);
+        }
+    } else {
+        if (x->dspUI->isMulti()) {
+            x->dspUI->setMultiValues(ins[0], sampleframes);
+            x->dsp->compute(sampleframes, ++ins, outs);
+        } else {
+            x->dsp->compute(sampleframes, ins, outs);
+        }
+        faust_update_outputs(x);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+void faust_dsp64(t_faust* x, t_object* dsp64, short* count, double samplerate, long maxvectorsize, long flags)
+{
+    object_method(dsp64, gensym("dsp_add64"), x, faust_perform64, 0, NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+extern "C" int main(void)
+{
+	setup((t_messlist**)&faust_class, (method)faust_new, (method)faust_free,
+		(short)sizeof(t_faust), 0L, A_DEFFLOAT, 0);
+
+	dsp* thedsp = new mydsp();
+    mspUI dspUI;
+	thedsp->buildUserInterface(&dspUI);
+
+    // 03/11/14 : use 'anything' to handle all parameter changes
+    addmess((method)faust_anything, (char*)"anything", A_GIMME, 0);
+
+    addmess((method)faust_dsp64, (char*)"dsp64", A_CANT, 0);
+	addmess((method)faust_assist, (char*)"assist", A_CANT, 0);
+    addmess((method)faust_mute, (char*)"mute", A_GIMME, 0);
+	dsp_initclass();
+
+    post((char*)"Faust DSP object v%s (sample = 64 bits code = %s)", EXTERNAL_VERSION, getCodeSize());
+    post((char*)"Copyright (c) 2012-2015 Grame");
+    Max_Meta1 meta1;
+    mydsp::metadata(&meta1);
+    if (meta1.fCount > 0) {
+        Max_Meta2 meta2;
+        post("------------------------------");
+        mydsp::metadata(&meta2);
+        post("------------------------------");
+    }
+    
+    delete(thedsp);
+	return 0;
+}
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
+
+
diff --git a/architecture/max-msp/ui.js b/architecture/max-msp/ui.js
new file mode 100644
index 0000000..b4b87cd
--- /dev/null
+++ b/architecture/max-msp/ui.js
@@ -0,0 +1,192 @@
+// ui.js
+// -----------------
+//
+// Automatically (re)generate/destroy sliders according to Faust DSP module
+// By Edgar Berdahl, July 2014
+// Grame, 2014
+//
+// Currently addHorizontalBargraph, addVerticalBargraph, declare,
+// openTabBox, openHorizontalBox, openVerticalBox, and closeBox are not really handled.
+//
+// Started from autosurface.js by rld, 5.04
+//
+
+// inlets and outlets
+inlets = 1;
+outlets = 2;
+
+// global variables and arrays
+var numwidgets = -1;  // The actual number if widgets is numwidgets+1
+var thevalues = new Array(128);
+
+var widgHeight = 30;
+var hBase = 150;
+
+// Maxobj variables for scripting
+var thecomments = new Array(128);
+var thesliders = new Array(128);
+var theMessages = new Array(128);
+var thenumberBoxes = new Array(128);
+var thefunnel;
+
+var inputs_items = new Array(128);
+var ouputs_items = new Array(128);
+
+// JSON parsing
+parse_ui = function(ui, patcher) 
+{
+    var i;
+    for (i = 0; i < ui.length; i++) {
+        parse_group(ui[i], patcher);
+    }
+}
+    
+parse_group = function(group, patcher) 
+{
+    if (group.items) {
+        parse_items(group.items, patcher);
+    }
+}
+
+parse_items = function(items, patcher) 
+{
+    var i;
+    for (i = 0; i < items.length; i++) {
+        parse_item(items[i], patcher);
+    }
+}
+
+startsWith = function(str, prefix) 
+{
+    return str.lastIndexOf(prefix, 0) === 0;
+}
+
+get_faustgen = function(patcher)
+{
+	var obj = patcher.firstobject;
+	while (obj) {
+		if (startsWith(obj.varname, "faustgen-")) {
+			return obj;
+		}
+		obj = obj.nextobject;
+	}
+	return null;
+}
+
+parse_item = function(item, patcher) 
+{
+	var msgSink = patcher.getnamed("mymsgScriptingName");
+	
+	//Does not work for now...
+	//var msgSink = get_faustgen(patcher); 
+	
+    if (item.type === "vgroup" || item.type === "hgroup" || item.type === "tgroup") {
+	
+        parse_items(item.items, patcher);
+
+    } else if (item.type === "hbargraph" || item.type === "vbargraph") {
+	
+		numwidgets++;
+	
+		thecomments[numwidgets] = patcher.newdefault(hBase,20+widgHeight*numwidgets,"comment");
+		thecomments[numwidgets].message("set","bargraph"+numwidgets);
+	
+		// TODO : create "meter" instead of "multiSlider" 
+		
+		thesliders[numwidgets] = patcher.newobject("user", "multiSlider", hBase+130, 20+widgHeight*numwidgets, 120, 20, 0., 1., 1, 2936, 15, 0, 0, 2, 0, 0, 0);
+		thesliders[numwidgets].message('settype', 1);
+		thesliders[numwidgets].message('contdata', 1);
+		thesliders[numwidgets].message('setstyle', 0);
+		thesliders[numwidgets].message('setminmax', parseFloat(item.min), parseFloat(item.max));
+   		thesliders[numwidgets].message(parseFloat(item.init));  // Set initial value
+        
+        // Bargraph ScriptingName is set with the complete parameter path, so that faustgen~ can directly address them
+		thesliders[numwidgets].message('varname', item.address);
+		
+		thenumberBoxes[numwidgets] = patcher.newobject("flonum",hBase+258,20+widgHeight*numwidgets,80,13);
+		thenumberBoxes[numwidgets].message('min',parseFloat(item.min));
+		thenumberBoxes[numwidgets].message('max',parseFloat(item.max));
+			
+		patcher.hiddenconnect(thesliders[numwidgets], 0, thenumberBoxes[numwidgets], 0);		
+		patcher.hiddenconnect(theMessages[numwidgets], 0, msgSink, 0);
+				
+		// direct connection to faustgen~ does not work...
+		//patcher.hiddenconnect(thenumberBoxes[numwidgets], 0, msgSink, 0);
+ 	
+    } else if (item.type === "vslider" || item.type === "hslider" ) {
+	
+		numwidgets++;
+	
+		thecomments[numwidgets] = patcher.newdefault(hBase,20+widgHeight*numwidgets,"comment");
+		thecomments[numwidgets].message("set",item.label);
+
+		thesliders[numwidgets] = patcher.newobject("user", "multiSlider", hBase+130, 20+widgHeight*numwidgets, 120, 20, 0., 1., 1, 2936, 15, 0, 0, 2, 0, 0, 0);
+		thesliders[numwidgets].message('settype', 1);
+		thesliders[numwidgets].message('contdata', 1);
+		thesliders[numwidgets].message('setstyle', 0);
+		thesliders[numwidgets].message('setminmax', parseFloat(item.min), parseFloat(item.max));
+   		thesliders[numwidgets].message(parseFloat(item.init));  // Set initial value
+		thesliders[numwidgets].message('varname', item.address);
+			
+		thenumberBoxes[numwidgets] = patcher.newobject("flonum",hBase+258,20+widgHeight*numwidgets,80,13);
+		thenumberBoxes[numwidgets].message('min',parseFloat(item.min));
+		thenumberBoxes[numwidgets].message('max',parseFloat(item.max));
+			
+		patcher.hiddenconnect(thesliders[numwidgets], 0, thenumberBoxes[numwidgets], 0);
+			
+		theMessages[numwidgets] = patcher.newobject("message",hBase+345,23+widgHeight*numwidgets,350,9);
+		theMessages[numwidgets].message("set",item.address,"\$1");
+		
+		patcher.hiddenconnect(thenumberBoxes[numwidgets], 0, theMessages[numwidgets], 0);
+		patcher.hiddenconnect(theMessages[numwidgets], 0, msgSink, 0);
+		
+		// direct connection to faustgen~ does not work...
+		//patcher.hiddenconnect(thenumberBoxes[numwidgets], 0, msgSink, 0);
+
+	} else if (item.type === "button" || item.type === "checkbox") {
+		
+		numwidgets++;
+		thecomments[numwidgets] = patcher.newdefault(hBase,20+widgHeight*numwidgets,"comment");
+		thecomments[numwidgets].message("set",item.label);
+	
+		thesliders[numwidgets] = patcher.newdefault(hBase+130,20+widgHeight*numwidgets,"toggle");  // Faust says always have default of zero--even for check buttons!  Ohhhh well...
+			
+		thenumberBoxes[numwidgets] = patcher.newobject("number",hBase+258,20+widgHeight*numwidgets,80,13);
+		thenumberBoxes[numwidgets].message('min',0);
+		thenumberBoxes[numwidgets].message('max',1);
+		
+		patcher.hiddenconnect(thesliders[numwidgets], 0, thenumberBoxes[numwidgets], 0);
+			
+		theMessages[numwidgets] = patcher.newobject("message",hBase+345,23+widgHeight*numwidgets,350,9);
+		theMessages[numwidgets].message("set",item.address,"\$1");
+		
+		patcher.hiddenconnect(thenumberBoxes[numwidgets], 0, theMessages[numwidgets], 0);
+		patcher.hiddenconnect(theMessages[numwidgets], 0, msgSink, 0);
+		
+		// direct connection to faustgen~ does not work...
+		//patcher.hiddenconnect(thenumberBoxes[numwidgets], 0, msgSink, 0)
+		
+ 	} else if (item.type === "nentry") {
+	
+        
+    }
+}
+
+function anything()
+{	
+	var args = arrayfromargs(messagename, arguments);
+	
+    // Remove old
+    while (numwidgets >= 0) {
+        this.patcher.remove(thecomments[numwidgets]);
+        this.patcher.remove(thesliders[numwidgets]);
+        this.patcher.remove(theMessages[numwidgets]);
+        this.patcher.remove(thenumberBoxes[numwidgets]);
+        numwidgets--;
+    }
+        
+    // Get and parse JSON description of the UI
+    var json = args[1];
+    parse_ui(JSON.parse(json).ui, this.patcher);
+}
+
diff --git a/architecture/max-msp/wrapper.maxpat b/architecture/max-msp/wrapper.maxpat
new file mode 100644
index 0000000..b59dbbc
--- /dev/null
+++ b/architecture/max-msp/wrapper.maxpat
@@ -0,0 +1,118 @@
+{
+	"patcher" : 	{
+		"fileversion" : 1,
+		"appversion" : 		{
+			"major" : 6,
+			"minor" : 1,
+			"revision" : 8,
+			"architecture" : "x86"
+		}
+        ,
+		"rect" : [ 150.0, 115.0, 1025.0, 735.0 ],
+		"bglocked" : 0,
+		"openinpresentation" : 0,
+		"default_fontsize" : 12.0,
+		"default_fontface" : 0,
+		"default_fontname" : "Arial",
+		"gridonopen" : 0,
+		"gridsize" : [ 15.0, 15.0 ],
+		"gridsnaponopen" : 0,
+		"statusbarvisible" : 2,
+		"toolbarvisible" : 1,
+		"boxanimatetime" : 200,
+		"imprint" : 0,
+		"enablehscroll" : 1,
+		"enablevscroll" : 1,
+		"devicewidth" : 0.0,
+		"description" : "",
+		"digest" : "",
+		"tags" : "",
+		"boxes" : [ 			{
+				"box" : 				{
+					"fontname" : "Arial",
+					"fontsize" : 13.0,
+					"hidden" : 1,
+					"id" : "obj-15",
+					"maxclass" : "newobj",
+					"numinlets" : 0,
+					"numoutlets" : 1,
+					"outlettype" : [ "" ],
+					"patching_rect" : [ 21.0, 128.0, 60.0, 21.0 ],
+					"text" : "r mymsg",
+					"varname" : "mymsgScriptingName[1]"
+				}
+
+			}
+            , 			
+            {
+				"box" : 				{
+					"fontname" : "Arial",
+					"fontsize" : 13.0,
+					"hidden" : 1,
+					"id" : "obj-63",
+					"maxclass" : "newobj",
+					"numinlets" : 1,
+					"numoutlets" : 0,
+					"patching_rect" : [ 21.0, 107.0, 60.0, 21.0 ],
+					"text" : "s mymsg",
+					"varname" : "mymsgScriptingName"
+				}
+			}
+            ,
+            {
+				"box" : 				{
+					"fontname" : "Arial",
+					"fontsize" : 12.0,
+					"hidden" : 1,
+					"id" : "obj-2",
+					"maxclass" : "newobj",
+					"numinlets" : 1,
+					"numoutlets" : 2,
+					"outlettype" : [ "", "" ],
+					"patching_rect" : [ 78.0, 128.0, 44.0, 20.0 ],
+					"saved_object_attributes" : 					{
+						"filename" : "UI_FILE",
+						"parameter_enable" : 0
+					}
+                    ,
+					"text" : "js UI_FILE"
+				}
+
+			}
+            ,
+            {
+				"box" : 				{
+					"fontname" : "Arial",
+					"fontsize" : 12.0,
+					"id" : "obj-1",
+					"maxclass" : "newobj",
+					"numinlets" : 1,
+					"numoutlets" : 2,
+					"outlettype" : [ "signal", "signal" ],
+					"patching_rect" : [ 21.0, 77.0, 101.0, 20.0 ]
+                    ,
+                    "text" : "DSP_NAME"
+				}
+			}
+        ],
+		"lines" : [ 			{
+				"patchline" : 				{
+					"destination" : [ "obj-1", 0 ],
+					"disabled" : 0,
+					"hidden" : 1,
+					"source" : [ "obj-15", 0 ]
+				}
+
+			}
+        ],
+		"dependency_cache" : [ 			{
+				"name" : "UI_FILE",
+				"patcherrelativepath" : ".",
+				"type" : "TEXT",
+				"implicit" : 1
+			}
+        , 			
+        {}
+        ]
+	}
+}
diff --git a/architecture/maxmsp.lib b/architecture/maxmsp.lib
index 27b2e92..240c79d 100644
--- a/architecture/maxmsp.lib
+++ b/architecture/maxmsp.lib
@@ -23,19 +23,18 @@
 declare name "MaxMSP compatibility Library";
 declare author "GRAME";
 declare copyright "GRAME";
-declare version "1.0";
+declare version "1.1";
 declare license "LGPL"; 
 
 import("music.lib");
 
-
 atodb = db2lin;
 
 //-------------------------------------------------------------------------
 // 
 // Implementation of MaxMSP filtercoeff 
 // 
-//		from : Cookbook formulae for audio EQ biquad filter coefficients
+//	from : Cookbook formulae for audio EQ biquad filter coefficients
 //        by : Robert Bristow-Johnson  <rbj at audioimagination.com>
 //       URL : http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
 // 
@@ -141,7 +140,7 @@ filtercoeff(f0, dBgain, Q) = environment
 	// --------------------- implementation ------------------------------
 	
 	// convert rbj coeffs to biquad coeffs
-	rbjcoef(a0,a1,a2,b0,b1,b2) = (b0/a0, b1/a0, b2/a0,-a1/a0,-a2/a0);
+	rbjcoef(a0,a1,a2,b0,b1,b2) = (b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
 	
 	// common values
 //	alpha 	= sin(w0)/(2*Q);
@@ -149,30 +148,28 @@ filtercoeff(f0, dBgain, Q) = environment
 	alpha 	= sin(w0)/(2*max(0.001,Q));
 	w0 		= 2*PI*max(0,f0)/Fs;
 	Fs 		= SR;
-	A  		= 10^(dBgain/40);     			// (for peaking and shelving EQ filters only)
+	A  		= 10^(dBgain/40);     		// (for peaking and shelving EQ filters only)
 	G  		= sqrt(max(0.00001, dBgain));   // When gain is a linear values (i.e. not in dB)
 };
 
 
 //-------------------------------------------------------------------------
 // Implementation of MaxMSP biquad~
-// y[n] = a0 * x[n] + a1 * x[n-1] + a2 * x[n-2] + b1 * y[n-1] + b2 * y[n-2] 
+// y[n] = a0 * x[n] + a1 * x[n-1] + a2 * x[n-2] - b1 * y[n-1] - b2 * y[n-2] 
 //-------------------------------------------------------------------------
 
-biquad(x,a0,a1,a2,b1,b2) = x : conv3(a0, a1, a2) : + ~ conv2(b1, b2)
+biquad(x,a0,a1,a2,b1,b2)  =  x : + ~ ((-1)*conv2(b1, b2)) : conv3(a0, a1, a2) 
 	with {
 		conv2(c0,c1,x) = c0*x+c1*x';
 		conv3(c0,c1,c2,x) = c0*x+c1*x'+c2*x'';
 	};
 
-
 //-------------------------------------------------------------------------
 // 
 // Filters using filtercoeff and biquad
 //
 //-------------------------------------------------------------------------
 
-
 // Low Pass Filter
 LPF(x, f0, gain, Q) 		= x , filtercoeff(f0,gain,Q).LPF : biquad;
 
@@ -201,8 +198,6 @@ lowShelf(x, f0, gain, Q) 	= x , filtercoeff(f0,gain,Q).lowShelf : biquad;
 highShelf(x, f0, gain, Q) 	= x , filtercoeff(f0,gain,Q).highShelf : biquad;
 
 
-
-
 //-------------------------------------------------------------------------
 // Implementation of Max/MSP line~. Generate signal ramp or envelope 
 // 
@@ -214,13 +209,11 @@ highShelf(x, f0, gain, Q) 	= x , filtercoeff(f0,gain,Q).highShelf : biquad;
 // output value changes. The interpolation time is sampled only then.
 //-------------------------------------------------------------------------
 
-line (value, time) = state ~ ( _ , _ ) : ! , _ 
+line (value, time) = state~(_,_):!,_ 
 	with {
-		state (t , c) = nt , if( nt <= 0 , value , c + (value - c) / nt)
+		state (t, c) = nt, if (nt <= 0, value, c+(value - c) / nt)
 		with {
-			nt = if( value != value' , samples, t - 1) ;
-			samples = time * SR / 1000.0 ;
-		} ;
-	} ;
-
-
+			nt = if( value != value', samples, t-1);
+			samples = time*SR/1000.0;
+		};
+	};
diff --git a/architecture/minimal.cpp b/architecture/minimal.cpp
index 61d75ba..f93274f 100644
--- a/architecture/minimal.cpp
+++ b/architecture/minimal.cpp
@@ -18,9 +18,9 @@
 
 #include <cmath>
 
-#include "gui/GUI.h"
-#include "audio/dsp.h"
-#include "misc.h"
+#include "faust/gui/UI.h"
+#include "faust/audio/dsp.h"
+#include "faust/gui/meta.h"
 
 /******************************************************************************
 *******************************************************************************
@@ -45,3 +45,9 @@
 //----------------------------------------------------------------------------
 
 <<includeclass>>
+
+int main(int argc, char *argv[])
+{
+	mydsp DSP;
+}
+
diff --git a/architecture/misc.h b/architecture/misc.h
deleted file mode 100644
index 16cd4ff..0000000
--- a/architecture/misc.h
+++ /dev/null
@@ -1,56 +0,0 @@
-
-#ifndef __misc__
-#define __misc__
-
-#include <map>
-#include <string.h>
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #define AVOIDDENORMALS
-#endif
-
-struct XXXX_Meta : std::map<const char*, const char*>
-{
-    void declare (const char* key, const char* value) { (*this)[key]=value; }
-};
-
-struct Meta
-{
-    virtual void declare (const char* key, const char* value) = 0;
-};
-
-struct MY_Meta : Meta, std::map<const char*, const char*>
-{
-    void declare (const char* key, const char* value) { (*this)[key]=value; }
-};
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-inline int		lsr (int x, int n)		{ return int(((unsigned int)x) >> n); }
-inline int 		int2pow2 (int x)		{ int r=0; while ((1<<r)<x) r++; return r; }
-
-long lopt(char *argv[], const char *name, long def)
-{
-	int	i;
-	for (i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
-	return def;
-}
-
-char* lopts(char *argv[], const char *name, char* def)
-{
-	int	i;
-	for (i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return argv[i+1];
-	return def;
-}
-#endif
-
diff --git a/architecture/module.cpp b/architecture/module.cpp
index 28220dd..3e22424 100644
--- a/architecture/module.cpp
+++ b/architecture/module.cpp
@@ -24,12 +24,9 @@
 #include <errno.h>
 #include <time.h>
 
-#include <map>
-#include <list>
-
-#include "gui/GUI.h"
-#include "misc.h"
-#include "audio/dsp.h"
+#include "faust/gui/GUI.h"
+#include "faust/misc.h"
+#include "faust/audio/dsp.h"
 
 using namespace std;
 
diff --git a/architecture/ms-jack-gtk.cpp b/architecture/ms-jack-gtk.cpp
index 3634674..ac7b834 100644
--- a/architecture/ms-jack-gtk.cpp
+++ b/architecture/ms-jack-gtk.cpp
@@ -70,8 +70,6 @@ using namespace std;
  
 	
 
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
 
 
 // abs is now predefined
@@ -1174,6 +1172,16 @@ int main(int argc, char *argv[] )
     jack_client_close(client);
     interface->saveState(rcfilename);
         
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
     return 0;
 }
 
diff --git a/architecture/music.lib b/architecture/music.lib
index c837389..e1bebbc 100644
--- a/architecture/music.lib
+++ b/architecture/music.lib
@@ -1,7 +1,7 @@
 /************************************************************************
  ************************************************************************
   	FAUST library file
-	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+	Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
     ---------------------------------------------------------------------
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU Lesser General Public License as 
@@ -17,6 +17,17 @@
  	License along with the GNU C Library; if not, write to the Free
   	Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   	02111-1307 USA. 
+  	  	
+  	EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
+  	larger FAUST program which directly or indirectly imports this library
+  	file and still distribute the compiled code generated by the FAUST
+  	compiler, or a modified version of this compiled code, under your own
+  	copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
+  	grants you the right to freely choose the license for the resulting
+  	compiled code. In particular the resulting compiled code has no obligation
+  	to be LGPL or GPL. For example you are free to choose a commercial or
+  	closed source license or any other license if you decide so.
+
  ************************************************************************
  ************************************************************************/
 
@@ -24,7 +35,7 @@ declare name "Music Library";
 declare author "GRAME";
 declare copyright "GRAME";
 declare version "1.0";
-declare license "LGPL"; 
+declare license "LGPL with exception"; 
 
 import("math.lib");
 
@@ -186,8 +197,8 @@ linear2db(x)	= 20*log10(x);
 // 			noise : Noise generator
 //-----------------------------------------------
 
-random 		= +(12345) ~ *(1103515245);
-RANDMAX		= 2147483647.0;
+random 		= +(12345) ~ *(1103515245); // "linear congruential"
+RANDMAX		= 2147483647.0; // = 2^31-1 = MAX_SIGNED_INT in 32 bits
 
 noise 		= random / RANDMAX;
 
@@ -229,10 +240,14 @@ samplingfreq	= SR;
 
 time 		= (+(1)~_ ) - 1; 			// 0,1,2,3,...
 sinwaveform 	= float(time)*(2.0*PI)/float(tablesize) : sin;
+coswaveform 	= float(time)*(2.0*PI)/float(tablesize) : cos;
 
 decimal(x)	= x - floor(x);
 phase(freq) 	= freq/float(samplingfreq) : (+ : decimal) ~ _ : *(float(tablesize));
-osc(freq)	= rdtable(tablesize, sinwaveform, int(phase(freq)) );
+oscsin(freq)	= rdtable(tablesize, sinwaveform, int(phase(freq)) );
+osccos(freq)	= rdtable(tablesize, coswaveform, int(phase(freq)) );
+oscp(freq,p)	= oscsin(freq) * cos(p) + osccos(freq) * sin(p);
+osc		= oscsin;
 osci(freq)	= s1 + d * (s2 - s1)
 		with {
 			i = int(phase(freq));
@@ -245,8 +260,8 @@ osci(freq)	= s1 + d * (s2 - s1)
 // 			ADSR envelop
 //-----------------------------------------------
 
-// a,d,s,r = attack (#samples), decay (sec), sustain (percentage), release (sec)
-// t       = trigger signal
+// a,d,s,r = attack (sec), decay (sec), sustain (percentage of t), release (sec)
+// t       = trigger signal ( >0 for attack, then release is when t back to 0)
 
 adsr(a,d,s,r,t) = env ~ (_,_) : (!,_) // the 2 'state' signals are fed back
 with {
@@ -329,7 +344,7 @@ TF2(b0,b1,b2,a1,a2) = sub ~ conv2(a1,a2) : conv3(b0,b1,b2)
 
 /*************************** Break Point Functions ***************************
 
-bpf is an environment (a group of related definitions) tha can be used to 
+bpf is an environment (a group of related definitions) that can be used to 
 create break-point functions. It contains three functions : 
   - start(x,y) to start a break-point function
   - end(x,y) to end a break-point function
@@ -374,4 +389,102 @@ bpf = environment
 };
 
 
+//----------------------------------Stereoize------------------------------
+// Transform an arbitrary processor p into a stereo processor with 2 inputs
+// and 2 outputs.
+//-----------------------------------------------------------------------
+stereoize(p) = S(inputs(p), outputs(p))
+	with {
+	  // degenerated processor with no outputs
+		S(n,0) = !,! : 0,0; 		// just in case, probably a rare case
+
+	  // processors with no inputs
+		S(0,1) = !,! : p <: _,_; 	// add two fake inputs and split output
+		S(0,2) = !,! : p;
+		S(0,n) = !,! : p,p :> _,_;	// we are sure this will work if n is odd
+ 
+	  // processors with one input
+		S(1,1) = p,p; 				// add two fake inputs and split output
+		S(1,n) = p,p :> _,_;		// we are sure this will work if n is odd
+ 
+	  // processors with two inputs
+		S(2,1) = p <: _,_; 			// split the output
+		S(2,2) = p; 				// nothing to do, p is already stereo
+ 
+	  // processors with inputs > 2 and outputs > 2
+		S(n,m) = _,_ <: p,p :> _,_;	// we are sure this works if n or p are odd
+	};
+
+
+//----------------------------------Recursivize------------------------------
+// Create a recursion from two arbitrary processors p and q 
+//-----------------------------------------------------------------------
+recursivize(p,q) = (_,_,_,_ :> stereoize(p)) ~ stereoize(q);
+
+
+//----------------------------------Automat------------------------------
+// Record and replay to the values the input signal in a loop
+//
+// USAGE: hslider(...) : automat(360, 15, 0.0)
+//-----------------------------------------------------------------------
+
+automat(bps, size, init, input) = rwtable(size+1, init, windex, input, rindex)
+	with {
+		clock 	= beat(bps);
+		rindex 	= int(clock) : (+ : %(size)) ~ _;		// each clock read the next entry of the table
+		windex 	= if (timeToRenew, rindex, size);		// we ignore input unless it is time to renew
+		if(cond,thn,els) = select2(cond,els,thn);
+		timeToRenew 	= int(clock) & (inputHasMoved | (input <= init));	
+		inputHasMoved 	= abs(input-input') : countfrom(int(clock)') : >(0);
+		countfrom(reset) = (+ : if(reset, 0, _)) ~ _;
+	};
+
+
+//----------------------------------bsmooth------------------------------
+// bsmooth : (block smooth) linear interpolation during a block of samples
+//
+// USAGE: hslider(...) : bsmooth
+//-----------------------------------------------------------------------
+
+bsmooth(c) = +(i) ~ _
+	with { 
+		i = (c-c at n)/n;
+		n = min(4096, max(1, fvariable(int count, <math.h>)));
+	};
+
+
+//--------------------------------chebychev-------------------------------
+// chebychev(n) : chebychev transformation of order n
+// USAGE: _ : chebychev(3) : _
+//
+//
+// Semantics:
+//	T[0](x) = 1,
+//	T[1](x) = x,
+//	T[n](x) = 2x*T[n-1](x) - T[n-2](x)
+//
+//	see : http://en.wikipedia.org/wiki/Chebyshev_polynomial
+//-------------------------------------------------------------------------
+
+chebychev(0) = !:1;
+chebychev(1) = _;
+chebychev(n) = _ <: *(2)*chebychev(n-1)-chebychev(n-2);
+
+
+
+//--------------------------------chebychevpoly-------------------------------
+//	chebychevpoly((c0,c1,...,cn)) : linear combination of the first Chebyshev polynomials
+// 	USAGE: _ : chebychevpoly((0.1,0.8,0.1)) : _
+//
+//
+// Semantics:
+// 	chebychevpoly((c0,c1,...,cn)) = Sum of chebychev(i)*ci
+//  see : http://www.csounds.com/manual/html/chebyshevpoly.html
+//-------------------------------------------------------------------------
+
+chebychevpoly(lcoef) = _ <: L(0,lcoef) :> _
+	with {
+		L(n,(c,cs)) = chebychev(n)*c, L(n+1,cs);
+		L(n,c)      = chebychev(n)*c;
+	};
 
diff --git a/architecture/netjack-console.cpp b/architecture/netjack-console.cpp
new file mode 100644
index 0000000..dd4a177
--- /dev/null
+++ b/architecture/netjack-console.cpp
@@ -0,0 +1,147 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <iostream>
+#include <cmath>
+
+
+#include "faust/misc.h"
+#include "faust/gui/FUI.h"
+#include "faust/gui/console.h"
+#include "faust/gui/GUI.h"
+#include "faust/audio/netjack-dsp.h"
+
+#ifdef OSCCTRL
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+/**************************BEGIN USER SECTION **************************/
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+mydsp DSP;
+std::list<GUI*>     GUI::fGuiList;
+
+//-------------------------------------------------------------------------
+// 									MAIN
+//-------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+    char appname[256];
+    char rcfilename[256];
+    char* home = getenv("HOME");
+
+    int	celt = lopt(argv, "--celt", -1);
+    const char* master_ip = lopts(argv, "--a", DEFAULT_MULTICAST_IP);
+    int master_port = lopt(argv, "--p", DEFAULT_PORT);
+    int mtu = lopt(argv, "--m", DEFAULT_MTU);
+    int latency = lopt(argv, "--l", 2);
+
+    snprintf(appname, 255, "%s", basename(argv[0]));
+    snprintf(rcfilename, 255, "%s/.%src", home, appname);
+
+    CMDUI* interface = new CMDUI(argc, argv);
+    FUI* finterface	= new FUI();
+    DSP.buildUserInterface(interface);
+    DSP.buildUserInterface(finterface);
+
+#ifdef OSCCTRL
+    GUI* oscinterface = new OSCUI(appname, argc, argv);
+    DSP.buildUserInterface(oscinterface);
+#endif
+
+#ifdef HTTPCTRL
+    httpdUI* httpdinterface = new httpdUI(appname, DSP.getNumInputs(), DSP.getNumOutputs(), argc, argv);
+    DSP.buildUserInterface(httpdinterface);
+ #endif
+
+    netjackaudio audio(celt, master_ip, master_port, mtu, latency);
+    if (!audio.init(appname, &DSP)) {
+        return 0;
+    }
+    finterface->recallState(rcfilename);
+    if (!audio.start()) {
+        return 0;
+    }
+
+#ifdef HTTPCTRL
+    httpdinterface->run();
+#endif
+
+#ifdef OSCCTRL
+    oscinterface->run();
+#endif
+    interface->run();
+
+    audio.stop();
+    finterface->saveState(rcfilename);
+    
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
+    return 0;
+}
+
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/netjack-qt.cpp b/architecture/netjack-qt.cpp
index 609608c..53340d8 100644
--- a/architecture/netjack-qt.cpp
+++ b/architecture/netjack-qt.cpp
@@ -38,13 +38,17 @@
 #include <stdlib.h>
 #include <iostream>
 
-#include "gui/FUI.h"
-#include "misc.h"
-#include "gui/faustqt.h"
-#include "audio/netjack-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/faustqt.h"
+#include "faust/audio/netjack-dsp.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
 #endif
 
 /**************************BEGIN USER SECTION **************************/
@@ -59,62 +63,87 @@
 
 <<includeIntrinsic>>
 
-
 <<includeclass>>
 
 /***************************END USER SECTION ***************************/
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 
-mydsp DSP;
-
-list<GUI*> GUI::fGuiList;
+mydsp       DSP;
+std::list<GUI*>  GUI::fGuiList;
 
 //-------------------------------------------------------------------------
 // 									MAIN
 //-------------------------------------------------------------------------
 int main(int argc, char *argv[])
 {
-	char appname[256];
-	char rcfilename[256];
-	char* home = getenv("HOME");
+    char appname[256];
+    char rcfilename[256];
+    char* home = getenv("HOME");
 
     int	celt = lopt(argv, "--celt", -1);
-    char* master_ip = lopts(argv, "--a", DEFAULT_MULTICAST_IP);
+    const char* master_ip = lopts(argv, "--a", DEFAULT_MULTICAST_IP);
     int master_port = lopt(argv, "--p", DEFAULT_PORT);
-
-	snprintf(appname, 255, "%s", basename(argv[0]));
-	snprintf(rcfilename, 255, "%s/.%src", home, appname);
-
-	GUI* interface = new QTGUI(argc, argv);
-	FUI* finterface	= new FUI();
-	DSP.buildUserInterface(interface);
-	DSP.buildUserInterface(finterface);
+    int mtu = lopt(argv, "--m", DEFAULT_MTU);
+    int latency = lopt(argv, "--l", 2);
+
+    snprintf(appname, 255, "%s", basename(argv[0]));
+    snprintf(rcfilename, 255, "%s/.%src", home, appname);
+    
+    QApplication myApp(argc, argv);
+    
+    QTGUI* interface = new QTGUI();
+    FUI* finterface	= new FUI();
+    DSP.buildUserInterface(interface);
+    DSP.buildUserInterface(finterface);
+
+#ifdef HTTPCTRL
+    httpdUI* httpdinterface = new httpdUI(appname, DSP.getNumInputs(), DSP.getNumOutputs(), argc, argv);
+    DSP.buildUserInterface(httpdinterface);
+#endif
 
 #ifdef OSCCTRL
-	GUI* oscinterface = new OSCUI(appname, argc, argv);
-	DSP.buildUserInterface(oscinterface);
+    GUI* oscinterface = new OSCUI(appname, argc, argv);
+    DSP.buildUserInterface(oscinterface);
 #endif
 
-	netjackaudio audio(celt, master_ip, master_port);
-	if (!audio.init(appname, &DSP)) {
+    netjackaudio audio(celt, master_ip, master_port, mtu, latency);
+    if (!audio.init(appname, &DSP)) {
         return 0;
     }
-	finterface->recallState(rcfilename);
-	if (!audio.start()) {
+    finterface->recallState(rcfilename);
+    if (!audio.start()) {
         return 0;
     }
 
+#ifdef HTTPCTRL
+    httpdinterface->run();
+#endif
+
+#ifdef OSCCTRL
+    oscinterface->run();
+#endif
+    interface->run();
+	
+    myApp.setStyleSheet(interface->styleSheet());
+    myApp.exec();
+    interface->stop();
+    
+    audio.stop();
+    finterface->saveState(rcfilename);
+    
+   // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
 #ifdef OSCCTRL
-	oscinterface->run();
+	 delete oscinterface;
 #endif
-	interface->run();
 
-	audio.stop();
-	finterface->saveState(rcfilename);
-  	return 0;
+    return 0;
 }
 
-
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
 
diff --git a/architecture/octave.cpp b/architecture/octave.cpp
index 5d455c2..1b8a7e7 100644
--- a/architecture/octave.cpp
+++ b/architecture/octave.cpp
@@ -19,7 +19,7 @@
 // 02111-1307 USA
 //-------------------------------------------------------------------
 
-
+#include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -43,8 +43,6 @@ struct Meta : map<const char*, const char*>
 };
 
 
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
 
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
diff --git a/architecture/oscillator.lib b/architecture/oscillator.lib
index caba38d..08bf45c 100644
--- a/architecture/oscillator.lib
+++ b/architecture/oscillator.lib
@@ -1,71 +1,151 @@
 declare name "Faust Oscillator Library";
 declare author "Julius O. Smith (jos at ccrma.stanford.edu)";
 declare copyright "Julius O. Smith III";
-declare version "1.10";
+declare version "1.11";
 declare license "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license)
 
-import("music.lib");  // SR, ...
-import("filter.lib"); // wgr, nlf2, tf2
+ml = library("music.lib");  // SR, db2linear, frac, PI, noise, ...
+fl = library("filter.lib"); // wgr, nlf2, tf2, smooth, tau2pole, iir, ...
 
-//===================== Virtual Analog Oscillators ========================
+//--------------------Oscillator library for Faust--------------------------
+//
+// Virtual analog oscillators and filter-based oscillators.
+// For wavetable-based oscillators, see osc* in ./music.lib
+//
+// Low-frequency oscillators have prefix "lf_"
+// (no aliasing suppression, signal-means not necessarily zero)
 
-//------------------------ Impulse Train: imptrain ------------------------
-imptrain(freq) = sawpos(freq)<:-(mem)<0;
+//-------- LF Impulse and Pulse Trains, Square and Triangle Waves ----------
+// lf_imptrain, lf_pulsetrainpos, lf_squarewavepos, lf_squarewave, lf_trianglepos
+// ### USAGE:
+//     lf_wavetype : _
+// ### NOTES:
+// + Suffix 'pos' means the function is nonnegative, otherwise ~ zero mean
+// + All impulse and pulse trains jump to 1 at time 0
 
-//--- Pulse-Train and Square-Wave Oscillators: pulsetrainpos, squarewave[pos]
-// In all cases, the first pulse jumps to 1 at time 0.
+// Unit-amplitude low-frequency impulse train:
+lf_imptrain(freq) = lf_sawpos(freq)<:-(mem)<0; // definition below
 
-// Basic unit-amplitude nonnegative pulse train with duty cycle between 0 and 1:
-pulsetrainpos(freq,duty) = float(sawpos(freq) <= duty);
+// Unit-amplitude nonnegative LF pulse train, duty cycle between 0 and 1:
+lf_pulsetrainpos(freq,duty) = float(lf_sawpos(freq) <= duty);
+//pulsetrainpos = lf_pulsetrainpos; // for backward compatibility
 
-// Positive square wave = pulse train with 50% duty cycle:
-squarewavepos(freq) = pulsetrainpos(freq,0.5);
+// Positive LF square wave in [0,1]:
+lf_squarewavepos(freq) = lf_pulsetrainpos(freq,0.5);
+// squarewavepos = lf_squarewavepos; // for backward compatibility
 
-// Unit amplitude square wave = zero-mean pulse train with 50% duty cycle:
-squarewave(freq) = 2*squarewavepos(freq) - 1;
+// Zero-mean unit-amplitude LF square wave:
+lf_squarewave(freq) = 2*lf_squarewavepos(freq) - 1;
+// squarewave = lf_squarewave; // for backward compatibility
 
-//---------- Sawtooth: rawsaw, sawpos, saw1, saw2, sawtooth -------------
+// Positive unit-amplitude LF triangle wave:
+lf_trianglepos(freq) = 1-abs(saw1(freq)); // saw1 defined below
 
+//---------- LF Sawtooths: lf_rawsaw, lf_sawpos, saw1 -------------------
+//
 // Sawtooth waveform oscillators for virtual analog synthesis et al.
-// The 'simple' versions (rawsaw, sawpos, saw1), are mere samplings of
+// The 'simple' versions (lf_rawsaw, lf_sawpos, saw1), are mere samplings of
 // the ideal continuous-time ("analog") waveforms.  While simple, the
 // aliasing due to sampling is quite audible.  The differentiated
-// polynomial waveform family (saw2, 
-
-// --- rawsaw ---
+// polynomial waveform family (saw2, sawN, and derived functions)
+// do some extra processing to suppress aliasing (not audible for
+// very low fundamental frequencies).  According to Lehtonen et al.
+// (JASA 2012), the aliasing of saw2 should be inaudible at fundamental
+// frequencies below 2 kHz or so, for a 44.1 kHz sampling rate and 60 dB SPL
+// presentation level;  fundamentals 415 and below required no aliasing
+// suppression (i.e., saw1 is ok).
+
+// --- lf_rawsaw ---
 // simple sawtooth waveform oscillator between 0 and period in samples:
-rawsaw(periodsamps) = (_,periodsamps : fmod) ~ +(1.0);
+lf_rawsaw(periodsamps) = (_,periodsamps : fmod) ~ +(1.0);
 
-// --- sawpos ---
+// --- lf_sawpos ---
 // simple sawtooth waveform oscillator between 0 and 1
-sawpos(freq) = rawsaw(periodsamps) / periodsamps
+lf_sawpos(freq) = lf_rawsaw(periodsamps) / periodsamps
 with {
-  periodsamps = float(SR)/freq; // period in samples (not nec. integer)
+  periodsamps = float(ml.SR)/freq; // period in samples (not nec. integer)
 };
 
 // --- saw1 ---
 // simple sawtooth waveform oscillator between -1 and 1
-saw1(freq) = 2.0 * sawpos(freq) - 1.0; // zero-mean in [-1,1)
+saw1(freq) = 2.0 * lf_sawpos(freq) - 1.0; // zero-mean in [-1,1)
+// no lf prefix because order 1 explicit called for here
+
+//---------------- Bandlimited Sawtooth sawN, saw2, ... ------------------
+//
+// ### METHOD:
+// Differentiated Polynomial Waves (DPW) (for aliasing suppression)
+// ### REFERENCE:
+// "Alias-Suppressed Oscillators based on Differentiated Polynomial Waveforms",
+// Vesa Valimaki, Juhan Nam, Julius Smith, and Jonathan Abel,
+// IEEE Tr. Acoustics, Speech, and Language Processing (IEEE-ASLP),
+// Vol. 18, no. 5, May 2010.
+
+// --- sawN for N = 1 to 6 ---
+sawN(N,freq) = saw1 : poly(N) : D(N-1) : gate(N-1)
+with {
+  p0n = float(ml.SR)/float(freq); // period in samples
+  lfsawpos = (_,1:fmod) ~ +(1.0/p0n); // sawtooth waveform in [0,1)
+  // To introduce a phase offset here (phase in [0,1]):
+  // lfsawpos(phase) = (+(phase*(1-1')), 1 : fmod ) ~ +(1.0/p0n);
+  saw1 = 2*lfsawpos - 1; // zero-mean, amplitude +/- 1
+  poly(1,x) =  x;
+  poly(2,x) =  x*x;
+  poly(3,x) =  x*x*x - x;
+  poly(4,x) =  x*x*(x*x - 2.0);
+  poly(5,x) =  pow(x,5) - pow(x,3)*10.0/3.0 + x*7.0/3.0;
+  poly(6,x) =  pow(x,6) - 5.0*pow(x,4) + 7.0*poly(2,x);
+  diff1(x) =  (x - x')/(2.0/p0n);
+  diff(N) = seq(n,N,diff1); // N diff1s in series
+  D(0) = _;
+  D(1) = diff1/2.0;
+  D(2) = diff(2)/6.0;
+  D(3) = diff(3)/24.0;
+  D(4) = diff(4)/120.0;
+  D(5) = diff(5)/720.0;
+  gate(N) = *(1@(N)); // delayed step for blanking startup glitch
+};
+
+// --- sawNp for N = 1 to 6 ---
+// Phase offset = delay (max 8191 samples is more than one period of audio):
+sawNp(N,freq,phase) = sawN(N,freq) : @(max(0,min(8191,int(phase*ml.SR/freq))));
+
+// Special named cases:
 
-// --- saw2 ---
-// Differentiated Parabolic Wave sawtooth (less aliasing)
-// Reference: Valimaki, IEEE Signal Processing Letters, March 2005
-saw2(freq) = saw1(freq) <: * <: -(mem) : *(0.25'*SR/freq);
+// --- sawN ---
+saw2(freq) = saw1(freq) <: * <: -(mem) : *(0.25'*ml.SR/freq);
+saw3 = sawN(3); saw4 = sawN(4); saw5 = sawN(5); saw6 = sawN(6);
 
 // --- sawtooth ---
-sawtooth = saw2; // default choice
+sawtooth = saw2; // default choice for sawtooth signal - see also sawN
+
+// --- Correction-filtered versions of saw2: saw2f2, saw2f4 ----
+// The correction filter compensates "droop" near half the sampling rate.
+// See reference for sawN.
+
+saw2f2 = saw2 : cf2 with {
+  cf2 = fl.tf2(1.155704605878911, 0.745184288225518,0.040305967265900,
+        0.823765146386639, 0.117420665547108);
+};
+
+saw2f4 = saw2 : cf4 with {
+  cf4 = fl.iir((1.155727435125014, 2.285861038554662,
+        1.430915027294021, 0.290713280893317, 0.008306401748854),
+        (2.156834679164532, 1.559532244409321, 0.423036498118354,
+        0.032080681130972));
+};
 
 //-------------------------- sawtooth_demo ---------------------------
-// USAGE:  sawtooth_demo : _
+// ### USAGE:  sawtooth_demo : _
 
-sawtooth_demo = signal with { 
-  osc_group(x) = vgroup("[0] SAWTOOTH OSCILLATOR 
+sawtooth_demo = signal with {
+  osc_group(x) = vgroup("[0] SAWTOOTH OSCILLATOR
     [tooltip: See Faust's oscillator.lib for documentation and references]",x);
   knob_group(x)  = osc_group(hgroup("[1]", x));
   ampdb  = knob_group(vslider("[1] Amplitude [unit:dB] [style:knob]
     [tooltip: Sawtooth waveform amplitude]",
     -20,-120,10,0.1));
-  amp = ampdb : smooth(0.999) : db2linear;
+  amp = ampdb : ml.db2linear : fl.smooth(0.999);
   freq = knob_group(
   vslider("[2] Frequency [unit:PK] [style:knob]
     [tooltip: Sawtooth frequency as a Piano Key (PK) number (A440 = key 49)]",
@@ -80,90 +160,143 @@ sawtooth_demo = signal with {
 [tooltip: Percentange frequency-shift up or down for third detuned oscillator]",
     +0.1,-10,10,0.01));
   portamento = knob_group(
-    vslider("[5] Portamento [unit:sec] [style:knob]
+    vslider("[5] Portamento [unit:sec] [style:knob] [scale:log]
       [tooltip: Portamento (frequency-glide) time-constant in seconds]",
-      0.1,0.01,1,0.001));
-  sfreq = freq : smooth(tau2pole(portamento));
-  tone = (amp/3) * 
+      0.1,0.001,10,0.001));
+  sfreq = freq : fl.smooth(fl.tau2pole(portamento));
+  tone = (amp/3) *
     (sawtooth(sfreq) + sawtooth(sfreq*detune1) + sawtooth(sfreq*detune2));
   signal = amp * select2(ei, select2(ss, tone, pink_noise), _);
   checkbox_group(x) = knob_group(vgroup("[6] Alternate Signals",x));
-  ss = checkbox_group(checkbox("[0] 
+  ss = checkbox_group(checkbox("[0]
 [tooltip: Pink Noise (or 1/f noise) is Constant-Q Noise, meaning that it has the same total power in every octave] Pink Noise Instead (uses only Amplitude control on the left)"));
   ei = checkbox_group(checkbox(
       "[1] External Input Instead (overrides Sawtooth/Noise selection above)"));
 };
 
-// --- Correction-filtered versions of saw2: saw2f2, saw2f4 ----
-saw2f2 = saw2 : cf2 with {
-  cf2 = tf2(1.155704605878911, 0.745184288225518,0.040305967265900,
-	0.823765146386639, 0.117420665547108);
+//---------- Bandlimited Pulse, Square, and Impulse Trains -------------
+// pulsetrain[N], square[N], imptrain[N], triangle[N]
+//
+// All are zero-mean and meant to oscillate in the audio frequency range.
+// Use simpler sample-rounded lf_* versions above for LFOs.
+
+pulsetrainN(N,freq,duty) = diffdel(sawN(N,freqC),del) with {
+ // non-interpolated-delay version: diffdel(x,del) = x - x at int(del+0.5);
+ // linearly interpolated delay version (sounds good to me):
+    diffdel(x,del) = x-x at int(del)*(1-ml.frac(del))-x@(int(del)+1)*ml.frac(del);
+ // Third-order Lagrange interpolated-delay version (see filter.lib):
+ // diffdel(x,del) = x - fl.fdelay3(DELPWR2,max(1,min(DELPWR2-2,ddel)));
+ DELPWR2 = 2048; // Needs to be a power of 2 when fdelay*() used above.
+ delmax = DELPWR2-1; // arbitrary upper limit on diff delay (duty=0.5)
+ SRmax = 96000.0; // assumed upper limit on sampling rate
+ fmin = SRmax / float(2.0*delmax); // 23.4 Hz (audio freqs only)
+ freqC = max(freq,fmin); // clip frequency at lower limit
+ period = (float(ml.SR) / freqC); // actual period
+ ddel = duty * period; // desired delay
+ del = max(0,min(delmax,ddel));
 };
+pulsetrain = pulsetrainN(2);
 
-saw2f4 = saw2 : cf4 with {
-  cf4 = iir((1.155727435125014, 2.285861038554662,
-	1.430915027294021, 0.290713280893317, 0.008306401748854),
-	(2.156834679164532, 1.559532244409321, 0.423036498118354,
-	0.032080681130972));
+squareN(N,freq) = pulsetrainN(N,freq,0.5);
+square = squareN(2);
+
+diffn(x) = x' - x; // negated first-order difference
+
+impulse = 1-1';
+imptrainN(N,freq) = impulse + 0.5*diffn(sawN(N,freq));
+imptrain = imptrainN(2); // default based on saw2
+
+triangleN(N,freq) = squareN(N,freq) : fl.pole(p) : *(gain) with {
+  gain = 4.0*freq/ml.SR; // for aproximate unit peak amplitude
+  p = 0.999;
 };
+triangle = triangleN(2); // default based on saw2
 
-// --- sawN, saw3,saw4,saw5,saw6 ---
-// Differentiated Polynomial Wave (DPW) sawtooth (progressively less aliasing)
-// Reference: 
-// "Alias-Suppressed Oscillators based on Differentiated Polynomial Waveforms",
-// Vesa Valimaki, Juhan Nam, Julius Smith, and Jonathan Abel, 
-// IEEE Tr. Acoustics, Speech, and Language Processing (IEEE-ASLP),
-// Vol. 18, no. 5, May 2010.
+//---------------------- virtual_analog_oscillator_demo ----------------------
+// ### USAGE:  virtual_analog_oscillator_demo : _
 
-sawN(N,freq) = saw1 : poly(N) : D(N-1) : gate(N-1)
-with {
-  p0n = SR/freq;
-  sawpos = (_,1:fmod) ~ +(1/p0n); // sawtooth waveform in [0,1)
-  saw1 = 2*sawpos - 1; // zero average mean, unit max amp
-  poly(2,x) =  x*x;
-  poly(3,x) =  x*x*x - x;
-  poly(4,x) =  poly(2,x)*(poly(2,x) - 2);
-  poly(5,x) =  pow(x,5) - pow(x,3)*10/3 + x*7/3;
-  poly(6,x) =  pow(x,6) - 5*pow(x,4) + 7*poly(2,x);
-  diff1(x) =  (x - x')/(2/p0n);
-  diff(N) = seq(n,N,diff1); // N diffs in series
-  D(1) = diff1/2;
-  D(2) = diff(2)/6;
-  D(3) = diff(3)/24;
-  D(4) = diff(4)/120;
-  D(5) = diff(5)/720;
-  gatedelay(n,d,x)    = x@(int(d)&(n-1)); // from music.lib
-  gate(N) = * (1 : gatedelay(8,N)); // delayed step for blanking startup glitch
+virtual_analog_oscillator_demo = signal with {
+  osc_group(x) = vgroup("[0] VIRTUAL ANALOG OSCILLATORS
+    [tooltip: See Faust's oscillator.lib for documentation and references]",x);
+
+  // Signals
+  saw = (amp/3) *
+    (sawtooth(sfreq) + sawtooth(sfreq*detune1) + sawtooth(sfreq*detune2));
+  sq = (amp/3) *
+    (square(sfreq) + square(sfreq*detune1) + square(sfreq*detune2));
+  tri = (amp/3) *
+    (triangle(sfreq) + triangle(sfreq*detune1) + triangle(sfreq*detune2));
+  pt = (amp/3) * (pulsetrain(sfreq,ptd)
+                + pulsetrain(sfreq*detune1,ptd)
+                + pulsetrain(sfreq*detune2,ptd));
+  ptN = (amp/3) * (pulsetrainN(N,sfreq,ptd)
+                + pulsetrainN(N,sfreq*detune1,ptd)
+                + pulsetrainN(N,sfreq*detune2,ptd)) with {N=3;};
+  pn = amp * pink_noise;
+
+  signal = ssaw*saw + ssq*sq + stri*tri
+           + spt*((ssptN*ptN)+(1-ssptN)*pt)
+           + spn*pn + sei*_;
+
+  // Signal controls:
+  signal_group(x) = osc_group(hgroup("[0] Signal Levels",x));
+  ssaw = signal_group(vslider("[0] Sawtooth [style:vslider]",1,0,1,0.01));
+
+  pt_group(x) = signal_group(vgroup("[1] Pulse Train",x));
+  ssptN = pt_group(checkbox("[0] Order 3
+    [tooltip: When checked, use 3rd-order aliasing suppression (up from 2)
+     See if you can hear a difference with the freq high and swept]"));
+  spt = pt_group(vslider("[1] [style:vslider]",0,0,1,0.01));
+  ptd = pt_group(vslider("[2] Duty Cycle [style:knob]",0.5,0,1,0.01))
+        : fl.smooth(0.99);
+
+  ssq = signal_group(vslider("[2] Square [style:vslider]",0,0,1,0.01));
+  stri = signal_group(vslider("[3] Triangle [style:vslider]",0,0,1,0.01));
+  spn = signal_group(vslider(
+      "[4] Pink Noise [style:vslider]
+       [tooltip: Pink Noise (or 1/f noise) is Constant-Q Noise, meaning that it has the same total power in every octave (uses only amplitude controls)]",0,0,1,0.01));
+  sei = signal_group(vslider("[5] Ext Input [style:vslider]",0,0,1,0.01));
+
+  // Signal Parameters
+  knob_group(x) = osc_group(hgroup("[1] Signal Parameters", x));
+  af_group(x) = knob_group(vgroup("[0]", x));
+  ampdb  = af_group(hslider("[1] Mix Amplitude [unit:dB] [style:hslider]
+    [tooltip: Sawtooth waveform amplitude]",
+    -20,-120,10,0.1));
+  amp = ampdb : ml.db2linear : fl.smooth(0.999);
+  freq = af_group(hslider("[2] Frequency [unit:PK] [style:hslider]
+    [tooltip: Sawtooth frequency as a Piano Key (PK) number (A440 = key 49)]",
+    49,1,88,0.01) : pianokey2hz);
+  pianokey2hz(x) = 440.0*pow(2.0, (x-49.0)/12); // piano key 49 = A440 (also defined in effect.lib)
+
+  detune1 = 1 - 0.01 * knob_group(
+    vslider("[3] Detuning 1 [unit:%%] [style:knob]
+      [tooltip: Percentange frequency-shift up or down for second oscillator]",
+      -0.1,-10,10,0.01));
+  detune2 = 1 + 0.01 * knob_group(
+    vslider("[4] Detuning 2 [unit:%%] [style:knob]
+      [tooltip: Percentange frequency-shift up or down for third detuned oscillator]",
+    +0.1,-10,10,0.01));
+  portamento = knob_group(
+    vslider("[5] Portamento [unit:sec] [style:knob] [scale:log]
+      [tooltip: Portamento (frequency-glide) time-constant in seconds]",
+      0.1,0.001,10,0.001));
+  sfreq = freq : fl.smooth(fl.tau2pole(portamento));
 };
-saw3 = sawN(3); saw4 = sawN(4); saw5 = sawN(5); saw6 = sawN(6);
 
 //----------------------- Filter-Based Oscillators ------------------------
 
-// Quick Guide (more complete documentation forthcoming):
-//
-//    USAGE: osc[b|r|rs|rc|s|w](f), where f = frequency in Hz.
-//
-//  oscb: fastest, amplitude varies with frequency, avoid dc
-//  oscr: 2nd fastest, amplitude unchanging with frequency, dc ok, 
-//        amp slowly drifts,
-//        sine and cosine outputs available (exact phase quadrature)
-// oscrs: sine output of oscr
-// oscrc: cosine output of oscr
-//  oscs: 3rd fastest, amplitude varies slightly with frequency, dc ok, 
-//        no amp drift, likely optimizable to be the fastest no-drift case
-//  oscw: 4th fastest, amplitude steady with frequency, no amp drift,
-//        sine and cosine outputs available (exact phase quadrature),
-//        numerical difficulty below 10 Hz,
-//        likely optimizable to be best (above 10 Hz) for custom silicon.
-
-impulse = 1-1'; // used to start filter-based oscillators
+// ### USAGE: osc[b|r|rs|rc|s|w](f), where f = frequency in Hz.
+// ### REFERENCES:
+//  http://lac.linuxaudio.org/2012/download/lac12-slides-jos.pdf
+//  https://ccrma.stanford.edu/~jos/pdf/lac12-paper-jos.pdf
 
 //-------------------------- oscb --------------------------------
 // Sinusoidal oscillator based on the biquad
 //
-oscb(f) = impulse : tf2(1,0,0,a1,1)
+oscb(f) = impulse : fl.tf2(1,0,0,a1,1)
 with {
-  a1 = -2*cos(2*PI*f/SR);
+  a1 = -2*cos(2*ml.PI*f/ml.SR);
 };
 
 //-------------------------- oscr --------------------------------
@@ -171,22 +304,24 @@ with {
 //  = undamped "coupled-form" resonator
 //  = lossless 2nd-order normalized ladder filter
 //
-// Reference:
+// ### Reference:
 // https://ccrma.stanford.edu/~jos/pasp/Normalized_Scattering_Junctions.html
 //
-oscrq(f) =  impulse : nlf2(f,1); // sine and cosine outputs
-oscrs(f) =  impulse : nlf2(f,1) : _,!; // sine
-oscrc(f) =  impulse : nlf2(f,1) : !,_; // cosine
-oscr = oscrs; // default = sine case
+oscrq(f) = impulse : fl.nlf2(f,1); // sine and cosine outputs
+oscrs(f) = impulse : fl.nlf2(f,1) : _,!; // sine
+oscrc(f) = impulse : fl.nlf2(f,1) : !,_; // cosine
+oscrp(f,p) = oscrq(f) : *(cos(p)), *(sin(p)) : + ; // p=0 for sine, p=PI/2 for cosine, etc.
+oscr = oscrs; // default = sine (starts without a pop)
 
 //-------------------------- oscs --------------------------------
 // Sinusoidal oscillator based on the state variable filter
 // = undamped "modified-coupled-form" resonator
+// = "magic circle" algorithm used in graphics
 //
-oscs(f) =  (*(0-1) : sint(wn) : sintp(wn,impulse)) ~ _
+oscs(f) =  (*(-1) : sint(wn) : sintp(wn,impulse)) ~ _
 with {
-  wn = 2*PI*f/SR; // approximate
-  // wn = 2*sin(PI*f/SR); // exact
+  wn = 2*ml.PI*f/ml.SR; // approximate
+  // wn = 2*sin(ml.PI*f/ml.SR); // exact
   sub(x,y) = y-x;
   sint(x) = *(x) : + ~ _ ; // frequency-scaled integrator
   sintp(x,y) = *(x) : +(y): + ~ _ ; // same + state input
@@ -200,37 +335,33 @@ with {
 // oscq  - unit-amplitude cosine and sine (quadrature) oscillator
 // oscw  - default = oscwc for maximum speed
 //
-// Reference:
+// ### Reference:
 // https://ccrma.stanford.edu/~jos/pasp/Digital_Waveguide_Oscillator.html
 //
-oscwc(fr) = impulse : wgr(fr,1) : _,!; // cosine (cheapest at 1 mpy/sample)
-oscws(fr) = impulse : wgr(fr,1) : !,_; // sine (needs a 2nd scaling mpy)
-oscq(fr)  = impulse : wgr(fr,1);       // phase quadrature outputs
+oscwc(fr) = impulse : fl.wgr(fr,1) : _,!; // cosine (cheapest at 1 mpy/sample)
+oscws(fr) = impulse : fl.wgr(fr,1) : !,_; // sine (needs a 2nd scaling mpy)
+oscq(fr)  = impulse : fl.wgr(fr,1);       // phase quadrature outputs
 oscw = oscwc;
 
 //-------------------------- oscrs_demo ---------------------------
 
-oscrs_demo = signal with { 
-  osc_group(x) = vgroup("[0] SINE WAVE OSCILLATOR oscrs 
+oscrs_demo = signal with {
+  osc_group(x) = vgroup("[0] SINE WAVE OSCILLATOR oscrs
     [tooltip: Sine oscillator based on 2D vector rotation]",x);
-  knob_group(x)  = osc_group(hgroup("[1]", x));
-//  ampdb  = knob_group(vslider("[1] Amplitude [unit:dB] [style:knob] 
-  ampdb  = knob_group(hslider("[1] Amplitude [unit:dB]
+  ampdb  = osc_group(hslider("[1] Amplitude [unit:dB]
     [tooltip: Sawtooth waveform amplitude]",
     -20,-120,10,0.1));
-  amp = ampdb : smooth(0.999) : db2linear;
-  freq = knob_group(
-//  vslider("[2] Frequency [unit:PK] [style:knob] 
+  amp = ampdb : ml.db2linear : fl.smooth(0.999);
+  freq = osc_group(
   hslider("[2] Frequency [unit:PK]
      [tooltip: Sine wave frequency as a Piano Key (PK) number (A440 = 49 PK)]",
      49,1,88,0.01) : pianokey2hz);
   pianokey2hz(x) = 440.0*pow(2.0, (x-49.0)/12); // (also defined in effect.lib)
-  portamento = knob_group(
-//    vslider("[3] Portamento [unit:sec] [style:knob] 
-    hslider("[3] Portamento [unit:sec]
+  portamento = osc_group(
+    hslider("[3] Portamento [unit:sec] [scale:log]
       [tooltip: Portamento (frequency-glide) time-constant in seconds]",
-      0.1,0,1,0.001));
-  sfreq = freq : smooth(tau2pole(portamento));
+      0.1,0.001,10,0.001));
+  sfreq = freq : fl.smooth(fl.tau2pole(portamento));
   signal = amp * oscrs(sfreq);
 };
 
@@ -239,12 +370,32 @@ oscr_demo = oscrs_demo; // synonym
 //--------------------------- pink_noise --------------------------
 // Pink noise (1/f noise) generator (third-order approximation)
 //
-// USAGE: pink_noise : _;
+// ### USAGE: pink_noise : _;
 //
-// Reference:
+// ### Reference:
 //  https://ccrma.stanford.edu/~jos/sasp/Example_Synthesis_1_F_Noise.html
 //
 
-pink_noise = noise : 
-   iir((0.049922035, -0.095993537, 0.050612699, -0.004408786),
+pink_noise = ml.noise :
+   fl.iir((0.049922035, -0.095993537, 0.050612699, -0.004408786),
                     (-2.494956002, 2.017265875, -0.522189400));
+
+//----------------------- lfnoise, lfnoise0, lfnoiseN ---------------------
+// Low-frequency noise generators
+// (Butterworth-filtered downsampled white noise)
+// Require: music.lib, filter.lib
+//
+// ### USAGE:
+//   lfnoise0(rate) : _;   // new random number every int(SR/rate) samples or so
+//   lfnoiseN(N,rate) : _; // same as "lfnoise0(rate) : lowpass(N,rate)" [see filter.lib]
+//   lfnoise(rate) : _;    // same as "lfnoise0(rate) : seq(i,5,lowpass(N,rate))" (no overshoot)
+//
+// EXAMPLES (view waveforms in faust2octave):
+//   rate = SR/100.0; // new random value every 100 samples (SR from music.lib)
+//   process = lfnoise0(rate),   // sampled/held noise (piecewise constant)
+//             lfnoiseN(3,rate), // lfnoise0 smoothed by 3rd order Butterworth LPF
+//             lfnoise(rate);    // lfnoise0 smoothed with no overshoot
+
+lfnoise0(freq) = ml.noise : fl.latch(oscrs(freq));
+lfnoiseN(N,freq) = lfnoise0(freq) : fl.lowpass(N,freq); // Nth-order Butterworth lowpass
+lfnoise(freq) = lfnoise0(freq) : seq(i,5,fl.lowpass(1,freq)); // non-overshooting lowpass
diff --git a/architecture/oscio-gtk.cpp b/architecture/oscio-gtk.cpp
index 98be588..f7f3eef 100644
--- a/architecture/oscio-gtk.cpp
+++ b/architecture/oscio-gtk.cpp
@@ -38,11 +38,11 @@
 #include <iostream>
 #include <list>
 
-#include "gui/FUI.h"
-#include "gui/faustgtk.h"
-#include "gui/OSCUI.h"
-#include "misc.h"
-#include "audio/oscdsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/gui/faustgtk.h"
+#include "faust/gui/OSCUI.h"
+#include "faust/misc.h"
+#include "faust/audio/osc-dsp.h"
 
 
 /**************************BEGIN USER SECTION **************************/
@@ -65,7 +65,7 @@
 					
 mydsp	DSP;
 
-list<GUI*>                   GUI::fGuiList;
+std::list<GUI*>                   GUI::fGuiList;
 
 /******************************************************************************
 *******************************************************************************
@@ -77,7 +77,7 @@ list<GUI*>                   GUI::fGuiList;
 int main( int argc, char *argv[] )
 {
 	char	name[256], dst[258];
-	char	rcfilename[256]; float oscio = 0;
+	char	rcfilename[256]; 
 
 	char* home = getenv("HOME");
 	snprintf(name, 255, "%s", basename(argv[0]));
@@ -105,6 +105,10 @@ int main( int argc, char *argv[] )
 	interface->run();	
 	finterface->saveState(rcfilename);
 	osca.stop();
+    
+    // desallocation
+    delete interface;
+    delete finterface;
 	delete oscinterface;
   	return 0;
 }
diff --git a/architecture/oscio-qt.cpp b/architecture/oscio-qt.cpp
index e6b6521..1abe558 100644
--- a/architecture/oscio-qt.cpp
+++ b/architecture/oscio-qt.cpp
@@ -37,11 +37,11 @@
 #include <libgen.h>
 #include <iostream>
 
-#include "gui/FUI.h"
-#include "gui/faustqt.h"
-#include "gui/OSCUI.h"
-#include "misc.h"
-#include "audio/oscdsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/gui/faustqt.h"
+#include "faust/gui/OSCUI.h"
+#include "faust/misc.h"
+#include "faust/audio/osc-dsp.h"
 
 
 /**************************BEGIN USER SECTION **************************/
@@ -64,7 +64,7 @@
 					
 mydsp	DSP;
 
-list<GUI*>               GUI::fGuiList;
+std::list<GUI*>               GUI::fGuiList;
 
 /******************************************************************************
 *******************************************************************************
@@ -76,14 +76,16 @@ list<GUI*>               GUI::fGuiList;
 int main( int argc, char *argv[] )
 {
 	char	name[256], dst[258];
-	char	rcfilename[256]; float oscio = 0;
+	char	rcfilename[256];
 
 	char* home = getenv("HOME");
 	snprintf(name, 255, "%s", basename(argv[0]));
 	snprintf(dst, 257, "/%s/", name);
 	snprintf(rcfilename, 255, "%s/.%src", home, name);
 
-	GUI* interface = new QTGUI(argc, argv);
+    QApplication myApp(argc, argv);
+    
+	QTGUI* interface = new QTGUI();
 	FUI* finterface = new FUI();
 	DSP.buildUserInterface(interface);
 	DSP.buildUserInterface(finterface);
@@ -101,8 +103,17 @@ int main( int argc, char *argv[] )
 	
 	oscinterface->run();
 	interface->run();	
+    
+    myApp.setStyleSheet(interface->styleSheet());
+    myApp.exec();
+    interface->stop();
+    
 	osca.stop();
 	finterface->saveState(rcfilename);
+    
+	// desallocation
+    delete interface;
+    delete finterface;
 	delete oscinterface;
   	return 0;
 }
diff --git a/architecture/osclib/Makefile b/architecture/osclib/Makefile
index fad6790..ecd13b1 100644
--- a/architecture/osclib/Makefile
+++ b/architecture/osclib/Makefile
@@ -6,19 +6,63 @@
 #           applications.
 #			
 ###############################################################
+VERSION=0.95
+SOVERSION=0
 
 .PHONY: all clean depend
 
+system	?= $(shell uname -s)
+
+ifeq ($(system), Darwin)
+ARCHFLAGS :=  -arch i386 -arch x86_64
+LIB_EXT = dylib
+TARGET = libOSCFaust.$(VERSION).$(LIB_EXT)
+LIB_SONAME = libOSCFaust.$(SOVERSION).$(LIB_EXT)
+else
+ARCHFLAGS := 
+ifneq ($(findstring MINGW32, $(system)),)
+LIB_EXT = dll
+TARGET = libOSCFaust-$(VERSION).$(LIB_EXT)
+LIB_SONAME = libOSCFaust-$(SOVERSION).$(LIB_EXT)
+else
+CXXFLAGS += -fPIC
+LIB_EXT = so
+TARGET = libOSCFaust.$(LIB_EXT).$(VERSION)
+LIB_SONAME = libOSCFaust.$(LIB_EXT).$(SOVERSION)
+endif
+endif
+
+LIB_NAME = libOSCFaust.$(LIB_EXT)
 
 all : liboscpack.a libOSCFaust.a
 
+dynamic : liboscpack.a $(TARGET)
+
 
 liboscpack.a : oscpack/liboscpack.a
 	cp oscpack/liboscpack.a $@
 
-libOSCFaust.a : faust/libOSCFaust.a
+libOSCFaust.a : liboscpack.a faust/libOSCFaust.a
 	cp faust/libOSCFaust.a $@
-	
+# This "links" liboscpack.a into libOSCFaust.a.
+ifeq ($(system), Darwin)
+# On Darwin, we need to use Apple's libtool here, since ar can't handle
+# archives containing more than one architecture.
+	libtool libOSCFaust.a liboscpack.a -o tmp.a && rm -f libOSCFaust.a && mv tmp.a libOSCFaust.a
+else
+# Other systems use ar. The following should work with most systems having a
+# modern ar (including GNU ar), but may need adjustments for systems with
+# older ar versions or fat binaries like on OS X.
+	(rm -Rf tmpdir && mkdir tmpdir && cd tmpdir && ar x ../liboscpack.a && ar q ../libOSCFaust.a `ar t ../liboscpack.a | grep .o` && cd .. && rm -Rf tmpdir)
+# Older ar versions might need this?
+#	ranlib $@
+endif
+
+$(TARGET) : faust/$(TARGET)
+	cp faust/$(TARGET) $@
+	ln -sf $(TARGET) $(LIB_SONAME)
+	ln -sf $(LIB_SONAME) $(LIB_NAME)
+
 	
 oscpack/liboscpack.a:
 	make -C oscpack
@@ -26,10 +70,16 @@ oscpack/liboscpack.a:
 faust/libOSCFaust.a:
 	make -C faust
 	
+faust/$(TARGET):
+	make -C faust VERSION=$(VERSION) SOVERSION=$(SOVERSION) PREFIX=$(PREFIX) MODE=SHARED
+
+ios : 
+	make -C oscpack ios
+	make -C faust ios
 	
 clean :
-	rm -f liboscpack.a 
-	rm -f libOSCFaust.a
+	rm -f liboscpack.a libOSCFaust.a
+	rm -f libOSCFaust*.dylib libOSCFaust.so* libOSCFaust*.dll
 	make -C oscpack clean
 	make -C faust clean
 
diff --git a/architecture/osclib/faust/Makefile b/architecture/osclib/faust/Makefile
index c394bcc..d11ecd2 100644
--- a/architecture/osclib/faust/Makefile
+++ b/architecture/osclib/faust/Makefile
@@ -1,4 +1,4 @@
-subprojects := include src src/lib src/msg src/nodes src/osc src/threads
+subprojects := . src src/lib src/msg src/nodes src/osc src/threads ../..
 sources = $(wildcard src/*.cpp) $(wildcard src/*/*.cpp) 
 objects = $(sources:.cpp=.o)
 
@@ -6,76 +6,145 @@ VPATH = $(subprojects)
 
 system	?= $(shell uname -s)
 
+# Darwin/OS X: default installation name prefix for the dynamic library. This
+# defaults to the installation prefix (a fixed path) if we have one, but
+# depending on usage (plugin or executable) you may want to keep it empty or
+# use some generic prefix such as @loader_path/ instead (see below).
+
+ifneq ($(PREFIX),)
+INSTALL_PREFIX = $(PREFIX)/lib/
+endif
+
+# Here are some useful alternative options for the installation name prefix
+# (cf., e.g., https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath):
+
+# @executable_path: Useful if the dylib is distributed with an application
+# (add path relative to the main executable if needed):
+#INSTALL_PREFIX = @executable_path/
+
+# @loader_path (OS X 10.4+): Useful if the dylib is distributed with a plugin
+# (add path relative to the plugin if needed):
+#INSTALL_PREFIX = @loader_path/
+
+# @rpath (OS X 10.5+): Useful if the dylib is distributed with an application
+# which has an rpath coded into it:
+#INSTALL_PREFIX = @rpath/
+
 ifeq ($(system), Darwin)
-ARCHFLAGS :=  -arch i386 -arch x86_64
+#ARCHFLAGS :=  -arch i386 -arch x86_64
 else
 ARCHFLAGS := 
+ifeq ($(findstring MINGW32, $(system)),)
+CXXFLAGS += -fPIC
+endif
 endif
 
+ifeq ($(MODE), SHARED)
+ifeq ($(system), Darwin)
+TARGET=libOSCFaust.$(VERSION).dylib
+SONAME=libOSCFaust.$(SOVERSION).dylib
+ifneq ($(INSTALL_PREFIX),)
+INSTALL_NAME = -install_name "$(INSTALL_PREFIX)$(SONAME)"
+endif
+else
+ifneq ($(findstring MINGW32, $(system)),)
+TARGET=libOSCFaust-$(VERSION).dll
+SONAME=libOSCFaust-$(SOVERSION).dll
+else
+TARGET=libOSCFaust.so.$(VERSION)
+SONAME=libOSCFaust.so.$(SOVERSION)
+endif
+endif
+else
+TARGET=libOSCFaust.a
+endif
+
+
 CXXFLAGS ?= -O3 -Wall -Wuninitialized $(ARCHFLAGS)
 CXXFLAGS += -Wno-parentheses -I../oscpack -I../oscpack/osc $(addprefix -I, $(subprojects)) -DINSTALL_PREFIX='"$(prefix)"'
 
-all : libOSCFaust.a
+all : $(TARGET)
+
+libOSCFaust.$(VERSION).dylib : $(objects)
+	$(CXX) -dynamiclib $(INSTALL_NAME) -compatibility_version $(SOVERSION) -current_version $(VERSION) $(ARCHFLAGS) $(objects) -L.. -loscpack -o libOSCFaust.$(VERSION).dylib
+
+libOSCFaust.so.$(VERSION) : $(objects)
+	$(CXX) -shared -Wl,-soname,$(SONAME) -fPIC $(ARCHFLAGS) $(objects) -L.. -loscpack -o libOSCFaust.so.$(VERSION)
+
+libOSCFaust-$(VERSION).dll : $(objects)
+	$(CXX) -shared $(ARCHFLAGS) $(objects) -L.. -loscpack -lwsock32 -lws2_32 -lwinmm -o libOSCFaust-$(VERSION).dll
 
 libOSCFaust.a : $(objects)
 	rm -f $@
 	ar cq $@ $(objects)
 	ranlib $@
 	
+
+ios: IPHONEOS_DEPLOYMENT_TARGET=5.0
+ios: CXX = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ 
+ios: CXXFLAGS += -std=c++11 -stdlib=libstdc++ -arch armv7 -arch armv7s -arch arm64 -pipe -O3 -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk
+ios: CXXFLAGS += -fvisibility=hidden -Wno-overloaded-virtual -Wno-parentheses $(addprefix -I, $(subprojects)) -DINSTALL_PREFIX='"$(prefix)"' 
+
+ios : libOSCFaust.a 
 	
 depend :
 	makedepend -fMakefile -w120 -Y -- $(CXXFLAGS) -- $(sources)
 	
 clean :
 	rm -f $(objects)
-	rm -f libOSCFaust.a
+	rm -f libOSCFaust.a libOSCFaust*.dylib libOSCFaust.so* libOSCFaust*.dll
 	
 
 
 # DO NOT DELETE
 
-src/OSCControler.o: include/OSCControler.h src/nodes/FaustFactory.h src/nodes/MessageDriven.h
-src/OSCControler.o: src/msg/MessageProcessor.h src/lib/smartpointer.h src/osc/OSCSetup.h src/osc/OSCStream.h
+src/OSCControler.o: faust/OSCControler.h faust/osc/FaustFactory.h faust/osc/FaustNode.h faust/osc/MessageDriven.h
+src/OSCControler.o: faust/osc/MessageProcessor.h faust/osc/smartpointer.h faust/osc/Message.h ../../faust/gui/GUI.h
+src/OSCControler.o: ../../faust/gui/UI.h faust/OSCIO.h src/osc/OSCSetup.h src/osc/OSCStream.h
 src/OSCControler.o: ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h
 src/OSCControler.o: ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h
-src/OSCControler.o: src/lib/OSCFError.h src/nodes/RootNode.h include/OSCIO.h
+src/OSCControler.o: src/lib/OSCFError.h src/nodes/RootNode.h src/lib/OSCRegexp.h src/lib/deelx.h
 src/lib/OSCFError.o: src/lib/OSCFError.h src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h
 src/lib/OSCFError.o: ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h ../oscpack/ip/UdpSocket.h
-src/lib/OSCFError.o: ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h src/msg/Message.h
-src/lib/OSCFError.o: src/lib/smartpointer.h
+src/lib/OSCFError.o: ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h faust/osc/Message.h
+src/lib/OSCFError.o: faust/osc/smartpointer.h
 src/lib/OSCRegexp.o: src/lib/OSCRegexp.h src/lib/deelx.h
-src/msg/Message.o: src/msg/Message.h src/lib/smartpointer.h src/lib/OSCFError.h src/osc/OSCStream.h
+src/msg/Message.o: faust/osc/Message.h faust/osc/smartpointer.h src/lib/OSCFError.h src/osc/OSCStream.h
 src/msg/Message.o: ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h
 src/msg/Message.o: ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h
-src/nodes/FaustFactory.o: src/nodes/FaustFactory.h src/nodes/MessageDriven.h src/msg/MessageProcessor.h
-src/nodes/FaustFactory.o: src/lib/smartpointer.h src/nodes/FaustNode.h src/nodes/RootNode.h src/osc/OSCAddress.h
-src/nodes/FaustNode.o: src/nodes/FaustNode.h src/nodes/MessageDriven.h src/msg/MessageProcessor.h
-src/nodes/FaustNode.o: src/lib/smartpointer.h src/msg/Message.h src/osc/OSCStream.h
-src/nodes/FaustNode.o: ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h
-src/nodes/FaustNode.o: ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h
-src/nodes/MessageDriven.o: src/msg/Message.h src/lib/smartpointer.h src/nodes/MessageDriven.h
-src/nodes/MessageDriven.o: src/msg/MessageProcessor.h src/osc/OSCAddress.h src/lib/OSCFError.h src/osc/OSCStream.h
+src/nodes/FaustFactory.o: faust/osc/FaustFactory.h faust/osc/FaustNode.h faust/osc/MessageDriven.h
+src/nodes/FaustFactory.o: faust/osc/MessageProcessor.h faust/osc/smartpointer.h faust/osc/Message.h
+src/nodes/FaustFactory.o: ../../faust/gui/GUI.h ../../faust/gui/UI.h src/nodes/RootNode.h src/osc/OSCAddress.h
+src/nodes/FaustNode.o: faust/osc/FaustNode.h faust/osc/MessageDriven.h faust/osc/MessageProcessor.h
+src/nodes/FaustNode.o: faust/osc/smartpointer.h faust/osc/Message.h ../../faust/gui/GUI.h ../../faust/gui/UI.h
+src/nodes/FaustNode.o: src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h
+src/nodes/FaustNode.o: ../oscpack/osc/OscException.h ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h
+src/nodes/FaustNode.o: ../oscpack/ip/IpEndpointName.h faust/OSCControler.h faust/osc/FaustFactory.h
+src/nodes/MessageDriven.o: faust/osc/Message.h faust/osc/smartpointer.h faust/osc/MessageDriven.h
+src/nodes/MessageDriven.o: faust/osc/MessageProcessor.h src/osc/OSCAddress.h src/lib/OSCFError.h src/osc/OSCStream.h
 src/nodes/MessageDriven.o: ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h
 src/nodes/MessageDriven.o: ../oscpack/osc/OscException.h ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h
 src/nodes/MessageDriven.o: ../oscpack/ip/IpEndpointName.h src/lib/OSCRegexp.h src/lib/deelx.h
-src/nodes/RootNode.o: src/nodes/RootNode.h src/nodes/MessageDriven.h src/msg/MessageProcessor.h src/lib/smartpointer.h
-src/nodes/RootNode.o: src/msg/Message.h src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h
-src/nodes/RootNode.o: ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h ../oscpack/ip/UdpSocket.h
-src/nodes/RootNode.o: ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h include/OSCControler.h
-src/nodes/RootNode.o: include/OSCIO.h ../oscpack/ip/NetworkingUtils.h
+src/nodes/RootNode.o: faust/OSCControler.h faust/osc/FaustFactory.h faust/osc/FaustNode.h faust/osc/MessageDriven.h
+src/nodes/RootNode.o: faust/osc/MessageProcessor.h faust/osc/smartpointer.h faust/osc/Message.h ../../faust/gui/GUI.h
+src/nodes/RootNode.o: ../../faust/gui/UI.h faust/OSCIO.h src/nodes/RootNode.h src/osc/OSCStream.h
+src/nodes/RootNode.o: ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h
+src/nodes/RootNode.o: ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h
+src/nodes/RootNode.o: ../oscpack/ip/NetworkingUtils.h
 src/osc/OSCAddress.o: src/osc/OSCAddress.h
-src/osc/OSCIO.o: include/OSCIO.h src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h
+src/osc/OSCIO.o: faust/OSCIO.h src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h
 src/osc/OSCIO.o: ../oscpack/osc/OscException.h ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h
 src/osc/OSCIO.o: ../oscpack/ip/IpEndpointName.h
-src/osc/OSCListener.o: src/osc/OSCListener.h src/lib/smartpointer.h src/msg/MessageProcessor.h
+src/osc/OSCListener.o: faust/osc/Message.h faust/osc/smartpointer.h src/osc/OSCListener.h faust/osc/MessageProcessor.h
 src/osc/OSCListener.o: ../oscpack/ip/UdpSocket.h ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h
 src/osc/OSCListener.o: ../oscpack/osc/OscPacketListener.h ../oscpack/osc/OscReceivedElements.h
 src/osc/OSCListener.o: ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h ../oscpack/ip/PacketListener.h
-src/osc/OSCListener.o: src/msg/Message.h ../oscpack/osc/OscReceivedElements.h ../oscpack/ip/IpEndpointName.h
+src/osc/OSCListener.o: src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h
+src/osc/OSCListener.o: ../oscpack/osc/OscReceivedElements.h ../oscpack/ip/IpEndpointName.h
 src/osc/OSCSetup.o: src/osc/OSCSetup.h src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h
 src/osc/OSCSetup.o: ../oscpack/osc/OscTypes.h ../oscpack/osc/OscException.h ../oscpack/ip/UdpSocket.h
 src/osc/OSCSetup.o: ../oscpack/ip/NetworkingUtils.h ../oscpack/ip/IpEndpointName.h src/threads/TThreads.h
-src/osc/OSCSetup.o: src/osc/OSCListener.h src/lib/smartpointer.h src/msg/MessageProcessor.h
+src/osc/OSCSetup.o: src/osc/OSCListener.h faust/osc/smartpointer.h faust/osc/MessageProcessor.h
 src/osc/OSCSetup.o: ../oscpack/osc/OscPacketListener.h ../oscpack/osc/OscReceivedElements.h
 src/osc/OSCSetup.o: ../oscpack/ip/PacketListener.h
 src/osc/OSCStream.o: src/osc/OSCStream.h ../oscpack/osc/OscOutboundPacketStream.h ../oscpack/osc/OscTypes.h
diff --git a/architecture/osclib/faust/changelog.txt b/architecture/osclib/faust/changelog.txt
index a92e9cb..41538b1 100644
--- a/architecture/osclib/faust/changelog.txt
+++ b/architecture/osclib/faust/changelog.txt
@@ -5,7 +5,46 @@ GRAME - Centre national de creation musicale
 http://www.grame.fr
 research at grame.fr
 ====================================================
-Copyright GRAME (c) 2011
+Copyright GRAME (c) 2011 - 2015
+
+----------------------------------------------------
+Version 0.95                           [May 26 2015]
+- a new 'get attribute' message is supported by the root node :
+'xmitfilter'
+
+----------------------------------------------------
+Version 0.94                           [Jul. 16 2014]
+- destination address can be set with the first incoming message:
+  first received packet from another host sets the destination address 
+  to this host (unless this address is not localhost)
+- runtime exception catched when opening too much sockets
+
+----------------------------------------------------
+Version 0.93                           [Nov. 13 2013]
+- 'get' message addressed to root node returns also the xmit, desthost,
+  outport and errport attributes values
+- 'get attribute' message supported by the root node
+  attribute should be one of 'desthost', 'outport', 'errport' or 'xmit'
+
+
+----------------------------------------------------
+Version 0.92                           [Nov. 8 2013]
+- new aliases management : support multiple targets 
+  for an alias including different mappings
+- OSC architecture can now be used as an OSC controler:
+  requires the support of the GUI architecture,
+  implemented in the QT architecture for the moment.
+- command line options changes:
+  -dest option is renamed -desthost (more explicit)
+  new -xmit 0 | 1 option to activate or deactivate the
+  OSC controler capability.
+- new messages supported at root level:
+  'desthost' hostname : to control the messages destination host
+  'outport' portnum : to change the OSC output port number
+  'errport' portnum : to change the OSC error port number
+  'xmit' [1 | 0] : to activate or deactivate the OSC controler capability.
+- 'get' message output change: aliases are now listed as 
+  /alias/address inmin inmax /target/address outmin outmax
 
 ----------------------------------------------------
 Version 0.91                           [Feb 25 2011]
diff --git a/architecture/osclib/faust/cmake/CMakeLists.txt b/architecture/osclib/faust/cmake/CMakeLists.txt
index 05c4d9d..cca6b69 100644
--- a/architecture/osclib/faust/cmake/CMakeLists.txt
+++ b/architecture/osclib/faust/cmake/CMakeLists.txt
@@ -8,7 +8,12 @@ set (CMAKE_CONFIGURATION_TYPES Debug Release)
 set (TARGET	OSCFaust)
 #######################################
 # versions management
-set (version 0.50)
+set (version 0.95)
+set (SOVERS 0)
+
+#######################################
+# Options disabled by default
+option ( SHARED 	"compiles a shared library" off )
 
 #######################################
 if(WIN32)
@@ -20,22 +25,16 @@ else(WIN32)
 	add_definitions(-Wall)
 endif(WIN32)
 
-if(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
-	if (${CMAKE_SYSTEM_VERSION} VERSION_LESS 9.0.0)
-		set (CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.4u.sdk)
-	else (${CMAKE_SYSTEM_VERSION} VERSION_LESS 9.0.0)
-		set (CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
-	endif (${CMAKE_SYSTEM_VERSION} VERSION_LESS 9.0.0)
 
+if(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
 	set (CMAKE_OSX_ARCHITECTURES "i386 x86_64")
-	set (CMAKE_C++_FLAGS -mmacosx-version-min=10.4)
-endif(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
+endif()
 
 #######################################
 # set directories, src and headers.
 set (ROOT 			${CMAKE_CURRENT_SOURCE_DIR}/../src)
 set (LIBDIR 		${CMAKE_CURRENT_SOURCE_DIR}/../..)
-set (SRCFOLDERS 	lib ../include msg osc nodes)
+set (SRCFOLDERS 	lib .. msg osc nodes)
 set (OSC_PATH  		"${ROOT}/../../oscpack")
 
 set(SRC ${SRC} "${ROOT}/*.cpp")						# add source files
@@ -54,12 +53,15 @@ foreach(folder ${SRCFOLDERS})
 	set(HEADERS ${HEADERS} "${ROOT}/${folder}/*.h")		# add header files
 endforeach(folder)
 set(HEADERS ${HEADERS} "${ROOT}/threads/*.h")		# add header files
+set(HEADERS ${HEADERS} "${ROOT}/../faust/*.h")		# add header files
+set(HEADERS ${HEADERS} "${ROOT}/../faust/osc/*.h")		# add header files
 file (GLOB HEADERFILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${HEADERS})
 
 foreach(folder ${SRCFOLDERS})
 	set(INCL ${INCL} "${ROOT}/${folder}")			# add include folders
 endforeach(folder)
 set(INCL ${INCL} "${ROOT}/threads")					# add other include folders
+set(INCL ${INCL} "${ROOT}/../../..")				# add faust arch include folder
 
 #######################################
 # set libraries
@@ -73,17 +75,30 @@ endif(WIN32)
 # set targets
 include_directories (${INCL} ${OSC_PATH} )
 
-add_library ( ${TARGET} STATIC ${SRCFILES} ${HEADERFILES} ${OSCPACK} )
+if(WIN32)
+  	set ( LIBS ws2_32.lib ${ROOT}/../../oscpack.lib)
+endif()
+if(UNIX)
+  	set ( LIBS -L${ROOT}/../.. -loscpack)
+endif()
+
+if (SHARED)
+	message (STATUS "Target is a shared library - Use -DSHARED=no to change.")
+	set(LIB SHARED)
+else()
+	message (STATUS "Target is a static library - Use -DSHARED=yes to change.")
+	set(LIB STATIC)
+endif()
+
+add_library ( ${TARGET} ${LIB} ${SRCFILES}  ${OSCPACK} ${HEADERFILES} )
 set_source_files_properties (${HEADERFILES} PROPERTIES HEADER_FILE_ONLY TRUE)
 set_target_properties (${TARGET} PROPERTIES 
 	VERSION ${version} 
+	SOVERSION ${SOVERS}
 	ARCHIVE_OUTPUT_DIRECTORY "${ROOT}/../.."
 	ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${ROOT}/../.."
 )
-
-if(WIN32)
-  target_link_libraries ( ${TARGET} ws2_32.lib )
-endif(WIN32)
+target_link_libraries ( ${TARGET} ${LIBS} )
 
 if (WIN32)
  set (OUTLIB "${TARGET}.lib")
diff --git a/architecture/osclib/faust/faust/OSCControler.h b/architecture/osclib/faust/faust/OSCControler.h
new file mode 100644
index 0000000..6368fe2
--- /dev/null
+++ b/architecture/osclib/faust/faust/OSCControler.h
@@ -0,0 +1,114 @@
+/*
+
+  Faust Project
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __OSCControler__
+#define __OSCControler__
+
+#include <string>
+#include "faust/osc/FaustFactory.h"
+
+class GUI;
+
+typedef void (*ErrorCallback)(void*);  
+
+namespace oscfaust
+{
+
+class OSCIO;
+class OSCSetup;
+class OSCRegexp;
+    
+//--------------------------------------------------------------------------
+/*!
+	\brief the main Faust OSC Lib API
+	
+	The OSCControler is essentially a glue between the memory representation (in charge of the FaustFactory),
+	and the network services (in charge of OSCSetup).
+*/
+class OSCControler
+{
+	int fUDPPort, fUDPOut, fUPDErr;		// the udp ports numbers
+	std::string		fDestAddress;		// the osc messages destination address, used at initialization only
+										// to collect the address from the command line
+	OSCSetup*		fOsc;				// the network manager (handles the udp sockets)
+	OSCIO*			fIO;				// hack for OSC IO support (actually only relayed to the factory)
+	FaustFactory *	fFactory;			// a factory to build the memory represetnatin
+
+    bool            fInit;
+    
+	public:
+		/*
+			base udp port is chosen in an unassigned range from IANA PORT NUMBERS (last updated 2011-01-24)
+			see at http://www.iana.org/assignments/port-numbers
+			5507-5552  Unassigned
+		*/
+		enum { kUDPBasePort = 5510};
+            
+        OSCControler (int argc, char *argv[], GUI* ui, OSCIO* io = 0, ErrorCallback errCallback = NULL, void* arg = NULL, bool init = true);
+
+        virtual ~OSCControler ();
+	
+		//--------------------------------------------------------------------------
+		// addnode, opengroup and closegroup are simply relayed to the factory
+		//--------------------------------------------------------------------------
+		// Add a node in the current group (top of the group stack)
+		template <typename T> void addnode (const char* label, T* zone, T init, T min, T max)
+							{ fFactory->addnode (label, zone, init, min, max, fInit); }
+		
+		//--------------------------------------------------------------------------
+		// This method is used for alias messages. The arguments imin and imax allow
+		// to map incomming values from the alias input range to the actual range 
+		template <typename T> void addAlias (const std::string& fullpath, T* zone, T imin, T imax, T init, T min, T max, const char* label)
+							{ fFactory->addAlias (fullpath, zone, imin, imax, init, min, max, label); }
+
+		void opengroup (const char* label)		{ fFactory->opengroup (label); }
+		void closegroup ()						{ fFactory->closegroup(); }
+	   
+		//--------------------------------------------------------------------------
+		void run ();				// starts the network services
+		void quit ();				// stop the network services
+		
+		int	getUDPPort() const			{ return fUDPPort; }
+		int	getUDPOut()	const			{ return fUDPOut; }
+		int	getUDPErr()	const			{ return fUPDErr; }
+		const char*	getDestAddress() const { return fDestAddress.c_str(); }
+		const char*	getRootName() const;	// probably useless, introduced for UI extension experiments
+
+    
+//      By default, an osc interface emits all parameters. You can filter specific params dynamically.
+        static std::vector<OSCRegexp*>     fFilteredPaths; // filtered paths will not be emitted
+        static void addFilteredPath(std::string path);
+        static bool isPathFiltered(std::string path);
+        static void resetFilteredPaths();
+    
+		static float version();				// the Faust OSC library version number
+		static const char* versionstr();	// the Faust OSC library version number as a string
+		static bool	gXmit;				// a static variable to control the transmission of values
+										// i.e. the use of the interface as a controler
+};
+
+}
+
+#endif
diff --git a/architecture/osclib/faust/include/OSCIO.h b/architecture/osclib/faust/faust/OSCIO.h
similarity index 100%
rename from architecture/osclib/faust/include/OSCIO.h
rename to architecture/osclib/faust/faust/OSCIO.h
diff --git a/architecture/osclib/faust/faust/osc/FaustFactory.h b/architecture/osclib/faust/faust/osc/FaustFactory.h
new file mode 100644
index 0000000..fa330b6
--- /dev/null
+++ b/architecture/osclib/faust/faust/osc/FaustFactory.h
@@ -0,0 +1,108 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __FaustFactory__
+#define __FaustFactory__
+
+#include <stack>
+#include <string>
+#include <sstream>
+
+#include "faust/osc/FaustNode.h"
+#include "faust/osc/smartpointer.h"
+
+class GUI;
+namespace oscfaust
+{
+
+class OSCIO;
+class RootNode;
+typedef class SMARTP<RootNode>		SRootNode;
+class MessageDriven;
+typedef class SMARTP<MessageDriven>	SMessageDriven;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a factory to build a OSC UI hierarchy
+	
+	Actually, makes use of a stack to build the UI hierarchy.
+	It includes a pointer to a OSCIO controler, but just to give it to the root node.
+*/
+class FaustFactory
+{
+	std::stack<SMessageDriven>	fNodes;		///< maintains the current hierarchy level
+	SRootNode					fRoot;		///< keep track of the root node
+	OSCIO * 					fIO;		///< hack to support audio IO via OSC, actually the field is given to the root node
+	GUI *						fGUI;		///< a GUI pointer to support updateAllGuis(), required for bi-directionnal OSC
+
+	private:
+		std::string addressFirst (const std::string& address) const;
+		std::string addressTail  (const std::string& address) const;
+
+	public:
+				 FaustFactory(GUI* ui, OSCIO * io=0); // : fIO(io), fGUI(ui) {}
+		virtual ~FaustFactory(); // {}
+
+		template <typename C> void addnode (const char* label, C* zone, C init, C min, C max, bool initZone);
+		template <typename C> void addAlias (const std::string& fullpath, C* zone, C imin, C imax, C init, C min, C max, const char* label);
+		void addAlias (const char* alias, const char* address, float imin, float imax, float omin, float omax);
+		void opengroup (const char* label);
+		void closegroup ();
+
+		SRootNode		root() const; //	{ return fRoot; }
+};
+
+/**
+ * Add a node to the OSC UI tree in the current group at the top of the stack 
+ */
+template <typename C> void FaustFactory::addnode (const char* label, C* zone, C init, C min, C max, bool initZone) 
+{
+//	SMessageDriven top = fNodes.size() ? fNodes.top() : fRoot;
+	SMessageDriven top;
+	if (fNodes.size()) top = fNodes.top();
+	if (top) {
+		std::string prefix = top->getOSCAddress();
+		top->add( FaustNode<C>::create (label, zone, init, min, max, prefix.c_str(), fGUI, initZone));
+	}
+}
+
+/**
+ * Add an alias (actually stored and handled at root node level
+ */
+template <typename C> void FaustFactory::addAlias (const std::string& fullpath, C* zone, C imin, C imax, C init, C min, C max, const char* label)
+{
+	std::istringstream 	ss(fullpath);
+	std::string 		realpath; 
+
+	ss >> realpath >> imin >> imax;
+	SMessageDriven top = fNodes.top();
+	if (top ) {
+		std::string target = top->getOSCAddress() + "/" + label;
+		addAlias (realpath.c_str(), target.c_str(), float(imin), float(imax), float(min), float(max));
+	}
+}
+
+} // end namespoace
+
+#endif
diff --git a/architecture/osclib/faust/faust/osc/FaustNode.h b/architecture/osclib/faust/faust/osc/FaustNode.h
new file mode 100644
index 0000000..db55154
--- /dev/null
+++ b/architecture/osclib/faust/faust/osc/FaustNode.h
@@ -0,0 +1,113 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __FaustNode__
+#define __FaustNode__
+
+#include <string>
+#include <vector>
+
+#include "faust/osc/MessageDriven.h"
+#include "faust/osc/Message.h"
+
+#include "faust/gui/GUI.h"
+class GUI;
+
+namespace oscfaust
+{
+
+/**
+ * map (rescale) input values to output values
+ */
+template <typename C> struct mapping
+{
+//	const C fMinIn;	
+//	const C fMaxIn;
+	const C fMinOut;
+	const C fMaxOut;
+//	const C fScale;
+
+//	mapping(C imin, C imax, C omin, C omax) : fMinIn(imin), fMaxIn(imax), 
+//											fMinOut(omin), fMaxOut(omax), 
+//											fScale( (fMaxOut-fMinOut)/(fMaxIn-fMinIn) ) {}
+	mapping(C omin, C omax) : fMinOut(omin), fMaxOut(omax) {}
+//	C scale (C x) { C z = (x < fMinIn) ? fMinIn : (x > fMaxIn) ? fMaxIn : x; return fMinOut + (z - fMinIn) * fScale; }
+	C clip (C x) { return (x < fMinOut) ? fMinOut : (x > fMaxOut) ? fMaxOut : x; }
+};
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a faust node is a terminal node and represents a faust parameter controler
+*/
+template <typename C> class FaustNode : public MessageDriven, public uiItem
+{
+	mapping<C>	fMapping;
+	
+	bool	store (C val)			{ *fZone = fMapping.clip(val); return true; }
+	void	sendOSC () const;
+
+
+	protected:
+		FaustNode(const char *name, C* zone, C init, C min, C max, const char* prefix, GUI* ui, bool initZone) 
+			: MessageDriven (name, prefix), uiItem (ui, zone), fMapping(min, max)
+			{ 
+                if(initZone)
+                    *zone = init; 
+            }
+			
+		virtual ~FaustNode() {}
+
+	public:
+		typedef SMARTP<FaustNode<C> > SFaustNode;
+		static SFaustNode create (const char* name, C* zone, C init, C min, C max, const char* prefix, GUI* ui, bool initZone)	
+        { 
+            SFaustNode node = new FaustNode(name, zone, init, min, max, prefix, ui, initZone); 
+            /*
+                Since FaustNode is a subclass of uiItem, the pointer will also be kept in the GUI class, and it's desallocation will be done there.
+                So we don't want to have smartpointer logic desallocate it and we increment the refcount.
+            */
+            node->addReference(); 
+            return node; 
+        }
+
+		virtual bool	accept( const Message* msg )			///< handler for the 'accept' message
+		{
+			if (msg->size() == 1) {			// checks for the message parameters count
+											// messages with a param count other than 1 are rejected
+				int ival; float fval;
+				if (msg->param(0, fval)) return store (C(fval));				// accepts float values
+				else if (msg->param(0, ival)) return store (C(ival));	// but accepts also int values
+			}
+			return MessageDriven::accept(msg);
+		}
+
+		virtual void	get (unsigned long ipdest) const;		///< handler for the 'get' message
+		virtual void 	reflectZone()			{ sendOSC (); fCache = *fZone;}
+};
+
+
+
+} // end namespoace
+
+#endif
diff --git a/architecture/osclib/faust/faust/osc/Message.h b/architecture/osclib/faust/faust/osc/Message.h
new file mode 100644
index 0000000..efb38e3
--- /dev/null
+++ b/architecture/osclib/faust/faust/osc/Message.h
@@ -0,0 +1,259 @@
+/*
+
+  Copyright (C) 2011  Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __Message__
+#define __Message__
+
+#include <string>
+#include <vector>
+#include "faust/osc/smartpointer.h"
+
+namespace oscfaust
+{
+
+class OSCStream;
+template <typename T> class MsgParam;
+class baseparam;
+typedef SMARTP<baseparam>	Sbaseparam;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief base class of a message parameters
+*/
+class baseparam : public smartable
+{
+	public:
+		virtual ~baseparam() {}
+
+		/*!
+		 \brief utility for parameter type checking
+		*/
+		template<typename X> bool isType() const { return dynamic_cast<const MsgParam<X>*> (this) != 0; }
+		/*!
+		 \brief utility for parameter convertion
+		 \param errvalue the returned value when no conversion applies
+		 \return the parameter value when the type matches
+		*/
+		template<typename X> X	value(X errvalue) const 
+			{ const MsgParam<X>* o = dynamic_cast<const MsgParam<X>*> (this); return o ? o->getValue() : errvalue; }
+		/*!
+		 \brief utility for parameter comparison
+		*/
+		template<typename X> bool	equal(const baseparam& p) const 
+			{ 
+				const MsgParam<X>* a = dynamic_cast<const MsgParam<X>*> (this); 
+				const MsgParam<X>* b = dynamic_cast<const MsgParam<X>*> (&p);
+				return a && b && (a->getValue() == b->getValue());
+			}
+		/*!
+		 \brief utility for parameter comparison
+		*/
+		bool operator==(const baseparam& p) const 
+			{ 
+				return equal<float>(p) || equal<int>(p) || equal<std::string>(p);
+			}
+		bool operator!=(const baseparam& p) const
+			{ 
+				return !equal<float>(p) && !equal<int>(p) && !equal<std::string>(p);
+			}
+			
+		virtual SMARTP<baseparam> copy() const = 0;
+};
+
+//--------------------------------------------------------------------------
+/*!
+	\brief template for a message parameter
+*/
+template <typename T> class MsgParam : public baseparam
+{
+	T fParam;
+	public:
+				 MsgParam(T val) : fParam(val)	{}
+		virtual ~MsgParam() {}
+		
+		T	getValue() const { return fParam; }
+		
+		virtual SMARTP<baseparam> copy() const { return new MsgParam<T>(fParam); }
+};
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a message description
+	
+	A message is composed of an address (actually an OSC address),
+	a message string that may be viewed as a method name
+	and a list of message parameters.
+*/
+class Message
+{
+	public:
+		typedef SMARTP<baseparam>		argPtr;		///< a message argument ptr type
+		typedef std::vector<argPtr>		argslist;	///< args list type
+
+	private:
+		unsigned long	fSrcIP;			///< the message source IP number
+		std::string	fAddress;			///< the message osc destination address
+		argslist	fArguments;			///< the message arguments
+	
+	public:
+			/*!
+				\brief an empty message constructor
+			*/
+			 Message() {}
+			/*!
+				\brief a message constructor
+				\param address the message destination address
+			*/
+			 Message(const std::string& address) : fAddress(address) {}
+			/*!
+				\brief a message constructor
+				\param address the message destination address
+				\param args the message parameters
+			*/
+			 Message(const std::string& address, const argslist& args) 
+				: fAddress(address), fArguments(args) {}
+			/*!
+				\brief a message constructor
+				\param msg a message
+			*/
+			 Message(const Message& msg);
+	virtual ~Message() {} //{ freed++; std::cout << "running messages: " << (allocated - freed) << std::endl; }
+
+	/*!
+		\brief adds a parameter to the message
+		\param val the parameter
+	*/
+	template <typename T> void add(T val)	{ fArguments.push_back(new MsgParam<T>(val)); }
+	/*!
+		\brief adds a float parameter to the message
+		\param val the parameter value
+	*/
+	void	add(float val)					{ add<float>(val); }
+	/*!
+		\brief adds an int parameter to the message
+		\param val the parameter value
+	*/
+	void	add(int val)					{ add<int>(val); }
+	/*!
+		\brief adds a string parameter to the message
+		\param val the parameter value
+	*/
+	void	add(const std::string& val)		{ add<std::string>(val); }
+	
+	/*!
+		\brief adds a parameter to the message
+		\param val the parameter
+	*/
+	void	add( argPtr val )				{ fArguments.push_back( val ); }
+
+	/*!
+		\brief sets the message address
+		\param addr the address
+	*/
+	void				setSrcIP(unsigned long addr)		{ fSrcIP = addr; }
+
+	/*!
+		\brief sets the message address
+		\param addr the address
+	*/
+	void				setAddress(const std::string& addr)		{ fAddress = addr; }
+	/*!
+		\brief print the message
+		\param out the output stream
+	*/
+	void				print(std::ostream& out) const;
+	/*!
+		\brief send the message to OSC
+		\param out the OSC output stream
+	*/
+	void				print(OSCStream& out) const;
+	/*!
+		\brief print message arguments
+		\param out the OSC output stream
+	*/
+	void				printArgs(OSCStream& out) const;
+
+	/// \brief gives the message address
+	const std::string&	address() const		{ return fAddress; }
+	/// \brief gives the message parameters list
+	const argslist&		params() const		{ return fArguments; }
+	/// \brief gives the message parameters list
+	argslist&			params()			{ return fArguments; }
+	/// \brief gives the message source IP 
+	unsigned long		src() const			{ return fSrcIP; }
+	/// \brief gives the message parameters count
+	int					size() const		{ return fArguments.size(); }
+	
+	bool operator == (const Message& other) const;	
+
+
+	/*!
+		\brief gives a message float parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+	*/
+	bool	param(int i, float& val) const		{ val = params()[i]->value<float>(val); return params()[i]->isType<float>(); }
+	/*!
+		\brief gives a message int parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+	*/
+	bool	param(int i, int& val) const		{ val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
+	/*!
+		\brief gives a message int parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+	*/
+	bool	param(int i, unsigned int& val) const		{ val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
+	/*!
+		\brief gives a message int parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+		\note a boolean value is handled as integer
+	*/
+	bool	param(int i, bool& val) const		{ int ival = 0; ival = params()[i]->value<int>(ival); val = ival!=0; return params()[i]->isType<int>(); }
+	/*!
+		\brief gives a message int parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+	*/
+	bool	param(int i, long int& val) const	{ val = long(params()[i]->value<int>(val)); return params()[i]->isType<int>(); }
+	/*!
+		\brief gives a message string parameter
+		\param i the parameter index (0 <= i < size())
+		\param val on output: the parameter value when the parameter type matches
+		\return false when types don't match
+	*/
+	bool	param(int i, std::string& val) const { val = params()[i]->value<std::string>(val); return params()[i]->isType<std::string>(); }
+};
+
+
+} // end namespoace
+
+#endif
diff --git a/architecture/osclib/faust/faust/osc/MessageDriven.h b/architecture/osclib/faust/faust/osc/MessageDriven.h
new file mode 100644
index 0000000..a768a8b
--- /dev/null
+++ b/architecture/osclib/faust/faust/osc/MessageDriven.h
@@ -0,0 +1,134 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+
+#ifndef __MessageDriven__
+#define __MessageDriven__
+
+#include <string>
+#include <vector>
+
+#include "faust/osc/MessageProcessor.h"
+#include "faust/osc/smartpointer.h"
+
+namespace oscfaust
+{
+
+class Message;
+class OSCRegexp;
+class MessageDriven;
+typedef class SMARTP<MessageDriven>	SMessageDriven;
+
+//--------------------------------------------------------------------------
+/*!
+	\brief a base class for objects accepting OSC messages
+	
+	Message driven objects are hierarchically organized in a tree.
+	They provides the necessary to dispatch an OSC message to its destination
+	node, according to the message OSC address. 
+	
+	The principle of the dispatch is the following:
+	- first the processMessage() method should be called on the top level node
+	- next processMessage call propose 
+	
+	
+*/
+class MessageDriven : public MessageProcessor, public smartable
+{
+	std::string						fName;			///< the node name
+	std::string						fOSCPrefix;		///< the node OSC address prefix (OSCAddress = fOSCPrefix + '/' + fName)
+	std::vector<SMessageDriven>		fSubNodes;		///< the subnodes of the current node
+
+	protected:
+				 MessageDriven(const char *name, const char *oscprefix) : fName (name), fOSCPrefix(oscprefix) {}
+		virtual ~MessageDriven() {}
+
+	public:
+		static SMessageDriven create (const char* name, const char *oscprefix)	{ return new MessageDriven(name, oscprefix); }
+
+		/*!
+			\brief OSC message processing method.
+			\param msg the osc message to be processed
+			The method should be called on the top level node.
+		*/
+		virtual void	processMessage( const Message* msg );
+
+		/*!
+			\brief propose an OSc message at a given hierarchy level.
+			\param msg the osc message currently processed
+			\param regexp a regular expression based on the osc address head
+			\param addrTail the osc address tail
+			
+			The method first tries to match the regular expression with the object name. 
+			When it matches:
+			- it calls \c accept when \c addrTail is empty 
+			- or it \c propose the message to its subnodes when \c addrTail is not empty. 
+			  In this case a new \c regexp is computed with the head of \c addrTail and a new \c addrTail as well.
+		*/
+		virtual void	propose( const Message* msg, const OSCRegexp* regexp, const std::string addrTail);
+
+		/*!
+			\brief accept an OSC message. 
+			\param msg the osc message currently processed
+			\return true when the message is processed by the node
+			
+			The method is called only for the destination nodes. The real message acceptance is the node 
+			responsability and may depend on the message content.
+		*/
+		virtual bool	accept( const Message* msg );
+
+		/*!
+			\brief handler for the \c 'get' message
+			\param ipdest the output message destination IP
+			
+			The \c 'get' message is supported by every node:
+			- it is propagated to the subnodes until it reaches terminal nodes
+			- a terminal node send its state on \c 'get' request to the IP address given as parameter.
+			The \c get method is basically called by the accept method.
+		*/
+		virtual void	get (unsigned long ipdest) const;
+
+		/*!
+			\brief handler for the \c 'get' 'attribute' message
+			\param ipdest the output message destination IP
+			\param what the requested attribute
+			
+			The \c 'get' message is supported by every node:
+			- it is propagated to the subnodes until it reaches terminal nodes
+			- a terminal node send its state on \c 'get' request to the IP address given as parameter.
+			The \c get method is basically called by the accept method.
+		*/
+		virtual void	get (unsigned long ipdest, const std::string & what) const {}
+
+		void			add ( SMessageDriven node )	{ fSubNodes.push_back (node); }
+		const char*		getName() const				{ return fName.c_str(); }
+		std::string		getOSCAddress() const;
+		int				size () const				{ return fSubNodes.size (); }
+		
+		const std::string&	name() const			{ return fName; }
+		SMessageDriven	subnode (int i) 			{ return fSubNodes[i]; }
+};
+
+} // end namespoace
+
+#endif
diff --git a/architecture/osclib/faust/src/msg/MessageProcessor.h b/architecture/osclib/faust/faust/osc/MessageProcessor.h
similarity index 100%
rename from architecture/osclib/faust/src/msg/MessageProcessor.h
rename to architecture/osclib/faust/faust/osc/MessageProcessor.h
diff --git a/architecture/osclib/faust/faust/osc/smartpointer.h b/architecture/osclib/faust/faust/osc/smartpointer.h
new file mode 100644
index 0000000..39e8bef
--- /dev/null
+++ b/architecture/osclib/faust/faust/osc/smartpointer.h
@@ -0,0 +1,139 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research at grame.fr
+
+*/
+
+#ifndef __smartpointer__
+#define __smartpointer__
+
+#include <cassert>
+
+namespace oscfaust
+{
+
+/*!
+\brief the base class for smart pointers implementation
+
+	Any object that want to support smart pointers should
+	inherit from the smartable class which provides reference counting
+	and automatic delete when the reference count drops to zero.
+*/
+class smartable {
+	private:
+		unsigned 	refCount;		
+	public:
+		//! gives the reference count of the object
+		unsigned refs() const         { return refCount; }
+		//! addReference increments the ref count and checks for refCount overflow
+		void addReference()           { refCount++; assert(refCount != 0); }
+		//! removeReference delete the object when refCount is zero		
+		void removeReference()		  { if (--refCount == 0) delete this; }
+		
+	protected:
+		smartable() : refCount(0) {}
+		smartable(const smartable&): refCount(0) {}
+		//! destructor checks for non-zero refCount
+		virtual ~smartable()    
+        { 
+            /* 
+                See "Static SFaustNode create (const char* name, C* zone, C init, C min, C max, const char* prefix, GUI* ui)" comment.
+                assert (refCount == 0); 
+            */
+         }
+		smartable& operator=(const smartable&) { return *this; }
+};
+
+/*!
+\brief the smart pointer implementation
+
+	A smart pointer is in charge of maintaining the objects reference count 
+	by the way of pointers operators overloading. It supports class 
+	inheritance and conversion whenever possible.
+\n	Instances of the SMARTP class are supposed to use \e smartable types (or at least
+	objects that implements the \e addReference and \e removeReference
+	methods in a consistent way).
+*/
+template<class T> class SMARTP {
+	private:
+		//! the actual pointer to the class
+		T* fSmartPtr;
+
+	public:
+		//! an empty constructor - points to null
+		SMARTP()	: fSmartPtr(0) {}
+		//! build a smart pointer from a class pointer
+		SMARTP(T* rawptr) : fSmartPtr(rawptr)              { if (fSmartPtr) fSmartPtr->addReference(); }
+		//! build a smart pointer from an convertible class reference
+		template<class T2> 
+		SMARTP(const SMARTP<T2>& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); }
+		//! build a smart pointer from another smart pointer reference
+		SMARTP(const SMARTP& ptr) : fSmartPtr((T*)ptr)     { if (fSmartPtr) fSmartPtr->addReference(); }
+
+		//! the smart pointer destructor: simply removes one reference count
+		~SMARTP()  { if (fSmartPtr) fSmartPtr->removeReference(); }
+		
+		//! cast operator to retrieve the actual class pointer
+		operator T*() const  { return fSmartPtr;	}
+
+		//! '*' operator to access the actual class pointer
+		T& operator*() const {
+			// checks for null dereference
+			assert (fSmartPtr != 0);
+			return *fSmartPtr;
+		}
+
+		//! operator -> overloading to access the actual class pointer
+		T* operator->() const	{ 
+			// checks for null dereference
+			assert (fSmartPtr != 0);
+			return fSmartPtr;
+		}
+
+		//! operator = that moves the actual class pointer
+		template <class T2>
+		SMARTP& operator=(T2 p1_)	{ *this=(T*)p1_; return *this; }
+
+		//! operator = that moves the actual class pointer
+		SMARTP& operator=(T* p_)	{
+			// check first that pointers differ
+			if (fSmartPtr != p_) {
+				// increments the ref count of the new pointer if not null
+				if (p_ != 0) p_->addReference();
+				// decrements the ref count of the old pointer if not null
+				if (fSmartPtr != 0) fSmartPtr->removeReference();
+				// and finally stores the new actual pointer
+				fSmartPtr = p_;
+			}
+			return *this;
+		}
+		//! operator < to support SMARTP map with Visual C++
+		bool operator<(const SMARTP<T>& p_)	const			  { return fSmartPtr < ((T *) p_); }
+		//! operator = to support inherited class reference
+		SMARTP& operator=(const SMARTP<T>& p_)                { return operator=((T *) p_); }
+		//! dynamic cast support
+		template<class T2> SMARTP& cast(T2* p_)               { return operator=(dynamic_cast<T*>(p_)); }
+		//! dynamic cast support
+		template<class T2> SMARTP& cast(const SMARTP<T2>& p_) { return operator=(dynamic_cast<T*>(p_)); }
+};
+
+}
+
+#endif
diff --git a/architecture/osclib/faust/include/OSCControler.h b/architecture/osclib/faust/include/OSCControler.h
deleted file mode 100644
index 3675cd8..0000000
--- a/architecture/osclib/faust/include/OSCControler.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-
-  Faust Project
-
-  Copyright (C) 2011 Grame
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
-  research at grame.fr
-
-*/
-
-#ifndef __OSCControler__
-#define __OSCControler__
-
-#include <string>
-
-namespace oscfaust
-{
-
-class OSCIO;
-class OSCSetup;
-class FaustFactory;
-
-//--------------------------------------------------------------------------
-/*!
-	\brief the main Faust OSC Lib API
-	
-	The OSCControler is essentially a glue between the memory representation (in charge of the FaustFactory), 
-	and the network services (in charge of OSCSetup).
-*/
-class OSCControler
-{
-	int fUDPPort, fUDPOut, fUPDErr;		// the udp ports numbers
-	std::string		fDestAddress;		// the osc messages destination address
-	FaustFactory *	fFactory;			// a factory to build the memory represetnatin
-	OSCSetup*		fOsc;				// the network manager (handles the udp sockets)
-	OSCIO*			fIO;				// hack for OSC IO support (actually only relayed to the factory)
-
-	public:
-		/*
-			base udp port is chosen in an unassigned range from IANA PORT NUMBERS (last updated 2011-01-24)
-			see at http://www.iana.org/assignments/port-numbers
-			5507-5552  Unassigned
-		*/
-		enum { kUDPBasePort = 5510};
-
-				 OSCControler (int argc, char *argv[], OSCIO* io=0);
-		virtual ~OSCControler ();
-	
-		//--------------------------------------------------------------------------
-		// addnode, opengroup and closegroup are simply relayed to the factory
-		//--------------------------------------------------------------------------
-		void addnode (const char* label, float* zone, float init, float min, float max);
-		void addfullpathnode (const std::string& fullpath, float* zone, float imin, float imax, float init, float min, float max);
-		void opengroup (const char* label);
-		void closegroup ();
-
-		//--------------------------------------------------------------------------
-		void run ();				// starts the network services
-		void quit ();				// stop the network services
-		
-		int	getUDPPort()			{ return fUDPPort; }
-		int	getUDPOut()				{ return fUDPOut; }
-		int	getUDPErr()				{ return fUPDErr; }
-		const char*	getDesAddress() { return fDestAddress.c_str(); }
-		const char*	getRootName();	// probably useless, introduced for UI extension experiments
-
-		static float version();				// the Faust OSC library version number
-		static const char* versionstr();	// the Faust OSC library version number as a string
-};
-
-}
-
-#endif
diff --git a/architecture/osclib/faust/src/OSCControler.cpp b/architecture/osclib/faust/src/OSCControler.cpp
index 0f35673..ae5802a 100644
--- a/architecture/osclib/faust/src/OSCControler.cpp
+++ b/architecture/osclib/faust/src/OSCControler.cpp
@@ -26,26 +26,36 @@
 #include <stdlib.h>
 #include <iostream>
 
-#include "OSCControler.h"
-#include "FaustFactory.h"
+#include "faust/OSCControler.h"
+#include "faust/osc/FaustFactory.h"
+#include "faust/OSCIO.h"
+
 #include "OSCSetup.h"
 #include "OSCFError.h"
 #include "RootNode.h"
-#include "OSCIO.h"
+
+#include "OSCRegexp.h"
 
 using namespace std;
 
 namespace oscfaust
 {
 
-#define kVersion	 0.91f
-#define kVersionStr	"0.91"
+#define kVersion	 0.95f
+#define kVersionStr	"0.95"
 
 static const char* kUDPPortOpt	= "-port";
 static const char* kUDPOutOpt	= "-outport";
 static const char* kUDPErrOpt	= "-errport";
-static const char* kUDPDestOpt	= "-dest";
+static const char* kUDPDestOpt	= "-desthost";
+static const char* kXmitOpt		= "-xmit";
+static const char* kXmitFilterOpt = "-xmitfilter";
+
+bool OSCControler::gXmit = false;		// a static variable to control the transmission of values
+										// i.e. the use of the interface as a controler
 
+std::vector<OSCRegexp*> OSCControler::fFilteredPaths;
+    
 //--------------------------------------------------------------------------
 // utilities for command line arguments 
 //--------------------------------------------------------------------------
@@ -69,20 +79,52 @@ static const char* getDestOption (int argc, char *argv[], const std::string& opt
 	return defaultValue;
 }
 
+static bool getXmitOption (int argc, char *argv[], const std::string& option, bool defaultValue)
+{
+	for (int i=0; i < argc-1; i++) {
+		if (option == argv[i]) {
+			int val = strtol( argv[i+1], 0, 10);
+			return val ? true : false;
+		}
+	}
+	return defaultValue;
+}
+
+static void treatXmitFilterOption (int argc, char *argv[], const std::string& option)
+{
+    for (int i = 0; i < argc-1; i++) {
+        
+        if (option == argv[i]) {
+            int j = i+1;
+            
+            while (j < argc) {
+                if (argv[j][0] == '-') {
+                    return;
+                } else {
+                    OSCControler::addFilteredPath(argv[j]);
+                }
+                j++;
+            }
+        }
+    }
+}
 
 //--------------------------------------------------------------------------
-OSCControler::OSCControler (int argc, char *argv[], OSCIO* io)
-	: fUDPPort(kUDPBasePort), fUDPOut(kUDPBasePort+1), fUPDErr(kUDPBasePort+2), fIO(io)
+OSCControler::OSCControler (int argc, char *argv[], GUI* ui, OSCIO* io, ErrorCallback errCallback, void* arg, bool init)
+	: fUDPPort(kUDPBasePort), fUDPOut(kUDPBasePort+1), fUPDErr(kUDPBasePort+2), fIO(io), fInit(init)
 {
 	fUDPPort = getPortOption (argc, argv, kUDPPortOpt, fUDPPort);
 	fUDPOut  = getPortOption (argc, argv, kUDPOutOpt, fUDPOut);
 	fUPDErr  = getPortOption (argc, argv, kUDPErrOpt, fUPDErr);
 	fDestAddress = getDestOption (argc, argv, kUDPDestOpt, "localhost");
-
-	fFactory = new FaustFactory(io);
-	fOsc = new OSCSetup();
+	gXmit = getXmitOption (argc, argv, kXmitOpt, false);
+    
+    treatXmitFilterOption(argc, argv, kXmitFilterOpt);
+ 
+	fFactory = new FaustFactory(ui, io);
+	fOsc	= new OSCSetup(errCallback, arg);
 }
-
+    
 OSCControler::~OSCControler ()
 { 
 	quit(); 
@@ -92,36 +134,7 @@ OSCControler::~OSCControler ()
 
 //--------------------------------------------------------------------------
 float OSCControler::version()				{ return kVersion; }
-const char* OSCControler::versionstr()		{ return kVersionStr; }
-
-//--------------------------------------------------------------------------
-// Add a node in the current group (top of the group stack)
-void OSCControler::addnode (const char* label, float* zone, float init, float min, float max)
-{
-	fFactory->addnode (label, zone, init, min, max);
-}
-
-//--------------------------------------------------------------------------
-// Add a node using its fullpath from the root instead of the current group
-// This method is used for alias messages. The arguments imin and imax allow
-// to map incomming values from the alias input range to the actual range 
-void OSCControler::addfullpathnode (const string& fullpath, float* zone, float imin, float imax, float init, float min, float max)
-{
-	fFactory->addfullpathnode (fullpath, zone, imin, imax, init, min, max);
-}
-
-
-//--------------------------------------------------------------------------
-void OSCControler::opengroup (const char* label)
-{
-	fFactory->opengroup (label);
-}
-
-//--------------------------------------------------------------------------
-void OSCControler::closegroup ()
-{
-	fFactory->closegroup ();
-}
+const char* OSCControler::versionstr()	{ return kVersionStr; }
 
 //--------------------------------------------------------------------------
 static std::string quote (const char* str)	{ 
@@ -135,34 +148,65 @@ static std::string quote (const char* str)	{
 // start the network services
 void OSCControler::run ()
 {
-	SMessageDriven root = fFactory->root();		// first get the root node
-	if (root) {
-		// and cast it to a RootNode
-		RootNode * rootnode = dynamic_cast<RootNode*> ((MessageDriven*)root);
+	SRootNode rootnode = fFactory->root();		// first get the root node
+	if (rootnode) {
 		// informs the root node of the udp ports numbers (required to handle the 'hello' message
-		if (rootnode) rootnode->setPorts (&fUDPPort, &fUDPOut, &fUPDErr);
+		rootnode->setPorts (&fUDPPort, &fUDPOut, &fUPDErr);
 		// starts the network services
-		fOsc->start (root, fUDPPort, fUDPOut, fUPDErr, getDesAddress());
+        
+		fOsc->start (rootnode, fUDPPort, fUDPOut, fUPDErr, getDestAddress());
 
 		// and outputs a message on the osc output port
 		oscout << OSCStart("Faust OSC version") << versionstr() << "-"
-				<< quote(root->getName()).c_str() << "is running on UDP ports "
+				<< quote(rootnode->getName()).c_str() << "is running on UDP ports "
 				<<  fUDPPort << fUDPOut << fUPDErr;
+        
+        // and also on the standard output 
+        cout << "Faust OSC version " << versionstr() << " application "
+             << quote(rootnode->getName()).c_str() << " is running on UDP ports "
+             <<  fUDPPort << ", " << fUDPOut << ", " << fUPDErr << endl;
+
 		if (fIO) oscout << " using OSC IO - in chans: " << fIO->numInputs() << " out chans: " << fIO->numOutputs();
 		oscout << OSCEnd();
-
-		// that should not occur unless a derivative changes the root node type
-		if (!rootnode) OSCFErr << root->getName() << ": is not a root node, 'hello' message won't be supported" << OSCFEndl;
 	}
 }
 
 //--------------------------------------------------------------------------
-const char*	OSCControler::getRootName()	{ return fFactory->root()->getName(); }
-
+const char*	OSCControler::getRootName()	const { return fFactory->root()->getName(); }
+
+    
+//--------------------------------------------------------------------------    
+void OSCControler::addFilteredPath(std::string path){
+        
+    OSCRegexp* regexp = new OSCRegexp(path.c_str());
+    fFilteredPaths.push_back(regexp);
+}
+    
+bool OSCControler::isPathFiltered(std::string path){
+        
+    for(size_t i=0; i<fFilteredPaths.size(); i++){
+            
+        if(fFilteredPaths[i]->match(path.c_str()))
+            return true;
+    }
+        
+    return false;
+}
+    
+void OSCControler::resetFilteredPaths(){
+    
+    for(int i=fFilteredPaths.size()-1; i>=0; i--){
+        
+        OSCRegexp* reg = fFilteredPaths[i];
+
+        fFilteredPaths.erase(fFilteredPaths.begin()+i);
+        delete reg;
+    }
+}  
 //--------------------------------------------------------------------------
 void OSCControler::quit ()
 {
 	fOsc->stop();
 }
 
-}
+} // namespace
diff --git a/architecture/osclib/faust/src/lib/OSCFError.cpp b/architecture/osclib/faust/src/lib/OSCFError.cpp
index c0e7003..428890f 100644
--- a/architecture/osclib/faust/src/lib/OSCFError.cpp
+++ b/architecture/osclib/faust/src/lib/OSCFError.cpp
@@ -20,7 +20,7 @@
 */
 
 #include "OSCFError.h"
-#include "Message.h"
+#include "faust/osc/Message.h"
 
 namespace oscfaust
 {
diff --git a/architecture/osclib/faust/src/lib/deelx.h b/architecture/osclib/faust/src/lib/deelx.h
old mode 100755
new mode 100644
diff --git a/architecture/osclib/faust/src/lib/smartpointer.h b/architecture/osclib/faust/src/lib/smartpointer.h
deleted file mode 100644
index d0f3122..0000000
--- a/architecture/osclib/faust/src/lib/smartpointer.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-
-  Copyright (C) 2011 Grame
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
-  research at grame.fr
-
-*/
-
-#ifndef __smartpointer__
-#define __smartpointer__
-
-#include <cassert>
-
-namespace oscfaust
-{
-
-/*!
-\brief the base class for smart pointers implementation
-
-	Any object that want to support smart pointers should
-	inherit from the smartable class which provides reference counting
-	and automatic delete when the reference count drops to zero.
-*/
-class smartable {
-	private:
-		unsigned 	refCount;		
-	public:
-		//! gives the reference count of the object
-		unsigned refs() const         { return refCount; }
-		//! addReference increments the ref count and checks for refCount overflow
-		void addReference()           { refCount++; assert(refCount != 0); }
-		//! removeReference delete the object when refCount is zero		
-		void removeReference()		  { if (--refCount == 0) delete this; }
-		
-	protected:
-		smartable() : refCount(0) {}
-		smartable(const smartable&): refCount(0) {}
-		//! destructor checks for non-zero refCount
-		virtual ~smartable()    { assert (refCount == 0); }
-		smartable& operator=(const smartable&) { return *this; }
-};
-
-/*!
-\brief the smart pointer implementation
-
-	A smart pointer is in charge of maintaining the objects reference count 
-	by the way of pointers operators overloading. It supports class 
-	inheritance and conversion whenever possible.
-\n	Instances of the SMARTP class are supposed to use \e smartable types (or at least
-	objects that implements the \e addReference and \e removeReference
-	methods in a consistent way).
-*/
-template<class T> class SMARTP {
-	private:
-		//! the actual pointer to the class
-		T* fSmartPtr;
-
-	public:
-		//! an empty constructor - points to null
-		SMARTP()	: fSmartPtr(0) {}
-		//! build a smart pointer from a class pointer
-		SMARTP(T* rawptr) : fSmartPtr(rawptr)              { if (fSmartPtr) fSmartPtr->addReference(); }
-		//! build a smart pointer from an convertible class reference
-		template<class T2> 
-		SMARTP(const SMARTP<T2>& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); }
-		//! build a smart pointer from another smart pointer reference
-		SMARTP(const SMARTP& ptr) : fSmartPtr((T*)ptr)     { if (fSmartPtr) fSmartPtr->addReference(); }
-
-		//! the smart pointer destructor: simply removes one reference count
-		~SMARTP()  { if (fSmartPtr) fSmartPtr->removeReference(); }
-		
-		//! cast operator to retrieve the actual class pointer
-		operator T*() const  { return fSmartPtr;	}
-
-		//! '*' operator to access the actual class pointer
-		T& operator*() const {
-			// checks for null dereference
-			assert (fSmartPtr != 0);
-			return *fSmartPtr;
-		}
-
-		//! operator -> overloading to access the actual class pointer
-		T* operator->() const	{ 
-			// checks for null dereference
-			assert (fSmartPtr != 0);
-			return fSmartPtr;
-		}
-
-		//! operator = that moves the actual class pointer
-		template <class T2>
-		SMARTP& operator=(T2 p1_)	{ *this=(T*)p1_; return *this; }
-
-		//! operator = that moves the actual class pointer
-		SMARTP& operator=(T* p_)	{
-			// check first that pointers differ
-			if (fSmartPtr != p_) {
-				// increments the ref count of the new pointer if not null
-				if (p_ != 0) p_->addReference();
-				// decrements the ref count of the old pointer if not null
-				if (fSmartPtr != 0) fSmartPtr->removeReference();
-				// and finally stores the new actual pointer
-				fSmartPtr = p_;
-			}
-			return *this;
-		}
-		//! operator < to support SMARTP map with Visual C++
-		bool operator<(const SMARTP<T>& p_)	const			  { return fSmartPtr < ((T *) p_); }
-		//! operator = to support inherited class reference
-		SMARTP& operator=(const SMARTP<T>& p_)                { return operator=((T *) p_); }
-		//! dynamic cast support
-		template<class T2> SMARTP& cast(T2* p_)               { return operator=(dynamic_cast<T*>(p_)); }
-		//! dynamic cast support
-		template<class T2> SMARTP& cast(const SMARTP<T2>& p_) { return operator=(dynamic_cast<T*>(p_)); }
-};
-
-}
-
-#endif
diff --git a/architecture/osclib/faust/src/msg/Message.cpp b/architecture/osclib/faust/src/msg/Message.cpp
index d130564..16fb532 100644
--- a/architecture/osclib/faust/src/msg/Message.cpp
+++ b/architecture/osclib/faust/src/msg/Message.cpp
@@ -26,7 +26,7 @@
 #include <iostream>
 #include <sstream>
 
-#include "Message.h"
+#include "faust/osc/Message.h"
 #include "OSCFError.h"
 
 using namespace std;
diff --git a/architecture/osclib/faust/src/msg/Message.h b/architecture/osclib/faust/src/msg/Message.h
deleted file mode 100644
index 8e4f846..0000000
--- a/architecture/osclib/faust/src/msg/Message.h
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-
-  Copyright (C) 2011  Grame
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
-  research at grame.fr
-
-*/
-
-
-#ifndef __Message__
-#define __Message__
-
-#include <string>
-#include <vector>
-#include <iostream>
-#include "smartpointer.h"
-
-namespace oscfaust
-{
-
-class OSCStream;
-template <typename T> class MsgParam;
-class baseparam;
-typedef SMARTP<baseparam>	Sbaseparam;
-
-//--------------------------------------------------------------------------
-/*!
-	\brief base class of a message parameters
-*/
-class baseparam : public smartable
-{
-	public:
-		virtual ~baseparam() {}
-
-		/*!
-		 \brief utility for parameter type checking
-		*/
-		template<typename X> bool isType() const { return dynamic_cast<const MsgParam<X>*> (this) != 0; }
-		/*!
-		 \brief utility for parameter convertion
-		 \param errvalue the returned value when no conversion applies
-		 \return the parameter value when the type matches
-		*/
-		template<typename X> X	value(X errvalue) const 
-			{ const MsgParam<X>* o = dynamic_cast<const MsgParam<X>*> (this); return o ? o->getValue() : errvalue; }
-		/*!
-		 \brief utility for parameter comparison
-		*/
-		template<typename X> bool	equal(const baseparam& p) const 
-			{ 
-				const MsgParam<X>* a = dynamic_cast<const MsgParam<X>*> (this); 
-				const MsgParam<X>* b = dynamic_cast<const MsgParam<X>*> (&p);
-				return a && b && (a->getValue() == b->getValue());
-			}
-		/*!
-		 \brief utility for parameter comparison
-		*/
-		bool operator==(const baseparam& p) const 
-			{ 
-				return equal<float>(p) || equal<int>(p) || equal<std::string>(p);
-			}
-		bool operator!=(const baseparam& p) const
-			{ 
-				return !equal<float>(p) && !equal<int>(p) && !equal<std::string>(p);
-			}
-			
-		virtual SMARTP<baseparam> copy() const = 0;
-};
-
-//--------------------------------------------------------------------------
-/*!
-	\brief template for a message parameter
-*/
-template <typename T> class MsgParam : public baseparam
-{
-	T fParam;
-	public:
-				 MsgParam(T val) : fParam(val)	{}
-		virtual ~MsgParam() {}
-		
-		T	getValue() const { return fParam; }
-		
-		virtual SMARTP<baseparam> copy() const { return new MsgParam<T>(fParam); }
-};
-
-//--------------------------------------------------------------------------
-/*!
-	\brief a message description
-	
-	A message is composed of an address (actually an OSC address),
-	a message string that may be viewed as a method name
-	and a list of message parameters.
-*/
-class Message
-{
-	public:
-		typedef SMARTP<baseparam>		argPtr;		///< a message argument ptr type
-		typedef std::vector<argPtr>		argslist;	///< args list type
-
-	private:
-		unsigned long	fSrcIP;			///< the message source IP number
-		std::string	fAddress;			///< the message osc destination address
-		argslist	fArguments;			///< the message arguments
-	
-	public:
-			/*!
-				\brief an empty message constructor
-			*/
-			 Message() {}
-			/*!
-				\brief a message constructor
-				\param address the message destination address
-			*/
-			 Message(const std::string& address) : fAddress(address) {}
-			/*!
-				\brief a message constructor
-				\param address the message destination address
-				\param args the message parameters
-			*/
-			 Message(const std::string& address, const argslist& args) 
-				: fAddress(address), fArguments(args) {}
-			/*!
-				\brief a message constructor
-				\param msg a message
-			*/
-			 Message(const Message& msg);
-	virtual ~Message() {} //{ freed++; std::cout << "running messages: " << (allocated - freed) << std::endl; }
-
-	/*!
-		\brief adds a parameter to the message
-		\param val the parameter
-	*/
-	template <typename T> void add(T val)	{ fArguments.push_back(new MsgParam<T>(val)); }
-	/*!
-		\brief adds a float parameter to the message
-		\param val the parameter value
-	*/
-	void	add(float val)					{ add<float>(val); }
-	/*!
-		\brief adds an int parameter to the message
-		\param val the parameter value
-	*/
-	void	add(int val)					{ add<int>(val); }
-	/*!
-		\brief adds a string parameter to the message
-		\param val the parameter value
-	*/
-	void	add(const std::string& val)		{ add<std::string>(val); }
-	
-	/*!
-		\brief adds a parameter to the message
-		\param val the parameter
-	*/
-	void	add( argPtr val )				{ fArguments.push_back( val ); }
-
-	/*!
-		\brief sets the message address
-		\param addr the address
-	*/
-	void				setSrcIP(unsigned long addr)		{ fSrcIP = addr; }
-
-	/*!
-		\brief sets the message address
-		\param addr the address
-	*/
-	void				setAddress(const std::string& addr)		{ fAddress = addr; }
-	/*!
-		\brief print the message
-		\param out the output stream
-	*/
-	void				print(std::ostream& out) const;
-	/*!
-		\brief send the message to OSC
-		\param out the OSC output stream
-	*/
-	void				print(OSCStream& out) const;
-	/*!
-		\brief print message arguments
-		\param out the OSC output stream
-	*/
-	void				printArgs(OSCStream& out) const;
-
-	/// \brief gives the message address
-	const std::string&	address() const		{ return fAddress; }
-	/// \brief gives the message parameters list
-	const argslist&		params() const		{ return fArguments; }
-	/// \brief gives the message parameters list
-	argslist&			params()			{ return fArguments; }
-	/// \brief gives the message source IP 
-	unsigned long		src() const			{ return fSrcIP; }
-	/// \brief gives the message parameters count
-	int					size() const		{ return fArguments.size(); }
-	
-	bool operator == (const Message& other) const;	
-
-
-	/*!
-		\brief gives a message float parameter
-		\param i the parameter index (0 <= i < size())
-		\param val on output: the parameter value when the parameter type matches
-		\return false when types don't match
-	*/
-	bool	param(int i, float& val) const		{ val = params()[i]->value<float>(val); return params()[i]->isType<float>(); }
-	/*!
-		\brief gives a message int parameter
-		\param i the parameter index (0 <= i < size())
-		\param val on output: the parameter value when the parameter type matches
-		\return false when types don't match
-	*/
-	bool	param(int i, int& val) const		{ val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
-	/*!
-		\brief gives a message int parameter
-		\param i the parameter index (0 <= i < size())
-		\param val on output: the parameter value when the parameter type matches
-		\return false when types don't match
-	*/
-	bool	param(int i, unsigned int& val) const		{ val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
-	/*!
-		\brief gives a message int parameter
-		\param i the parameter index (0 <= i < size())
-		\param val on output: the parameter value when the parameter type matches
-		\return false when types don't match
-		\note a boolean value is handled as integer
-	*/
-	bool	param(int i, bool& val) const		{ int ival = 0; ival = params()[i]->value<int>(ival); val = ival!=0; return params()[i]->isType<int>(); }
-	/*!
-		\brief gives a message int parameter
-		\param i the parameter index (0 <= i < size())
-		\param val on output: the parameter value when the parameter type matches
-		\return false when types don't match
-	*/
-	bool	param(int i, long int& val) const	{ val = long(params()[i]->value<int>(val)); return params()[i]->isType<int>(); }
-	/*!
-		\brief gives a message string parameter
-		\param i the parameter index (0 <= i < size())
-		\param val on output: the parameter value when the parameter type matches
-		\return false when types don't match
-	*/
-	bool	param(int i, std::string& val) const { val = params()[i]->value<std::string>(val); return params()[i]->isType<std::string>(); }
-};
-
-
-} // end namespoace
-
-#endif
diff --git a/architecture/osclib/faust/src/nodes/FaustFactory.cpp b/architecture/osclib/faust/src/nodes/FaustFactory.cpp
index ffab29a..b5cfde3 100644
--- a/architecture/osclib/faust/src/nodes/FaustFactory.cpp
+++ b/architecture/osclib/faust/src/nodes/FaustFactory.cpp
@@ -24,10 +24,11 @@
 #include <iostream>
 #include <sstream>
 
-#include "FaustFactory.h"
-#include "FaustNode.h"
+#include "faust/osc/FaustFactory.h"
+#include "faust/osc/FaustNode.h"
+#include "faust/osc/MessageDriven.h"
+
 #include "RootNode.h"
-#include "MessageDriven.h"
 #include "OSCAddress.h"
 
 using namespace std;
@@ -35,77 +36,8 @@ using namespace std;
 namespace oscfaust
 {
 
-
-/**
- * Add a node to the OSC UI tree in the current group at the top of the stack 
- */
-void FaustFactory::addnode (const char* label, float* zone, float init, float min, float max)
-{
-	SMessageDriven top = fNodes.size() ? fNodes.top() : fRoot;
-	if (top) {
-		string prefix = top->getOSCAddress();
-		top->add( FaustNode::create (label, zone, init, min, max, prefix.c_str()) );
-	}
-}
-
-/**
- * Add a node to the OSC UI tree using its fullpath directly from the root and bypassing the current group.
- * The argument fullpath = "/foo/fii/faa [imin [imax]]" can contain optional imin and imax values
- */
-void FaustFactory::addfullpathnode (const string& fullpath, float* zone, float imin, float imax, float init, float min, float max)
-{
-	istringstream 	ss(fullpath);
-	string 			realpath; 
-	string			remainingpath;
-	
-	// Extract realpath and optional imin and imax fields. Note that if no values for imin and imax 
-	// are specified in the fullpath string, the values passed as parameters will be used.
-	ss >> realpath >> imin >> imax;
-	// Note that realpath is prefixed before being added in the tree : /root/alias/realpath
-	SMessageDriven node = followPath(fRoot, string("/alias") + realpath, remainingpath);
-	createNodeChain(node, remainingpath, zone, imin, imax, init, min, max);
-}
-
-
-/**
- * Follows fullpath as much as possible. Return the deepest node reached and
- * the remaining path.  We have path(node)++remainingpath = fullpath
- */
-SMessageDriven FaustFactory::followPath(SMessageDriven node, const string& fullpath, string& remainingpath)
-{
-	if (fullpath.size()>0) {
-		string label = OSCAddress::addressFirst (fullpath);
-		for (int i = 0; i < node->size(); i++) {
-			if (node->subnode(i)->name() == label) {
-				return followPath(node->subnode(i), OSCAddress::addressTail(fullpath), remainingpath);
-			}
-		}
-	}
-	remainingpath = fullpath;
-	return node;
-}
-
-
-/**
- * Creates a chain of nodes starting at node and following pathtoleaf
- */
-void FaustFactory::createNodeChain(SMessageDriven node, const string& pathtoleaf, float* zone, float imin, float imax, float init, float min, float max)
-{
-	if (pathtoleaf.size() > 0) {
-		string label 	= OSCAddress::addressFirst (pathtoleaf);
-		string tail 	= OSCAddress::addressTail (pathtoleaf);
-		if (tail.size() == 0) {
-			string prefix = node->getOSCAddress();
-			node->add( FaustNode::create (label.c_str(), zone, imin, imax, init, min, max, prefix.c_str()) );
-		} else {
-			SMessageDriven group = MessageDriven::create (label.c_str(), node->getOSCAddress().c_str());
-			node->add(group);
-			createNodeChain(group, tail, zone, imin, imax, init, min, max);
-		}
-	} else {
-		cerr << "osc address too short" << endl;
-	}
-}
+FaustFactory::FaustFactory(GUI* ui, OSCIO * io) : fIO(io), fGUI(ui) {}
+FaustFactory::~FaustFactory() {}
 
 
 /**
@@ -138,6 +70,22 @@ void FaustFactory::opengroup (const char* label)
 	}
 }
 
+
+//--------------------------------------------------------------------------
+SRootNode FaustFactory::root() const	{ return fRoot; }
+
+//--------------------------------------------------------------------------
+// add an alias to the root node
+//--------------------------------------------------------------------------
+void FaustFactory::addAlias (const char* alias, const char* address, float imin, float imax, float omin, float omax)
+{
+	if (fRoot) fRoot->addAlias (alias, address, imin, imax, omin, omax);
+}
+
+//--------------------------------------------------------------------------
+std::string FaustFactory::addressFirst (const std::string& address) const	{ return OSCAddress::addressFirst(address); }
+std::string FaustFactory::addressTail  (const std::string& address) const	{ return OSCAddress::addressTail(address); }
+
 //--------------------------------------------------------------------------
 void FaustFactory::closegroup ()
 {
diff --git a/architecture/osclib/faust/src/nodes/FaustFactory.h b/architecture/osclib/faust/src/nodes/FaustFactory.h
deleted file mode 100644
index 3deb9c7..0000000
--- a/architecture/osclib/faust/src/nodes/FaustFactory.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-
-  Copyright (C) 2011 Grame
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
-  research at grame.fr
-
-*/
-
-
-#ifndef __FaustFactory__
-#define __FaustFactory__
-
-#include <stack>
-#include <string>
-
-#include "MessageDriven.h"
-
-namespace oscfaust
-{
-
-class OSCIO;
-class MessageDriven;
-typedef class SMARTP<MessageDriven>	SMessageDriven;
-
-//--------------------------------------------------------------------------
-/*!
-	\brief a factory to build a OSC UI hierarchy
-	
-	Actually, makes use of a stack to build the UI hierarchy.
-	It includes a pointer to a OSCIO controler, but just to give it to the root node.
-*/
-class FaustFactory
-{
-	std::stack<SMessageDriven>	fNodes;		///< maintains the current hierarchy level
-	SMessageDriven				fRoot;		///< keep track of the root node
-	OSCIO * 					fIO;		///< hack to support audio IO via OSC, actually the field is given to the root node
-
-	private:
-		SMessageDriven 	followPath	(SMessageDriven fRoot, const std::string& fullpath, std::string& pathtoleaf);
-		void 			createNodeChain	(SMessageDriven node, const std::string& pathtoleaf, float* zone, float imin, float imax, float init, float min, float max);
-
-	public:
-				 FaustFactory(OSCIO * io=0) : fIO(io) {}
-		virtual ~FaustFactory() {}
-
-		void addnode (const char* label, float* zone, float init, float min, float max);
-		void addfullpathnode (const std::string& fullpath, float* zone, float imin, float imax, float init, float min, float max);
-		void opengroup (const char* label);
-		void closegroup ();
-
-		SMessageDriven	root() const	{ return fRoot; }
-};
-
-} // end namespoace
-
-#endif
diff --git a/architecture/osclib/faust/src/nodes/FaustNode.cpp b/architecture/osclib/faust/src/nodes/FaustNode.cpp
index d2900b9..7b5f225 100644
--- a/architecture/osclib/faust/src/nodes/FaustNode.cpp
+++ b/architecture/osclib/faust/src/nodes/FaustNode.cpp
@@ -21,41 +21,40 @@
 
 */
 
-#include "FaustNode.h"
-#include "Message.h"
+
+#include "faust/osc/FaustNode.h"
 #include "OSCStream.h"
+#include "faust/OSCControler.h"
 
 namespace oscfaust
 {
 
 //--------------------------------------------------------------------------
-bool FaustNode::store( float val )
-{
-	*fZone = fMapping.scale(val);
-	return true;
+template<> void FaustNode<float>::sendOSC () const {
+		if (OSCControler::gXmit && !OSCControler::isPathFiltered(getOSCAddress())) oscout << OSCStart(getOSCAddress().c_str()) << 	float(*fZone) << OSCEnd();
+}
+template<> void FaustNode<double>::sendOSC () const {
+		if (OSCControler::gXmit && !OSCControler::isPathFiltered(getOSCAddress())) oscout << OSCStart(getOSCAddress().c_str()) << 	float(*fZone) << OSCEnd();
 }
 
 //--------------------------------------------------------------------------
-bool FaustNode::accept( const Message* msg )
+template<> void FaustNode<float>::get (unsigned long ipdest) const		///< handler for the 'get' message
 {
-	if (msg->size() == 1) {			// checks for the message parameters count
-									// messages with a param count other than 1 are rejected
-		int ival; float fval;
-		if (msg->param(0, fval)) return store (fval);				// accepts float values
-		else if (msg->param(0, ival)) return store (float(ival));	// but accepts also int values
-	}
-	return MessageDriven::accept(msg);
+	unsigned long savedip = oscout.getAddress();		// saves the current destination IP
+	oscout.setAddress(ipdest);							// sets the osc stream dest IP
+	// send a state message on 'get' request
+	oscout << OSCStart(getOSCAddress().c_str()) << 	float(*fZone) << float(fMapping.fMinOut) << float(fMapping.fMaxOut) << OSCEnd();
+	oscout.setAddress(savedip);							// and restores the destination IP
 }
 
-
-//--------------------------------------------------------------------------
-void FaustNode::get (unsigned long ipdest ) const
+template<> void FaustNode<double>::get (unsigned long ipdest) const		///< handler for the 'get' message
 {
 	unsigned long savedip = oscout.getAddress();		// saves the current destination IP
 	oscout.setAddress(ipdest);							// sets the osc stream dest IP
 	// send a state message on 'get' request
-	oscout << OSCStart(getOSCAddress().c_str()) << 	*fZone << fMapping.fMinOut << fMapping.fMaxOut << OSCEnd();
+	oscout << OSCStart(getOSCAddress().c_str()) << 	float(*fZone) << float(fMapping.fMinOut) << float(fMapping.fMaxOut) << OSCEnd();
 	oscout.setAddress(savedip);							// and restores the destination IP
 }
 
+
 } // end namespoace
diff --git a/architecture/osclib/faust/src/nodes/FaustNode.h b/architecture/osclib/faust/src/nodes/FaustNode.h
deleted file mode 100644
index 8dc645b..0000000
--- a/architecture/osclib/faust/src/nodes/FaustNode.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-
-  Copyright (C) 2011 Grame
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
-  research at grame.fr
-
-*/
-
-
-#ifndef __FaustNode__
-#define __FaustNode__
-
-#include <string>
-#include <vector>
-
-#include "MessageDriven.h"
-
-namespace oscfaust
-{
-
-class FaustNode;
-typedef class SMARTP<FaustNode>	SFaustNode;
-
-/**
- * map (rescale) input values to output values
- */
-struct mapping
-{
-	const float fMinIn;	
-	const float fMaxIn;
-	const float fMinOut;
-	const float fMaxOut;
-	const float fScale;
-
-	mapping(float imin, float imax, float omin, float omax) : fMinIn(imin), fMaxIn(imax), 
-											fMinOut(omin), fMaxOut(omax), 
-											fScale( (fMaxOut-fMinOut)/(fMaxIn-fMinIn) ) {}
-	float scale (float x) { float z = (x < fMinIn) ? fMinIn : (x > fMaxIn) ? fMaxIn : x; return fMinOut + (z - fMinIn) * fScale; }
-};
-
-
-//--------------------------------------------------------------------------
-/*!
-	\brief a faust node is a terminal node and represents a faust parameter controler
-*/
-class FaustNode : public MessageDriven
-{
-	float *	fZone;			// the parameter memory zone
-	mapping	fMapping;
-	
-	bool store (float val);
-
-	protected:
-		FaustNode(const char *name, float* zone, float init, float min, float max, const char* prefix) 
-			: MessageDriven (name, prefix), fZone(zone), fMapping(min, max, min, max) 
-			{ *zone = init; }
-			
-		FaustNode(const char *name, float* zone,  float imin, float imax, float init, float min, float max, const char* prefix) 
-			: MessageDriven (name, prefix), fZone(zone), fMapping(imin, imax, min, max) 
-			{ *zone = init; }
-		virtual ~FaustNode() {}
-
-	public:
-		static SFaustNode create (const char* name, float* zone, float init, float min, float max, const char* prefix)	
-							{ return new FaustNode(name, zone, init, min, max, prefix); }
-		static SFaustNode create (const char* name, float* zone, float imin, float imax, float init, float min, float max, const char* prefix)	
-							{ return new FaustNode(name, zone, imin, imax, init, min, max, prefix); }
-
-
-		virtual bool	accept( const Message* msg );			///< handler for the 'accept' message
-		virtual void	get (unsigned long ipdest) const;		///< handler for the 'get' message
-};
-
-} // end namespoace
-
-#endif
diff --git a/architecture/osclib/faust/src/nodes/MessageDriven.cpp b/architecture/osclib/faust/src/nodes/MessageDriven.cpp
index 7f9f21d..7de27f4 100644
--- a/architecture/osclib/faust/src/nodes/MessageDriven.cpp
+++ b/architecture/osclib/faust/src/nodes/MessageDriven.cpp
@@ -21,11 +21,11 @@
 
 */
 
-#include <iostream>
 #include <sstream>
 
-#include "Message.h"
-#include "MessageDriven.h"
+#include "faust/osc/Message.h"
+#include "faust/osc/MessageDriven.h"
+
 #include "OSCAddress.h"
 #include "OSCFError.h"
 #include "OSCRegexp.h"
@@ -45,38 +45,6 @@ void MessageDriven::processMessage( const Message* msg )
 	OSCRegexp r (OSCAddress::addressFirst(addr).c_str());
 	// and call propose with this regexp and with the dest osc address tail
 	propose (msg, &r, OSCAddress::addressTail (addr));
-	
-	if (addr != "/*") {
-		// search for alias root (fixme : could be stored in a field)
-		MessageDriven * aliasroot = 0;
-		for (int i=0; i<size(); i++) {
-			if (subnode(i)->name() == "alias") {
-				aliasroot = subnode(i);
-			}
-		}
-	
-		// if we have aliases in the tree
-		// we need to check if the message if for an alias address
-		if (aliasroot != 0) {
-			OSCRegexp r2 ("alias");
-			
-			if (msg->size() == 1) {
-				aliasroot->propose (msg, &r2, addr);
-			} else if (msg->size() > 1) {
-				// we simulated several messages
-				for (int i=0; i< msg->size(); i++) {
-					ostringstream 	as; as << addr << '/' << i;
-					string 			a(as.str());
-					Message 		m(a);
-					float			v;
-					
-					msg->param(i, v);
-					m.add(v);
-					aliasroot->propose (&m, &r2, a);
-				}
-			}
-		}
-	}
 }
 
 //--------------------------------------------------------------------------
@@ -101,10 +69,14 @@ void MessageDriven::get (unsigned long ipdest) const
 //--------------------------------------------------------------------------
 bool MessageDriven::accept( const Message* msg )
 {
-	string val;
+	string val, what;
+	int n = msg->size();
 	// the basic accept method only checks for the 'get' message
-	if ((msg->size() == 1) && (msg->param(0, val)) && (val == kGetMsg)) {
-		get (msg->src());
+	if ((n >= 1) && (msg->param(0, val)) && (val == kGetMsg)) {
+		if ( n == 1 )
+			get (msg->src());
+		else if (( n == 2 ) && msg->param(1, what))
+			get (msg->src(), what);
 		return true;
 	}
 	return false;
diff --git a/architecture/osclib/faust/src/nodes/MessageDriven.h b/architecture/osclib/faust/src/nodes/MessageDriven.h
deleted file mode 100644
index cb96019..0000000
--- a/architecture/osclib/faust/src/nodes/MessageDriven.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-
-  Copyright (C) 2011 Grame
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
-  research at grame.fr
-
-*/
-
-
-#ifndef __MessageDriven__
-#define __MessageDriven__
-
-#include <string>
-#include <vector>
-
-#include "MessageProcessor.h"
-#include "smartpointer.h"
-
-namespace oscfaust
-{
-
-class Message;
-class OSCRegexp;
-class MessageDriven;
-typedef class SMARTP<MessageDriven>	SMessageDriven;
-
-//--------------------------------------------------------------------------
-/*!
-	\brief a base class for objects accepting OSC messages
-	
-	Message driven objects are hierarchically organized in a tree.
-	They provides the necessary to dispatch an OSC message to its destination
-	node, according to the message OSC address. 
-	
-	The principle of the dispatch is the following:
-	- first the processMessage() method should be called on the top level node
-	- next processMessage call propose 
-	
-	
-*/
-class MessageDriven : public MessageProcessor, public smartable
-{
-	std::string						fName;			///< the node name
-	std::string						fOSCPrefix;		///< the node OSC address prefix (OSCAddress = fOSCPrefix + '/' + fName)
-	std::vector<SMessageDriven>		fSubNodes;		///< the subnodes of the current node
-
-	protected:
-				 MessageDriven(const char *name, const char *oscprefix) : fName (name), fOSCPrefix(oscprefix) {}
-		virtual ~MessageDriven() {}
-
-	public:
-		static SMessageDriven create (const char* name, const char *oscprefix)	{ return new MessageDriven(name, oscprefix); }
-
-		/*!
-			\brief OSC message processing method.
-			\param msg the osc message to be processed
-			The method should be called on the top level node.
-		*/
-		virtual void	processMessage( const Message* msg );
-
-		/*!
-			\brief propose an OSc message at a given hierarchy level.
-			\param msg the osc message currently processed
-			\param regexp a regular expression based on the osc address head
-			\param addrTail the osc address tail
-			
-			The method first tries to match the regular expression with the object name. 
-			When it matches:
-			- it calls \c accept when \c addrTail is empty 
-			- or it \c propose the message to its subnodes when \c addrTail is not empty. 
-			  In this case a new \c regexp is computed with the head of \c addrTail and a new \c addrTail as well.
-		*/
-		virtual void	propose( const Message* msg, const OSCRegexp* regexp, const std::string addrTail);
-
-		/*!
-			\brief accept an OSC message. 
-			\param msg the osc message currently processed
-			\return true when the message is processed by the node
-			
-			The method is called only for the destination nodes. The real message acceptance is the node 
-			responsability and may depend on the message content.
-		*/
-		virtual bool	accept( const Message* msg );
-
-		/*!
-			\brief handler for the \c 'get' message
-			\param ipdest the output message destination IP
-			
-			The \c 'get' message is supported by every node:
-			- it is propagated to the subnodes until it reaches terminal nodes
-			- a terminal node send its state on \c 'get' request to the IP address given as parameter.
-			The \c get method is basically called by the accept method.
-		*/
-		virtual void	get (unsigned long ipdest) const;		///< handler for the 'get' message
-
-		void			add ( SMessageDriven node )	{ fSubNodes.push_back (node); }
-		const char*		getName() const				{ return fName.c_str(); }
-		std::string		getOSCAddress() const;
-		int				size () const				{ return fSubNodes.size (); }
-		
-		const std::string&	name() const			{ return fName; }
-		SMessageDriven	subnode (int i) 			{ return fSubNodes[i]; }
-};
-
-} // end namespoace
-
-#endif
diff --git a/architecture/osclib/faust/src/nodes/RootNode.cpp b/architecture/osclib/faust/src/nodes/RootNode.cpp
index 0165c3d..96d0c9b 100644
--- a/architecture/osclib/faust/src/nodes/RootNode.cpp
+++ b/architecture/osclib/faust/src/nodes/RootNode.cpp
@@ -24,11 +24,16 @@
 #include <string>
 #include <sstream>
 
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include "faust/OSCControler.h"
+#include "faust/osc/Message.h"
+#include "faust/OSCIO.h"
+
 #include "RootNode.h"
-#include "Message.h"
 #include "OSCStream.h"
-#include "OSCControler.h"
-#include "OSCIO.h"
 
 #ifdef WIN32
 # include "winsock2.h"
@@ -41,8 +46,12 @@ using namespace std;
 namespace oscfaust
 {
 
-static const char * kHelloMsg = "hello";
-
+static const char * kHelloMsg		= "hello";
+static const char * kDestMsg		= "desthost";
+static const char * kUdpOutPortMsg	= "outport";
+static const char * kUdpErrPortMsg	= "errport";
+static const char * kXmitMsg		= "xmit";
+static const char * kXmitFilter     = "xmitfilter";
 
 //--------------------------------------------------------------------------
 // ip address utility
@@ -69,6 +78,111 @@ string getIP()
 	return ipStr.str();
 }
 
+
+//--------------------------------------------------------------------------
+void RootNode::addAlias (const char* alias, const char* address, float imin, float imax, float omin, float omax)
+{
+	aliastarget target (address, imin, imax, omin, omax);
+	fAliases[alias].push_back(target);
+}
+
+//--------------------------------------------------------------------------
+static string ip2string (unsigned long ip)
+{
+	stringstream str;
+	str << ((ip >> 24) & 0xff) << '.' << ((ip >> 16) & 0xff) << '.' << ((ip >> 8) & 0xff) << '.' << (ip & 0xff);
+	return str.str();
+}
+
+//--------------------------------------------------------------------------
+// handler for the get attribute message
+//--------------------------------------------------------------------------
+void RootNode::get (unsigned long ipdest, const std::string& what) const		///< handler for the 'get' message
+{
+	unsigned long savedip = oscout.getAddress();	// saves the current destination IP
+	oscout.setAddress(ipdest);						// sets the osc stream dest IP to the request src IP
+
+	if (what == kXmitMsg)
+		oscout << OSCStart(getOSCAddress().c_str()) << kXmitMsg << OSCControler::gXmit << OSCEnd();
+	else if (what == kDestMsg)
+		oscout << OSCStart(getOSCAddress().c_str()) << kDestMsg << ip2string(savedip) << OSCEnd();
+	else if (what == kUdpOutPortMsg)
+		oscout << OSCStart(getOSCAddress().c_str()) << kUdpOutPortMsg << oscout.getPort() << OSCEnd();
+	else if (what == kUdpErrPortMsg)
+		oscout << OSCStart(getOSCAddress().c_str()) << kUdpErrPortMsg << oscerr.getPort() << OSCEnd();
+
+	oscout.setAddress(savedip);			// restores the destination IP
+	MessageDriven::get (ipdest, what);		// and call the default behavior
+}
+
+//--------------------------------------------------------------------------
+// handler for the get message
+//--------------------------------------------------------------------------
+void RootNode::get (unsigned long ipdest) const		///< handler for the 'get' message
+{
+	unsigned long savedip = oscout.getAddress();	// saves the current destination IP
+	oscout.setAddress(ipdest);						// sets the osc stream dest IP to the request src IP
+
+	oscout << OSCStart(getOSCAddress().c_str()) << kXmitMsg << OSCControler::gXmit << OSCEnd();
+	oscout << OSCStart(getOSCAddress().c_str()) << kDestMsg << ip2string(savedip) << OSCEnd();
+	oscout << OSCStart(getOSCAddress().c_str()) << kUdpOutPortMsg << oscout.getPort() << OSCEnd();
+	oscout << OSCStart(getOSCAddress().c_str()) << kUdpErrPortMsg << oscerr.getPort() << OSCEnd();
+
+	std::map<std::string, std::vector<aliastarget> >::const_iterator i = fAliases.begin();
+	while (i != fAliases.end()) {
+		vector<aliastarget> targets = i->second;
+		for (size_t n=0; n<targets.size(); n++) {
+			// send a alias message for each target
+			const aliastarget& t = targets[n];
+			oscout << OSCStart(i->first.c_str()) << t.fMinIn << t.fMaxIn << "alias" << targets[n].fTarget.c_str() << t.fMinOut << t.fMaxOut << OSCEnd();
+		}
+		i++;
+	}
+	oscout.setAddress(savedip);			// restores the destination IP
+	MessageDriven::get (ipdest);		// and call the default behavior
+}
+
+//--------------------------------------------------------------------------
+// handling aliases
+//--------------------------------------------------------------------------
+void RootNode::processAlias (const string& address, float val)
+{
+	vector<aliastarget> targets = fAliases[address];	// retrieve the addess aliases
+	size_t n = targets.size();							// no that could point to an arbitraty number of targets
+	for (size_t i = 0; i < n; i++) {					// for each target
+		Message m(targets[i].fTarget);					// create a new message with the target address
+		m.add (targets[i].scale(val));					// add the scaled value of the value
+		MessageDriven::processMessage (&m);				// and do a regular processing of the message
+	}
+}
+
+//--------------------------------------------------------------------------
+// specific processMessage at RootNode: intended to handle aliases
+//--------------------------------------------------------------------------
+void RootNode::processMessage( const Message* msg )
+{
+	const string& addr = msg->address();
+	float v; int iv;
+	if (msg->size() == 1) {				// there is a single parameter
+		if (msg->param(0, v))			// check the parameter float value
+			processAlias (addr, v);		// and try to process as an alias
+		else if (msg->param(0, iv))		// not a float value : try with an int value
+			processAlias (addr, float(iv) );
+	}
+	else if (msg->size() > 1) {			// there are several parameters
+		// we simulated several messages, one for each value
+		for (int i=0; i< msg->size(); i++) {
+			ostringstream 	as; as << addr << '/' << i;		// compute an address in the form /address/i
+			if (msg->param(i, v))							// get the parameter float value
+				processAlias (as.str(), v);					// and try to process as an alias using the extended address
+			else if (msg->param(i, iv))						// not a float value : try with an int value
+				processAlias (as.str(), float(iv));
+		}
+	}
+	// do also a regular processing of the message
+	MessageDriven::processMessage (msg);
+}
+
 //--------------------------------------------------------------------------
 // signal data handler
 //--------------------------------------------------------------------------
@@ -102,10 +216,34 @@ bool RootNode::accept( const Message* msg )
 		hello (msg->src());
 		return true;
 	}
-	else if (MessageDriven::accept (msg))	// next checks for standard handlers ('get' for example)
+
+	if (MessageDriven::accept (msg)) {
 		return true;
-	else if (fIO)							// when still not handled and if a IO controler is set
+	} else if ((msg->size() >= 2) && (msg->param(0, val))) {
+		string str; int num;
+		if ((val == kDestMsg) && (msg->param(1, str))) {
+			oscout.setAddress(str);
+		} else if ((val == kUdpOutPortMsg) && (msg->param(1, num))) {
+			*fUDPOut = num;
+			oscout.setPort(num);
+		} else if ((val == kUdpErrPortMsg) && (msg->param(1, num))) {
+			*fUDPErr = num;
+			oscerr.setPort(num);
+		} else if ((val == kXmitMsg) && (msg->param(1, num))) {
+			OSCControler::gXmit = num ? true : false;
+        } else if (val == kXmitFilter) {
+            for (int i = 1 ; i < msg->size(); i++) {
+                msg->param(i, str);
+                OSCControler::addFilteredPath(str);
+            }
+        }
+    } else if((msg->size() == 1) && (msg->param(0, val))) { 
+        if (val == kXmitFilter) {
+            OSCControler::resetFilteredPaths();
+        }
+    } else if (fIO) {						// when still not handled and if a IO controler is set
 		return acceptSignal (msg);			// try to read signal data
+    }
 	return false;
 }
 
diff --git a/architecture/osclib/faust/src/nodes/RootNode.h b/architecture/osclib/faust/src/nodes/RootNode.h
index 0fb4b2b..14acc1e 100644
--- a/architecture/osclib/faust/src/nodes/RootNode.h
+++ b/architecture/osclib/faust/src/nodes/RootNode.h
@@ -25,10 +25,11 @@
 #ifndef __RootNode__
 #define __RootNode__
 
+#include <map>
 #include <string>
 #include <vector>
 
-#include "MessageDriven.h"
+#include "faust/osc/MessageDriven.h"
 
 namespace oscfaust
 {
@@ -37,6 +38,45 @@ class OSCIO;
 class RootNode;
 typedef class SMARTP<RootNode>	SRootNode;
 
+
+/**
+ * an alias target includes a map to rescale input values to output values
+ * and a target osc address. The input values can be given in reversed order
+ * to reverse the control
+ */
+struct aliastarget
+{
+	float       fMinIn;
+	float       fMaxIn;
+	float       fMinOut;
+	float       fMaxOut;
+	std::string fTarget;	// the real osc address
+
+	aliastarget (const char* address, float imin, float imax, float omin, float omax)
+		: fMinIn(imin), fMaxIn(imax), fMinOut(omin), fMaxOut(omax), fTarget(address) {}
+
+	aliastarget (const aliastarget& t)
+		: fMinIn(t.fMinIn), fMaxIn(t.fMaxIn), fMinOut(t.fMinOut), fMaxOut(t.fMaxOut), fTarget(t.fTarget) {}
+
+	float scale (float x) const {
+        
+        if (fMinIn < fMaxIn) {
+            // increasing control
+            float z = (x < fMinIn) ? fMinIn : (x > fMaxIn) ? fMaxIn : x;
+            return fMinOut + (z-fMinIn)*(fMaxOut-fMinOut)/(fMaxIn-fMinIn);
+            
+        } else if (fMinIn > fMaxIn) {
+            // reversed control
+            float z = (x < fMaxIn) ? fMaxIn : (x > fMinIn) ? fMinIn : x;
+            return fMinOut + (fMinIn-z)*(fMaxOut-fMinOut)/(fMinIn-fMaxIn);
+            
+        } else {
+            // no control !
+            return (fMinOut+fMaxOut)/2.0;
+        }
+    }
+};
+
 //--------------------------------------------------------------------------
 /*!
 	\brief a faust root node
@@ -48,6 +88,9 @@ class RootNode : public MessageDriven
 {
 	int *fUPDIn, *fUDPOut, *fUDPErr;	// the osc port numbers (required by the hello method)
 	OSCIO * fIO;						// an OSC IO controler
+	std::map<std::string, std::vector<aliastarget> >	fAliases;
+
+	void processAlias (const std::string& address, float val);
 	
 	protected:
 				 RootNode(const char *name, OSCIO* io=0) : MessageDriven (name, ""), fUPDIn(0), fUDPOut(0), fUDPErr(0), fIO(io) {}
@@ -56,8 +99,12 @@ class RootNode : public MessageDriven
 	public:
 		static SRootNode create (const char* name, OSCIO* io=0) { return new RootNode(name, io); }
 
+		virtual void	processMessage( const Message* msg );
 		virtual bool	accept( const Message* msg );
-				
+		virtual void	get (unsigned long ipdest) const;
+		virtual void	get (unsigned long ipdest, const std::string& what) const;
+
+				void	addAlias (const char* alias, const char* address, float imin, float imax, float omin, float omax);
 				bool	acceptSignal( const Message* msg );				///< handler for signal data
 				void	hello (unsigned long ipdest) const;				///< handler for the 'hello' message
 				void	setPorts (int* in, int* out, int* err);
diff --git a/architecture/osclib/faust/src/osc/OSCIO.cpp b/architecture/osclib/faust/src/osc/OSCIO.cpp
index d8859dc..b1a7499 100644
--- a/architecture/osclib/faust/src/osc/OSCIO.cpp
+++ b/architecture/osclib/faust/src/osc/OSCIO.cpp
@@ -22,7 +22,7 @@
 */
 
 #include <sstream>
-#include "OSCIO.h"
+#include "faust/OSCIO.h"
 #include "OSCStream.h"
 
 namespace oscfaust
diff --git a/architecture/osclib/faust/src/osc/OSCListener.cpp b/architecture/osclib/faust/src/osc/OSCListener.cpp
index f29e764..e1c284e 100644
--- a/architecture/osclib/faust/src/osc/OSCListener.cpp
+++ b/architecture/osclib/faust/src/osc/OSCListener.cpp
@@ -25,8 +25,10 @@
 
 #include <iostream>
 
+#include "faust/osc/Message.h"
+
 #include "OSCListener.h"
-#include "Message.h"
+#include "OSCStream.h"
 
 #include "osc/OscReceivedElements.h"
 #include "ip/IpEndpointName.h"
@@ -40,10 +42,13 @@ namespace oscfaust
 //--------------------------------------------------------------------------
 OSCListener::OSCListener(MessageProcessor *mp, int port) 
 		: fSocket(0), fMsgHandler(mp), 
-		  fRunning(false), fPort(port) 
+		  fRunning(false), fSetDest(true), fPort(port)
 {
 	fSocket = new UdpListeningReceiveSocket(IpEndpointName( IpEndpointName::ANY_ADDRESS, fPort ), this);
 	fPort = 0;
+	// check osc out destination address
+	// warning ! osc stream must be created before the listener
+	if (oscout.getAddress() != kLocalhost) fSetDest = false;
 }
 
 OSCListener::~OSCListener()	{ stop(); delete fSocket; }
@@ -53,17 +58,16 @@ void OSCListener::run()
 { 
 	fRunning = true;
 	while (fRunning) {
-		try {
 			if (fPort) {
 				delete fSocket;
-				fSocket = new UdpListeningReceiveSocket(IpEndpointName( IpEndpointName::ANY_ADDRESS, fPort ), this);
+                fSocket = NULL;
+            	fSocket = new UdpListeningReceiveSocket(IpEndpointName( IpEndpointName::ANY_ADDRESS, fPort ), this);
 				fPort = 0;
 			}
-			fSocket->Run();
-		}
-		catch (osc::Exception e) {
-			cerr << "osc error: " << e.what() << endl;
-		}
+        
+            if(fSocket != NULL)
+                fSocket->Run();
+
 	}
 }
 
@@ -72,6 +76,11 @@ void OSCListener::ProcessMessage( const osc::ReceivedMessage& m, const IpEndpoin
 {
 	Message* msg = new Message(m.AddressPattern());
 	msg->setSrcIP (src.address);
+	if (fSetDest && (src.address != kLocalhost))
+	{
+		oscout.setAddress(src.address);
+		fSetDest = false;
+	}
 	ReceivedMessageArgumentIterator i = m.ArgumentsBegin();
 	while (i != m.ArgumentsEnd()) {
 		if (i->IsString()) {
diff --git a/architecture/osclib/faust/src/osc/OSCListener.h b/architecture/osclib/faust/src/osc/OSCListener.h
index 26f7ec1..6e7c525 100644
--- a/architecture/osclib/faust/src/osc/OSCListener.h
+++ b/architecture/osclib/faust/src/osc/OSCListener.h
@@ -25,13 +25,15 @@
 #ifndef __OSCListener__
 #define __OSCListener__
 
-#include "smartpointer.h"
-#include "MessageProcessor.h"
+#include "faust/osc/smartpointer.h"
+#include "faust/osc/MessageProcessor.h"
 
 // oscpack include files
 #include "ip/UdpSocket.h"
 #include "osc/OscPacketListener.h"
 
+typedef void (*ErrorCallback)(void*);  
+
 namespace oscfaust
 {
 
@@ -48,6 +50,7 @@ class OSCListener : public osc::OscPacketListener, public smartable
 	UdpListeningReceiveSocket *fSocket;	///< the udp socket listener
 	MessageProcessor * fMsgHandler;
 	bool	fRunning;
+	bool	fSetDest;
 	int		fPort;
 
 	public:
diff --git a/architecture/osclib/faust/src/osc/OSCSetup.cpp b/architecture/osclib/faust/src/osc/OSCSetup.cpp
index dab5dfc..0f8e5f6 100644
--- a/architecture/osclib/faust/src/osc/OSCSetup.cpp
+++ b/architecture/osclib/faust/src/osc/OSCSetup.cpp
@@ -39,13 +39,35 @@ class OscThread : public TThreads
 {
 	public:
 		SOSCListener fListener;	
+        ErrorCallback fErrCallback;
+        void*         fArg;
 	
 				 OscThread(MessageProcessor* mp, int udpport)  
 							 { fListener = OSCListener::create (mp, udpport); }
+    
+                OscThread(MessageProcessor* mp, int udpport, ErrorCallback errCallback, void* arg){
+                        fListener = OSCListener::create (mp, udpport);
+                    fErrCallback = errCallback;
+                    fArg = arg;
+                }
 		virtual ~OscThread() { stop(); }
 
 		/// \brief starts the osc listener
-		void run ()				{ fListener->run(); }
+    void run ()				{ 
+        try {
+            fListener->run(); 
+        }
+	catch (osc::Exception& e){
+            
+            if(fErrCallback != NULL)
+                (*fErrCallback)(fArg);
+        }        
+	catch (std::runtime_error& err) {
+            
+            if(fErrCallback != NULL)
+                (*fErrCallback)(fArg);
+        }
+        }
 		void stop ()			{ fListener->stop(); quit(); }
 		SOSCListener&	listener()		{ return fListener; }
 };
@@ -66,10 +88,11 @@ bool OSCSetup::start(MessageProcessor* mp, int& inPort, int outPort, int errPort
 			oscerr.setPort (errPort);
 			oscout.setAddress(address);
 			oscerr.setAddress(address);
-			fOSCThread = new OscThread (mp, port);
-			fOSCThread->start();
+			fOSCThread = new OscThread (mp, port, fErrCallback, fArg);
+            fOSCThread->start();
 			done = true;
 		}
+//        In case the OSC Listener could not be allocated = PORT IS BUSY
 		catch (std::runtime_error e) {
 			if ( port - inPort > 1000) return false;
 			do {
diff --git a/architecture/osclib/faust/src/osc/OSCSetup.h b/architecture/osclib/faust/src/osc/OSCSetup.h
index 782c3a4..5b7e526 100644
--- a/architecture/osclib/faust/src/osc/OSCSetup.h
+++ b/architecture/osclib/faust/src/osc/OSCSetup.h
@@ -30,6 +30,9 @@
 
 #include "OSCStream.h"
 
+
+typedef void (*ErrorCallback)(void*);  
+
 namespace oscfaust
 {
 
@@ -42,8 +45,11 @@ class MessageProcessor;
 class OSCSetup
 {
 	OscThread*	fOSCThread;		// a thread that is listening to the osc in socket
+    ErrorCallback fErrCallback;
+    void*       fArg;
+    
 	public:
-		 		 OSCSetup() : fOSCThread(0) {} 
+                OSCSetup(ErrorCallback errCallback = NULL, void* arg = NULL) : fOSCThread(0), fErrCallback(errCallback), fArg(arg) {}
 		virtual ~OSCSetup();
 
 		bool start(MessageProcessor* mp, int& inPort, int outPort, int errPort, const char* address);
diff --git a/architecture/osclib/faust/src/osc/OSCStream.cpp b/architecture/osclib/faust/src/osc/OSCStream.cpp
index afe09c5..0bba8cd 100644
--- a/architecture/osclib/faust/src/osc/OSCStream.cpp
+++ b/architecture/osclib/faust/src/osc/OSCStream.cpp
@@ -28,35 +28,39 @@ namespace oscfaust
 {
 
 OSCStream* _oscout = 0;				// OSC standard output stream
-OSCStream* _oscerr = 0;				// OSC standard input stream
+OSCStream* _oscerr = 0;				// OSC standard error stream
 
 static UdpSocket* _socket = 0;		// a shared transmit socket
 
-
-//--------------------------------------------------------------------------
-OSCStream::OSCStream ()
-	: fState(kIdle), fPort(1024), fAddress(kLocalhost), fOutStream(fBuffer, kOutBufferSize), fSocket(_socket)
-{
-	if (!fSocket) cerr << "warning: incorrect OSCStream, _socket not initialized" << endl;
-}
+int OSCStream::fRefCount = 0;
 
 //--------------------------------------------------------------------------
 bool OSCStream::start ()
 {
-	_socket = new UdpSocket;
-	_oscout = new OSCStream(_socket);
-	_oscerr = new OSCStream(_socket);
+    if(_socket == 0)
+        _socket = new UdpSocket;
+	
+    if(_oscout == 0)
+        _oscout = new OSCStream(_socket);
+    
+    if(_oscerr == 0)
+        _oscerr = new OSCStream(_socket);
+    
+    fRefCount++;
 	return (_socket && _oscout && _oscerr);
 }
 
 //--------------------------------------------------------------------------
 void OSCStream::stop ()
 {
-	delete _socket;
-	delete _oscout;
-	delete _oscerr;
-	_oscout = _oscerr = 0;
-	_socket = 0;
+    if(fRefCount == 0){
+        
+        delete _socket;
+        delete _oscout;
+        delete _oscerr;
+        _oscout = _oscerr = 0;
+        _socket = 0;
+    }
 }
 
 //--------------------------------------------------------------------------
@@ -79,13 +83,19 @@ OSCStream& OSCStream::start(const char * address)
 //--------------------------------------------------------------------------
 OSCStream& OSCStream::end()
 {
+	send (fAddress, fPort);
+	return *this;
+}
+
+//--------------------------------------------------------------------------
+void OSCStream::send(unsigned long ipdest, int port)
+{
 	if (state() == kInProgress) {
 		stream() << osc::EndMessage;
 		if (fSocket) 
-			fSocket->SendTo (IpEndpointName (fAddress, fPort), stream().Data(), stream().Size() );
+			fSocket->SendTo (IpEndpointName (ipdest, port), stream().Data(), stream().Size() );
 		fState = kIdle;
 	}
-	return *this;
 }
 
 //--------------------------------------------------------------------------
diff --git a/architecture/osclib/faust/src/osc/OSCStream.h b/architecture/osclib/faust/src/osc/OSCStream.h
index 5203808..c6ba77d 100644
--- a/architecture/osclib/faust/src/osc/OSCStream.h
+++ b/architecture/osclib/faust/src/osc/OSCStream.h
@@ -67,15 +67,19 @@ class OSCStream
 	osc::OutboundPacketStream	fOutStream;
 	UdpSocket*					fSocket;
 	
+    static    int         fRefCount; // For this stream is shared, a counter is needed to know when to delete object.
+    
 //	void initSocket();
 	
 	public:
 	static bool start();
 	static void stop();
 
-				 OSCStream();
-				 OSCStream(UdpSocket* socket) 
-					: fState(kIdle), fPort(1024), fAddress(kLocalhost), fOutStream(fBuffer, kOutBufferSize), fSocket(socket) {} 
+        OSCStream(UdpSocket* socket) 
+            : fState(kIdle), fPort(1024), fAddress(kLocalhost), fOutStream(fBuffer, kOutBufferSize), fSocket(socket) 
+        {
+            fSocket->allowBroadcast();
+        } 
 		virtual ~OSCStream() {}
 		
 		osc::OutboundPacketStream& stream()				{ return fOutStream; }
@@ -86,6 +90,7 @@ class OSCStream
 		
 		OSCStream&			start(const char * address);
 		OSCStream&			end();
+		void				send(unsigned long ipdest, int port);
 
 		void setPort (int port)							{ fPort = port; }
 		void setAddress (unsigned long address)			{ fAddress = address; }
diff --git a/architecture/osclib/faust/src/threads/pthreads_impl.cpp b/architecture/osclib/faust/src/threads/pthreads_impl.cpp
index 044062a..23981d7 100644
--- a/architecture/osclib/faust/src/threads/pthreads_impl.cpp
+++ b/architecture/osclib/faust/src/threads/pthreads_impl.cpp
@@ -32,7 +32,6 @@
 
 #include "TThreads.h"
 
-
 //_____________________________________________________________________
 static void * baseThreadProc (void * ptr)
 {
@@ -40,6 +39,7 @@ static void * baseThreadProc (void * ptr)
 	thread->running (true);
 	thread->run();
 	thread->running (false);
+	pthread_exit(NULL);
 	return 0;
 }
 
diff --git a/architecture/osclib/oscpack/Makefile b/architecture/osclib/oscpack/Makefile
index 180ae85..1fada77 100644
--- a/architecture/osclib/oscpack/Makefile
+++ b/architecture/osclib/oscpack/Makefile
@@ -4,13 +4,14 @@ system	?= $(shell uname -s)
 ifeq ($(system), Darwin)
 subprojects := ip ip/posix osc
 sources     := $(wildcard ip/*.cpp)  $(wildcard ip/posix/*.cpp)  $(wildcard osc/*.cpp)
-ARCHFLAGS 	:=  -arch i386 -arch x86_64
+#ARCHFLAGS 	:=  -arch i386 -arch x86_64
 
 else 
 ifeq ($(system), Linux)
 subprojects := ip ip/posix osc
 sources     := $(wildcard ip/*.cpp)  $(wildcard ip/posix/*.cpp)  $(wildcard osc/*.cpp)
 ARCHFLAGS 	:= 
+CXXFLAGS += -fPIC
 
 else
 subprojects := ip ip/win32 osc
@@ -37,7 +38,14 @@ $(libname): $(objects)
 	ranlib $@
 	
 depend :
-	makedepend -fMakefile -w120 -Y -- $(CXXFLAGS) -- $(sources)
+	makedepend -fMakefile -w120 -Y -- $(CXXFLAGS) -- $(sources)
+
+ios: IPHONEOS_DEPLOYMENT_TARGET=5.0
+ios: CXX = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
+ios: CXXFLAGS += -std=c++11 -stdlib=libstdc++  -arch armv7 -arch armv7s -arch arm64 -pipe -O3 -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk
+ios: CXXFLAGS += -fvisibility=hidden -Wno-overloaded-virtual -Wno-parentheses $(addprefix -I, $(subprojects)) -DINSTALL_PREFIX='"$(prefix)"' 
+
+ios : liboscpack.a
 	
 clean :
 	rm -f $(objects)
diff --git a/architecture/osclib/oscpack/cmake/CMakeLists.txt b/architecture/osclib/oscpack/cmake/CMakeLists.txt
index 17db1b9..9e7842e 100644
--- a/architecture/osclib/oscpack/cmake/CMakeLists.txt
+++ b/architecture/osclib/oscpack/cmake/CMakeLists.txt
@@ -29,9 +29,7 @@ endif (${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL powerpc OR
 
 if(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
 	set (CMAKE_OSX_ARCHITECTURES "x86_64 i386")
-	set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
-	set(CMAKE_C++_FLAGS -mmacosx-version-min=10.4)
-endif(APPLE AND (${CMAKE_GENERATOR} STREQUAL Xcode) )
+endif()
 
 
 # SET MAIN DIRECTORY.
@@ -77,7 +75,6 @@ if (${GENTOOLS})
 	target_link_libraries( ${tool} oscpack)
 	add_dependencies(${tool} oscpack)
  endforeach(tool)
- set_target_properties( examples/OscDump PROPERTIES CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
 
 else (${GENTOOLS})
   message (STATUS "Don't generates tools. Use -DGENTOOLS=1 to change")
diff --git a/architecture/osclib/oscpack/ip/IpEndpointName.h b/architecture/osclib/oscpack/ip/IpEndpointName.h
index 7d61d85..5ba46f9 100644
--- a/architecture/osclib/oscpack/ip/IpEndpointName.h
+++ b/architecture/osclib/oscpack/ip/IpEndpointName.h
@@ -51,8 +51,10 @@ public:
 		, port( port_ ) {}
 
 	// address and port are maintained in host byte order here
-    unsigned long address;
-    int port;
+	unsigned long address;
+	int port;
+
+	unsigned long destAddress; // Destination address of the packet.
 
 	enum { ADDRESS_STRING_LENGTH=17 };
 	void AddressAsString( char *s ) const;
diff --git a/architecture/osclib/oscpack/ip/UdpSocket.h b/architecture/osclib/oscpack/ip/UdpSocket.h
index de75de2..b5572a1 100644
--- a/architecture/osclib/oscpack/ip/UdpSocket.h
+++ b/architecture/osclib/oscpack/ip/UdpSocket.h
@@ -85,6 +85,9 @@ public:
 	UdpSocket();
 	virtual ~UdpSocket();
 
+	// allow to transmit on broadcast adresses
+    void allowBroadcast();
+
 	// the socket is created in an unbound, unconnected state
 	// such a socket can only be used to send to an arbitrary
 	// address using SendTo(). To use Send() you need to first
diff --git a/architecture/osclib/oscpack/ip/posix/UdpSocket.cpp b/architecture/osclib/oscpack/ip/posix/UdpSocket.cpp
index ddb7e9e..0a69de6 100644
--- a/architecture/osclib/oscpack/ip/posix/UdpSocket.cpp
+++ b/architecture/osclib/oscpack/ip/posix/UdpSocket.cpp
@@ -51,7 +51,6 @@
 #include "ip/PacketListener.h"
 #include "ip/TimerListener.h"
 
-
 #if defined(__APPLE__) && !defined(_SOCKLEN_T)
 // pre system 10.3 didn have socklen_t
 typedef ssize_t socklen_t;
@@ -161,6 +160,12 @@ public:
 		return IpEndpointNameFromSockaddr( sockAddr );
 	}
 
+	void allowBroadcast()
+	{
+		int val = 1;
+		setsockopt (socket_, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val));
+	}
+
 	void Connect( const IpEndpointName& remoteEndpoint )
 	{
 		SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint );
@@ -205,16 +210,52 @@ public:
 	{
 		assert( isBound_ );
 
-		struct sockaddr_in fromAddr;
-        socklen_t fromAddrLen = sizeof(fromAddr);
-             	 
-        int result = recvfrom(socket_, data, size, 0,
-                    (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
+		// Main structure to read the message
+		struct msghdr mh;
+		memset(&mh, 0, sizeof(mh));
+
+		// Structure to write remote/source sockaddr
+		struct sockaddr_in peeraddr;
+		mh.msg_name = &peeraddr;
+		mh.msg_namelen = sizeof(peeraddr);
+
+		// Structure for control data, the control data is dumped here
+		char cmbuf[0x100];memset(&cmbuf, 0, sizeof(cmbuf));
+		mh.msg_control = cmbuf;
+		mh.msg_controllen = sizeof(cmbuf);
+
+		// Structure to access the message data.
+		struct iovec    iov;
+		iov.iov_base = data;
+		iov.iov_len = size;
+		mh.msg_iov = &iov;
+		mh.msg_iovlen = 1;
+
+		// Set socket option
+		int val = 1;
+		setsockopt (socket_, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
+		int result = recvmsg(socket_, &mh, 0);
 		if( result < 0 )
 			return 0;
 
-		remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
-		remoteEndpoint.port = ntohs(fromAddr.sin_port);
+		for ( // iterate through all the control headers
+			struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
+			cmsg != NULL;
+			cmsg = CMSG_NXTHDR(&mh, cmsg))
+		{
+			// ignore the control headers that don't match what we want
+			if (cmsg->cmsg_level != IPPROTO_IP ||
+				cmsg->cmsg_type != IP_PKTINFO)
+			{
+				continue;
+			}
+			// Get the destination address
+			struct in_pktinfo *pi = (struct in_pktinfo *)CMSG_DATA(cmsg);
+			// pi->ipi_addr is the destination in_addr
+			remoteEndpoint.destAddress = ntohl(pi->ipi_addr.s_addr);
+		}
+		remoteEndpoint.address = ntohl(peeraddr.sin_addr.s_addr);
+		remoteEndpoint.port = ntohs(peeraddr.sin_port);
 
 		return result;
 	}
@@ -232,6 +273,11 @@ UdpSocket::~UdpSocket()
 	delete impl_;
 }
 
+void UdpSocket::allowBroadcast()
+{
+	impl_->allowBroadcast();
+}
+
 IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
 {
 	return impl_->LocalEndpointFor( remoteEndpoint );
diff --git a/architecture/osclib/oscpack/ip/win32/UdpSocket.cpp b/architecture/osclib/oscpack/ip/win32/UdpSocket.cpp
index 9370b9d..5b7b4e0 100644
--- a/architecture/osclib/oscpack/ip/win32/UdpSocket.cpp
+++ b/architecture/osclib/oscpack/ip/win32/UdpSocket.cpp
@@ -30,6 +30,8 @@
 #include "ip/UdpSocket.h"
 
 #include <winsock2.h>   // this must come first to prevent errors with MSVC7
+#include <Ws2tcpip.h>
+#include <Mswsock.h>
 #include <windows.h>
 #include <mmsystem.h>   // for timeGetTime()
 
@@ -43,7 +45,6 @@
 #include "ip/PacketListener.h"
 #include "ip/TimerListener.h"
 
-
 typedef int socklen_t;
 
 
@@ -94,7 +95,7 @@ public:
 		, isConnected_( false )
 		, socket_( INVALID_SOCKET )
 	{
-		if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == INVALID_SOCKET ){
+		if( (socket_ = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0)) == INVALID_SOCKET ){
             throw std::runtime_error("unable to create udp socket\n");
         }
 
@@ -106,6 +107,12 @@ public:
 	{
 		if (socket_ != INVALID_SOCKET) closesocket(socket_);
 	}
+	
+	void allowBroadcast()
+	{
+		int val = 1;
+		setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, (char *)&val, sizeof(val));
+	}
 
 	IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
 	{
@@ -194,19 +201,70 @@ public:
     int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
 	{
 		assert( isBound_ );
+	
+		// Load WSARecvMsg function
+		static LPFN_WSARECVMSG WSARecvMsg = NULL;
+		if (WSARecvMsg == NULL) {
+        GUID guid = WSAID_WSARECVMSG;
+        DWORD bytes_returned;
+			if (WSAIoctl(socket_, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
+					&WSARecvMsg, sizeof(WSARecvMsg), &bytes_returned, NULL, NULL) == SOCKET_ERROR) {
+				return 0;
+			}
+		}
 
-		struct sockaddr_in fromAddr;
-        socklen_t fromAddrLen = sizeof(fromAddr);
-             	 
-        int result = recvfrom(socket_, data, size, 0,
-                    (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
-		if( result < 0 )
+		// Main structure to read the message
+		WSAMSG msg;
+
+		// Structure to write remote/source sockaddr
+		struct sockaddr_in peeraddr;
+		socklen_t fromAddrLen = sizeof(peeraddr);	
+		msg.name =  (struct sockaddr *)&peeraddr;
+		msg.namelen = fromAddrLen;
+	
+		// Structure for control data
+		char controlbuf[0x100];
+		msg.Control.len = sizeof(controlbuf);
+		msg.Control.buf = controlbuf;
+
+		// Structure to access the message data.
+		WSABUF buffer;		
+		buffer.buf = data;
+		buffer.len = size;
+		msg.lpBuffers = &buffer;
+		msg.dwBufferCount = 1;
+
+		msg.dwFlags = 0;
+
+		// Set socket option
+		int val = 1;
+		setsockopt(socket_, IPPROTO_IP, IP_PKTINFO, (char *)&val, sizeof(val));
+
+		DWORD readLen = 0; // Size of data read
+		WSARecvMsg(socket_, &msg, &readLen, 0, 0);
+
+		if( readLen < 0 )
 			return 0;
 
-		remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
-		remoteEndpoint.port = ntohs(fromAddr.sin_port);
-
-		return result;
+		for ( // iterate through all the control headers
+			LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg);
+			cmsg != NULL;
+			cmsg = WSA_CMSG_NXTHDR(&msg, cmsg))
+		{
+			// ignore the control headers that don't match what we want
+			if (cmsg->cmsg_level != IPPROTO_IP ||
+				cmsg->cmsg_type != IP_PKTINFO)
+			{
+				continue;
+			}
+			// Get the destination address
+			struct in_pktinfo *pi = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
+			// pi->ipi_addr is the destination in_addr
+			remoteEndpoint.destAddress = ntohl(pi->ipi_addr.s_addr);
+		}
+		remoteEndpoint.address = ntohl(peeraddr.sin_addr.s_addr);
+		remoteEndpoint.port = ntohs(peeraddr.sin_port);
+		return readLen;
 	}
 
 	SOCKET& Socket() { return socket_; }
@@ -222,6 +280,11 @@ UdpSocket::~UdpSocket()
 	delete impl_;
 }
 
+void UdpSocket::allowBroadcast()
+{
+	impl_->allowBroadcast();
+}
+
 IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
 {
 	return impl_->LocalEndpointFor( remoteEndpoint );
diff --git a/architecture/oss-gtk.cpp b/architecture/oss-gtk.cpp
index 7c731d2..840ad54 100644
--- a/architecture/oss-gtk.cpp
+++ b/architecture/oss-gtk.cpp
@@ -87,52 +87,7 @@ struct Meta : map<const char*, const char*>
 
 //#define BENCHMARKMODE
 
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-		
+	
 
 inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
 
diff --git a/architecture/owl.cpp b/architecture/owl.cpp
new file mode 100644
index 0000000..84a3d85
--- /dev/null
+++ b/architecture/owl.cpp
@@ -0,0 +1,238 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __FaustPatch_h__
+#define __FaustPatch_h__
+
+#include "StompBox.h"
+#include <cstddef>
+#include <string.h>
+#include <strings.h>
+
+
+#ifndef __FaustCommonInfrastructure__
+#define __FaustCommonInfrastructure__
+
+
+#include "faust/audio/dsp.h"
+#include "faust/gui/UI.h"
+
+
+
+struct Meta
+{
+    virtual void declare(const char* key, const char* value) = 0;
+};
+
+
+
+/**************************************************************************************
+
+	OwlWidget : object used by OwlUI to ensures the connection between an owl parameter 
+	and a faust widget
+	
+***************************************************************************************/
+
+class OwlWidget
+{
+  protected:
+	Patch* 	fPatch;		// needed to register and read owl parameters
+	PatchParameterId	fParameter;		// OWL parameter code : PARAMETER_A,...
+	FAUSTFLOAT* 		fZone;			// Faust widget zone
+	const char*			fLabel;			// Faust widget label 
+	float				fMin;			// Faust widget minimal value
+	float				fSpan;			// Faust widget value span (max-min)
+	
+  public:
+	OwlWidget() :
+		fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
+	OwlWidget(const OwlWidget& w) :
+		fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
+	OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
+		fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
+	void bind() 	{ fPatch->registerParameter(fParameter, fLabel); }
+	void update()	{ *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
+	
+};
+
+
+/**************************************************************************************
+
+	OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
+	the mapping between owl parameters and faust widgets. It relies on specific
+	metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any 
+	faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B 
+	(the second knob).
+	
+***************************************************************************************/
+
+// The maximun number of mappings between owl parameters and faust widgets 
+#define MAXOWLWIDGETS 8
+
+class OwlUI : public UI
+{
+	Patch* 	fPatch;
+	PatchParameterId	fParameter;					// current parameter ID, value PARAMETER_F means not set
+	int					fIndex;						// number of OwlWidgets collected so far
+	OwlWidget			fTable[MAXOWLWIDGETS];		// kind of static list of OwlWidgets
+	
+	// check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
+	void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
+		if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
+			fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
+			fTable[fIndex].bind();
+			fIndex++;
+		}
+		fParameter = PARAMETER_F; 		// clear current parameter ID
+	}
+
+	// we dont want to create a widget by-ut we clear the current parameter ID just in case
+	void skip() {
+		fParameter = PARAMETER_F; 		// clear current parameter ID
+	}
+
+ public:
+
+	OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
+	
+	virtual ~OwlUI() {}
+	
+	// should be called before compute() to update widget's zones registered as Owl parameters
+	void update() {
+		for (int i=0; i<fIndex; i++)  fTable[i].update();
+	}
+
+	//---------------------- virtual methods called by buildUserInterface ----------------
+	
+    // -- widget's layouts
+
+    virtual void openTabBox(const char* label) {}
+    virtual void openHorizontalBox(const char* label) {}
+    virtual void openVerticalBox(const char* label) {}
+    virtual void closeBox() {}
+
+    // -- active widgets
+
+    virtual void addButton(const char* label, FAUSTFLOAT* zone) 																			{ skip(); }
+    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) 																		{ skip(); }
+    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) 	{ addOwlWidget(label, zone, lo, hi); }
+    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) 	{ addOwlWidget(label, zone, lo, hi); }
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) 			{ addOwlWidget(label, zone, lo, hi); }
+
+    // -- passive widgets
+
+    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) 									{ skip(); }
+    virtual void addVerticalBargraph  (const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) 									{ skip(); }
+
+	// -- metadata declarations
+
+    virtual void declare(FAUSTFLOAT* z, const char* k, const char* id) {
+    	if (strcasecmp(k,"OWL") == 0) {
+    		     if (strcasecmp(id,"PARAMETER_A") == 0)  fParameter = PARAMETER_A;
+    		else if (strcasecmp(id,"PARAMETER_B") == 0)  fParameter = PARAMETER_B;
+    		else if (strcasecmp(id,"PARAMETER_C") == 0)  fParameter = PARAMETER_C;
+    		else if (strcasecmp(id,"PARAMETER_D") == 0)  fParameter = PARAMETER_D;
+    		else if (strcasecmp(id,"PARAMETER_E") == 0)  fParameter = PARAMETER_E;
+    	}
+    }
+};
+
+#endif // __FaustCommonInfrastructure__
+
+/**************************BEGIN USER SECTION **************************/
+
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+
+
+/**************************************************************************************
+
+	FaustPatch : an OWL patch that calls Faust generated DSP code
+	
+***************************************************************************************/
+
+class FaustPatch : public Patch
+{
+    mydsp   fDSP;
+    OwlUI	fUI;
+    
+public:
+
+    FaustPatch() : fUI(this)
+    {
+        fDSP.init(int(getSampleRate()));		// Init Faust code with the OWL sampling rate
+        fDSP.buildUserInterface(&fUI);			// Maps owl parameters and faust widgets 
+    }
+    
+    void processAudio(AudioBuffer &buffer)
+    {
+        // Reasonably assume we will not have more than 32 channels
+        float*  ins[32];
+        float*  outs[32];
+        int     n = buffer.getChannels();
+        
+        if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
+            
+            // create the table of input channels
+            for(int ch=0; ch<fDSP.getNumInputs(); ++ch) {
+                ins[ch] = buffer.getSamples(ch%n);
+            }
+            
+            // create the table of output channels
+            for(int ch=0; ch<fDSP.getNumOutputs(); ++ch) {
+                outs[ch] = buffer.getSamples(ch%n);
+            }
+            
+            // read OWL parameters and updates corresponding Faust Widgets zones
+            fUI.update(); 
+            
+            // Process the audio samples
+            fDSP.compute(buffer.getSize(), ins, outs);
+        }
+    }
+
+};
+
+#endif // __FaustPatch_h__
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/architecture/pa-gtk.cpp b/architecture/pa-gtk.cpp
index 908be20..2650e1d 100644
--- a/architecture/pa-gtk.cpp
+++ b/architecture/pa-gtk.cpp
@@ -37,13 +37,13 @@
 #include <libgen.h>
 #include <iostream>
 
-#include "gui/FUI.h"
-#include "misc.h"
-#include "audio/portaudio-dsp.h"
-#include "gui/faustgtk.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/audio/portaudio-dsp.h"
+#include "faust/gui/faustgtk.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
 #endif
 
 /**************************BEGIN USER SECTION **************************/
@@ -107,13 +107,6 @@ int main(int argc, char *argv[] )
 }
 #endif
 
-long lopt(char *argv[], const char *name, long def)
-{
-	int	i;
-	for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
-	return def;
-}
-
 int main(int argc, char *argv[])
 {
 	char	appname[256];
@@ -148,9 +141,19 @@ int main(int argc, char *argv[])
 
 	audio.stop();
 	finterface->saveState(rcfilename);
+    
+   // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
   	return 0;
 }
 
-
 /********************END ARCHITECTURE SECTION (part 2/2)****************/
 
diff --git a/architecture/pa-qt.cpp b/architecture/pa-qt.cpp
index 0613277..ca8c056 100644
--- a/architecture/pa-qt.cpp
+++ b/architecture/pa-qt.cpp
@@ -37,16 +37,15 @@
 #include <libgen.h>
 #include <iostream>
 
-#include "gui/FUI.h"
-#include "gui/faustqt.h"
-#include "misc.h"
-#include "audio/portaudio-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/gui/faustqt.h"
+#include "faust/misc.h"
+#include "faust/audio/portaudio-dsp.h"
 
 #ifdef OSCCTRL
-#include "gui/OSCUI.h"
+#include "faust/gui/OSCUI.h"
 #endif
 
-
 /******************************************************************************
 *******************************************************************************
 
@@ -57,7 +56,6 @@
 
 <<includeIntrinsic>>
 
-
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
 /**************************BEGIN USER SECTION **************************/
@@ -69,7 +67,7 @@
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 
 mydsp		DSP;
-list<GUI*>	GUI::fGuiList;
+std::list<GUI*>	GUI::fGuiList;
 
 /******************************************************************************
 *******************************************************************************
@@ -79,14 +77,6 @@ list<GUI*>	GUI::fGuiList;
 *******************************************************************************
 *******************************************************************************/
 
-
-long lopt(char *argv[], const char *name, long def)
-{
-	int	i;
-	for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
-	return def;
-}
-
 int main(int argc, char *argv[])
 {
 	char	appname[256];
@@ -95,8 +85,10 @@ int main(int argc, char *argv[])
 
 	snprintf(appname, 255, "%s", basename(argv[0]));
 	snprintf(rcfilename, 255, "%s/.%src", home, appname);
-
-	GUI* interface 	= new QTGUI(argc, argv);
+    
+    QApplication myApp(argc, argv);
+    
+	QTGUI* interface = new QTGUI();
 	FUI* finterface	= new FUI();
 	DSP.buildUserInterface(interface);
 	DSP.buildUserInterface(finterface);
@@ -113,14 +105,32 @@ int main(int argc, char *argv[])
 	audio.init(appname, &DSP);
 	finterface->recallState(rcfilename);
 	audio.start();
+    
+    printf("ins %d\n", audio.get_num_inputs());
+    printf("outs %d\n", audio.get_num_outputs());
 
 #ifdef OSCCTRL
 	oscinterface->run();
 #endif
 	interface->run();
-
+	
+    myApp.setStyleSheet(interface->styleSheet());
+    myApp.exec();
+    interface->stop();
+    
 	audio.stop();
 	finterface->saveState(rcfilename);
+    
+    // desallocation
+    delete interface;
+    delete finterface;
+#ifdef HTTPCTRL
+	 delete httpdinterface;
+#endif
+#ifdef OSCCTRL
+	 delete oscinterface;
+#endif
+
   	return 0;
 }
 
diff --git a/architecture/plot.cpp b/architecture/plot.cpp
index d2181d1..c315cda 100644
--- a/architecture/plot.cpp
+++ b/architecture/plot.cpp
@@ -34,7 +34,6 @@
  ************************************************************************
  ************************************************************************/
 
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -50,67 +49,9 @@
 #include <map>
 #include <iostream> 
 
-// g++ -O3 -lm -lsndfile  myfx.cpp
-
-using namespace std;
-
-struct Meta : map<const char*, const char*>
-{
-    void declare (const char* key, const char* value) { (*this)[key]=value; }
-};
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-		
-
-
-inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
-		
-template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
-
+#include "faust/gui/console.h"
+#include "faust/audio/dsp.h"
+#include "faust/misc.h"
 
 /******************************************************************************
 *******************************************************************************
@@ -120,275 +61,7 @@ template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
 *******************************************************************************
 *******************************************************************************/
 
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
 <<includeIntrinsic>>
-
-
-
-
-/******************************************************************************
-*******************************************************************************
-
-								USER INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-class UI
-{
-	bool	fStopped;
-public:
-		
-	UI() : fStopped(false) {}
-	virtual ~UI() {}
-	
-	// -- active widgets
-	
-	virtual void addButton(const char* label, float* zone) = 0;
-	virtual void addToggleButton(const char* label, float* zone) = 0;
-	virtual void addCheckButton(const char* label, float* zone) = 0;
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	
-	// -- passive widgets
-	
-	virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-	virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
-	virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-	
-	// -- frames and labels
-	
-	virtual void openFrameBox(const char* label) = 0;
-	virtual void openTabBox(const char* label) = 0;
-	virtual void openHorizontalBox(const char* label) = 0;
-	virtual void openVerticalBox(const char* label) = 0;
-	virtual void closeBox() = 0;
-	
-	virtual void show() = 0;
-	virtual void run() = 0;
-	
-	void stop()		{ fStopped = true; }
-	bool stopped() 	{ return fStopped; }
-
-    virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
-struct param {
-	float* fZone; float fMin; float fMax;
-	param(float* z, float init, float a, float b) : fZone(z), fMin(a), fMax(b) { *z = init; }
-};
-
-
-class CMDUI : public UI
-{
-	int					fArgc;
-	char**				fArgv;
-	vector<char*>		fFiles;
-	stack<string>		fPrefix;
-	map<string, param>	fKeyParam;
-	
-	void openAnyBox(const char* label)
-	{
-		string prefix;
-		
-		if (label && label[0]) {
-			prefix = fPrefix.top() + "-" + label;
-		} else {
-			prefix = fPrefix.top();
-		}
-		fPrefix.push(prefix);
-	}
-
-	string simplify(const string& src)
-	{
-		int		i=0;
-		int		level=0;
-		string	dst;
-		
-		while (src[i] ) {
-		
-			switch (level) {
-			
-				case 0 : 	
-				case 1 : 			
-				case 2 : 	
-					// Skip the begin of the label "--foo-"
-					// until 3 '-' have been read
-					if (src[i]=='-') { level++; }
-					break;
-							
-				case 3 :	
-					// copy the content, but skip non alphnum
-					// and content in parenthesis
-					switch (src[i]) {
-						case '(' : 	
-						case '[' : 	
-							level++;
-							break;
-							
-						case '-' : 	
-							dst += '-';
-							break;
-									
-						default :
-							if (isalnum(src[i])) {
-								dst+= tolower(src[i]); 
-							}
-							
-					}
-					break;
-					
-				default :	
-					// here we are inside parenthesis and 
-					// we skip the content until we are back to
-					// level 3
-					switch (src[i]) {
-		
-						case '(' : 	
-						case '[' : 
-							level++;
-							break;
-									
-						case ')' : 	
-						case ']' : 
-							level--;
-							break;
-							
-						default :
-							break;
-					}
-						
-			}
-			i++;
-		}
-		return dst;
-	}
-	
-	
-public:
-		
-	CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("-"); }
-	virtual ~CMDUI() {}
-	
-		
-	void addOption(const char* label, float* zone, float init, float min, float max)
-	{
-		string fullname = "-" + simplify(fPrefix.top() + "-" + label);
-		fKeyParam.insert(make_pair(fullname, param(zone, init, min, max)));
-	}
-
-	
-	virtual void addButton(const char* label, float* zone)
-	{
-		addOption(label,zone,0,0,1);
-	}
-	
-	virtual void addToggleButton(const char* label, float* zone)
-	{
-		addOption(label,zone,0,0,1);
-	}
-	
-	virtual void addCheckButton(const char* label, float* zone)
-	{
-		addOption(label,zone,0,0,1);
-	}
-		
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,init,min,max);
-	}
-		
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,init,min,max);
-	}
-
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,init,min,max);
-	}
-		
-	// -- passive widgets
-	
-	virtual void addNumDisplay(const char* label, float* zone, int precision) 						{}
-	virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) 	{}
-	virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) 			{}
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) 			{}
-	
-	virtual void openFrameBox(const char* label)		{ openAnyBox(label); }
-	virtual void openTabBox(const char* label)			{ openAnyBox(label); }
-	virtual void openHorizontalBox(const char* label)	{ openAnyBox(label); }
-	virtual void openVerticalBox(const char* label)		{ openAnyBox(label); }
-	
-	virtual void closeBox() 							{ fPrefix.pop(); }
-	
-	virtual void show() {}
-	virtual void run() 	{}
-	
-	void printhelp() 
-	{
-		map<string, param>::iterator i;
-		cout << fArgc << "\n";
-		cout << fArgv[0] << " option list : ";
-		for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
-			cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
-		}
-		cout << " infile outfile\n";
-	}
-		
-	void process_command()
-	{
-		map<string, param>::iterator p;
-		for (int i = 1; i < fArgc; i++) {
-			if (fArgv[i][0] == '-') {
-				if (	(strcmp(fArgv[i], "-help") == 0) 
-					 || (strcmp(fArgv[i], "-h") == 0)
-					 || (strcmp(fArgv[i], "--help") == 0) ) 	{
-					printhelp();
-					exit(1);
-				}
-				p = fKeyParam.find(fArgv[i]); 
-				if (p == fKeyParam.end()) {
-					cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
-					printhelp();
-					exit(1);
-				}
-				char*	end;
-				*(p->second.fZone) = float(strtod(fArgv[i+1], &end));
-				i++;
-			} else {
-				fFiles.push_back(fArgv[i]);
-			}
-		}
-	}
-			
-	int 	files()			{ return fFiles.size(); }
-	char* 	file (int n)	{ return fFiles[n]; }
-		
-};
-
-//----------------------------------------------------------------
-//  d�inition du processeur de signal
-//----------------------------------------------------------------
-			
-class dsp {
- protected:
-	int fSamplingFreq;
- public:
-	dsp() {}
-	virtual ~dsp() {}
-	
-	virtual int getNumInputs() 										= 0;
-	virtual int getNumOutputs() 									= 0;
-	virtual void buildUserInterface(UI* interface) 					= 0;
-	virtual void init(int samplingRate) 							= 0;
- 	virtual void compute(int len, float** inputs, float** outputs) 	= 0;
- 	virtual void conclude() 										{}
-};
 		
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
@@ -402,12 +75,11 @@ class dsp {
 					
 mydsp	DSP;
 	
-	
 class channels
 {
 	int 	fNumFrames;
 	int		fNumChannels;
-	float*	fBuffers[256];
+	FAUSTFLOAT*	fBuffers[256];
 
   public:
 		  
@@ -418,7 +90,7 @@ class channels
 		
 		// allocate audio  channels
 		for (int i = 0; i < fNumChannels; i++) {
-			fBuffers[i] = (float*) calloc (fNumFrames, sizeof(float));
+			fBuffers[i] = (FAUSTFLOAT*) calloc (fNumFrames, sizeof(FAUSTFLOAT));
 		}
 	}
 	
@@ -426,21 +98,18 @@ class channels
 	{
 		// free separate input channels
 		for (int i = 0; i < fNumChannels; i++) {
-		//	free(fBuffers[i]);
+            free(fBuffers[i]);
 		}		
 	}
 	
-	float**	buffers()		{ return fBuffers; }
+	FAUSTFLOAT**	buffers()		{ return fBuffers; }
 };
 
-
-
 #define kFrames 512
 	
 int main(int argc, char *argv[] )
 {
-	float			fnbsamples;
-	
+	float fnbsamples;
 
 	CMDUI* interface = new CMDUI(argc, argv);
 	DSP.buildUserInterface(interface);
@@ -454,7 +123,7 @@ int main(int argc, char *argv[] )
 	// init signal processor and the user interface values
 	DSP.init(44100);
 	
-	// modifie the UI valuez according to the command line options
+	// modify the UI values according to the command line options
 	interface->process_command();
 	
 	int nouts = DSP.getNumOutputs();
@@ -467,7 +136,7 @@ int main(int argc, char *argv[] )
 			for (int c = 0; c < nouts; c++) {
 				printf("%8f\t", chan.buffers()[c][i]);
 			}
-			cout << endl;
+			std::cout << std::endl;
 		}
 		nbsamples -= kFrames;
 	}
@@ -477,7 +146,7 @@ int main(int argc, char *argv[] )
 		for (int c = 0; c < nouts; c++) {
 			printf("%8f\t", chan.buffers()[c][i]);
 		}
-		cout << endl;
+		std::cout << std::endl;
 	}
 	return 0;
 } 
diff --git a/architecture/pure.cpp b/architecture/pure.cpp
index aca3555..a8d4abd 100644
--- a/architecture/pure.cpp
+++ b/architecture/pure.cpp
@@ -22,7 +22,7 @@
 
 /* Pure architecture for Faust. This is similar to the Q architecture, but
    uses double precision for the audio buffers and control variables. See
-   http://pure-lang.googlecode.com for a Pure module which can load these
+   http://purelang.bitbucket.org for a Pure module which can load these
    extensions. */
 
 #include <stdlib.h>
@@ -41,52 +41,6 @@ struct Meta
   { data.push_back(strpair(key, value)); }
 };
 
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 	max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 	max (int a, int b)		{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int	min (int a, int b)		{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-
 // abs is now predefined
 //template<typename T> T abs (T a)		{ return (a<T(0)) ? -a : a; }
 
@@ -122,18 +76,14 @@ public:
   virtual ~UI() {}
 
   virtual void addButton(const char* label, double* zone) = 0;
-  virtual void addToggleButton(const char* label, double* zone) = 0;
   virtual void addCheckButton(const char* label, double* zone) = 0;
-  virtual void addVerticalSlider(const char* label, double* zone, float init, float min, float max, float step) = 0;
-  virtual void addHorizontalSlider(const char* label, double* zone, float init, float min, float max, float step) = 0;
-  virtual void addNumEntry(const char* label, double* zone, float init, float min, float max, float step) = 0;
+  virtual void addVerticalSlider(const char* label, double* zone, double init, double min, double max, double step) = 0;
+  virtual void addHorizontalSlider(const char* label, double* zone, double init, double min, double max, double step) = 0;
+  virtual void addNumEntry(const char* label, double* zone, double init, double min, double max, double step) = 0;
 
-  virtual void addNumDisplay(const char* label, double* zone, int precision) = 0;
-  virtual void addTextDisplay(const char* label, double* zone, char* names[], float min, float max) = 0;
-  virtual void addHorizontalBargraph(const char* label, double* zone, float min, float max) = 0;
-  virtual void addVerticalBargraph(const char* label, double* zone, float min, float max) = 0;
+  virtual void addHorizontalBargraph(const char* label, double* zone, double min, double max) = 0;
+  virtual void addVerticalBargraph(const char* label, double* zone, double min, double max) = 0;
 
-  virtual void openFrameBox(const char* label) = 0;
   virtual void openTabBox(const char* label) = 0;
   virtual void openHorizontalBox(const char* label) = 0;
   virtual void openVerticalBox(const char* label) = 0;
@@ -152,7 +102,7 @@ public:
  ***************************************************************************/
 
 enum ui_elem_type_t {
-  UI_BUTTON, UI_TOGGLE_BUTTON, UI_CHECK_BUTTON,
+  UI_BUTTON, UI_CHECK_BUTTON,
   UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
   UI_V_BARGRAPH, UI_H_BARGRAPH,
   UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
@@ -163,7 +113,7 @@ struct ui_elem_t {
   const char *label;
   double *zone;
   void *ref;
-  float init, min, max, step;
+  double init, min, max, step;
 };
 
 class PureUI : public UI
@@ -180,24 +130,20 @@ protected:
   void add_elem(ui_elem_type_t type, const char *label = NULL);
   void add_elem(ui_elem_type_t type, const char *label, double *zone);
   void add_elem(ui_elem_type_t type, const char *label, double *zone,
-		float init, float min, float max, float step);
+		double init, double min, double max, double step);
   void add_elem(ui_elem_type_t type, const char *label, double *zone,
-		float min, float max);
+		double min, double max);
 
 public:
   virtual void addButton(const char* label, double* zone);
-  virtual void addToggleButton(const char* label, double* zone);
   virtual void addCheckButton(const char* label, double* zone);
-  virtual void addVerticalSlider(const char* label, double* zone, float init, float min, float max, float step);
-  virtual void addHorizontalSlider(const char* label, double* zone, float init, float min, float max, float step);
-  virtual void addNumEntry(const char* label, double* zone, float init, float min, float max, float step);
+  virtual void addVerticalSlider(const char* label, double* zone, double init, double min, double max, double step);
+  virtual void addHorizontalSlider(const char* label, double* zone, double init, double min, double max, double step);
+  virtual void addNumEntry(const char* label, double* zone, double init, double min, double max, double step);
 
-  virtual void addNumDisplay(const char* label, double* zone, int precision);
-  virtual void addTextDisplay(const char* label, double* zone, char* names[], float min, float max);
-  virtual void addHorizontalBargraph(const char* label, double* zone, float min, float max);
-  virtual void addVerticalBargraph(const char* label, double* zone, float min, float max);
+  virtual void addHorizontalBargraph(const char* label, double* zone, double min, double max);
+  virtual void addVerticalBargraph(const char* label, double* zone, double min, double max);
 
-  virtual void openFrameBox(const char* label);
   virtual void openTabBox(const char* label);
   virtual void openHorizontalBox(const char* label);
   virtual void openVerticalBox(const char* label);
@@ -265,7 +211,7 @@ inline void PureUI::add_elem(ui_elem_type_t type, const char *label, double *zon
 }
 
 inline void PureUI::add_elem(ui_elem_type_t type, const char *label, double *zone,
-			     float init, float min, float max, float step)
+			     double init, double min, double max, double step)
 {
   ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
   if (elems1)
@@ -284,7 +230,7 @@ inline void PureUI::add_elem(ui_elem_type_t type, const char *label, double *zon
 }
 
 inline void PureUI::add_elem(ui_elem_type_t type, const char *label, double *zone,
-			     float min, float max)
+			     double min, double max)
 {
   ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
   if (elems1)
@@ -304,26 +250,20 @@ inline void PureUI::add_elem(ui_elem_type_t type, const char *label, double *zon
 
 void PureUI::addButton(const char* label, double* zone)
 { add_elem(UI_BUTTON, label, zone); }
-void PureUI::addToggleButton(const char* label, double* zone)
-{ add_elem(UI_TOGGLE_BUTTON, label, zone); }
 void PureUI::addCheckButton(const char* label, double* zone)
 { add_elem(UI_CHECK_BUTTON, label, zone); }
-void PureUI::addVerticalSlider(const char* label, double* zone, float init, float min, float max, float step)
+void PureUI::addVerticalSlider(const char* label, double* zone, double init, double min, double max, double step)
 { add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
-void PureUI::addHorizontalSlider(const char* label, double* zone, float init, float min, float max, float step)
+void PureUI::addHorizontalSlider(const char* label, double* zone, double init, double min, double max, double step)
 { add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
-void PureUI::addNumEntry(const char* label, double* zone, float init, float min, float max, float step)
+void PureUI::addNumEntry(const char* label, double* zone, double init, double min, double max, double step)
 { add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
 
-// FIXME: addNumDisplay and addTextDisplay not implemented in Faust yet?
-void PureUI::addNumDisplay(const char* label, double* zone, int precision) {}
-void PureUI::addTextDisplay(const char* label, double* zone, char* names[], float min, float max) {}
-void PureUI::addHorizontalBargraph(const char* label, double* zone, float min, float max)
+void PureUI::addHorizontalBargraph(const char* label, double* zone, double min, double max)
 { add_elem(UI_H_BARGRAPH, label, zone, min, max); }
-void PureUI::addVerticalBargraph(const char* label, double* zone, float min, float max)
+void PureUI::addVerticalBargraph(const char* label, double* zone, double min, double max)
 { add_elem(UI_V_BARGRAPH, label, zone, min, max); }
 
-void PureUI::openFrameBox(const char* label) {}
 void PureUI::openTabBox(const char* label)
 { add_elem(UI_T_GROUP, label); }
 void PureUI::openHorizontalBox(const char* label)
diff --git a/architecture/puredata.cpp b/architecture/puredata.cpp
index a41324a..0e9ff9f 100644
--- a/architecture/puredata.cpp
+++ b/architecture/puredata.cpp
@@ -26,82 +26,15 @@
    then loaded dynamically by Pd as an external. */
 
 #include <stdlib.h>
-#include <string.h>
 #include <math.h>
 #include <string>
 
-using namespace std;
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-  #warning *** puredata.cpp: NO SSE FLAG (denormals may slow things down) ***
-  #define AVOIDDENORMALS
-#endif
-
-struct Meta 
-{
-    void declare (const char* key, const char* value) {}
-};
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/gui/meta.h"
+#include "faust/audio/dsp.h"
 
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-
-// abs is now predefined
-//template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
-
-
-inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
+//using namespace std;
 
 /******************************************************************************
 *******************************************************************************
@@ -111,59 +44,14 @@ inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
 *******************************************************************************
 *******************************************************************************/
 
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
 <<includeIntrinsic>>
 
-/******************************************************************************
-*******************************************************************************
-
-			ABSTRACT USER INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-class UI
-{
-  bool	fStopped;
-public:
-		
-  UI() : fStopped(false) {}
-  virtual ~UI() {}
-	
-  virtual void addButton(const char* label, float* zone) = 0;
-  virtual void addToggleButton(const char* label, float* zone) = 0;
-  virtual void addCheckButton(const char* label, float* zone) = 0;
-  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-
-  virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-  virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) = 0;
-  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-	
-  virtual void openFrameBox(const char* label) = 0;
-  virtual void openTabBox(const char* label) = 0;
-  virtual void openHorizontalBox(const char* label) = 0;
-  virtual void openVerticalBox(const char* label) = 0;
-  virtual void closeBox() = 0;
-	
-  virtual void run() = 0;
-	
-  void stop()	{ fStopped = true; }
-  bool stopped() 	{ return fStopped; }
-
-  virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
 /***************************************************************************
    Pd UI interface
  ***************************************************************************/
 
 enum ui_elem_type_t {
-  UI_BUTTON, UI_TOGGLE_BUTTON, UI_CHECK_BUTTON,
+  UI_BUTTON, UI_CHECK_BUTTON,
   UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
   UI_V_BARGRAPH, UI_H_BARGRAPH,
   UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
@@ -179,15 +67,16 @@ struct ui_elem_t {
 class PdUI : public UI
 {
 public:
-  int nelems;
+  const char *name;
+  int nelems, level;
   ui_elem_t *elems;
 		
   PdUI();
-  PdUI(const char *s);
+  PdUI(const char *nm, const char *s);
   virtual ~PdUI();
 
 protected:
-  string path;
+  std::string path;
   void add_elem(ui_elem_type_t type, const char *label = NULL);
   void add_elem(ui_elem_type_t type, const char *label, float *zone);
   void add_elem(ui_elem_type_t type, const char *label, float *zone,
@@ -197,18 +86,14 @@ protected:
 
 public:
   virtual void addButton(const char* label, float* zone);
-  virtual void addToggleButton(const char* label, float* zone);
   virtual void addCheckButton(const char* label, float* zone);
   virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
   virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
   virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
 
-  virtual void addNumDisplay(const char* label, float* zone, int precision);
-  virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max);
   virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
   virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
   
-  virtual void openFrameBox(const char* label);
   virtual void openTabBox(const char* label);
   virtual void openHorizontalBox(const char* label);
   virtual void openVerticalBox(const char* label);
@@ -217,11 +102,24 @@ public:
   virtual void run();
 };
 
-static string mangle(const char *s)
+static std::string mangle(const char *name, int level, const char *s)
 {
   const char *s0 = s;
-  string t = "";
+  std::string t = "";
   if (!s) return t;
+  // Get rid of bogus "0x00" labels in recent Faust revisions. Also, for
+  // backward compatibility with old Faust versions, make sure that default
+  // toplevel groups and explicit toplevel groups with an empty label are
+  // treated alike (these both return "0x00" labels in the latest Faust, but
+  // would be treated inconsistently in earlier versions).
+  if (!*s || strcmp(s, "0x00") == 0) {
+    if (level == 0)
+      // toplevel group with empty label, map to dsp name
+      s = name;
+    else
+      // empty label
+      s = "";
+  }
   while (*s)
     if (isalnum(*s))
       t += *(s++);
@@ -233,18 +131,21 @@ static string mangle(const char *s)
   return t;
 }
 
-static string normpath(string path)
+static std::string normpath(std::string path)
 {
-  path = string("/")+path;
+  path = std::string("/")+path;
   int pos = path.find("//");
   while (pos >= 0) {
     path.erase(pos, 1);
     pos = path.find("//");
   }
+  size_t len = path.length();
+  if (len > 1 && path[len-1] == '/')
+    path.erase(len-1, 1);
   return path;
 }
 
-static string pathcat(string path, string label)
+static std::string pathcat(std::string path, std::string label)
 {
   if (path.empty())
     return normpath(label);
@@ -256,15 +157,17 @@ static string pathcat(string path, string label)
 
 PdUI::PdUI()
 {
-  nelems = 0;
+  nelems = level = 0;
   elems = NULL;
+  name = "";
   path = "";
 }
 
-PdUI::PdUI(const char *s)
+PdUI::PdUI(const char *nm, const char *s)
 {
-  nelems = 0;
+  nelems = level = 0;
   elems = NULL;
+  name = nm?nm:"";
   path = s?s:"";
 }
 
@@ -285,7 +188,7 @@ inline void PdUI::add_elem(ui_elem_type_t type, const char *label)
     elems = elems1;
   else
     return;
-  string s = pathcat(path, mangle(label));
+  std::string s = pathcat(path, mangle(name, level, label));
   elems[nelems].type = type;
   elems[nelems].label = strdup(s.c_str());
   elems[nelems].zone = NULL;
@@ -303,7 +206,7 @@ inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone)
     elems = elems1;
   else
     return;
-  string s = pathcat(path, mangle(label));
+  std::string s = pathcat(path, mangle(name, level, label));
   elems[nelems].type = type;
   elems[nelems].label = strdup(s.c_str());
   elems[nelems].zone = zone;
@@ -322,7 +225,7 @@ inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
     elems = elems1;
   else
     return;
-  string s = pathcat(path, mangle(label));
+  std::string s = pathcat(path, mangle(name, level, label));
   elems[nelems].type = type;
   elems[nelems].label = strdup(s.c_str());
   elems[nelems].zone = zone;
@@ -341,7 +244,7 @@ inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
     elems = elems1;
   else
     return;
-  string s = pathcat(path, mangle(label));
+  std::string s = pathcat(path, mangle(name, level, label));
   elems[nelems].type = type;
   elems[nelems].label = strdup(s.c_str());
   elems[nelems].zone = zone;
@@ -354,8 +257,6 @@ inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
 
 void PdUI::addButton(const char* label, float* zone)
 { add_elem(UI_BUTTON, label, zone); }
-void PdUI::addToggleButton(const char* label, float* zone)
-{ add_elem(UI_TOGGLE_BUTTON, label, zone); }
 void PdUI::addCheckButton(const char* label, float* zone)
 { add_elem(UI_CHECK_BUTTON, label, zone); }
 void PdUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
@@ -365,39 +266,35 @@ void PdUI::addHorizontalSlider(const char* label, float* zone, float init, float
 void PdUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
 { add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
 
-// FIXME: addNumDisplay and addTextDisplay not implemented in Faust yet?
-void PdUI::addNumDisplay(const char* label, float* zone, int precision) {}
-void PdUI::addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) {}
 void PdUI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
 { add_elem(UI_H_BARGRAPH, label, zone, min, max); }
 void PdUI::addVerticalBargraph(const char* label, float* zone, float min, float max)
 { add_elem(UI_V_BARGRAPH, label, zone, min, max); }
 
-void PdUI::openFrameBox(const char* label)
-{
-  if (!path.empty()) path += "/";
-  path += mangle(label);
-}
 void PdUI::openTabBox(const char* label)
 {
   if (!path.empty()) path += "/";
-  path += mangle(label);
+  path += mangle(name, level, label);
+  level++;
 }
 void PdUI::openHorizontalBox(const char* label)
 {
   if (!path.empty()) path += "/";
-  path += mangle(label);
+  path += mangle(name, level, label);
+  level++;
 }
 void PdUI::openVerticalBox(const char* label)
 {
   if (!path.empty()) path += "/";
-  path += mangle(label);
+  path += mangle(name, level, label);
+  level++;
 }
 void PdUI::closeBox()
 {
   int pos = path.rfind("/");
   if (pos < 0) pos = 0;
   path.erase(pos);
+  level--;
 }
 
 void PdUI::run() {}
@@ -410,40 +307,20 @@ void PdUI::run() {}
 *******************************************************************************
 *******************************************************************************/
 
-
-
-//----------------------------------------------------------------
-//  abstract definition of a signal processor
-//----------------------------------------------------------------
-			
-class dsp {
- protected:
-	int fSamplingFreq;
- public:
-	dsp() {}
-	virtual ~dsp() {}
-	virtual int getNumInputs() = 0;
-	virtual int getNumOutputs() = 0;
-	virtual void buildUserInterface(UI* interface) = 0;
-	virtual void init(int samplingRate) = 0;
- 	virtual void compute(int len, float** inputs, float** outputs) = 0;
-};
-
 //----------------------------------------------------------------------------
 //  FAUST generated signal processor
 //----------------------------------------------------------------------------
 		
-
 <<includeclass>>
 
 #include <stdio.h>
-#include <string.h>
+#include <string>
 #include "m_pd.h"
 
-#define faust_setup(name) xfaust_setup(name)
-#define xfaust_setup(name) name ## _tilde_setup(void)
 #define sym(name) xsym(name)
 #define xsym(name) #name
+#define faust_setup(name) xfaust_setup(name)
+#define xfaust_setup(name) name ## _tilde_setup(void)
 
 // time for "active" toggle xfades in secs
 #define XFADE_TIME 0.1f
@@ -459,7 +336,7 @@ struct t_faust {
 #endif
   mydsp *dsp;
   PdUI *ui;
-  string *label;
+  std::string *label;
   int active, xfade, n_xfade, rate, n_in, n_out;
   t_sample **inputs, **outputs, **buf;
   t_outlet *out;
@@ -601,7 +478,6 @@ static void faust_any(t_faust *x, t_symbol *s, int argc, t_atom *argv)
 	case UI_BUTTON:
 	  _s = s_button;
 	  break;
-	case UI_TOGGLE_BUTTON:
 	case UI_CHECK_BUTTON:
 	  _s = s_checkbox;
 	  break;
@@ -700,9 +576,9 @@ static void *faust_new(t_symbol *s, int argc, t_atom *argv)
   if (sr <= 0) sr = 44100;
   x->xfade = 0; x->n_xfade = (int)(sr*XFADE_TIME/64);
   x->inputs = x->outputs = x->buf = NULL;
-  x->label = new string(sym(mydsp) "~");
+    x->label = new std::string(sym(mydsp) "~");
   x->dsp = new mydsp();
-  x->ui = new PdUI(id?id->s_name:NULL);
+  x->ui = new PdUI(sym(mydsp), id?id->s_name:NULL);
   if (!x->dsp || !x->ui || !x->label) goto error;
   if (id) {
     *x->label += " ";
@@ -752,7 +628,7 @@ extern "C" void faust_setup(mydsp)
   s_hslider = gensym((char*)"hslider");
   s_nentry = gensym((char*)"nentry");
   s_vbargraph = gensym((char*)"vbargraph");
-  s_hbargraph = gensym((char*)"hbargrap");
+  s_hbargraph = gensym((char*)"hbargraph");
   /* give some indication that we're loaded and ready to go */
   mydsp dsp = mydsp();
   post("[faust] %s: %d inputs, %d outputs", sym(mydsp) "~",
diff --git a/architecture/q.cpp b/architecture/q.cpp
index 8189c4d..8bfac38 100644
--- a/architecture/q.cpp
+++ b/architecture/q.cpp
@@ -32,52 +32,6 @@ struct Meta
     void declare (const char* key, const char* value) { }
 };
 
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
 
@@ -114,18 +68,14 @@ public:
   virtual ~UI() {}
 	
   virtual void addButton(char* label, float* zone) = 0;
-  virtual void addToggleButton(char* label, float* zone) = 0;
   virtual void addCheckButton(char* label, float* zone) = 0;
   virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
   virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
   virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
 
-  virtual void addNumDisplay(char* label, float* zone, int precision) = 0;
-  virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max) = 0;
   virtual void addHorizontalBargraph(char* label, float* zone, float min, float max) = 0;
   virtual void addVerticalBargraph(char* label, float* zone, float min, float max) = 0;
 	
-  virtual void openFrameBox(char* label) = 0;
   virtual void openTabBox(char* label) = 0;
   virtual void openHorizontalBox(char* label) = 0;
   virtual void openVerticalBox(char* label) = 0;
@@ -144,7 +94,7 @@ public:
  ***************************************************************************/
 
 enum ui_elem_type_t {
-  UI_BUTTON, UI_TOGGLE_BUTTON, UI_CHECK_BUTTON,
+  UI_BUTTON, UI_CHECK_BUTTON,
   UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
   UI_V_BARGRAPH, UI_H_BARGRAPH,
   UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
@@ -177,18 +127,14 @@ protected:
 
 public:
   virtual void addButton(char* label, float* zone);
-  virtual void addToggleButton(char* label, float* zone);
   virtual void addCheckButton(char* label, float* zone);
   virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step);
   virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step);
   virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step);
 
-  virtual void addNumDisplay(char* label, float* zone, int precision);
-  virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max);
   virtual void addHorizontalBargraph(char* label, float* zone, float min, float max);
   virtual void addVerticalBargraph(char* label, float* zone, float min, float max);
   
-  virtual void openFrameBox(char* label);
   virtual void openTabBox(char* label);
   virtual void openHorizontalBox(char* label);
   virtual void openVerticalBox(char* label);
@@ -284,8 +230,6 @@ inline void QUI::add_elem(ui_elem_type_t type, char *label, float *zone,
 
 void QUI::addButton(char* label, float* zone)
 { add_elem(UI_BUTTON, label, zone); }
-void QUI::addToggleButton(char* label, float* zone)
-{ add_elem(UI_TOGGLE_BUTTON, label, zone); }
 void QUI::addCheckButton(char* label, float* zone)
 { add_elem(UI_CHECK_BUTTON, label, zone); }
 void QUI::addVerticalSlider(char* label, float* zone, float init, float min, float max, float step)
@@ -295,15 +239,11 @@ void QUI::addHorizontalSlider(char* label, float* zone, float init, float min, f
 void QUI::addNumEntry(char* label, float* zone, float init, float min, float max, float step)
 { add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
 
-// FIXME: addNumDisplay and addTextDisplay not implemented in Faust yet?
-void QUI::addNumDisplay(char* label, float* zone, int precision) {}
-void QUI::addTextDisplay(char* label, float* zone, char* names[], float min, float max) {}
 void QUI::addHorizontalBargraph(char* label, float* zone, float min, float max)
 { add_elem(UI_H_BARGRAPH, label, zone, min, max); }
 void QUI::addVerticalBargraph(char* label, float* zone, float min, float max)
 { add_elem(UI_V_BARGRAPH, label, zone, min, max); }
 
-void QUI::openFrameBox(char* label) {}
 void QUI::openTabBox(char* label)
 { add_elem(UI_T_GROUP, label); }
 void QUI::openHorizontalBox(char* label)
diff --git a/architecture/ra-qt.cpp b/architecture/ra-qt.cpp
new file mode 100644
index 0000000..e7e7351
--- /dev/null
+++ b/architecture/ra-qt.cpp
@@ -0,0 +1,195 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections :
+	the ARCHITECTURE section (in two parts) and the USER section. Each section
+	is governed by its own copyright and license. Please check individually
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work
+	that contains this FAUST architecture section and distribute
+	that work under terms of your choice, so long as this FAUST
+	architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <iostream>
+#include <list>
+
+#include "faust/gui/FUI.h"
+#include "faust/gui/faustqt.h"
+#include "faust/misc.h"
+#include "faust/audio/rtaudio-dsp.h"
+#include "faust/midi/midi.h"
+
+#ifdef OSCCTRL
+#include "faust/gui/OSCUI.h"
+#endif
+
+#ifdef HTTPCTRL
+#include "faust/gui/httpdUI.h"
+#endif
+
+#if MIDICTRL
+#include "faust/midi/rt-midi.h"
+#include "faust/gui/MidiUI.h"
+#endif
+
+/**************************BEGIN USER SECTION **************************/
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+#ifdef POLY
+#include "faust/dsp/poly-dsp.h"
+mydsp_poly*	DSP;
+#else
+mydsp* DSP;
+#endif
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+std::list<GUI*> GUI::fGuiList;
+
+/******************************************************************************
+*******************************************************************************
+
+                                MAIN PLAY THREAD
+
+*******************************************************************************
+*******************************************************************************/
+
+int main(int argc, char *argv[])
+{
+	char name[256];
+	char rcfilename[256];
+	char* home = getenv("HOME");
+
+	snprintf(name, 255, "%s", basename(argv[0]));
+	snprintf(rcfilename, 255, "%s/.%src", home, basename(argv[0]));
+    
+    long srate = (long)lopt(argv, "--frequency", 44100);
+    int fpb = lopt(argv, "--buffer", 512);
+    int poly = lopt(argv, "--poly", 4);
+    
+#if MIDICTRL
+    rtmidi midi;
+#endif
+
+#ifdef POLY
+#if MIDICTRL
+    DSP = new mydsp_poly(poly, true);
+    midi.addMidiIn(DSP);
+#else
+    DSP = new mydsp_poly(poly);
+#endif
+#else
+    DSP = new mydsp();
+#endif
+    if (DSP == 0) {
+        std::cerr << "Unable to allocate Faust DSP object" << std::endl;
+        exit(1);
+    }
+ 
+	QApplication myApp(argc, argv);
+    
+    QTGUI interface;
+    FUI finterface;
+    DSP->buildUserInterface(&interface);
+    DSP->buildUserInterface(&finterface);
+
+#ifdef MIDICTRL
+    MidiUI midiinterface(name);
+    DSP->buildUserInterface(&midiinterface);
+    std::cout << "MIDI is on" << std::endl;
+#endif
+
+#ifdef HTTPCTRL
+    httpdUI httpdinterface(name, DSP->getNumInputs(), DSP->getNumOutputs(), argc, argv);
+    DSP->buildUserInterface(&httpdinterface);
+    std::cout << "HTTPD is on" << std::endl;
+ #endif
+
+#ifdef OSCCTRL
+	OSCUI oscinterface(name, argc, argv);
+	DSP->buildUserInterface(&oscinterface);
+    std::cout << "OSC is on" << std::endl;
+#endif
+
+	rtaudio audio(srate, fpb);
+	audio.init(name, DSP);
+	finterface.recallState(rcfilename);
+	audio.start();
+    
+    printf("ins %d\n", audio.get_num_inputs());
+    printf("outs %d\n", audio.get_num_outputs());
+    
+#if MIDICTRL
+    midi.start();
+#endif
+
+#ifdef HTTPCTRL
+	httpdinterface.run();
+#ifdef QRCODECTRL
+    interface.displayQRCode(httpdinterface.getTCPPort());
+#endif
+#endif
+
+#ifdef OSCCTRL
+	oscinterface.run();
+#endif
+#ifdef MIDICTRL
+	midiinterface.run();
+#endif
+	interface.run();
+
+    myApp.setStyleSheet(interface.styleSheet());
+    myApp.exec();
+    interface.stop();
+    
+	audio.stop();
+	finterface.saveState(rcfilename);
+    
+#ifdef MIDICTRL
+    midi.stop();
+#endif
+
+  	return 0;
+}
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
+
diff --git a/architecture/ros-callbacks.cpp b/architecture/ros-callbacks.cpp
new file mode 100644
index 0000000..26275b0
--- /dev/null
+++ b/architecture/ros-callbacks.cpp
@@ -0,0 +1,122 @@
+/************************************************************************
+
+	IMPORTANT NOTE : this file contains two clearly delimited sections : 
+	the ARCHITECTURE section (in two parts) and the USER section. Each section 
+	is governed by its own copyright and license. Please check individually 
+	each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2014-2015 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section 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 3 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, see <http://www.gnu.org/licenses/>.
+
+	EXCEPTION : As a special exception, you may create a larger work 
+	that contains this FAUST architecture section and distribute  
+	that work under terms of your choice, so long as this FAUST 
+	architecture section is not modified. 
+
+
+ ************************************************************************
+ ************************************************************************/
+
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+
+
+#include "faust/misc.h"
+#include "faust/gui/RosCI.h"
+#include "faust/audio/dsp.h"
+
+
+
+/**************************BEGIN USER SECTION **************************/
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+
+<<includeclass>>
+
+/***************************END USER SECTION ***************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
+
+/************************************************************************
+*************************************************************************
+			
+							BE CAREFUL :
+			
+	This architecture file cannot be used to deal with any stream.
+	It has been written to be used before an over architecture file :
+		- jack-ros.cpp
+		- jack-gtk-ros.cpp
+		
+	It has been written for faust2appls tools like faust2ros or 
+	faust2rosgtk
+	
+*************************************************************************
+*************************************************************************/
+				
+mydsp*	DSP;
+
+//-------------------------------------------------------------------------
+// 									MAIN
+//-------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+    char	appname[256];
+	
+	snprintf(appname, 255, "%s", basename(argv[0]));
+    
+	// Create DSP Object
+	DSP = new mydsp();
+	if (DSP==0) {
+        std::cout<<"Unable to allocate Faust DSP object" <<std::endl;
+		exit(1);
+	}
+	
+	// Create and build ROS Callbacks Interface
+	RosCI* interface = new RosCI();
+	DSP->buildUserInterface(interface);
+	
+	// Gets the number of ROS metadata declared
+	int count = interface->getParamsCount();
+	
+	// Gets the callbacks parameters
+	std::vector<RosCI::CallbackParams> parameters = interface->getCallbacksParameters();
+	
+	std::string name = static_cast<std::string>(appname);
+	// Writes the rosCallbacks.h file
+	interface->callbacksWriter(count, parameters, name);
+
+	// desallocation
+	delete interface;
+
+	return 0;
+}
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
+
diff --git a/architecture/scheduler.cpp b/architecture/scheduler.cpp
index b8262e7..b04370f 100644
--- a/architecture/scheduler.cpp
+++ b/architecture/scheduler.cpp
@@ -1,10 +1,941 @@
 
+#include <stdlib.h>
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <semaphore.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <math.h>
+
+using namespace std;
+
+// Globals
+
 #define THREAD_SIZE 64
+#define QUEUE_SIZE 4096
+
+#define WORK_STEALING_INDEX 0
+#define LAST_TASK_INDEX 1
+
+
+#ifdef __ICC
+#define INLINE __forceinline
+#else
+#define INLINE inline
+#endif
+
+
+// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
+// flags to avoid costly denormals
+#ifdef __SSE__
+#include <xmmintrin.h>
+#ifdef __SSE2__
+#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#else
+#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+#endif
+#else
+#define AVOIDDENORMALS 
+#endif
+
+#ifdef __linux__
+
+// handle 32/64 bits int size issues
+#ifdef __x86_64__
+#define UInt32	unsigned int
+#define UInt64	unsigned long int
+#else
+#define UInt32	unsigned int
+#define UInt64	unsigned long long int
+#endif
+
+#endif
+
+#ifdef __APPLE__
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#endif
 
 class TaskQueue;
-class DSPThreadPool;
+struct DSPThreadPool;
+
+extern TaskQueue* gTaskQueueList[THREAD_SIZE];
+extern DSPThreadPool* gThreadPool;
+extern int gClientCount;
+extern UInt64 gMaxStealing;
+    
+void Yield();
+
+/**
+ * Returns the number of clock cycles elapsed since the last reset
+ * of the processor
+ */
+static INLINE UInt64 DSP_rdtsc(void)
+{
+	union {
+		UInt32 i32[2];
+		UInt64 i64;
+	} count;
+	
+	__asm__ __volatile__("rdtsc" : "=a" (count.i32[0]), "=d" (count.i32[1]));
+     return count.i64;
+}
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#define LOCK "lock ; "
+
+static INLINE void NOP(void)
+{
+	__asm__ __volatile__("nop \n\t");
+}
+
+static INLINE char CAS1(volatile void* addr, volatile int value, int newvalue)
+{
+    register char ret;
+    __asm__ __volatile__ (
+						  "# CAS \n\t"
+						  LOCK "cmpxchg %2, (%1) \n\t"
+						  "sete %0               \n\t"
+						  : "=a" (ret)
+						  : "c" (addr), "d" (newvalue), "a" (value)
+                          : "memory"
+						  );
+    return ret;
+}
+
+static INLINE int atomic_xadd(volatile int* atomic, int val) 
+{ 
+    register int result;
+    __asm__ __volatile__ ("# atomic_xadd \n\t"
+                          LOCK "xaddl %0,%1 \n\t"
+                          : "=r" (result), "=m" (*atomic) 
+                          : "0" (val), "m" (*atomic));
+    return result;
+} 
+
+#endif
+
+
+/*
+static INLINE int INC_ATOMIC(volatile int* val)
+{
+    int actual;
+    do {
+        actual = *val;
+    } while (!CAS1(val, actual, actual + 1));
+    return actual;
+}
+
+static INLINE int DEC_ATOMIC(volatile int* val)
+{
+    int actual;
+    do {
+        actual = *val;
+    } while (!CAS1(val, actual, actual - 1));
+    return actual;
+}
+*/
+
+static INLINE int INC_ATOMIC(volatile int* val)
+{
+    return atomic_xadd(val, 1);
+}
+ 
+static INLINE int DEC_ATOMIC(volatile int* val)
+{
+    return atomic_xadd(val, -1);
+}
+ 
+// To be used in lock-free queue
+struct AtomicCounter
+{
+    union {
+        struct {
+            short fHead;	
+            short fTail;	
+        }
+        scounter;
+        int fValue;
+    }info;
+    
+	INLINE AtomicCounter()
+	{
+        info.fValue = 0;
+    }
+     
+ 	INLINE  AtomicCounter& operator=(AtomicCounter& obj)
+    {
+        info.fValue = obj.info.fValue;
+        return *this;
+    }
+    
+	INLINE  AtomicCounter& operator=(volatile AtomicCounter& obj)
+	{
+        info.fValue = obj.info.fValue;
+        return *this;
+    }
+    
+};
+
+int get_max_cpu()
+{
+    return sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+static int GetPID()
+{
+#ifdef WIN32
+    return  _getpid();
+#else
+    return getpid();
+#endif
+}
+
+#define Value(e) (e).info.fValue
+
+#define Head(e) (e).info.scounter.fHead
+#define IncHead(e) (e).info.scounter.fHead++
+#define DecHead(e) (e).info.scounter.fHead--
+
+#define Tail(e) (e).info.scounter.fTail
+#define IncTail(e) (e).info.scounter.fTail++
+#define DecTail(e) (e).info.scounter.fTail--
+
+#define MASTER_THREAD 0
+
+#define MAX_STEAL_DUR 50                    // in usec
+#define DEFAULT_CLOCKSPERSEC 2500000000     // in cycles (2,5 Ghz)
+
+class TaskQueue 
+{
+    private:
+    
+        int fTaskList[QUEUE_SIZE];
+        volatile AtomicCounter fCounter;
+        UInt64 fStealingStart;
+     
+    public:
+  
+        INLINE TaskQueue(int cur_thread)
+        {
+            for (int i = 0; i < QUEUE_SIZE; i++) {
+                fTaskList[i] = -1;
+            }
+            gTaskQueueList[cur_thread] = this;	
+            fStealingStart = 0;
+        }
+         
+        INLINE void PushHead(int item)
+        {
+            fTaskList[Head(fCounter)] = item;
+            IncHead(fCounter);
+        }
+        
+        INLINE int PopHead()
+        {
+            AtomicCounter old_val;
+            AtomicCounter new_val;
+            
+            do {
+                old_val = fCounter;
+                new_val = old_val;
+                if (Head(old_val) == Tail(old_val)) {
+                    return WORK_STEALING_INDEX;
+                } else {
+                    DecHead(new_val);
+                }
+            } while (!CAS1(&fCounter, Value(old_val), Value(new_val)));
+            
+            return fTaskList[Head(old_val) - 1];
+        }
+        
+        INLINE int PopTail()
+        {
+            AtomicCounter old_val;
+            AtomicCounter new_val;
+            
+            do {
+                old_val = fCounter;
+                new_val = old_val;
+                if (Head(old_val) == Tail(old_val)) {
+                   return WORK_STEALING_INDEX;
+                } else {
+                    IncTail(new_val);
+                }
+            } while (!CAS1(&fCounter, Value(old_val), Value(new_val)));
+            
+            return fTaskList[Tail(old_val)];
+        }
+
+		INLINE void MeasureStealingDur()
+		{
+            // Takes first timetamp
+            if (fStealingStart == 0) {
+                fStealingStart = DSP_rdtsc();
+            } else if ((DSP_rdtsc() - fStealingStart) > gMaxStealing) {
+                Yield();
+            }
+		}
+
+		INLINE void ResetStealingDur()
+		{
+            fStealingStart = 0;
+		}
+        
+        static INLINE int GetNextTask(int thread, int num_threads)
+        {
+            int tasknum;
+            for (int i = 0; i < num_threads; i++) {
+                if ((i != thread) && gTaskQueueList[i] && (tasknum = gTaskQueueList[i]->PopTail()) != WORK_STEALING_INDEX) {
+                #ifdef __linux__
+					//if (thread != MASTER_THREAD)
+						gTaskQueueList[thread]->ResetStealingDur();
+                #endif
+                    return tasknum;    // Task is found
+                }
+            }
+            NOP();
+          #ifdef __linux__
+			//if (thread != MASTER_THREAD)
+				gTaskQueueList[thread]->MeasureStealingDur();
+        #endif
+            return WORK_STEALING_INDEX;    // Otherwise will try "workstealing" again next cycle...
+        }
+        
+        INLINE void InitTaskList(int task_list_size, int* task_list, int thread_num, int cur_thread, int& tasknum)
+        {
+            int task_slice = task_list_size / thread_num;
+            int task_slice_rest = task_list_size % thread_num;
+
+            if (task_slice == 0) {
+                // Each thread directly executes one task
+                tasknum = task_list[cur_thread];
+                // Thread 0 takes remaining ready tasks 
+                if (cur_thread == 0) { 
+                    for (int index = 0; index < task_slice_rest - thread_num; index++) {
+                        PushHead(task_list[task_slice_rest + index]);
+                    }
+                }
+            } else {
+                // Each thread takes a part of ready tasks
+                int index;
+                for (index = 0; index < task_slice - 1; index++) {
+                    PushHead(task_list[cur_thread * task_slice + index]);
+                }
+                // Each thread directly executes one task 
+                tasknum = task_list[cur_thread * task_slice + index];
+                // Thread 0 takes remaining ready tasks 
+                if (cur_thread == 0) {
+                    for (index = 0; index < task_slice_rest; index++) {
+                        PushHead(task_list[thread_num * task_slice + index]);
+                    }
+                }
+            }
+        }
+        
+        static INLINE void Init()
+        {
+            for (int i = 0; i < THREAD_SIZE; i++) {
+                gTaskQueueList[i] = 0;
+            }
+        }
+     
+};
+
+struct TaskGraph 
+{
+    volatile int gTaskList[QUEUE_SIZE];
+    
+    TaskGraph()
+    {
+        for (int i = 0; i < QUEUE_SIZE; i++) {
+            gTaskList[i] = 0;
+        } 
+    }
+
+    INLINE void InitTask(int task, int val)
+    {
+        gTaskList[task] = val;
+    }
+    
+    void Display()
+    {
+        for (int i = 0; i < QUEUE_SIZE; i++) {
+            printf("Task = %d activation = %d\n", i, gTaskList[i]);
+        } 
+    }
+      
+    INLINE void ActivateOutputTask(TaskQueue& queue, int task, int& tasknum)
+    {
+        if (DEC_ATOMIC(&gTaskList[task]) == 1) {
+            if (tasknum == WORK_STEALING_INDEX) {
+                tasknum = task;
+            } else {
+                queue.PushHead(task);
+            }
+        }    
+    }
+      
+    INLINE void ActivateOutputTask(TaskQueue& queue, int task)
+    {
+        if (DEC_ATOMIC(&gTaskList[task]) == 1) {
+            queue.PushHead(task);
+        }
+    }
+    
+    INLINE void ActivateOneOutputTask(TaskQueue& queue, int task, int& tasknum)
+    {
+        if (DEC_ATOMIC(&gTaskList[task]) == 1) {
+            tasknum = task;
+        } else {
+            tasknum = queue.PopHead(); 
+        }
+    }
+    
+    INLINE void GetReadyTask(TaskQueue& queue, int& tasknum)
+    {
+        if (tasknum == WORK_STEALING_INDEX) {
+            tasknum = queue.PopHead();
+        }
+    }
+ 
+};
+
+
+#define THREAD_POOL_SIZE 16
+#define JACK_SCHED_POLICY SCHED_FIFO
+
+/* use 512KB stack per thread - the default is way too high to be feasible
+ * with mlockall() on many systems */
+#define THREAD_STACK 524288
+
+
+#ifdef __APPLE__
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <mach/thread_policy.h>
+#include <mach/thread_act.h>
+
+#define THREAD_SET_PRIORITY         0
+#define THREAD_SCHEDULED_PRIORITY   1
+
+static UInt32 GetThreadPriority(pthread_t thread, int inWhichPriority);
+
+// returns the thread's priority as it was last set by the API
+static UInt32 GetThreadSetPriority(pthread_t thread)
+{
+    return GetThreadPriority(thread, THREAD_SET_PRIORITY);
+}
+
+// returns the thread's priority as it was last scheduled by the Kernel
+static UInt32 GetThreadScheduledPriority(pthread_t thread)
+{
+    return GetThreadPriority(thread, THREAD_SCHEDULED_PRIORITY);
+}
+
+static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint)
+{
+    if (inPriority == 96) {
+        // REAL-TIME / TIME-CONSTRAINT THREAD
+        thread_time_constraint_policy_data_t theTCPolicy;
+        theTCPolicy.period = period;
+        theTCPolicy.computation = computation;
+        theTCPolicy.constraint = constraint;
+        theTCPolicy.preemptible = true;
+        kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
+        return (res == KERN_SUCCESS) ? 0 : -1;
+    } else {
+        // OTHER THREADS
+        thread_extended_policy_data_t theFixedPolicy;
+        thread_precedence_policy_data_t thePrecedencePolicy;
+        SInt32 relativePriority;
+        
+        // [1] SET FIXED / NOT FIXED
+        theFixedPolicy.timeshare = !inIsFixed;
+        thread_policy_set(pthread_mach_thread_np(thread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
+        
+        // [2] SET PRECEDENCE
+        // N.B.: We expect that if thread A created thread B, and the program wishes to change
+        // the priority of thread B, then the call to change the priority of thread B must be
+        // made by thread A.
+        // This assumption allows us to use pthread_self() to correctly calculate the priority
+        // of the feeder thread (since precedency policy's importance is relative to the
+        // spawning thread's priority.)
+        relativePriority = inPriority - GetThreadSetPriority(pthread_self());
+        
+        thePrecedencePolicy.importance = relativePriority;
+        kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT);
+        return (res == KERN_SUCCESS) ? 0 : -1;
+    }
+}
+
+static UInt32 GetThreadPriority(pthread_t thread, int inWhichPriority)
+{
+    thread_basic_info_data_t threadInfo;
+    policy_info_data_t thePolicyInfo;
+    unsigned int count;
+    
+    // get basic info
+    count = THREAD_BASIC_INFO_COUNT;
+    thread_info(pthread_mach_thread_np(thread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count);
+    
+    switch (threadInfo.policy) {
+        case POLICY_TIMESHARE:
+            count = POLICY_TIMESHARE_INFO_COUNT;
+            thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count);
+            if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) {
+                return thePolicyInfo.ts.cur_priority;
+            } else {
+                return thePolicyInfo.ts.base_priority;
+            }
+            break;
+            
+        case POLICY_FIFO:
+            count = POLICY_FIFO_INFO_COUNT;
+            thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count);
+            if ((thePolicyInfo.fifo.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY)) {
+                return thePolicyInfo.fifo.depress_priority;
+            }
+            return thePolicyInfo.fifo.base_priority;
+            break;
+            
+        case POLICY_RR:
+            count = POLICY_RR_INFO_COUNT;
+            thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count);
+            if ((thePolicyInfo.rr.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY)) {
+                return thePolicyInfo.rr.depress_priority;
+            }
+            return thePolicyInfo.rr.base_priority;
+            break;
+    }
+    
+    return 0;
+}
+
+static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint)
+{
+    thread_time_constraint_policy_data_t theTCPolicy;
+    mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;
+    boolean_t get_default = false;
+    
+    kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread),
+                                          THREAD_TIME_CONSTRAINT_POLICY,
+                                          (thread_policy_t)&theTCPolicy,
+                                          &count,
+                                          &get_default);
+    if (res == KERN_SUCCESS) {
+        *period = theTCPolicy.period;
+        *computation = theTCPolicy.computation;
+        *constraint = theTCPolicy.constraint;
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+static UInt64 period = 0;
+static UInt64 computation = 0;
+static UInt64 constraint = 0;
+
+INLINE void GetRealTime()
+{
+    if (period == 0) {
+        GetParams(pthread_self(), &period, &computation, &constraint);
+    }
+}
+
+INLINE void SetRealTime()
+{
+    SetThreadToPriority(pthread_self(), 96, true, period, computation, constraint);
+}
+
+void CancelThread(pthread_t fThread)
+{
+    mach_port_t machThread = pthread_mach_thread_np(fThread);
+    thread_terminate(machThread);
+}
+
+INLINE void Yield()
+{
+    //sched_yield();
+}
+
+#endif
+
+#ifdef __linux__
+
+static int faust_sched_policy = -1;
+static struct sched_param faust_rt_param; 
+
+INLINE void GetRealTime()
+{
+    if (faust_sched_policy == -1) {
+        memset(&faust_rt_param, 0, sizeof(faust_rt_param));
+    	pthread_getschedparam(pthread_self(), &faust_sched_policy, &faust_rt_param);
+    }
+}
+
+INLINE void SetRealTime()
+{
+	faust_rt_param.sched_priority--;
+    pthread_setschedparam(pthread_self(), faust_sched_policy, &faust_rt_param);
+}
+
+void CancelThread(pthread_t fThread)
+{
+    pthread_cancel(fThread);
+    pthread_join(fThread, NULL);
+}
+
+INLINE void Yield()
+{
+    pthread_yield();
+}
+
+
+#endif
+
+#define KDSPMESURE 50
+
+static INLINE int Range(int min, int max, int val)
+{
+    if (val < min) {
+        return min;
+    } else if (val > max) {
+        return max;
+    } else {
+        return val;
+    }
+}
+
+struct Runnable {
+    
+    UInt64 fTiming[KDSPMESURE];
+    UInt64 fStart;
+    UInt64 fStop;
+    int fCounter;
+    float fOldMean;
+    int fOldfDynamicNumThreads;
+    bool fDynAdapt;
+    
+    virtual void computeThread(int cur_thread) = 0;
+    
+    Runnable():fCounter(0), fOldMean(1000000000.f), fOldfDynamicNumThreads(1)
+    {
+    	memset(fTiming, 0, sizeof(long long int ) * KDSPMESURE);
+        fDynAdapt = getenv("OMP_DYN_THREAD") ? strtol(getenv("OMP_DYN_THREAD"), NULL, 10) : false;
+    }
+    
+    INLINE float ComputeMean()
+    {
+        float mean = 0;
+        for (int i = 0; i < KDSPMESURE; i++) {
+            mean += float(fTiming[i]);
+        }
+        mean /= float(KDSPMESURE);
+        return mean;
+    }
+    
+    INLINE void StartMeasure()
+    {
+        if (!fDynAdapt)
+            return;
+        
+        fStart = DSP_rdtsc();
+    }
+     
+    INLINE void StopMeasure(int staticthreadnum, int& dynthreadnum)
+    {
+        if (!fDynAdapt)
+            return;
+        
+        fStop = DSP_rdtsc();
+        fCounter = (fCounter + 1) % KDSPMESURE;
+        if (fCounter == 0) {
+            float mean = ComputeMean();
+            if (fabs(mean - fOldMean) > 5000) {
+                if (mean > fOldMean) { // Worse...
+                    //printf("Worse %f %f\n", mean, fOldMean);
+                    if (fOldfDynamicNumThreads > dynthreadnum) {
+                        fOldfDynamicNumThreads = dynthreadnum;
+                        dynthreadnum += 1;
+                    } else {
+                        fOldfDynamicNumThreads = dynthreadnum;
+                        dynthreadnum -= 1;
+                    }
+                 } else { // Better...
+                    //printf("Better %f %f\n", mean, fOldMean);
+                    if (fOldfDynamicNumThreads > dynthreadnum) {
+                        fOldfDynamicNumThreads = dynthreadnum;
+                        dynthreadnum -= 1;
+                    } else {
+                        fOldfDynamicNumThreads = dynthreadnum;
+                        dynthreadnum += 1;
+                    }
+                }
+                fOldMean = mean;
+                dynthreadnum = Range(1, staticthreadnum, dynthreadnum);
+                //printf("dynthreadnum %d\n", dynthreadnum);
+            }
+        }
+        fTiming[fCounter] = fStop - fStart; 
+    }
+};
+
+struct DSPThread;
+
+struct DSPThreadPool {
+    
+    DSPThread* fThreadPool[THREAD_POOL_SIZE];
+    int fThreadCount; 
+    volatile int fCurThreadCount;
+      
+    DSPThreadPool();
+    ~DSPThreadPool();
+    
+    void StartAll(int num, bool realtime);
+    void StopAll();
+    void SignalAll(int num, Runnable* runnable);
+    
+    void SignalOne();
+    bool IsFinished();
+    
+    static DSPThreadPool* Init();
+    static void Destroy();
+    
+};
+
+struct DSPThread {
+
+    pthread_t fThread;
+    DSPThreadPool* fThreadPool;
+    Runnable* fRunnable;
+    sem_t* fSemaphore;
+    char fName[128];
+    bool fRealTime;
+    int fNum;
+    
+    DSPThread(int num, DSPThreadPool* pool)
+    {
+        fNum = num;
+        fThreadPool = pool;
+        fRunnable = NULL;
+        fRealTime = false;
+        
+        sprintf(fName, "faust_sem_%d_%p", GetPID(), this);
+        
+        if ((fSemaphore = sem_open(fName, O_CREAT, 0777, 0)) == (sem_t*)SEM_FAILED) {
+            printf("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
+        }
+    }
+
+    virtual ~DSPThread()
+    {
+        sem_unlink(fName);
+        sem_close(fSemaphore);
+    }
+    
+    void Run()
+    {
+        while (sem_wait(fSemaphore) != 0) {}
+        fRunnable->computeThread(fNum + 1);
+        fThreadPool->SignalOne();
+    }
+    
+    static void* ThreadHandler(void* arg)
+    {
+        DSPThread* thread = static_cast<DSPThread*>(arg);
+        
+        AVOIDDENORMALS;
+        
+        // One "dummy" cycle to setup thread
+        if (thread->fRealTime) {
+            thread->Run();
+            SetRealTime();
+        }
+                  
+        while (true) {
+            thread->Run();
+        }
+        
+        return NULL;
+    }
+    
+    int Start(bool realtime)
+    {
+        pthread_attr_t attributes;
+        struct sched_param rt_param;
+        pthread_attr_init(&attributes);
+        
+        int priority = 60; // TODO
+        int res;
+        
+        if (realtime) {
+            fRealTime = true;
+        }else {
+            fRealTime = getenv("OMP_REALTIME") ? strtol(getenv("OMP_REALTIME"), NULL, 10) : true;
+        }
+                               
+        if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
+            printf("Cannot request joinable thread creation for real-time thread res = %d err = %s\n", res, strerror(errno));
+            return -1;
+        }
+
+        if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
+            printf("Cannot set scheduling scope for real-time thread res = %d err = %s\n", res, strerror(errno));
+            return -1;
+        }
+
+        if (realtime) {
+            
+            if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
+                printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno));
+                return -1;
+            }
+        
+            if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) {
+                printf("Cannot set RR scheduling class for RT thread res = %d err = %s\n", res, strerror(errno));
+                return -1;
+            }
+            
+            memset(&rt_param, 0, sizeof(rt_param));
+            rt_param.sched_priority = priority;
+
+            if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
+                printf("Cannot set scheduling priority for RT thread res = %d err = %s\n", res, strerror(errno));
+                return -1;
+            }
+
+        } else {
+            
+            if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_INHERIT_SCHED))) {
+                printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno));
+                return -1;
+            }
+        }
+     
+        if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) {
+            printf("Cannot set thread stack size res = %d err = %s\n", res, strerror(errno));
+            return -1;
+        }
+        
+        if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) {
+            printf("Cannot create thread res = %d err = %s\n", res, strerror(errno));
+            return -1;
+        }
+
+        pthread_attr_destroy(&attributes);
+        return 0;
+    }
+    
+    void Signal(bool stop, Runnable* runnable)
+    {
+        fRunnable = runnable;
+        sem_post(fSemaphore);
+    }
+    
+    void Stop()
+    {
+        CancelThread(fThread);
+    }
+
+};
+
+DSPThreadPool::DSPThreadPool()
+{
+    for (int i = 0; i < THREAD_POOL_SIZE; i++) {
+        fThreadPool[i] = NULL;
+    }
+    fThreadCount = 0;
+    fCurThreadCount = 0;
+}
+
+DSPThreadPool::~DSPThreadPool()
+{
+    StopAll();
+    
+    for (int i = 0; i < fThreadCount; i++) {
+        delete(fThreadPool[i]);
+        fThreadPool[i] = NULL;
+    }
+    
+    fThreadCount = 0;
+ }
+
+void DSPThreadPool::StartAll(int num, bool realtime)
+{
+    if (fThreadCount == 0) {  // Protection for multiple call...  (like LADSPA plug-ins in Ardour)
+        for (int i = 0; i < num; i++) {
+            fThreadPool[i] = new DSPThread(i, this);
+            fThreadPool[i]->Start(realtime);
+            fThreadCount++;
+        }
+    }
+}
+
+void DSPThreadPool::StopAll()
+{
+    for (int i = 0; i < fThreadCount; i++) {
+        fThreadPool[i]->Stop();
+    }
+}
+
+void DSPThreadPool::SignalAll(int num, Runnable* runnable)
+{
+    fCurThreadCount = num;
+        
+    for (int i = 0; i < num; i++) {  // Important : use local num here...
+        fThreadPool[i]->Signal(false, runnable);
+    }
+}
+
+void DSPThreadPool::SignalOne()
+{
+    DEC_ATOMIC(&fCurThreadCount);
+}
+
+bool DSPThreadPool::IsFinished()
+{
+    return (fCurThreadCount == 0);
+}
+
+DSPThreadPool* DSPThreadPool::Init()
+{
+    if (gClientCount++ == 0 && !gThreadPool) {
+        gThreadPool = new DSPThreadPool();
+    }
+    return gThreadPool;
+}
+
+void DSPThreadPool::Destroy()
+{
+    if (--gClientCount == 0 && gThreadPool) {
+        delete gThreadPool;
+        gThreadPool = NULL;
+    }
+}
+
+#ifndef PLUG_IN
 
 // Globals
 TaskQueue* gTaskQueueList[THREAD_SIZE] = {0};
+
 DSPThreadPool* gThreadPool = 0;
 int gClientCount = 0;
+
+int clock_per_microsec = (getenv("CLOCKSPERSEC") 
+                ? strtoll(getenv("CLOCKSPERSEC"), NULL, 10) 
+                : DEFAULT_CLOCKSPERSEC) / 1000000;
+                
+UInt64  gMaxStealing = getenv("OMP_STEALING_DUR") 
+                ? strtoll(getenv("OMP_STEALING_DUR"), NULL, 10) * clock_per_microsec 
+                : MAX_STEAL_DUR * clock_per_microsec;
+
+#endif
+
diff --git a/architecture/scheduler.h b/architecture/scheduler.h
deleted file mode 100644
index b04370f..0000000
--- a/architecture/scheduler.h
+++ /dev/null
@@ -1,941 +0,0 @@
-
-#include <stdlib.h>
-#include <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <semaphore.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-
-using namespace std;
-
-// Globals
-
-#define THREAD_SIZE 64
-#define QUEUE_SIZE 4096
-
-#define WORK_STEALING_INDEX 0
-#define LAST_TASK_INDEX 1
-
-
-#ifdef __ICC
-#define INLINE __forceinline
-#else
-#define INLINE inline
-#endif
-
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-#include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-#else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-#endif
-#else
-#define AVOIDDENORMALS 
-#endif
-
-#ifdef __linux__
-
-// handle 32/64 bits int size issues
-#ifdef __x86_64__
-#define UInt32	unsigned int
-#define UInt64	unsigned long int
-#else
-#define UInt32	unsigned int
-#define UInt64	unsigned long long int
-#endif
-
-#endif
-
-#ifdef __APPLE__
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
-#endif
-
-class TaskQueue;
-struct DSPThreadPool;
-
-extern TaskQueue* gTaskQueueList[THREAD_SIZE];
-extern DSPThreadPool* gThreadPool;
-extern int gClientCount;
-extern UInt64 gMaxStealing;
-    
-void Yield();
-
-/**
- * Returns the number of clock cycles elapsed since the last reset
- * of the processor
- */
-static INLINE UInt64 DSP_rdtsc(void)
-{
-	union {
-		UInt32 i32[2];
-		UInt64 i64;
-	} count;
-	
-	__asm__ __volatile__("rdtsc" : "=a" (count.i32[0]), "=d" (count.i32[1]));
-     return count.i64;
-}
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#define LOCK "lock ; "
-
-static INLINE void NOP(void)
-{
-	__asm__ __volatile__("nop \n\t");
-}
-
-static INLINE char CAS1(volatile void* addr, volatile int value, int newvalue)
-{
-    register char ret;
-    __asm__ __volatile__ (
-						  "# CAS \n\t"
-						  LOCK "cmpxchg %2, (%1) \n\t"
-						  "sete %0               \n\t"
-						  : "=a" (ret)
-						  : "c" (addr), "d" (newvalue), "a" (value)
-                          : "memory"
-						  );
-    return ret;
-}
-
-static INLINE int atomic_xadd(volatile int* atomic, int val) 
-{ 
-    register int result;
-    __asm__ __volatile__ ("# atomic_xadd \n\t"
-                          LOCK "xaddl %0,%1 \n\t"
-                          : "=r" (result), "=m" (*atomic) 
-                          : "0" (val), "m" (*atomic));
-    return result;
-} 
-
-#endif
-
-
-/*
-static INLINE int INC_ATOMIC(volatile int* val)
-{
-    int actual;
-    do {
-        actual = *val;
-    } while (!CAS1(val, actual, actual + 1));
-    return actual;
-}
-
-static INLINE int DEC_ATOMIC(volatile int* val)
-{
-    int actual;
-    do {
-        actual = *val;
-    } while (!CAS1(val, actual, actual - 1));
-    return actual;
-}
-*/
-
-static INLINE int INC_ATOMIC(volatile int* val)
-{
-    return atomic_xadd(val, 1);
-}
- 
-static INLINE int DEC_ATOMIC(volatile int* val)
-{
-    return atomic_xadd(val, -1);
-}
- 
-// To be used in lock-free queue
-struct AtomicCounter
-{
-    union {
-        struct {
-            short fHead;	
-            short fTail;	
-        }
-        scounter;
-        int fValue;
-    }info;
-    
-	INLINE AtomicCounter()
-	{
-        info.fValue = 0;
-    }
-     
- 	INLINE  AtomicCounter& operator=(AtomicCounter& obj)
-    {
-        info.fValue = obj.info.fValue;
-        return *this;
-    }
-    
-	INLINE  AtomicCounter& operator=(volatile AtomicCounter& obj)
-	{
-        info.fValue = obj.info.fValue;
-        return *this;
-    }
-    
-};
-
-int get_max_cpu()
-{
-    return sysconf(_SC_NPROCESSORS_ONLN);
-}
-
-static int GetPID()
-{
-#ifdef WIN32
-    return  _getpid();
-#else
-    return getpid();
-#endif
-}
-
-#define Value(e) (e).info.fValue
-
-#define Head(e) (e).info.scounter.fHead
-#define IncHead(e) (e).info.scounter.fHead++
-#define DecHead(e) (e).info.scounter.fHead--
-
-#define Tail(e) (e).info.scounter.fTail
-#define IncTail(e) (e).info.scounter.fTail++
-#define DecTail(e) (e).info.scounter.fTail--
-
-#define MASTER_THREAD 0
-
-#define MAX_STEAL_DUR 50                    // in usec
-#define DEFAULT_CLOCKSPERSEC 2500000000     // in cycles (2,5 Ghz)
-
-class TaskQueue 
-{
-    private:
-    
-        int fTaskList[QUEUE_SIZE];
-        volatile AtomicCounter fCounter;
-        UInt64 fStealingStart;
-     
-    public:
-  
-        INLINE TaskQueue(int cur_thread)
-        {
-            for (int i = 0; i < QUEUE_SIZE; i++) {
-                fTaskList[i] = -1;
-            }
-            gTaskQueueList[cur_thread] = this;	
-            fStealingStart = 0;
-        }
-         
-        INLINE void PushHead(int item)
-        {
-            fTaskList[Head(fCounter)] = item;
-            IncHead(fCounter);
-        }
-        
-        INLINE int PopHead()
-        {
-            AtomicCounter old_val;
-            AtomicCounter new_val;
-            
-            do {
-                old_val = fCounter;
-                new_val = old_val;
-                if (Head(old_val) == Tail(old_val)) {
-                    return WORK_STEALING_INDEX;
-                } else {
-                    DecHead(new_val);
-                }
-            } while (!CAS1(&fCounter, Value(old_val), Value(new_val)));
-            
-            return fTaskList[Head(old_val) - 1];
-        }
-        
-        INLINE int PopTail()
-        {
-            AtomicCounter old_val;
-            AtomicCounter new_val;
-            
-            do {
-                old_val = fCounter;
-                new_val = old_val;
-                if (Head(old_val) == Tail(old_val)) {
-                   return WORK_STEALING_INDEX;
-                } else {
-                    IncTail(new_val);
-                }
-            } while (!CAS1(&fCounter, Value(old_val), Value(new_val)));
-            
-            return fTaskList[Tail(old_val)];
-        }
-
-		INLINE void MeasureStealingDur()
-		{
-            // Takes first timetamp
-            if (fStealingStart == 0) {
-                fStealingStart = DSP_rdtsc();
-            } else if ((DSP_rdtsc() - fStealingStart) > gMaxStealing) {
-                Yield();
-            }
-		}
-
-		INLINE void ResetStealingDur()
-		{
-            fStealingStart = 0;
-		}
-        
-        static INLINE int GetNextTask(int thread, int num_threads)
-        {
-            int tasknum;
-            for (int i = 0; i < num_threads; i++) {
-                if ((i != thread) && gTaskQueueList[i] && (tasknum = gTaskQueueList[i]->PopTail()) != WORK_STEALING_INDEX) {
-                #ifdef __linux__
-					//if (thread != MASTER_THREAD)
-						gTaskQueueList[thread]->ResetStealingDur();
-                #endif
-                    return tasknum;    // Task is found
-                }
-            }
-            NOP();
-          #ifdef __linux__
-			//if (thread != MASTER_THREAD)
-				gTaskQueueList[thread]->MeasureStealingDur();
-        #endif
-            return WORK_STEALING_INDEX;    // Otherwise will try "workstealing" again next cycle...
-        }
-        
-        INLINE void InitTaskList(int task_list_size, int* task_list, int thread_num, int cur_thread, int& tasknum)
-        {
-            int task_slice = task_list_size / thread_num;
-            int task_slice_rest = task_list_size % thread_num;
-
-            if (task_slice == 0) {
-                // Each thread directly executes one task
-                tasknum = task_list[cur_thread];
-                // Thread 0 takes remaining ready tasks 
-                if (cur_thread == 0) { 
-                    for (int index = 0; index < task_slice_rest - thread_num; index++) {
-                        PushHead(task_list[task_slice_rest + index]);
-                    }
-                }
-            } else {
-                // Each thread takes a part of ready tasks
-                int index;
-                for (index = 0; index < task_slice - 1; index++) {
-                    PushHead(task_list[cur_thread * task_slice + index]);
-                }
-                // Each thread directly executes one task 
-                tasknum = task_list[cur_thread * task_slice + index];
-                // Thread 0 takes remaining ready tasks 
-                if (cur_thread == 0) {
-                    for (index = 0; index < task_slice_rest; index++) {
-                        PushHead(task_list[thread_num * task_slice + index]);
-                    }
-                }
-            }
-        }
-        
-        static INLINE void Init()
-        {
-            for (int i = 0; i < THREAD_SIZE; i++) {
-                gTaskQueueList[i] = 0;
-            }
-        }
-     
-};
-
-struct TaskGraph 
-{
-    volatile int gTaskList[QUEUE_SIZE];
-    
-    TaskGraph()
-    {
-        for (int i = 0; i < QUEUE_SIZE; i++) {
-            gTaskList[i] = 0;
-        } 
-    }
-
-    INLINE void InitTask(int task, int val)
-    {
-        gTaskList[task] = val;
-    }
-    
-    void Display()
-    {
-        for (int i = 0; i < QUEUE_SIZE; i++) {
-            printf("Task = %d activation = %d\n", i, gTaskList[i]);
-        } 
-    }
-      
-    INLINE void ActivateOutputTask(TaskQueue& queue, int task, int& tasknum)
-    {
-        if (DEC_ATOMIC(&gTaskList[task]) == 1) {
-            if (tasknum == WORK_STEALING_INDEX) {
-                tasknum = task;
-            } else {
-                queue.PushHead(task);
-            }
-        }    
-    }
-      
-    INLINE void ActivateOutputTask(TaskQueue& queue, int task)
-    {
-        if (DEC_ATOMIC(&gTaskList[task]) == 1) {
-            queue.PushHead(task);
-        }
-    }
-    
-    INLINE void ActivateOneOutputTask(TaskQueue& queue, int task, int& tasknum)
-    {
-        if (DEC_ATOMIC(&gTaskList[task]) == 1) {
-            tasknum = task;
-        } else {
-            tasknum = queue.PopHead(); 
-        }
-    }
-    
-    INLINE void GetReadyTask(TaskQueue& queue, int& tasknum)
-    {
-        if (tasknum == WORK_STEALING_INDEX) {
-            tasknum = queue.PopHead();
-        }
-    }
- 
-};
-
-
-#define THREAD_POOL_SIZE 16
-#define JACK_SCHED_POLICY SCHED_FIFO
-
-/* use 512KB stack per thread - the default is way too high to be feasible
- * with mlockall() on many systems */
-#define THREAD_STACK 524288
-
-
-#ifdef __APPLE__
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
-#include <mach/thread_policy.h>
-#include <mach/thread_act.h>
-
-#define THREAD_SET_PRIORITY         0
-#define THREAD_SCHEDULED_PRIORITY   1
-
-static UInt32 GetThreadPriority(pthread_t thread, int inWhichPriority);
-
-// returns the thread's priority as it was last set by the API
-static UInt32 GetThreadSetPriority(pthread_t thread)
-{
-    return GetThreadPriority(thread, THREAD_SET_PRIORITY);
-}
-
-// returns the thread's priority as it was last scheduled by the Kernel
-static UInt32 GetThreadScheduledPriority(pthread_t thread)
-{
-    return GetThreadPriority(thread, THREAD_SCHEDULED_PRIORITY);
-}
-
-static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint)
-{
-    if (inPriority == 96) {
-        // REAL-TIME / TIME-CONSTRAINT THREAD
-        thread_time_constraint_policy_data_t theTCPolicy;
-        theTCPolicy.period = period;
-        theTCPolicy.computation = computation;
-        theTCPolicy.constraint = constraint;
-        theTCPolicy.preemptible = true;
-        kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
-        return (res == KERN_SUCCESS) ? 0 : -1;
-    } else {
-        // OTHER THREADS
-        thread_extended_policy_data_t theFixedPolicy;
-        thread_precedence_policy_data_t thePrecedencePolicy;
-        SInt32 relativePriority;
-        
-        // [1] SET FIXED / NOT FIXED
-        theFixedPolicy.timeshare = !inIsFixed;
-        thread_policy_set(pthread_mach_thread_np(thread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
-        
-        // [2] SET PRECEDENCE
-        // N.B.: We expect that if thread A created thread B, and the program wishes to change
-        // the priority of thread B, then the call to change the priority of thread B must be
-        // made by thread A.
-        // This assumption allows us to use pthread_self() to correctly calculate the priority
-        // of the feeder thread (since precedency policy's importance is relative to the
-        // spawning thread's priority.)
-        relativePriority = inPriority - GetThreadSetPriority(pthread_self());
-        
-        thePrecedencePolicy.importance = relativePriority;
-        kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT);
-        return (res == KERN_SUCCESS) ? 0 : -1;
-    }
-}
-
-static UInt32 GetThreadPriority(pthread_t thread, int inWhichPriority)
-{
-    thread_basic_info_data_t threadInfo;
-    policy_info_data_t thePolicyInfo;
-    unsigned int count;
-    
-    // get basic info
-    count = THREAD_BASIC_INFO_COUNT;
-    thread_info(pthread_mach_thread_np(thread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count);
-    
-    switch (threadInfo.policy) {
-        case POLICY_TIMESHARE:
-            count = POLICY_TIMESHARE_INFO_COUNT;
-            thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count);
-            if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) {
-                return thePolicyInfo.ts.cur_priority;
-            } else {
-                return thePolicyInfo.ts.base_priority;
-            }
-            break;
-            
-        case POLICY_FIFO:
-            count = POLICY_FIFO_INFO_COUNT;
-            thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count);
-            if ((thePolicyInfo.fifo.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY)) {
-                return thePolicyInfo.fifo.depress_priority;
-            }
-            return thePolicyInfo.fifo.base_priority;
-            break;
-            
-        case POLICY_RR:
-            count = POLICY_RR_INFO_COUNT;
-            thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count);
-            if ((thePolicyInfo.rr.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY)) {
-                return thePolicyInfo.rr.depress_priority;
-            }
-            return thePolicyInfo.rr.base_priority;
-            break;
-    }
-    
-    return 0;
-}
-
-static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint)
-{
-    thread_time_constraint_policy_data_t theTCPolicy;
-    mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;
-    boolean_t get_default = false;
-    
-    kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread),
-                                          THREAD_TIME_CONSTRAINT_POLICY,
-                                          (thread_policy_t)&theTCPolicy,
-                                          &count,
-                                          &get_default);
-    if (res == KERN_SUCCESS) {
-        *period = theTCPolicy.period;
-        *computation = theTCPolicy.computation;
-        *constraint = theTCPolicy.constraint;
-        return 0;
-    } else {
-        return -1;
-    }
-}
-
-static UInt64 period = 0;
-static UInt64 computation = 0;
-static UInt64 constraint = 0;
-
-INLINE void GetRealTime()
-{
-    if (period == 0) {
-        GetParams(pthread_self(), &period, &computation, &constraint);
-    }
-}
-
-INLINE void SetRealTime()
-{
-    SetThreadToPriority(pthread_self(), 96, true, period, computation, constraint);
-}
-
-void CancelThread(pthread_t fThread)
-{
-    mach_port_t machThread = pthread_mach_thread_np(fThread);
-    thread_terminate(machThread);
-}
-
-INLINE void Yield()
-{
-    //sched_yield();
-}
-
-#endif
-
-#ifdef __linux__
-
-static int faust_sched_policy = -1;
-static struct sched_param faust_rt_param; 
-
-INLINE void GetRealTime()
-{
-    if (faust_sched_policy == -1) {
-        memset(&faust_rt_param, 0, sizeof(faust_rt_param));
-    	pthread_getschedparam(pthread_self(), &faust_sched_policy, &faust_rt_param);
-    }
-}
-
-INLINE void SetRealTime()
-{
-	faust_rt_param.sched_priority--;
-    pthread_setschedparam(pthread_self(), faust_sched_policy, &faust_rt_param);
-}
-
-void CancelThread(pthread_t fThread)
-{
-    pthread_cancel(fThread);
-    pthread_join(fThread, NULL);
-}
-
-INLINE void Yield()
-{
-    pthread_yield();
-}
-
-
-#endif
-
-#define KDSPMESURE 50
-
-static INLINE int Range(int min, int max, int val)
-{
-    if (val < min) {
-        return min;
-    } else if (val > max) {
-        return max;
-    } else {
-        return val;
-    }
-}
-
-struct Runnable {
-    
-    UInt64 fTiming[KDSPMESURE];
-    UInt64 fStart;
-    UInt64 fStop;
-    int fCounter;
-    float fOldMean;
-    int fOldfDynamicNumThreads;
-    bool fDynAdapt;
-    
-    virtual void computeThread(int cur_thread) = 0;
-    
-    Runnable():fCounter(0), fOldMean(1000000000.f), fOldfDynamicNumThreads(1)
-    {
-    	memset(fTiming, 0, sizeof(long long int ) * KDSPMESURE);
-        fDynAdapt = getenv("OMP_DYN_THREAD") ? strtol(getenv("OMP_DYN_THREAD"), NULL, 10) : false;
-    }
-    
-    INLINE float ComputeMean()
-    {
-        float mean = 0;
-        for (int i = 0; i < KDSPMESURE; i++) {
-            mean += float(fTiming[i]);
-        }
-        mean /= float(KDSPMESURE);
-        return mean;
-    }
-    
-    INLINE void StartMeasure()
-    {
-        if (!fDynAdapt)
-            return;
-        
-        fStart = DSP_rdtsc();
-    }
-     
-    INLINE void StopMeasure(int staticthreadnum, int& dynthreadnum)
-    {
-        if (!fDynAdapt)
-            return;
-        
-        fStop = DSP_rdtsc();
-        fCounter = (fCounter + 1) % KDSPMESURE;
-        if (fCounter == 0) {
-            float mean = ComputeMean();
-            if (fabs(mean - fOldMean) > 5000) {
-                if (mean > fOldMean) { // Worse...
-                    //printf("Worse %f %f\n", mean, fOldMean);
-                    if (fOldfDynamicNumThreads > dynthreadnum) {
-                        fOldfDynamicNumThreads = dynthreadnum;
-                        dynthreadnum += 1;
-                    } else {
-                        fOldfDynamicNumThreads = dynthreadnum;
-                        dynthreadnum -= 1;
-                    }
-                 } else { // Better...
-                    //printf("Better %f %f\n", mean, fOldMean);
-                    if (fOldfDynamicNumThreads > dynthreadnum) {
-                        fOldfDynamicNumThreads = dynthreadnum;
-                        dynthreadnum -= 1;
-                    } else {
-                        fOldfDynamicNumThreads = dynthreadnum;
-                        dynthreadnum += 1;
-                    }
-                }
-                fOldMean = mean;
-                dynthreadnum = Range(1, staticthreadnum, dynthreadnum);
-                //printf("dynthreadnum %d\n", dynthreadnum);
-            }
-        }
-        fTiming[fCounter] = fStop - fStart; 
-    }
-};
-
-struct DSPThread;
-
-struct DSPThreadPool {
-    
-    DSPThread* fThreadPool[THREAD_POOL_SIZE];
-    int fThreadCount; 
-    volatile int fCurThreadCount;
-      
-    DSPThreadPool();
-    ~DSPThreadPool();
-    
-    void StartAll(int num, bool realtime);
-    void StopAll();
-    void SignalAll(int num, Runnable* runnable);
-    
-    void SignalOne();
-    bool IsFinished();
-    
-    static DSPThreadPool* Init();
-    static void Destroy();
-    
-};
-
-struct DSPThread {
-
-    pthread_t fThread;
-    DSPThreadPool* fThreadPool;
-    Runnable* fRunnable;
-    sem_t* fSemaphore;
-    char fName[128];
-    bool fRealTime;
-    int fNum;
-    
-    DSPThread(int num, DSPThreadPool* pool)
-    {
-        fNum = num;
-        fThreadPool = pool;
-        fRunnable = NULL;
-        fRealTime = false;
-        
-        sprintf(fName, "faust_sem_%d_%p", GetPID(), this);
-        
-        if ((fSemaphore = sem_open(fName, O_CREAT, 0777, 0)) == (sem_t*)SEM_FAILED) {
-            printf("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
-        }
-    }
-
-    virtual ~DSPThread()
-    {
-        sem_unlink(fName);
-        sem_close(fSemaphore);
-    }
-    
-    void Run()
-    {
-        while (sem_wait(fSemaphore) != 0) {}
-        fRunnable->computeThread(fNum + 1);
-        fThreadPool->SignalOne();
-    }
-    
-    static void* ThreadHandler(void* arg)
-    {
-        DSPThread* thread = static_cast<DSPThread*>(arg);
-        
-        AVOIDDENORMALS;
-        
-        // One "dummy" cycle to setup thread
-        if (thread->fRealTime) {
-            thread->Run();
-            SetRealTime();
-        }
-                  
-        while (true) {
-            thread->Run();
-        }
-        
-        return NULL;
-    }
-    
-    int Start(bool realtime)
-    {
-        pthread_attr_t attributes;
-        struct sched_param rt_param;
-        pthread_attr_init(&attributes);
-        
-        int priority = 60; // TODO
-        int res;
-        
-        if (realtime) {
-            fRealTime = true;
-        }else {
-            fRealTime = getenv("OMP_REALTIME") ? strtol(getenv("OMP_REALTIME"), NULL, 10) : true;
-        }
-                               
-        if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
-            printf("Cannot request joinable thread creation for real-time thread res = %d err = %s\n", res, strerror(errno));
-            return -1;
-        }
-
-        if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
-            printf("Cannot set scheduling scope for real-time thread res = %d err = %s\n", res, strerror(errno));
-            return -1;
-        }
-
-        if (realtime) {
-            
-            if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
-                printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno));
-                return -1;
-            }
-        
-            if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) {
-                printf("Cannot set RR scheduling class for RT thread res = %d err = %s\n", res, strerror(errno));
-                return -1;
-            }
-            
-            memset(&rt_param, 0, sizeof(rt_param));
-            rt_param.sched_priority = priority;
-
-            if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
-                printf("Cannot set scheduling priority for RT thread res = %d err = %s\n", res, strerror(errno));
-                return -1;
-            }
-
-        } else {
-            
-            if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_INHERIT_SCHED))) {
-                printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno));
-                return -1;
-            }
-        }
-     
-        if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) {
-            printf("Cannot set thread stack size res = %d err = %s\n", res, strerror(errno));
-            return -1;
-        }
-        
-        if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) {
-            printf("Cannot create thread res = %d err = %s\n", res, strerror(errno));
-            return -1;
-        }
-
-        pthread_attr_destroy(&attributes);
-        return 0;
-    }
-    
-    void Signal(bool stop, Runnable* runnable)
-    {
-        fRunnable = runnable;
-        sem_post(fSemaphore);
-    }
-    
-    void Stop()
-    {
-        CancelThread(fThread);
-    }
-
-};
-
-DSPThreadPool::DSPThreadPool()
-{
-    for (int i = 0; i < THREAD_POOL_SIZE; i++) {
-        fThreadPool[i] = NULL;
-    }
-    fThreadCount = 0;
-    fCurThreadCount = 0;
-}
-
-DSPThreadPool::~DSPThreadPool()
-{
-    StopAll();
-    
-    for (int i = 0; i < fThreadCount; i++) {
-        delete(fThreadPool[i]);
-        fThreadPool[i] = NULL;
-    }
-    
-    fThreadCount = 0;
- }
-
-void DSPThreadPool::StartAll(int num, bool realtime)
-{
-    if (fThreadCount == 0) {  // Protection for multiple call...  (like LADSPA plug-ins in Ardour)
-        for (int i = 0; i < num; i++) {
-            fThreadPool[i] = new DSPThread(i, this);
-            fThreadPool[i]->Start(realtime);
-            fThreadCount++;
-        }
-    }
-}
-
-void DSPThreadPool::StopAll()
-{
-    for (int i = 0; i < fThreadCount; i++) {
-        fThreadPool[i]->Stop();
-    }
-}
-
-void DSPThreadPool::SignalAll(int num, Runnable* runnable)
-{
-    fCurThreadCount = num;
-        
-    for (int i = 0; i < num; i++) {  // Important : use local num here...
-        fThreadPool[i]->Signal(false, runnable);
-    }
-}
-
-void DSPThreadPool::SignalOne()
-{
-    DEC_ATOMIC(&fCurThreadCount);
-}
-
-bool DSPThreadPool::IsFinished()
-{
-    return (fCurThreadCount == 0);
-}
-
-DSPThreadPool* DSPThreadPool::Init()
-{
-    if (gClientCount++ == 0 && !gThreadPool) {
-        gThreadPool = new DSPThreadPool();
-    }
-    return gThreadPool;
-}
-
-void DSPThreadPool::Destroy()
-{
-    if (--gClientCount == 0 && gThreadPool) {
-        delete gThreadPool;
-        gThreadPool = NULL;
-    }
-}
-
-#ifndef PLUG_IN
-
-// Globals
-TaskQueue* gTaskQueueList[THREAD_SIZE] = {0};
-
-DSPThreadPool* gThreadPool = 0;
-int gClientCount = 0;
-
-int clock_per_microsec = (getenv("CLOCKSPERSEC") 
-                ? strtoll(getenv("CLOCKSPERSEC"), NULL, 10) 
-                : DEFAULT_CLOCKSPERSEC) / 1000000;
-                
-UInt64  gMaxStealing = getenv("OMP_STEALING_DUR") 
-                ? strtoll(getenv("OMP_STEALING_DUR"), NULL, 10) * clock_per_microsec 
-                : MAX_STEAL_DUR * clock_per_microsec;
-
-#endif
-
diff --git a/architecture/snd-rt-gtk.cpp b/architecture/snd-rt-gtk.cpp
index feb5c7a..85a64e6 100644
--- a/architecture/snd-rt-gtk.cpp
+++ b/architecture/snd-rt-gtk.cpp
@@ -54,8 +54,6 @@
 
 #include <rt-various.h> // realtime memory allocation in Snd.
 
-
-
 using namespace std;
 
 struct Meta : map<const char*, const char*>
@@ -63,29 +61,18 @@ struct Meta : map<const char*, const char*>
   void declare (const char* key, const char* value) { (*this)[key]=value; }
 };
 	 	 
-
-
 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
 inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
 
 // g++ -O3 -lm -ljack `gtk-config --cflags --libs` ex2.cpp
  
-	
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
 
-
 inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
 
 inline int 		int2pow2 (int x)	{ int r=0; while ((1<<r)<x) r++; return r; }
 
-
-
 /******************************************************************************
 *******************************************************************************
 
@@ -96,14 +83,8 @@ inline int 		int2pow2 (int x)	{ int r=0; while ((1<<r)<x) r++; return r; }
 
 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
 
-
 <<includeIntrinsic>>
 
-
-
-
-
-
 /******************************************************************************
 *******************************************************************************
 
@@ -121,7 +102,6 @@ using namespace std;
 struct uiItem;
 typedef void (*uiCallback)(float val, void* data);
 
-
 #ifdef MAKE_GUI // It's enough to compile GUI code once.
 
 /**
diff --git a/architecture/sndfile.cpp b/architecture/sndfile.cpp
index 4e9ebdd..1a0a934 100644
--- a/architecture/sndfile.cpp
+++ b/architecture/sndfile.cpp
@@ -31,8 +31,8 @@
 	architecture section is not modified.
 
 
- ************************************************************************
- ************************************************************************/
+	************************************************************************
+	************************************************************************/
 
 
 #include <stdlib.h>
@@ -49,239 +49,27 @@
 #include <map>
 #include <iostream>
 
-#include "gui/GUI.h"
-#include "audio/dsp.h"
-#include "misc.h"
+#include "faust/gui/console.h"
+#include "faust/gui/FUI.h"
+#include "faust/audio/dsp.h"
+#include "faust/misc.h"
 
-/******************************************************************************
-*******************************************************************************
-
-							       VECTOR INTRINSICS
-
-*******************************************************************************
-*******************************************************************************/
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif  
 
-<<includeIntrinsic>>
+#define READ_SAMPLE sf_readf_float
+//#define READ_SAMPLE sf_readf_double
 
 /******************************************************************************
 *******************************************************************************
 
-								USER INTERFACE
+VECTOR INTRINSICS
 
 *******************************************************************************
 *******************************************************************************/
 
-struct param {
-	float* fZone; float fMin; float fMax;
-	param(float* z, float init, float a, float b) : fZone(z), fMin(a), fMax(b) { *z = init; }
-};
-
-class CMDUI : public UI
-{
-	int					fArgc;
-	char**				fArgv;
-	vector<char*>		fFiles;
-	stack<string>		fPrefix;
-	map<string, param>	fKeyParam;
-
-	void openAnyBox(const char* label)
-	{
-		string prefix;
-
-		if (label && label[0]) {
-			prefix = fPrefix.top() + "-" + label;
-		} else {
-			prefix = fPrefix.top();
-		}
-		fPrefix.push(prefix);
-	}
-
-	string simplify(const string& src)
-	{
-		int		i=0;
-		int		level=0;
-		string	dst;
-
-		while (src[i] ) {
-
-			switch (level) {
-
-				case 0 :
-				case 1 :
-				case 2 :
-					// Skip the begin of the label "--foo-"
-					// until 3 '-' have been read
-					if (src[i]=='-') { level++; }
-					break;
-
-				case 3 :
-					// copy the content, but skip non alphnum
-					// and content in parenthesis
-					switch (src[i]) {
-						case '(' :
-						case '[' :
-							level++;
-							break;
-
-						case '-' :
-							dst += '-';
-							break;
-
-						default :
-							if (isalnum(src[i])) {
-								dst+= tolower(src[i]);
-							}
-
-					}
-					break;
-
-				default :
-					// here we are inside parenthesis and
-					// we skip the content until we are back to
-					// level 3
-					switch (src[i]) {
-
-						case '(' :
-						case '[' :
-							level++;
-							break;
-
-						case ')' :
-						case ']' :
-							level--;
-							break;
-
-						default :
-							break;
-					}
-
-			}
-			i++;
-		}
-		return dst;
-	}
-
-
-public:
-
-	CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("-"); }
-	virtual ~CMDUI() {}
-
-
-	void addOption(const char* label, float* zone, float init, float min, float max)
-	{
-		string fullname = "-" + simplify(fPrefix.top() + "-" + label);
-		fKeyParam.insert(make_pair(fullname, param(zone, init, min, max)));
-	}
-
-
-	virtual void addButton(const char* label, float* zone)
-	{
-		addOption(label,zone,0,0,1);
-	}
-
-	virtual void addToggleButton(const char* label, float* zone)
-	{
-		addOption(label,zone,0,0,1);
-	}
-
-	virtual void addCheckButton(const char* label, float* zone)
-	{
-		addOption(label,zone,0,0,1);
-	}
-
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,init,min,max);
-	}
-
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,init,min,max);
-	}
-
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-	{
-		addOption(label,zone,init,min,max);
-	}
-
-	// -- passive widgets
-
-	virtual void addNumDisplay(const char* label, float* zone, int precision) 						{}
-	virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) 	{}
-	virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) 			{}
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) 			{}
-
-	virtual void openFrameBox(const char* label)		{ openAnyBox(label); }
-	virtual void openTabBox(const char* label)			{ openAnyBox(label); }
-	virtual void openHorizontalBox(const char* label)	{ openAnyBox(label); }
-	virtual void openVerticalBox(const char* label)		{ openAnyBox(label); }
-
-	virtual void closeBox() 							{ fPrefix.pop(); }
-
-	virtual void show() {}
-	virtual void run() 	{}
-
-	void printhelp()
-	{
-		map<string, param>::iterator i;
-		cout << fArgc << "\n";
-		cout << fArgv[0] << " option list : ";
-		for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
-			cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
-		}
-		cout << " infile outfile\n";
-	}
-
-	void process_command()
-	{
-		map<string, param>::iterator p;
-		for (int i = 1; i < fArgc; i++) {
-			if (fArgv[i][0] == '-') {
-				if (	(strcmp(fArgv[i], "-help") == 0)
-					 || (strcmp(fArgv[i], "-h") == 0)
-					 || (strcmp(fArgv[i], "--help") == 0) ) 	{
-					printhelp();
-					exit(1);
-				}
-				p = fKeyParam.find(fArgv[i]);
-				if (p == fKeyParam.end()) {
-					cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
-					printhelp();
-					exit(1);
-				}
-				char*	end;
-				*(p->second.fZone) = float(strtod(fArgv[i+1], &end));
-				i++;
-			} else {
-				fFiles.push_back(fArgv[i]);
-			}
-		}
-	}
-
-	int 	files()		{ return fFiles.size(); }
-	char* 	file (int n)	{ return fFiles[n]; }
-
-	char* input_file ()	{ cout << "input file " << fFiles[0]; return fFiles[0]; }
-	char* output_file() 	{  cout << "output file " << fFiles[1]; return fFiles[1]; }
-
-	void process_init()
-	{
-		map<string, param>::iterator p;
-		for (int i = 1; i < fArgc; i++) {
-			if (fArgv[i][0] == '-') {
-				p = fKeyParam.find(fArgv[i]);
-				if (p == fKeyParam.end()) {
-					cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
-					exit(1);
-				}
-				char*	end;
-				*(p->second.fZone) = float(strtod(fArgv[i+1], &end));
-				i++;
-			}
-		}
-	}
-};
+<<includeIntrinsic>>
 
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
@@ -295,161 +83,198 @@ public:
 
 mydsp	DSP;
 
-
 class Separator
 {
-	int		fNumFrames;
-	int		fNumInputs;
-	int		fNumOutputs;
-
-	float*	fInput;
-	float*	fOutputs[256];
-
-  public:
-
-	Separator(int numFrames, int numInputs, int numOutputs)
-	{
-		fNumFrames 	= numFrames;
-		fNumInputs 	= numInputs;
-		fNumOutputs = max(numInputs, numOutputs);
-
-		// allocate interleaved input channel
-		fInput = (float*) calloc(fNumFrames*fNumInputs, sizeof(float));
-
-		// allocate separate output channels
-		for (int i = 0; i < fNumOutputs; i++) {
-			fOutputs[i] = (float*) calloc (fNumFrames, sizeof(float));
-		}
-	}
-
-	~Separator()
-	{
-		// free interleaved input channel
-		free(fInput);
-
-		// free separate output channels
-		for (int i = 0; i < fNumOutputs; i++) {
-			free(fOutputs[i]);
-		}
-	}
-
-	float*	input()		{ return fInput; }
-
-	float** outputs()	{ return fOutputs; }
-
-	void 	separate()
-	{
-		for (int s = 0; s < fNumFrames; s++) {
-			for (int c = 0; c < fNumInputs; c++) {
-				fOutputs[c][s] = fInput[c + s*fNumInputs];
-			}
-		}
-	}
+  int		fNumFrames;
+  int		fNumInputs;
+  int		fNumOutputs;
+
+  FAUSTFLOAT*	fInput;
+  FAUSTFLOAT*	fOutputs[256];
+
+public:
+
+  Separator(int numFrames, int numInputs, int numOutputs)
+  {
+    fNumFrames 	= numFrames;
+    fNumInputs 	= numInputs;
+    fNumOutputs = max(numInputs, numOutputs);
+
+    // allocate interleaved input channel
+    fInput = (FAUSTFLOAT*) calloc(fNumFrames * fNumInputs, sizeof(FAUSTFLOAT));
+
+    // allocate separate output channels
+    for (int i = 0; i < fNumOutputs; i++) {
+      fOutputs[i] = (FAUSTFLOAT*) calloc (fNumFrames, sizeof(FAUSTFLOAT));
+    }
+  }
+
+  ~Separator()
+  {
+    // free interleaved input channel
+    free(fInput);
+
+    // free separate output channels
+    for (int i = 0; i < fNumOutputs; i++) {
+      free(fOutputs[i]);
+    }
+  }
+
+  FAUSTFLOAT*	input()		{ return fInput; }
+
+  FAUSTFLOAT** outputs()	{ return fOutputs; }
+
+  void 	separate()
+  {
+    for (int s = 0; s < fNumFrames; s++) {
+      for (int c = 0; c < fNumInputs; c++) {
+        fOutputs[c][s] = fInput[c + s*fNumInputs];
+      }
+    }
+  }
 };
 
 class Interleaver
 {
-	int		fNumFrames;
-	int		fNumInputs;
-	int		fNumOutputs;
-
-	float*	fInputs[256];
-	float*	fOutput;
-
-  public:
-
-	Interleaver(int numFrames, int numInputs, int numOutputs)
-	{
-		fNumFrames 	= numFrames;
-		fNumInputs 	= max(numInputs, numOutputs);
-		fNumOutputs = numOutputs;
-
-		// allocate separate input channels
-		for (int i = 0; i < fNumInputs; i++) {
-			fInputs[i] = (float*) calloc (fNumFrames, sizeof(float));
-		}
-
-		// allocate interleaved output channel
-		fOutput = (float*) calloc(fNumFrames*fNumOutputs, sizeof(float));
-
-	}
-
-	~Interleaver()
-	{
-		// free separate input channels
-		for (int i = 0; i < fNumInputs; i++) {
-			free(fInputs[i]);
-		}
-
-		// free interleaved output channel
-		free(fOutput);
-	}
-
-	float**	inputs()		{ return fInputs; }
-
-	float* 	output()		{ return fOutput; }
-
-	void 	interleave()
-	{
-		for (int s = 0; s < fNumFrames; s++) {
-			for (int c = 0; c < fNumOutputs; c++) {
-				fOutput[c + s*fNumOutputs] = fInputs[c][s];
-			}
-		}
-	}
+  int fNumFrames;
+  int fNumChans;
+
+  FAUSTFLOAT* fInputs[256];
+  FAUSTFLOAT* fOutput;
+
+public:
+
+  Interleaver(int numFrames, int numChans)
+  {
+    fNumFrames = numFrames;
+    fNumChans  = numChans;
+
+    // allocate separate input channels
+    for (int i = 0; i < fNumChans; i++) {
+      fInputs[i] = (FAUSTFLOAT*) calloc (fNumFrames, sizeof(FAUSTFLOAT));
+    }
+
+    // allocate interleaved output channel
+    fOutput = (FAUSTFLOAT*) calloc(fNumFrames * fNumChans, sizeof(FAUSTFLOAT));
+
+  }
+
+  ~Interleaver()
+  {
+    // free separate input channels
+    for (int i = 0; i < fNumChans; i++) {
+      free(fInputs[i]);
+    }
+
+    // free interleaved output channel
+    free(fOutput);
+  }
+
+  FAUSTFLOAT**	inputs()		{ return fInputs; }
+
+  FAUSTFLOAT* 	output()		{ return fOutput; }
+
+  void interleave()
+  {
+    for (int s = 0; s < fNumFrames; s++) {
+      for (int c = 0; c < fNumChans; c++) {
+        fOutput[c + s*fNumChans] = fInputs[c][s];
+      }
+    }
+  }
 };
 
 #define kFrames 512
 
-int main(int argc, char *argv[] )
+// loptrm : Scan command-line arguments and remove and return long int value when found
+long loptrm(int *argcP, char *argv[], const char* longname, const char* shortname, long def)
 {
-	SNDFILE*		in_sf;
-	SNDFILE*		out_sf;
-	SF_INFO			in_info;
-	SF_INFO			out_info;
-
-	CMDUI* interface = new CMDUI(argc, argv);
-	DSP.buildUserInterface(interface);
-	interface->process_command();
-
-	// open input file
-	in_info.format = 0;
-	in_sf = sf_open (interface->input_file(), SFM_READ, &in_info);
-	if (in_sf == NULL) { sf_perror(in_sf); exit(0); }
-
-	// open output file
-	out_info = in_info;
-    out_info.format = in_info.format;
-	out_info.channels = DSP.getNumOutputs();
-	out_sf = sf_open(interface->output_file(), SFM_WRITE, &out_info);
-	if (out_sf == NULL) { sf_perror(out_sf); exit(0); }
-
-
-	// create separator and interleaver
-	Separator 	sep (kFrames, in_info.channels, DSP.getNumInputs());
-	Interleaver ilv (kFrames, DSP.getNumOutputs(), DSP.getNumOutputs());
-
-	// init signal processor
-	DSP.init(in_info.samplerate);
-	//DSP.buildUserInterface(interface);
-	interface->process_init();
-
-	// process all samples
-	int nbf;
-	do {
-		nbf = sf_readf_float(in_sf, sep.input(), kFrames);
-		sep.separate();
-		DSP.compute(nbf, sep.outputs(), ilv.inputs());
-		ilv.interleave();
-		sf_writef_float(out_sf, ilv.output(), nbf);
-		//sf_write_raw(out_sf, ilv.output(), nbf);
-	} while (nbf == kFrames);
-
-	// close the input and output files
-	sf_close(in_sf);
-	sf_close(out_sf);
+  int argc = *argcP;
+  for (int i=2; i<argc; i++) {
+    if (strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0) {
+      int optval = atoi(argv[i]);
+      for (int j=i-1; j<argc-2; j++) {  // make it go away for sake of "faust/gui/console.h"
+        argv[j] = argv[j+2];
+      }
+      *argcP -= 2;
+      return optval;
+    }
+  }
+  return def;
 }
 
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
+int main(int argc, char *argv[])
+{
+  SNDFILE*	in_sf;
+  SNDFILE*	out_sf;
+  SF_INFO	in_info;
+  SF_INFO	out_info;
+  unsigned int nAppend = 0; // number of frames to append beyond input file
+
+  if (argc < 3) {
+    fprintf(stderr,"*** USAGE: %s input_soundfile output_soundfile\n",argv[0]);
+    exit(1);
+  }
+
+  nAppend = loptrm(&argc, argv, "--continue", "-c", 0);
+    
+  CMDUI* interface = new CMDUI(argc, argv);
+  DSP.buildUserInterface(interface);
+  interface->process_command();
+
+  // open input file
+  in_info.format = 0;
+  in_sf = sf_open(interface->input_file(), SFM_READ, &in_info);
+  if (in_sf == NULL) {
+    fprintf(stderr,"*** Input file not found.\n");
+    sf_perror(in_sf); 
+    exit(1); 
+  }
+
+  // open output file
+  out_info = in_info;
+  out_info.format = in_info.format;
+  out_info.channels = DSP.getNumOutputs();
+  out_sf = sf_open(interface->output_file(), SFM_WRITE, &out_info);
+  if (out_sf == NULL) { 
+    fprintf(stderr,"*** Cannot write output file.\n");
+    sf_perror(out_sf); 
+    exit(1); 
+  }
+
+  // create separator and interleaver
+  Separator   sep(kFrames, in_info.channels, DSP.getNumInputs());
+  Interleaver ilv(kFrames, DSP.getNumOutputs());
+
+  // init signal processor
+  DSP.init(in_info.samplerate);
+  //DSP.buildUserInterface(interface);
+  interface->process_init();
+
+  // process all samples
+  int nbf;
+  do {
+    nbf = READ_SAMPLE(in_sf, sep.input(), kFrames);
+    sep.separate();
+    DSP.compute(nbf, sep.outputs(), ilv.inputs());
+    ilv.interleave();
+    sf_writef_float(out_sf, ilv.output(), nbf);
+    //sf_write_raw(out_sf, ilv.output(), nbf);
+  } while (nbf == kFrames);
+
+  sf_close(in_sf);
+
+  // compute tail, if any
+  if (nAppend>0) {
+    FAUSTFLOAT *input = (FAUSTFLOAT*) calloc(nAppend * DSP.getNumInputs(), sizeof(FAUSTFLOAT));
+    FAUSTFLOAT *inputs[1] = { input };
+    Interleaver ailv(nAppend, DSP.getNumOutputs());
+    DSP.compute(nAppend, inputs, ailv.inputs());
+    ailv.interleave();
+    sf_writef_float(out_sf, ailv.output(), nAppend);
+  }
+
+  sf_close(out_sf);
+}
 
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
diff --git a/architecture/supercollider.cpp b/architecture/supercollider.cpp
index fc63de8..4d4993e 100644
--- a/architecture/supercollider.cpp
+++ b/architecture/supercollider.cpp
@@ -1,9 +1,11 @@
 // If other than 'faust2sc --prefix Faust' is used, sed this as well:
-#define SC_FAUST_PREFIX "Faust"
+#if !defined(SC_FAUST_PREFIX)
+# define SC_FAUST_PREFIX "Faust"
+#endif
 
 //-------------------------------------------------------------------
 // FAUST architecture file for SuperCollider.
-// Copyright (C) 2005-2008 Stefan Kersten.
+// Copyright (C) 2005-2012 Stefan Kersten.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
@@ -21,142 +23,43 @@
 // 02111-1307 USA
 //-------------------------------------------------------------------
 
-#include <ctype.h>
-#include <limits.h>
 #include <map>
 #include <string>
 #include <string.h>
 #include <SC_PlugIn.h>
 
+#include <faust/audio/dsp.h>
+#include <faust/gui/UI.h>
+#include <faust/misc.h>
+
+using namespace std;
+
 #if defined(__GNUC__) && __GNUC__ >= 4
 # define FAUST_EXPORT __attribute__((visibility("default")))
 #else
 # define FAUST_EXPORT /* NOP */
 #endif
 
-//-------------------------------------------------------------------
-// Generic min and max using C++ inline
-//-------------------------------------------------------------------
-
-inline int      max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int      max (int a, int b)          { return (a>b) ? a : b; }
-
-inline long     max (long a, long b)        { return (a>b) ? a : b; }
-inline long     max (int a, long b)         { return (a>b) ? a : b; }
-inline long     max (long a, int b)         { return (a>b) ? a : b; }
-
-inline float    max (float a, float b)      { return (a>b) ? a : b; }
-inline float    max (int a, float b)        { return (a>b) ? a : b; }
-inline float    max (float a, int b)        { return (a>b) ? a : b; }
-inline float    max (long a, float b)       { return (a>b) ? a : b; }
-inline float    max (float a, long b)       { return (a>b) ? a : b; }
-
-inline double   max (double a, double b)    { return (a>b) ? a : b; }
-inline double   max (int a, double b)       { return (a>b) ? a : b; }
-inline double   max (double a, int b)       { return (a>b) ? a : b; }
-inline double   max (long a, double b)      { return (a>b) ? a : b; }
-inline double   max (double a, long b)      { return (a>b) ? a : b; }
-inline double   max (float a, double b)     { return (a>b) ? a : b; }
-inline double   max (double a, float b)     { return (a>b) ? a : b; }
-
-
-inline int      min (int a, int b)          { return (a<b) ? a : b; }
-
-inline long     min (long a, long b)        { return (a<b) ? a : b; }
-inline long     min (int a, long b)         { return (a<b) ? a : b; }
-inline long     min (long a, int b)         { return (a<b) ? a : b; }
-
-inline float    min (float a, float b)      { return (a<b) ? a : b; }
-inline float    min (int a, float b)        { return (a<b) ? a : b; }
-inline float    min (float a, int b)        { return (a<b) ? a : b; }
-inline float    min (long a, float b)       { return (a<b) ? a : b; }
-inline float    min (float a, long b)       { return (a<b) ? a : b; }
-
-inline double   min (double a, double b)    { return (a<b) ? a : b; }
-inline double   min (int a, double b)       { return (a<b) ? a : b; }
-inline double   min (double a, int b)       { return (a<b) ? a : b; }
-inline double   min (long a, double b)      { return (a<b) ? a : b; }
-inline double   min (double a, long b)      { return (a<b) ? a : b; }
-inline double   min (float a, double b)     { return (a<b) ? a : b; }
-inline double   min (double a, float b)     { return (a<b) ? a : b; }
-
-inline int      lsr (int x, int n)          { return int(((unsigned int)x) >> n); }
-inline int      int2pow2 (int x)            { int r=0; while ((1<<r)<x) r++; return r; }
-
-
-/******************************************************************************
-*******************************************************************************
-
-                                   VECTOR INTRINSICS
-
-*******************************************************************************
-*******************************************************************************/
-
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-inline void *aligned_calloc(size_t nmemb, size_t size)
-{
-    return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15);
-}
+//----------------------------------------------------------------------------
+// Vector intrinsics
+//----------------------------------------------------------------------------
 
 <<includeIntrinsic>>
 
-/******************************************************************************
-*******************************************************************************
-
-                                META DATA
-
-*******************************************************************************
-*******************************************************************************/
+//----------------------------------------------------------------------------
+// Metadata
+//----------------------------------------------------------------------------
 
-struct Meta : std::map<std::string, std::string>
+class MetaData : public Meta
+               , public std::map<std::string, std::string>
 {
+public:
     void declare(const char* key, const char* value)
     {
         (*this)[key] = value;
     }
 };
 
-/******************************************************************************
-*******************************************************************************
-
-                                GRAPHIC USER INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
-
-//----------------------------------------------------------------------------
-// Abstract user interface
-//----------------------------------------------------------------------------
-
-class UI
-{
-public:
-    virtual ~UI() { }
-
-    // active widgets
-    virtual void addButton(const char* label, float* zone) = 0;
-    virtual void addToggleButton(const char* label, float* zone) = 0;
-    virtual void addCheckButton(const char* label, float* zone) = 0;
-    virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-    virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-
-    // passive widgets
-    virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-    virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
-    virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-    virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-
-    // layout widgets
-    virtual void openFrameBox(const char* label) = 0;
-    virtual void openTabBox(const char* label) = 0;
-    virtual void openHorizontalBox(const char* label) = 0;
-    virtual void openVerticalBox(const char* label) = 0;
-    virtual void closeBox() = 0;
-
-    virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
 //----------------------------------------------------------------------------
 // Control counter
 //----------------------------------------------------------------------------
@@ -173,32 +76,29 @@ public:
     size_t getNumControlInputs() const { return mNumControlInputs; }
     size_t getNumControlOutputs() const { return mNumControlOutputs; }
 
-    // active widgets
-    virtual void addButton(const char* label, float* zone)
-    { addControlInput(); }
-    virtual void addToggleButton(const char* label, float* zone)
+    // Layout widgets
+    virtual void openTabBox(const char* label) { }
+    virtual void openHorizontalBox(const char* label) { }
+    virtual void openVerticalBox(const char* label) { }
+    virtual void closeBox() { }
+
+    // Active widgets
+    virtual void addButton(const char* label, FAUSTFLOAT* zone)
     { addControlInput(); }
-    virtual void addCheckButton(const char* label, float* zone)
+    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
     { addControlInput(); }
-    virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     { addControlInput(); }
-    virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     { addControlInput(); }
-    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     { addControlInput(); }
 
-    // passive widgets
-    virtual void addNumDisplay(const char* label, float* zone, int precision) { addControlOutput(); }
-    virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) { addControlOutput(); }
-    virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) { addControlOutput(); }
-    virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) { addControlOutput(); }
-
-    // layout widgets
-    virtual void openFrameBox(const char* label) { }
-    virtual void openTabBox(const char* label) { }
-    virtual void openHorizontalBox(const char* label) { }
-    virtual void openVerticalBox(const char* label) { }
-    virtual void closeBox() { }
+    // Passive widgets
+    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+    { addControlOutput(); }
+    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+    { addControlOutput(); }
 
 protected:
     void addControlInput() { mNumControlInputs++; }
@@ -215,22 +115,22 @@ private:
 
 struct Control
 {
-    typedef void (*UpdateFunction)(Control* self, float value);
+    typedef void (*UpdateFunction)(Control* self, FAUSTFLOAT value);
 
     UpdateFunction updateFunction;
-    float min, max, step;
-    float* zone;
+    FAUSTFLOAT* zone;
+    FAUSTFLOAT min, max;
 
-    inline void update(float value)
+    inline void update(FAUSTFLOAT value)
     {
         (*updateFunction)(this, value);
     }
 
-    static void simpleUpdate(Control* self, float value)
+    static void simpleUpdate(Control* self, FAUSTFLOAT value)
     {
         *self->zone = value;
     }
-    static void boundedUpdate(Control* self, float value)
+    static void boundedUpdate(Control* self, FAUSTFLOAT value)
     {
         *self->zone = sc_clip(value, self->min, self->max);
     }
@@ -247,48 +147,42 @@ public:
         : mControls(controls)
     { }
 
-    // active widgets
-    virtual void addButton(const char* label, float* zone)
-    { addSimpleControl(zone); }
-    virtual void addToggleButton(const char* label, float* zone)
+    // Layout widgets
+    virtual void openTabBox(const char* label) { }
+    virtual void openHorizontalBox(const char* label) { }
+    virtual void openVerticalBox(const char* label) { }
+    virtual void closeBox() { }
+
+    // Active widgets
+    virtual void addButton(const char* label, FAUSTFLOAT* zone)
     { addSimpleControl(zone); }
-    virtual void addCheckButton(const char* label, float* zone)
+    virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
     { addSimpleControl(zone); }
-    virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+    virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     { addBoundedControl(zone, min, max, step); }
-    virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+    virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     { addBoundedControl(zone, min, max, step); }
-    virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+    virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     { addBoundedControl(zone, min, max, step); }
 
-    // passive widgets
-    virtual void addNumDisplay(const char* label, float* zone, int precision) { }
-    virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) { }
-    virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) { }
-    virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) { }
-
-    // layout widgets
-    virtual void openFrameBox(const char* label) { }
-    virtual void openTabBox(const char* label) { }
-    virtual void openHorizontalBox(const char* label) { }
-    virtual void openVerticalBox(const char* label) { }
-    virtual void closeBox() { }
+    // Passive widgets
+    virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { }
+    virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { }
 
 private:
-    void addControl(Control::UpdateFunction updateFunction, float* zone, float min, float max, float step)
+    void addControl(Control::UpdateFunction updateFunction, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /* step */)
     {
         Control* ctrl        = mControls++;
         ctrl->updateFunction = updateFunction;
+        ctrl->zone           = zone;
         ctrl->min            = min;
         ctrl->max            = max;
-        ctrl->step           = step;
-        ctrl->zone           = zone;
     }
-    void addSimpleControl(float* zone)
+    void addSimpleControl(FAUSTFLOAT* zone)
     {
         addControl(Control::simpleUpdate, zone, 0.f, 0.f, 0.f);
     }
-    void addBoundedControl(float* zone, float min, float max, float step)
+    void addBoundedControl(FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
     {
         addControl(Control::boundedUpdate, zone, min, max, step);
     }
@@ -297,54 +191,20 @@ private:
     Control* mControls;
 };
 
-
-/******************************************************************************
-*******************************************************************************
-
-                                FAUST DSP
-
-*******************************************************************************
-*******************************************************************************/
-
-//----------------------------------------------------------------------------
-// Abstract DSP interface
-//----------------------------------------------------------------------------
-
-class dsp
-{
-public:
-    virtual ~dsp();
-    virtual int getNumInputs()                                      = 0;
-    virtual int getNumOutputs()                                     = 0;
-    virtual void buildUserInterface(UI* interface)                  = 0;
-    virtual void init(int samplingRate)                             = 0;
-    virtual void compute(int len, float** inputs, float** outputs)  = 0;
-
-protected:
-    int fSamplingFreq;
-};
-
-dsp::~dsp() { }
-
 //----------------------------------------------------------------------------
 // FAUST generated code
 //----------------------------------------------------------------------------
 
 <<includeclass>>
 
-
-/******************************************************************************
-*******************************************************************************
-
-                            SUPERCOLLIDER DSP INTERFACE
-
-*******************************************************************************
-*******************************************************************************/
+//----------------------------------------------------------------------------
+// SuperCollider/Faust interface
+//----------------------------------------------------------------------------
 
 struct Faust : public Unit
 {
     // Faust dsp instance
-    mydsp       mDSP;
+    FAUSTCLASS  mDSP;
     // Buffers for control to audio rate conversion
     float**     mInBufCopy;
     float*      mInBufValue;
@@ -380,7 +240,7 @@ void initState(const std::string& name, int sampleRate)
 {
     g_unitName = strdup(name.c_str());
 
-    mydsp* dsp = new mydsp;
+    mydsp* dsp = new FAUSTCLASS;
     ControlCounter* cc = new ControlCounter;
 
     dsp->classInit(sampleRate);
@@ -421,7 +281,7 @@ static std::string normalizeClassName(const std::string& name)
 
   unsigned int i=0;
   bool upnext=true;
-  while (c=name[i++]) {
+  while ((c=name[i++])) {
     if (upnext) { c = toupper(c); upnext=false; }
     if ( (c == '_') || (c == '-') || isspace(c)) { upnext=true; continue; }
     s += c;
@@ -432,6 +292,9 @@ static std::string normalizeClassName(const std::string& name)
 
 extern "C"
 {
+#ifdef SC_API_EXPORT
+    int api_version(void);
+#endif
     void load(InterfaceTable*);
     void Faust_next(Faust*, int);
     void Faust_next_copy(Faust*, int);
@@ -536,8 +399,8 @@ void Faust_Ctor(Faust* unit)  // module constructor
             // and linear interpolation state (numInputs)
             // = numInputs * (bufLength + 1)
             unit->mInBufValue = (float*)RTAlloc(unit->mWorld, unit->getNumAudioInputs()*sizeof(float));
-            float* mem = (float*)RTAlloc(unit->mWorld, unit->getNumAudioInputs()*BUFLENGTH*sizeof(float));
             // Aquire memory for interpolator state.
+            float* mem = (float*)RTAlloc(unit->mWorld, unit->getNumAudioInputs()*BUFLENGTH*sizeof(float));
             for (int i=0; i < unit->getNumAudioInputs(); ++i) {
                 // Initialize interpolator.
                 unit->mInBufValue[i] = IN0(i);
@@ -580,13 +443,16 @@ void Faust_Dtor(Faust* unit)  // module destructor
     }
 }
 
+#ifdef SC_API_EXPORT
+FAUST_EXPORT int api_version(void) { return sc_api_version; }
+#endif
+
 FAUST_EXPORT void load(InterfaceTable* inTable)
 {
-
     ft = inTable;
 
-    Meta meta;
-    mydsp::metadata(&meta);
+    MetaData meta;
+    FAUSTCLASS::metadata(&meta);
 
     std::string name = meta["name"];
 
@@ -596,11 +462,15 @@ FAUST_EXPORT void load(InterfaceTable* inTable)
 
     name = normalizeClassName(name);
 
+#if !defined(NDEBUG) & defined(SC_API_EXPORT)
+    Print("Faust: supercollider.cpp: sc_api_version = %d\n",sc_api_version);
+#endif
+
     if (name.empty()) {
         // Catch empty name
-        Print("*** Faust: supercollider.cpp: "
-	      "Could not create unit-generator module name from filename\n"
-              "       bailing out ...\n");
+        Print("Faust [supercollider.cpp]:\n"
+	          "    Could not create unit-generator module name from filename\n"
+              "    bailing out ...\n");
         return;
     }
 
diff --git a/architecture/synthfile.cpp b/architecture/synthfile.cpp
index 30dedb5..59d2878 100644
--- a/architecture/synthfile.cpp
+++ b/architecture/synthfile.cpp
@@ -59,17 +59,11 @@ struct Meta : map<const char*, const char*>
     void declare (const char* key, const char* value) { (*this)[key]=value; }
 };
 
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
 
-
 inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
 
-
 /******************************************************************************
 *******************************************************************************
 
@@ -78,12 +72,8 @@ inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
 *******************************************************************************
 *******************************************************************************/
 
-
 <<includeIntrinsic>>
 
-
-
-
 /******************************************************************************
 *******************************************************************************
 
diff --git a/architecture/tonestack.lib b/architecture/tonestack.lib
new file mode 100644
index 0000000..242ff17
--- /dev/null
+++ b/architecture/tonestack.lib
@@ -0,0 +1,427 @@
+/**
+ **  Guitar tone stacks (based on the work from D.T. Yeh)
+ **  some values are taken from CAPS plugin tonestack 
+ ** 
+ **  this tonestack library provide the following tonestack models:
+ **  bassman, mesa, twin, princeton, jcm800, jcm2000, jtm45, mlead,
+ **  m2199, ac30, ac15, soldano, sovtek, peavey, ibanez, roland, 
+ **  ampeg, ampeg_rev, bogner, groove, crunch, fender_blues,
+ **  fender_default, fender_deville, gibsen
+ **  
+ **  USAGE :
+ **        _:component("tonestack.lib").model(t,m,l):_
+ **  WHERE :
+ **       model is on of the models above.
+ **       t is treble freq control in range of (0.0 - 1.0)
+ **       m is middle freq control in range of (0.0 - 1.0)
+ **       l is low freq control in range of (0.0 - 1.0)
+ ** 
+ **  EXAMPLE :
+ **       process = component("tonestack.lib").jcm2000(t,m,l) 
+ **       with {
+ **         t = vslider("Treble ", 0.5, 0, 1, 0.01);
+ **         m = vslider("Middle ", 0.5, 0, 1, 0.01);
+ **         l = vslider("Bass ", 0.5, 0, 1, 0.01);
+ **       };
+ **/
+
+declare name      "Tonestack Emulation Library";
+declare author    "Guitarix project (http://guitarix.sourceforge.net/)";
+declare copyright "Guitarix project";
+declare version   "0.28";
+declare license   "LGPL";
+
+
+import("filter.lib");
+
+/****************************************************************
+ **           Equalisation 3 bandes
+ **                    C1
+ **       IN >---------||---------
+ **            |                 |
+ **            |                 |
+ **           | | R4            | | R1 Treble
+ **           | |               | |<------<  Out
+ **           | |               | | 
+ **            |       C2        |
+ **            |-------||--------|------
+ **            |                 |     |
+ **            |                | |    |
+ **            |                | |<---- R2 Bass
+ **            |                | |
+ **            |                 |
+ **            |       C3       | |
+ **            --------||------>| |  R3 Middle
+ **                             | |
+ **                              |
+ **                             _|_
+ **                              -
+ **
+ ****************************************************************/
+
+tonestack(C1,C2,C3,R1,R2,R3,R4,t,m,L) = 
+    1/A0*iir((B0,B1,B2,B3),(A1/A0,A2/A0,A3/A0)) 
+    with {
+    
+    l = L : (_-1)*3.4 : exp;
+    
+    b1 = t*C1*R1 + m*C3*R3 + l*(C1*R2 + C2*R2) + (C1*R3 + C2*R3);
+
+    b2 = t*(C1*C2*R1*R4 + C1*C3*R1*R4) - m*m*(C1*C3*R3*R3 + C2*C3*R3*R3)
+         + m*(C1*C3*R1*R3 + C1*C3*R3*R3 + C2*C3*R3*R3)
+         + l*(C1*C2*R1*R2 + C1*C2*R2*R4 + C1*C3*R2*R4)
+         + l*m*(C1*C3*R2*R3 + C2*C3*R2*R3)
+         + (C1*C2*R1*R3 + C1*C2*R3*R4 + C1*C3*R3*R4);
+
+    b3 = l*m*(C1*C2*C3*R1*R2*R3 + C1*C2*C3*R2*R3*R4)
+         - m*m*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4)
+         + m*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4)
+         + t*C1*C2*C3*R1*R3*R4 - t*m*C1*C2*C3*R1*R3*R4
+         + t*l*C1*C2*C3*R1*R2*R4;
+
+    a0 = 1;
+
+    a1 = (C1*R1 + C1*R3 + C2*R3 + C2*R4 + C3*R4)
+         + m*C3*R3 + l*(C1*R2 + C2*R2);
+
+    a2 = m*(C1*C3*R1*R3 - C2*C3*R3*R4 + C1*C3*R3*R3 + C2*C3*R3*R3)
+         + l*m*(C1*C3*R2*R3 + C2*C3*R2*R3)
+         - m*m*(C1*C3*R3*R3 + C2*C3*R3*R3)
+         + l*(C1*C2*R2*R4 + C1*C2*R1*R2 + C1*C3*R2*R4 + C2*C3*R2*R4)
+         + (C1*C2*R1*R4 + C1*C3*R1*R4 + C1*C2*R3*R4 + C1*C2*R1*R3 + C1*C3*R3*R4 + C2*C3*R3*R4);
+
+    a3 = l*m*(C1*C2*C3*R1*R2*R3 + C1*C2*C3*R2*R3*R4)
+         - m*m*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4)
+         + m*(C1*C2*C3*R3*R3*R4 + C1*C2*C3*R1*R3*R3 - C1*C2*C3*R1*R3*R4)
+         + l*C1*C2*C3*R1*R2*R4
+         + C1*C2*C3*R1*R3*R4;
+
+    c = 2*float(SR);
+
+    B0 = -b1*c - b2*pow(c,2) - b3*pow(c,3);
+    B1 = -b1*c + b2*pow(c,2) + 3*b3*pow(c,3);
+    B2 = b1*c + b2*pow(c,2) - 3*b3*pow(c,3);
+    B3 = b1*c - b2*pow(c,2) + b3*pow(c,3);
+    A0 = -a0 - a1*c - a2*pow(c,2) - a3*pow(c,3);
+    A1 = -3*a0 - a1*c + a2*pow(c,2) + 3*a3*pow(c,3);
+    A2 = -3*a0 + a1*c + a2*pow(c,2) - 3*a3*pow(c,3);
+    A3 = -a0 + a1*c - a2*pow(c,2) + a3*pow(c,3);
+};
+
+ts = environment {
+    k = *(1e3);
+    M = *(1e6);
+    nF = *(1e-9);
+    pF = *(1e-12);
+
+    /* Fender */
+
+    bassman = environment { /* 59 Bassman 5F6-A */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 56:k;
+        C1 = 250:pF;
+        C2 = 20:nF;
+        C3 = 20:nF;
+        };
+        
+    mesa = environment { /* Mesa Boogie Mark */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    twin = environment { /* 69 Twin Reverb AA270 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 120:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+
+    princeton = environment { /* 64 Princeton AA1164 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 4.8:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+
+    /* Marshall */
+
+    jcm800 = environment { /* 59/81 JCM-800 Lead 100 2203 */
+        R1 = 220:k;
+        R2 = 1:M;
+        R3 = 22:k;
+        R4 = 33:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+    /* 90 JCM-900 Master 2100: same as JCM-800 */
+
+    jcm2000 = environment { /* 81 2000 Lead */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 56:k; /* a 10 k fixed + 100 k pot in series actually */
+        C1 = 500:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    jtm45 = environment { /* JTM 45 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 33:k; 
+        C1 = 270:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+
+    /* parameter order is R1 - R4, C1 - C3 */
+    mlead = environment { /* 67 Major Lead 200 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 33:k;
+        C1 = 500:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+
+    m2199 = environment { /* undated M2199 30W solid state */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 56:k;
+        C1 = 250:pF;
+        C2 = 47:nF;
+        C3 = 47:nF;
+        };
+
+    /* Vox */
+    ac30 = environment { /* 59/86 AC-30 */
+        /* R3 is fixed (circuit differs anyway) */
+        R1 = 1:M;
+        R2 = 1:M;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 50:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    ac15 = environment { /* VOX AC-15 */
+        R1 = 220:k;
+        R2 = 220:k;
+        R3 = 220:k;
+        R4 = 100:k;
+        C1 = 470:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    soldano = environment { /* Soldano SLO 100 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 47:k;
+        C1 = 470:pF;
+        C2 = 20:nF;
+        C3 = 20:nF;
+        };
+        
+    sovtek = environment { /* MIG 100 H*/
+        R1 = 500:k;
+        R2 = 1:M;
+        R3 = 10:k;
+        R4 = 47:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+
+    peavey = environment { /* c20*/
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 20:k;
+        R4 = 68:k;
+        C1 = 270:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    ibanez = environment { /* gx20 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 270:pF;
+        C2 = 100:nF;
+        C3 = 40:nF;
+        };
+        
+    roland = environment { /* Cube 60 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 41:k;
+        C1 = 240:pF;
+        C2 = 33:nF;
+        C3 = 82:nF;
+        };
+        
+    ampeg = environment { /* VL 501 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 32:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+    
+    ampeg_rev = environment { /* reverbrocket*/
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 100:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    bogner = environment { /* Triple Giant Preamp  */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 33:k;
+        R4 = 51:k;
+        C1 = 220:pF;
+        C2 = 15:nF;
+        C3 = 47:nF;
+        };
+        
+    groove = environment { /* Trio Preamp  */
+        R1 = 220:k;
+        R2 = 1:M;
+        R3 = 22:k;
+        R4 = 68:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    crunch = environment { /* Hughes&Kettner  */
+        R1 = 220:k;
+        R2 = 220:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 220:pF;
+        C2 = 47:nF;
+        C3 = 47:nF;
+        };
+        
+    fender_blues = environment { /* Fender blues junior  */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    fender_default = environment { /* Fender   */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    fender_deville = environment { /* Fender Hot Rod  */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 130:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 22:nF;
+        };
+        
+    gibsen = environment { /* gs12 reverbrocket   */
+        R1 = 1:M;
+        R2 = 1:M;
+        R3 = 94:k;  // 47k fixed
+        R4 = 270:k;
+        C1 = 25:pF;
+        C2 = 60:nF;
+        C3 = 20:nF;
+        };
+
+};
+
+bassman(T,M,L)  = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.bassman;};
+mesa(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.mesa;};
+twin(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.twin;};
+princeton(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.princeton;};
+jcm800(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.jcm800;};
+jcm2000(T,M,L)  = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.jcm2000;};
+jtm45(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.jtm45;};
+mlead(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.mlead;};
+m2199(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.m2199;};
+ac30(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ac30;};
+ac15(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ac15;};
+soldano(T,M,L)  = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.soldano;};
+sovtek(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.sovtek;};
+peavey(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.peavey;};
+ibanez(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ibanez;};
+roland(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.roland;};
+ampeg(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ampeg;};
+ampeg_rev(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ampeg_rev;};
+bogner(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.bogner;};
+groove(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.groove;};
+crunch(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.crunch;};
+fender_blues(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.fender_blues;};
+fender_default(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.fender_default;};
+fender_deville(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.fender_deville;};
+gibsen(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.gibsen;};
+
diff --git a/architecture/tube.lib b/architecture/tube.lib
new file mode 100644
index 0000000..b46d8e9
--- /dev/null
+++ b/architecture/tube.lib
@@ -0,0 +1,4989 @@
+/******************************************************************************
+ **  Guitar(ix) tube amp emulations
+ **  
+ **  
+ **  this tube library provide the following tube models:
+ **  T1_12AX7, T2_12AX7, T3_12AX7, T1_12AT7, T2_12AT7, T3_12AT7, 
+ **  T1_12AU7, T2_12AU7, T3_12AU7, T1_6V6, T2_6V6, T3_6V6, 
+ **  T1_6DJ8, T2_6DJ8, T3_6DJ8, T1_6C16, T2_6C16, T3_6C16 
+ **
+ **  
+ **  USAGE:
+ **        _:component("tube.lib").model:_
+ **  where
+ **       model is on of the models above.
+ ** 
+ **  EXAMPLE 2 STAGE TUBE PREAMP:
+ **    process = component("tube.lib").T1_12AX7 : *(preamp):
+ **      lowpass(1,6531.0) : component("tube.lib").T2_12AX7 : *(preamp): 
+ **      lowpass(1,6531.0) : component("tube.lib").T3_12AX7 : *(gain) with {
+ **      preamp = vslider("Pregain",-6,-20,20,0.1) : db2linear : smooth(0.999);
+ **      gain  = vslider("Gain", -6, -20.0, 20.0, 0.1) : db2linear : smooth(0.999);
+ **    };  
+ **
+ ******************************************************************************/
+
+tubestageF(tb,vplus,divider,fck,Rk,Vk0) = tube : hpf with {
+    lpfk = lowpass(1,fck);
+    Rp = 100.0e3;
+    VkC = Vk0 * (Rp/Rk);
+
+// Characteristics of the tubes
+    low = -5;
+    high = 5;
+    step = 200;
+    size = 2001;
+
+    tube = (+ : -(Vk0) : tubeF(tb, low, high, step, size) : +(VkC-vplus)) ~ (*(Rk/Rp) : lpfk) : /(divider);
+    hpf = highpass(1,31.0);
+};
+
+tubestage(tb,fck,Rk,Vk0)       = tubestageF(tb,250.0,40.0,fck,Rk,Vk0);
+tubestage130_20(tb,fck,Rk,Vk0) = tubestageF(tb,130.0,20.0,fck,Rk,Vk0);
+
+/********************* basic tube settings to model stage 1 - 2 *************************/
+
+T1_12AX7 = tubestage(tubetable_12AX7_0,86.0,2700.0,1.581656);
+T2_12AX7 = tubestage(tubetable_12AX7_1,132.0,1500.0,1.204285);
+T3_12AX7 = tubestage(tubetable_12AX7_1,194.0,820.0,0.840703);
+T1_12AT7 = tubestage(tubetable_12AT7_0,86.0,2700.0,2.617753);
+T2_12AT7 = tubestage(tubetable_12AT7_1,132.0,1500.0,1.887332);
+T3_12AT7 = tubestage(tubetable_12AT7_1,194.0,820.0,1.256962);
+T1_12AU7 = tubestage(tubetable_12AU7_0,86.0,2700.0,3.718962);
+T2_12AU7 = tubestage(tubetable_12AU7_1,132.0,1500.0,2.314844);
+T3_12AU7 = tubestage(tubetable_12AU7_1,194.0,820.0,1.356567);
+T1_6V6   = tubestage(tubetable_6V6_0,86.0,2700.0,2.296150);
+T2_6V6   = tubestage(tubetable_6V6_1,132.0,1500.0,1.675587);
+T3_6V6   = tubestage(tubetable_6V6_1,194.0,820.0,1.130462);
+T1_6DJ8  = tubestage130_20(tubetable_6DJ8_0,86.0,2700.0,1.863946);
+T2_6DJ8  = tubestage130_20(tubetable_6DJ8_1,132.0,1500.0,1.271609);
+T3_6DJ8  = tubestage130_20(tubetable_6DJ8_0,194.0,820.0,0.799031);
+T1_6C16  = tubestage(tubetable_6C16_0,86.0,2700.0,2.921806);
+T2_6C16  = tubestage(tubetable_6C16_1,132.0,1500.0,2.097743);
+T3_6C16  = tubestage(tubetable_6C16_1,194.0,820.0,1.378742);
+
+/****************************************************************************************
+*	declare all the waveforms
+****************************************************************************************/  
+
+// generated by ../../tools/tube_transfer.py
+// tube: 6C16
+// plate current function: triode
+// mu: 42.2
+// kx: 2.21
+// kg1: 393
+// kp: 629
+// kvb: 446
+
+tubetable_6C16_0 = waveform{
+	214.806581677,214.650587712,214.494441388,214.338143449,214.181694635,
+	214.025095677,213.868347304,213.711450238,213.554405194,213.397212884,
+	213.239874013,213.082389282,212.924759385,212.766985013,212.60906685,
+	212.451005576,212.292801864,212.134456385,211.975969802,211.817342776,
+	211.658575961,211.499670005,211.340625555,211.181443251,211.022123727,
+	210.862667614,210.703075539,210.543348122,210.383485982,210.22348973,
+	210.063359973,209.903097317,209.742702359,209.582175694,209.421517913,
+	209.260729602,209.099811343,208.938763714,208.777587287,208.616282633,
+	208.454850316,208.293290899,208.131604938,207.969792986,207.807855593,
+	207.645793304,207.483606661,207.321296202,207.15886246,206.996305965,
+	206.833627244,206.67082682,206.507905211,206.344862933,206.181700497,
+	206.018418412,205.855017182,205.691497309,205.527859289,205.364103618,
+	205.200230785,205.036241278,204.872135582,204.707914176,204.543577538,
+	204.379126141,204.214560458,204.049880955,203.885088096,203.720182343,
+	203.555164155,203.390033984,203.224792285,203.059439505,202.893976089,
+	202.728402482,202.562719123,202.396926447,202.23102489,202.065014882,
+	201.898896852,201.732671223,201.56633842,201.399898861,201.233352963,
+	201.066701141,200.899943805,200.733081363,200.566114223,200.399042787,
+	200.231867455,200.064588626,199.897206695,199.729722054,199.562135094,
+	199.394446202,199.226655764,199.058764161,198.890771775,198.722678983,
+	198.554486159,198.386193678,198.217801909,198.04931122,197.880721977,
+	197.712034543,197.54324928,197.374366545,197.205386696,197.036310087,
+	196.86713707,196.697867994,196.528503206,196.359043053,196.189487877,
+	196.019838019,195.850093818,195.680255611,195.510323732,195.340298515,
+	195.170180288,194.999969382,194.829666122,194.659270832,194.488783835,
+	194.318205451,194.147535999,193.976775794,193.805925153,193.634984386,
+	193.463953805,193.292833719,193.121624434,192.950326255,192.778939486,
+	192.607464428,192.43590138,192.264250641,192.092512505,191.920687267,
+	191.74877522,191.576776653,191.404691857,191.232521118,191.060264721,
+	190.887922951,190.715496088,190.542984415,190.370388209,190.197707747,
+	190.024943305,189.852095157,189.679163575,189.50614883,189.33305119,
+	189.159870923,188.986608295,188.813263571,188.639837013,188.466328882,
+	188.292739439,188.119068941,187.945317645,187.771485807,187.597573681,
+	187.423581518,187.249509571,187.075358088,186.901127317,186.726817506,
+	186.552428899,186.377961741,186.203416274,186.028792738,185.854091375,
+	185.679312422,185.504456116,185.329522693,185.154512388,184.979425434,
+	184.804262062,184.629022504,184.453706988,184.278315742,184.102848994,
+	183.927306968,183.751689889,183.57599798,183.400231463,183.224390558,
+	183.048475484,182.872486461,182.696423704,182.520287429,182.344077852,
+	182.167795186,181.991439642,181.815011432,181.638510767,181.461937854,
+	181.285292902,181.108576118,180.931787707,180.754927872,180.577996819,
+	180.400994749,180.223921863,180.046778361,179.869564443,179.692280306,
+	179.514926148,179.337502164,179.16000855,178.982445499,178.804813204,
+	178.627111857,178.449341649,178.27150277,178.093595408,177.915619752,
+	177.737575989,177.559464305,177.381284884,177.203037911,177.024723568,
+	176.846342039,176.667893504,176.489378144,176.310796138,176.132147665,
+	175.953432902,175.774652027,175.595805214,175.416892639,175.237914476,
+	175.058870898,174.879762077,174.700588185,174.521349393,174.342045871,
+	174.162677786,173.983245308,173.803748604,173.624187839,173.444563181,
+	173.264874792,173.085122839,172.905307483,172.725428887,172.545487212,
+	172.365482621,172.185415271,172.005285324,171.825092937,171.644838268,
+	171.464521474,171.284142712,171.103702136,170.923199902,170.742636163,
+	170.562011074,170.381324785,170.20057745,170.019769219,169.838900242,
+	169.65797067,169.476980651,169.295930334,169.114819866,168.933649395,
+	168.752419065,168.571129024,168.389779415,168.208370384,168.026902072,
+	167.845374625,167.663788182,167.482142887,167.300438881,167.118676302,
+	166.936855292,166.754975989,166.573038531,166.391043057,166.208989703,
+	166.026878606,165.844709901,165.662483725,165.480200212,165.297859496,
+	165.11546171,164.933006988,164.750495462,164.567927263,164.385302523,
+	164.202621372,164.019883941,163.837090358,163.654240754,163.471335255,
+	163.288373991,163.105357087,162.922284672,162.739156871,162.555973809,
+	162.372735612,162.189442404,162.00609431,161.822691453,161.639233955,
+	161.45572194,161.272155529,161.088534844,160.904860005,160.721131134,
+	160.537348349,160.353511771,160.169621519,159.98567771,159.801680463,
+	159.617629896,159.433526124,159.249369266,159.065159437,158.880896752,
+	158.696581327,158.512213277,158.327792715,158.143319755,157.958794511,
+	157.774217096,157.589587621,157.4049062,157.220172943,157.035387961,
+	156.850551366,156.665663268,156.480723775,156.295732998,156.110691046,
+	155.925598028,155.74045405,155.555259222,155.37001365,155.184717441,
+	154.999370702,154.813973539,154.628526057,154.443028363,154.25748056,
+	154.071882754,153.886235049,153.700537548,153.514790354,153.328993572,
+	153.143147302,152.957251649,152.771306713,152.585312596,152.3992694,
+	152.213177225,152.027036171,151.840846339,151.654607829,151.46832074,
+	151.28198517,151.09560122,150.909168986,150.722688568,150.536160062,
+	150.349583566,150.162959178,149.976286994,149.78956711,149.602799623,
+	149.415984628,149.22912222,149.042212495,148.855255548,148.668251473,
+	148.481200364,148.294102315,148.106957419,147.919765771,147.732527463,
+	147.545242587,147.357911237,147.170533503,146.983109479,146.795639255,
+	146.608122923,146.420560573,146.232952297,146.045298185,145.857598327,
+	145.669852813,145.482061732,145.294225174,145.106343228,144.918415983,
+	144.730443527,144.542425949,144.354363336,144.166255777,143.978103358,
+	143.789906168,143.601664294,143.413377821,143.225046837,143.036671428,
+	142.848251681,142.65978768,142.471279512,142.282727262,142.094131015,
+	141.905490856,141.71680687,141.528079142,141.339307755,141.150492794,
+	140.961634343,140.772732485,140.583787303,140.394798882,140.205767303,
+	140.016692651,139.827575006,139.638414453,139.449211072,139.259964947,
+	139.070676158,138.881344788,138.691970919,138.50255463,138.313096004,
+	138.123595121,137.934052062,137.744466908,137.554839739,137.365170636,
+	137.175459677,136.985706944,136.795912515,136.606076471,136.416198891,
+	136.226279854,136.036319439,135.846317724,135.65627479,135.466190714,
+	135.276065574,135.08589945,134.895692419,134.70544456,134.515155949,
+	134.324826666,134.134456787,133.94404639,133.753595552,133.563104351,
+	133.372572864,133.182001167,132.991389337,132.800737452,132.610045587,
+	132.41931382,132.228542226,132.037730882,131.846879864,131.655989247,
+	131.465059109,131.274089524,131.083080569,130.892032318,130.700944849,
+	130.509818235,130.318652552,130.127447876,129.936204281,129.744921843,
+	129.553600637,129.362240737,129.170842219,128.979405156,128.787929624,
+	128.596415698,128.404863451,128.213272959,128.021644295,127.829977533,
+	127.638272749,127.446530017,127.254749409,127.062931001,126.871074867,
+	126.679181079,126.487249713,126.295280842,126.103274541,125.911230881,
+	125.719149938,125.527031786,125.334876497,125.142684145,124.950454804,
+	124.758188548,124.565885449,124.373545582,124.18116902,123.988755837,
+	123.796306105,123.603819898,123.41129729,123.218738354,123.026143164,
+	122.833511792,122.640844313,122.448140799,122.255401324,122.062625961,
+	121.869814784,121.676967866,121.484085281,121.291167101,121.098213401,
+	120.905224253,120.712199732,120.51913991,120.326044862,120.132914661,
+	119.93974938,119.746549093,119.553313874,119.360043796,119.166738933,
+	118.973399359,118.780025148,118.586616373,118.393173109,118.19969543,
+	118.006183409,117.81263712,117.619056639,117.425442039,117.231793394,
+	117.038110779,116.844394268,116.650643936,116.456859857,116.263042107,
+	116.069190759,115.87530589,115.681387573,115.487435884,115.293450898,
+	115.09943269,114.905381337,114.711296912,114.517179492,114.323029153,
+	114.128845971,113.93463002,113.740381379,113.546100122,113.351786326,
+	113.157440068,112.963061424,112.768650472,112.574207287,112.379731948,
+	112.185224531,111.990685114,111.796113774,111.601510589,111.406875638,
+	111.212208997,111.017510746,110.822780964,110.628019727,110.433227116,
+	110.238403209,110.043548087,109.848661827,109.65374451,109.458796215,
+	109.263817024,109.068807015,108.87376627,108.678694869,108.483592894,
+	108.288460425,108.093297545,107.898104334,107.702880875,107.507627251,
+	107.312343543,107.117029835,106.921686209,106.726312749,106.530909539,
+	106.335476663,106.140014205,105.944522249,105.749000881,105.553450185,
+	105.357870248,105.162261155,104.966622992,104.770955847,104.575259805,
+	104.379534954,104.183781382,103.987999177,103.792188428,103.596349222,
+	103.40048165,103.204585801,103.008661765,102.812709632,102.616729493,
+	102.420721441,102.224685566,102.02862196,101.832530717,101.636411929,
+	101.440265691,101.244092096,101.047891239,100.851663216,100.655408121,
+	100.459126052,100.262817104,100.066481377,99.8701189658,99.673729971,
+	99.477314491,99.2808726256,99.0844044752,98.8879101407,98.6913897236,
+	98.4948433264,98.2982710519,98.1016730037,97.9050492862,97.7084000044,
+	97.5117252641,97.3150251718,97.1182998349,96.9215493615,96.7247738603,
+	96.5279734411,96.3311482144,96.1342982917,95.9374237851,95.7405248079,
+	95.5436014741,95.3466538988,95.1496821978,94.9526864881,94.7556668877,
+	94.5586235156,94.3615564917,94.1644659371,93.9673519741,93.7702147259,
+	93.5730543171,93.3758708733,93.1786645213,92.9814353893,92.7841836066,
+	92.5869093039,92.3896126132,92.1922936679,91.9949526028,91.7975895541,
+	91.6002046595,91.4027980582,91.205369891,91.0079203002,90.8104494298,
+	90.6129574255,90.4154444347,90.2179106065,90.0203560919,89.8227810438,
+	89.6251856168,89.4275699678,89.2299342554,89.0322786405,88.8346032859,
+	88.636908357,88.4391940209,88.2414604476,88.0437078089,87.8459362796,
+	87.6481460367,87.4503372598,87.2525101312,87.0546648361,86.8568015623,
+	86.6589205007,86.461021845,86.2631057922,86.0651725422,85.8672222985,
+	85.6692552677,85.47127166,85.2732716892,85.0752555725,84.8772235314,
+	84.6791757908,84.4811125799,84.2830341322,84.084940685,83.8868324806,
+	83.6887097654,83.4905727907,83.2924218127,83.0942570925,82.8960788963,
+	82.6978874958,82.499683168,82.3014661959,82.1032368679,81.9049954788,
+	81.7067423296,81.5084777275,81.3102019866,81.1119154278,80.9136183791,
+	80.7153111759,80.516994161,80.3186676851,80.1203321072,79.9219877944,
+	79.7236351224,79.5252744761,79.3269062494,79.1285308459,78.9301486789,
+	78.7317601719,78.533365759,78.3349658854,78.1365610071,77.9381515922,
+	77.7397381206,77.5413210848,77.34290099,77.1444783551,76.9460537123,
+	76.7476276085,76.5492006051,76.350773279,76.1523462226,75.9539200451,
+	75.7554953721,75.5570728472,75.3586531317,75.160236906,74.9618248697,
+	74.7634177425,74.5650162649,74.3666211991,74.1682333293,73.969853463,
+	73.7714824312,73.57312109,73.3747703208,73.1764310315,72.9781041575,
+	72.7797906624,72.5814915392,72.3832078112,72.1849405333,71.9866907928,
+	71.7884597106,71.5902484426,71.3920581808,71.1938901544,70.9957456312,
+	70.7976259192,70.5995323675,70.4014663683,70.203429358,70.0054228187,
+	69.8074482801,69.6095073209,69.4116015707,69.2137327114,69.0159024793,
+	68.8181126671,68.6203651253,68.4226617647,68.2250045581,68.0273955426,
+	67.8298368217,67.6323305676,67.4348790234,67.2374845055,67.0401494061,
+	66.8428761956,66.6456674255,66.4485257304,66.2514538315,66.0544545389,
+	65.8575307545,65.6606854752,65.4639217957,65.2672429117,65.070652123,
+	64.8741528369,64.6777485713,64.4814429582,64.2852397473,64.0891428094,
+	63.89315614,63.6972838629,63.5015302341,63.3058996458,63.1103966298,
+	62.9150258617,62.7197921649,62.5247005146,62.3297560418,62.1349640375,
+	61.9403299569,61.7458594236,61.5515582334,61.3574323592,61.1634879547,
+	60.9697313588,60.7761690999,60.5828078998,60.3896546781,60.1967165562,
+	60.0040008615,59.811515131,59.6192671154,59.427264783,59.2355163231,
+	59.0440301495,58.852814904,58.6618794596,58.4712329231,58.2808846382,
+	58.090844188,57.9011213969,57.7117263328,57.5226693086,57.3339608836,
+	57.1456118642,56.9576333046,56.7700365068,56.58283302,56.3960346403,
+	56.2096534086,56.0237016094,55.8381917678,55.6531366466,55.4685492428,
+	55.284442783,55.1008307186,54.9177267197,54.7351446693,54.5530986556,
+	54.3716029642,54.1906720696,54.0103206254,53.8305634543,53.6514155368,
+	53.4728919991,53.295008101,53.1177792216,52.9412208454,52.7653485472,
+	52.5901779759,52.4157248378,52.2420048797,52.0690338701,51.8968275811,
+	51.7254017683,51.5547721516,51.3849543941,51.2159640815,51.0478167004,
+	50.8805276169,50.7141120546,50.5485850721,50.3839615409,50.220256123,
+	50.0574832487,49.895657094,49.7347915589,49.5749002458,49.4159964377,
+	49.2580930777,49.1012027484,48.9453376526,48.7905095938,48.6367299582,
+	48.4840096974,48.3323593121,48.1817888365,48.0323078239,47.8839253338,
+	47.7366499195,47.5904896174,47.4454519373,47.3015438542,47.1587718012,
+	47.0171416637,46.876658775,46.7373279131,46.5991532994,46.4621385973,
+	46.326286914,46.1916008015,46.0580822608,45.9257327457,45.7945531685,
+	45.6645439069,45.5357048113,45.4080352138,45.2815339377,45.1561993078,
+	45.032029162,44.9090208631,44.7871713114,44.6664769582,44.5469338196,
+	44.4285374906,44.3112831602,44.195165626,44.08017931,43.9663182736,
+	43.8535762342,43.7419465802,43.6314223873,43.5219964345,43.4136612197,
+	43.3064089756,43.2002316854,43.0951210982,42.9910687444,42.8880659502,
+	42.7861038533,42.6851734163,42.5852654418,42.4863705854,42.3884793696,
+	42.2915821966,42.1956693612,42.1007310628,42.0067574174,41.913738469,
+	41.8216642003,41.7305245439,41.6403093918,41.5510086055,41.4626120252,
+	41.3751094786,41.2884907892,41.2027457849,41.1178643049,41.0338362075,
+	40.9506513767,40.8682997286,40.7867712177,40.7060558425,40.6261436509,
+	40.5470247451,40.4686892867,40.3911275007,40.3143296798,40.238286188,
+	40.1629874645,40.0884240263,40.0145864718,39.9414654832,39.869051829,
+	39.7973363663,39.7263100428,39.6559638986,39.5862890679,39.5172767805,
+	39.4489183628,39.381205239,39.3141289323,39.2476810652,39.1818533604,
+	39.1166376415,39.0520258329,38.9880099602,38.9245821507,38.861734633,
+	38.799459737,38.7377498939,38.6765976358,38.6159955956,38.5559365061,
+	38.4964132002,38.4374186098,38.3789457655,38.3209877958,38.2635379265,
+	38.20658948,38.1501358741,38.0941706218,38.03868733,37.9836796987,
+	37.9291415199,37.8750666772,37.821449144,37.7682829833,37.7155623461,
+	37.6632814707,37.6114346815,37.5600163879,37.5090210835,37.4584433446,
+	37.4082778296,37.3585192774,37.3091625068,37.260202415,37.2116339769,
+	37.1634522436,37.1156523417,37.0682294717,37.0211789077,36.9744959955,
+	36.9281761519,36.882214864,36.8366076874,36.7913502455,36.7464382288,
+	36.7018673933,36.6576335597,36.6137326126,36.5701604991,36.5269132281,
+	36.4839868692,36.4413775518,36.3990814641,36.3570948521,36.3154140187,
+	36.2740353227,36.2329551782,36.1921700533,36.1516764693,36.1114710002,
+	36.0715502713,36.0319109585,35.9925497878,35.953463534,35.9146490203,
+	35.8761031172,35.8378227417,35.7998048569,35.7620464706,35.7245446353,
+	35.6872964468,35.6502990438,35.6135496072,35.5770453592,35.5407835628,
+	35.5047615211,35.4689765763,35.4334261096,35.3981075401,35.3630183243,
+	35.3281559555,35.2935179634,35.2591019128,35.2249054039,35.190926071,
+	35.1571615823,35.1236096394,35.0902679764,35.0571343594,35.0242065864,
+	34.9914824864,34.9589599188,34.9266367732,34.8945109687,34.8625804535,
+	34.8308432042,34.7992972259,34.7679405508,34.7367712388,34.7057873762,
+	34.6749870757,34.6443684758,34.6139297407,34.5836690592,34.553584645,
+	34.523674736,34.4939375938,34.4643715034,34.4349747732,34.4057457337,
+	34.3766827382,34.3477841616,34.3190484007,34.2904738733,34.2620590183,
+	34.2338022949,34.2057021827,34.1777571813,34.1499658098,34.1223266066,
+	34.094838129,34.067498953,34.0403076731,34.0132629019,33.9863632696,
+	33.9596074241,33.9329940306,33.906521771,33.8801893442,33.8539954655,
+	33.8279388664,33.8020182942,33.7762325121,33.7505802987,33.7250604478,
+	33.6996717682,33.6744130834,33.6492832315,33.624281065,33.5994054503,
+	33.5746552679,33.5500294117,33.5255267892,33.5011463214,33.4768869419,
+	33.4527475975,33.4287272476,33.404824864,33.3810394309,33.3573699445,
+	33.333815413,33.3103748565,33.2870473064,33.2638318058,33.2407274087,
+	33.2177331806,33.1948481976,33.1720715466,33.1494023254,33.1268396418,
+	33.1043826143,33.0820303713,33.0597820513,33.0376368026,33.0155937833,
+	32.9936521611,32.971811113,32.9500698254,32.928427494,32.9068833234,
+	32.885436527,32.8640863273,32.8428319553,32.8216726506,32.8006076611,
+	32.7796362431,32.7587576613,32.7379711881,32.7172761042,32.696671698,
+	32.6761572657,32.6557321111,32.6353955456,32.615146888,32.5949854646,
+	32.5749106086,32.5549216607,32.5350179685,32.5151988864,32.4954637759,
+	32.4758120052,32.4562429491,32.4367559889,32.4173505127,32.3980259148,
+	32.3787815958,32.3596169627,32.3405314284,32.3215244122,32.3025953392,
+	32.2837436404,32.2649687528,32.246270119,32.2276471875,32.2090994121,
+	32.1906262525,32.1722271737,32.1539016461,32.1356491454,32.1174691527,
+	32.0993611542,32.0813246412,32.0633591103,32.0454640627,32.027639005,
+	32.0098834483,31.9921969088,31.9745789073,31.9570289692,31.9395466249,
+	31.922131409,31.9047828608,31.8875005241,31.870283947,31.8531326821,
+	31.8360462862,31.8190243203,31.8020663499,31.7851719442,31.768340677,
+	31.7515721256,31.7348658718,31.7182215011,31.7016386029,31.6851167705,
+	31.6686556011,31.6522546954,31.6359136583,31.6196320978,31.603409626,
+	31.5872458584,31.571140414,31.5550929153,31.5391029884,31.5231702628,
+	31.5072943712,31.49147495,31.4757116385,31.4600040794,31.4443519189,
+	31.4287548061,31.4132123933,31.3977243359,31.3822902925,31.3669099247,
+	31.3515828971,31.3363088772,31.3210875356,31.3059185458,31.2908015839,
+	31.2757363292,31.2607224636,31.245759672,31.2308476417,31.2159860631,
+	31.2011746291,31.1864130351,31.1717009795,31.1570381631,31.1424242891,
+	31.1278590637,31.1133421951,31.0988733943,31.0844523748,31.0700788523,
+	31.0557525451,31.0414731739,31.0272404614,31.0130541332,30.9989139168,
+	30.9848195421,30.9707707411,30.9567672485,30.9428088006,30.9288951362,
+	30.9150259964,30.9012011241,30.8874202647,30.8736831652,30.8599895751,
+	30.8463392459,30.8327319308,30.8191673854,30.805645367,30.7921656351,
+	30.778727951,30.7653320779,30.751977781,30.7386648273,30.7253929858,
+	30.7121620271,30.6989717239,30.6858218505,30.6727121831,30.6596424997,
+	30.64661258,30.6336222053,30.6206711589,30.6077592256,30.5948861919,
+	30.582051846,30.5692559778,30.5564983788,30.543778842,30.5310971622,
+	30.5184531356,30.5058465602,30.4932772352,30.4807449617,30.4682495421,
+	30.4557907804,30.4433684821,30.430982454,30.4186325047,30.4063184439,
+	30.394040083,30.3817972346,30.369589713,30.3574173335,30.3452799132,
+	30.3331772701,30.3211092241,30.309075596,30.2970762081,30.285110884,
+	30.2731794486,30.2612817281,30.24941755,30.237586743,30.2257891371,
+	30.2140245634,30.2022928546,30.1905938442,30.1789273672,30.1672932596,
+	30.1556913586,30.1441215028,30.1325835317,30.1210772861,30.1096026079,
+	30.09815934,30.0867473267,30.0753664132,30.0640164459,30.0526972721,
+	30.0414087405,30.0301507006,30.018923003,30.0077254995,29.9965580428,
+	29.9854204867,29.974312686,29.9632344964,29.9521857749,29.9411663791,
+	29.930176168,29.9192150012,29.9082827395,29.8973792446,29.8865043791,
+	29.8756580067,29.8648399918,29.8540501999,29.8432884974,29.8325547515,
+	29.8218488304,29.8111706032,29.8005199399,29.7898967112,29.7793007888,
+	29.7687320454,29.7581903544,29.74767559,29.7371876273,29.7267263422,
+	29.7162916116,29.705883313,29.6955013249,29.6851455263,29.6748157973,
+	29.6645120188,29.6542340722,29.64398184,29.6337552052,29.6235540517,
+	29.6133782642,29.6032277281,29.5931023295,29.5830019553,29.5729264931,
+	29.5628758312,29.5528498587,29.5428484654,29.5328715418,29.5229189789,
+	29.5129906688,29.503086504,29.4932063777,29.4833501839,29.4735178172,
+	29.4637091728,29.4539241467,29.4441626356,29.4344245366,29.4247097476,
+	29.4150181672,29.4053496945,29.3957042294,29.3860816723,29.3764819242,
+	29.3669048868,29.3573504624,29.3478185538,29.3383090646,29.3288218988,
+	29.3193569611,29.3099141568,29.3004933916,29.2910945721,29.2817176051,
+	29.2723623983,29.2630288597,29.2537168981,29.2444264227,29.2351573433,
+	29.2259095701,29.2166830142,29.2074775868,29.1982931999,29.189129766,
+	29.1799871982,29.1708654098,29.161764315,29.1526838283,29.1436238647,
+	29.1345843399,29.1255651698,29.1165662711,29.1075875607,29.0986289563,
+	29.0896903759,29.0807717379,29.0718729614,29.0629939658,29.054134671,
+	29.0452949975,29.0364748662,29.0276741982,29.0188929155,29.0101309403,
+	29.0013881953,28.9926646035,28.9839600886,28.9752745746,28.9666079859,
+	28.9579602474,28.9493312845,28.9407210228,28.9321293887,28.9235563085,
+	28.9150017094,28.9064655188,28.8979476644,28.8894480746,28.880966678,
+	28.8725034037,28.864058181,28.8556309398,28.8472216105,28.8388301235,
+	28.8304564099,28.8221004011,28.813762029,28.8054412256,28.7971379235,
+	28.7888520556,28.7805835552,28.772332356,28.764098392,28.7558815975,
+	28.7476819073,28.7394992566,28.7313335807,28.7231848155,28.7150528972,
+	28.7069377621,28.6988393474,28.69075759,28.6826924275,28.6746437979,
+	28.6666116394,28.6585958904,28.6505964899,28.6426133771,28.6346464915,
+	28.626695773,28.6187611617,28.6108425982,28.6029400232,28.595053378,
+	28.5871826039,28.5793276427,28.5714884365,28.5636649277,28.5558570589,
+	28.5480647731,28.5402880136,28.532526724,28.5247808482,28.5170503302,
+	28.5093351147,28.5016351463,28.4939503701,28.4862807313,28.4786261758,
+	28.4709866492,28.4633620978,28.4557524681,28.4481577067,28.4405777608,
+	28.4330125775,28.4254621044,28.4179262893,28.4104050804,28.4028984259,
+	28.3954062746,28.3879285752,28.3804652769,28.3730163292,28.3655816816,
+	28.3581612841,28.3507550868,28.3433630402,28.3359850949,28.3286212019,
+	28.3212713123,28.3139353775,28.3066133492,28.2993051793,28.2920108199,
+	28.2847302234,28.2774633423,28.2702101296,28.2629705384,28.2557445219,
+	28.2485320337,28.2413330275,28.2341474574,28.2269752777,28.2198164427,
+	28.2126709072,28.205538626,28.1984195544,28.1913136475,28.1842208611,
+	28.1771411508,28.1700744728,28.1630207831,28.1559800382,28.1489521948,
+	28.1419372097,28.13493504,28.1279456429,28.1209689759,28.1140049966,
+	28.107053663,28.1001149332,28.0931887653,28.0862751179,28.0793739497,
+	28.0724852196,28.0656088866,28.0587449099,28.0518932492,28.0450538639,
+	28.038226714,28.0314117595,28.0246089606,28.0178182778,28.0110396715,
+	28.0042731028,27.9975185324,27.9907759215,27.9840452315,27.9773264239,
+	27.9706194605,27.9639243029,27.9572409134,27.9505692542,27.9439092876,
+	27.9372609763,27.9306242829,27.9239991704,27.917385602,27.9107835408,
+	27.9041929503,27.8976137942,27.8910460361,27.8844896401,27.8779445702,
+	27.8714107907,27.8648882661,27.8583769608,27.8518768397,27.8453878678,
+	27.8389100099,27.8324432315,27.8259874979,27.8195427746,27.8131090273,
+	27.806686222,27.8002743245,27.7938733011,27.7874831181,27.781103742,
+	27.7747351393,27.7683772768,27.7620301215,27.7556936405,27.7493678008,
+	27.74305257,27.7367479154,27.7304538047,27.7241702058,27.7178970865,
+	27.7116344149,27.7053821593,27.6991402879,27.6929087694,27.6866875722,
+	27.6804766652,27.6742760174,27.6680855976,27.6619053752,27.6557353194,
+	27.6495753996,27.6434255855,27.6372858468,27.6311561533,27.6250364749,
+	27.6189267819,27.6128270443,27.6067372327,27.6006573174,27.594587269,
+	27.5885270585,27.5824766565,27.5764360341,27.5704051624,27.5643840127,
+	27.5583725563,27.5523707647,27.5463786095,27.5403960625,27.5344230955,
+	27.5284596804,27.5225057894,27.5165613947,27.5106264685,27.5047009834,
+	27.4987849119,27.4928782266,27.4869809004,27.4810929061,27.4752142168,
+	27.4693448056,27.4634846457,27.4576337105,27.4517919735,27.4459594082,
+	27.4401359884,27.4343216877,27.4285164802,27.4227203398,27.4169332407,
+	27.411155157,27.4053860632,27.3996259336,27.3938747428,27.3881324655,
+	27.3823990764,27.3766745503,27.3709588622,27.3652519873,27.3595539006,
+	27.3538645774,27.3481839931,27.3425121231,27.3368489431,27.3311944287,
+	27.3255485556,27.3199112998,27.3142826371,27.3086625437,27.3030509957,
+	27.2974479694,27.291853441,27.2862673871,27.2806897842,27.2751206089,
+	27.2695598379,27.2640074481,27.2584634164,27.2529277198,27.2474003354,
+	27.2418812403,27.2363704118,27.2308678274,27.2253734644,27.2198873005,
+	27.2144093132,27.2089394803,27.2034777796,27.1980241889,27.1925786864,
+	27.18714125,27.181711858,27.1762904885,27.1708771199,27.1654717306,
+	27.1600742991,27.1546848041,27.1493032241,27.1439295379,27.1385637244,
+	27.1332057625,27.1278556311,27.1225133094,27.1171787765,27.1118520117,
+	27.1065329942,27.1012217036,27.0959181192,27.0906222206,27.0853339875,
+	27.0800533996,27.0747804366,27.0695150786,27.0642573053,27.0590070968,
+	27.0537644333,27.048529295,27.0433016619,27.0380815146,27.0328688334,
+	27.0276635988,27.0224657913,27.0172753915,27.0120923803,27.0069167383,
+	27.0017484463,26.9965874854,26.9914338364,26.9862874805,26.9811483988,
+	26.9760165725,26.9708919829,26.9657746112,26.960664439,26.9555614477,
+	26.9504656189,26.9453769341,26.9402953751,26.9352209236,26.9301535615,
+	26.9250932707,26.920040033,26.9149938306,26.9099546455,26.9049224599,
+	26.899897256,26.8948790161,26.8898677226,26.8848633578,26.8798659043,
+	26.8748753447,26.8698916614,26.8649148373,26.8599448551,26.8549816974,
+	26.8500253473,26.8450757877,26.8401330015,26.8351969718,26.8302676817,
+	26.8253451143,26.820429253,26.815520081,26.8106175817,26.8057217385,
+	26.8008325349,26.7959499543,26.7910739805,26.786204597,26.7813417876,
+	26.7764855361,26.7716358262,26.7667926419,26.7619559671,26.7571257859,
+	26.7523020822,26.7474848402,26.7426740441,26.737869678,26.7330717264,
+	26.7282801735,26.7234950037,26.7187162015,26.7139437514,26.7091776379,
+	26.7044178457,26.6996643594,26.6949171638,26.6901762436,26.6854415837,
+	26.680713169,26.6759909844,26.6712750148,26.6665652454,26.6618616612,
+	26.6571642474,26.6524729891,26.6477878717,26.6431088804,26.6384360006,
+	26.6337692177,26.6291085171,26.6244538844,26.6198053051,26.6151627648,
+	26.6105262491,26.6058957438,26.6012712347,26.5966527074,26.592040148,
+	26.5874335422,26.5828328761,26.5782381356,26.5736493067,26.5690663756,
+	26.5644893285,26.5599181514,26.5553528306,26.5507933525,26.5462397032,
+	26.5416918693,26.5371498371,26.5326135931,26.5280831239,26.5235584158,
+	26.5190394557,26.5145262301,26.5100187257,26.5055169292,26.5010208275,
+	26.4965304073,26.4920456556,26.4875665593,26.4830931052,26.4786252805,
+	26.4741630721,26.4697064672,26.4652554529,26.4608100163,26.4563701447,
+	26.4519358254,26.4475070456,26.4430837927,26.4386660541,26.4342538172,
+	26.4298470695,26.4254457985,26.4210499918,26.4166596369,26.4122747215,
+	26.4078952332,26.4035211598,26.3991524891,26.3947892088,26.3904313068,
+	26.3860787709,26.3817315891,26.3773897493,26.3730532396,26.3687220479,
+	26.3643961623,26.360075571,26.3557602621,26.3514502237,26.3471454442,
+	26.3428459118,26.3385516148,26.3342625415,26.3299786803,26.3257000197,
+	26.3214265481,26.3171582539,26.3128951257,26.3086371522,26.3043843218,
+	26.3001366232,26.2958940452,26.2916565763,26.2874242055,26.2831969213,
+	26.2789747128,26.2747575687,26.2705454778,26.2663384293,26.2621364119,
+	26.2579394148,26.2537474269,26.2495604373,26.2453784351,26.2412014095,
+	26.2370293495,26.2328622446,26.2287000837,26.2245428563,26.2203905517,
+	26.2162431591,26.212100668,26.2079630678,26.2038303479,26.1997024978,
+	26.1955795069,26.1914613649,26.1873480613,26.1832395857,26.1791359278,
+	26.1750370772,26.1709430235,26.1668537567,26.1627692664,26.1586895424,
+	26.1546145745,26.1505443526,26.1464788667,26.1424181066,26.1383620622,
+	26.1343107237,26.1302640809,26.1262221239,26.1221848429,26.1181522279,
+	26.114124269,26.1101009565,26.1060822805,26.1020682313,26.098058799,
+	26.0940539741,26.0900537468,26.0860581075,26.0820670466,26.0780805544,
+	26.0740986214,26.070121238,26.0661483949,26.0621800824,26.0582162911,
+	26.0542570117,26.0503022347,26.0463519507,26.0424061505,26.0384648247,
+	26.0345279641,26.0305955593,26.0266676012,26.0227440806,26.0188249883,
+	26.0149103152,26.0110000522,26.0070941901,26.00319272,25.9992956327,
+	25.9954029194,25.9915145709,25.9876305784,25.983750933,25.9798756257,
+	25.9760046476,25.97213799,25.9682756441,25.9644176009,25.9605638518,
+	25.956714388,25.9528692009,25.9490282816,25.9451916216,25.9413592122,
+	25.9375310449,25.9337071109,25.9298874018,25.9260719091,25.9222606242,
+	25.9184535386,25.9146506439,25.9108519316,25.9070573933,25.9032670207,
+	25.8994808054
+	};
+
+tubetable_6C16_1 = waveform{
+	214.806581677,214.650587712,214.494441388,214.338143449,214.181694635,
+	214.025095677,213.868347304,213.711450238,213.554405194,213.397212884,
+	213.239874013,213.082389282,212.924759385,212.766985013,212.60906685,
+	212.451005576,212.292801864,212.134456385,211.975969802,211.817342776,
+	211.658575961,211.499670005,211.340625555,211.181443251,211.022123727,
+	210.862667614,210.703075539,210.543348122,210.383485982,210.22348973,
+	210.063359973,209.903097317,209.742702359,209.582175694,209.421517913,
+	209.260729602,209.099811343,208.938763714,208.777587287,208.616282633,
+	208.454850316,208.293290899,208.131604938,207.969792986,207.807855593,
+	207.645793304,207.483606661,207.321296202,207.15886246,206.996305965,
+	206.833627244,206.67082682,206.507905211,206.344862933,206.181700497,
+	206.018418412,205.855017182,205.691497309,205.527859289,205.364103618,
+	205.200230785,205.036241278,204.872135582,204.707914176,204.543577538,
+	204.379126141,204.214560458,204.049880955,203.885088096,203.720182343,
+	203.555164155,203.390033984,203.224792285,203.059439505,202.893976089,
+	202.728402482,202.562719123,202.396926447,202.23102489,202.065014882,
+	201.898896852,201.732671223,201.56633842,201.399898861,201.233352963,
+	201.066701141,200.899943805,200.733081363,200.566114223,200.399042787,
+	200.231867455,200.064588626,199.897206695,199.729722054,199.562135094,
+	199.394446202,199.226655764,199.058764161,198.890771775,198.722678983,
+	198.554486159,198.386193678,198.217801909,198.04931122,197.880721977,
+	197.712034543,197.54324928,197.374366545,197.205386696,197.036310087,
+	196.86713707,196.697867994,196.528503206,196.359043053,196.189487877,
+	196.019838019,195.850093818,195.680255611,195.510323732,195.340298515,
+	195.170180288,194.999969382,194.829666122,194.659270832,194.488783835,
+	194.318205451,194.147535999,193.976775794,193.805925153,193.634984386,
+	193.463953805,193.292833719,193.121624434,192.950326255,192.778939486,
+	192.607464428,192.43590138,192.264250641,192.092512505,191.920687267,
+	191.74877522,191.576776653,191.404691857,191.232521118,191.060264721,
+	190.887922951,190.715496088,190.542984415,190.370388209,190.197707747,
+	190.024943305,189.852095157,189.679163575,189.50614883,189.33305119,
+	189.159870923,188.986608295,188.813263571,188.639837013,188.466328882,
+	188.292739439,188.119068941,187.945317645,187.771485807,187.597573681,
+	187.423581518,187.249509571,187.075358088,186.901127317,186.726817506,
+	186.552428899,186.377961741,186.203416274,186.028792738,185.854091375,
+	185.679312422,185.504456116,185.329522693,185.154512388,184.979425434,
+	184.804262062,184.629022504,184.453706988,184.278315742,184.102848994,
+	183.927306968,183.751689889,183.57599798,183.400231463,183.224390558,
+	183.048475484,182.872486461,182.696423704,182.520287429,182.344077852,
+	182.167795186,181.991439642,181.815011432,181.638510767,181.461937854,
+	181.285292902,181.108576118,180.931787707,180.754927872,180.577996819,
+	180.400994749,180.223921863,180.046778361,179.869564443,179.692280306,
+	179.514926148,179.337502164,179.16000855,178.982445499,178.804813204,
+	178.627111857,178.449341649,178.27150277,178.093595408,177.915619752,
+	177.737575989,177.559464305,177.381284884,177.203037911,177.024723568,
+	176.846342039,176.667893504,176.489378144,176.310796138,176.132147665,
+	175.953432902,175.774652027,175.595805214,175.416892639,175.237914476,
+	175.058870898,174.879762077,174.700588185,174.521349393,174.342045871,
+	174.162677786,173.983245308,173.803748604,173.624187839,173.444563181,
+	173.264874793,173.085122839,172.905307483,172.725428887,172.545487212,
+	172.365482621,172.185415272,172.005285324,171.825092937,171.644838268,
+	171.464521475,171.284142712,171.103702136,170.923199902,170.742636163,
+	170.562011074,170.381324785,170.20057745,170.019769219,169.838900242,
+	169.65797067,169.476980651,169.295930334,169.114819867,168.933649395,
+	168.752419065,168.571129024,168.389779415,168.208370384,168.026902072,
+	167.845374625,167.663788183,167.482142888,167.300438881,167.118676302,
+	166.936855292,166.754975989,166.573038531,166.391043057,166.208989703,
+	166.026878606,165.844709901,165.662483725,165.480200212,165.297859496,
+	165.115461711,164.933006988,164.750495462,164.567927263,164.385302523,
+	164.202621372,164.019883941,163.837090359,163.654240754,163.471335256,
+	163.288373991,163.105357088,162.922284672,162.739156871,162.555973809,
+	162.372735612,162.189442405,162.006094311,161.822691453,161.639233956,
+	161.455721941,161.27215553,161.088534844,160.904860006,160.721131134,
+	160.53734835,160.353511772,160.169621519,159.985677711,159.801680464,
+	159.617629896,159.433526125,159.249369267,159.065159438,158.880896753,
+	158.696581328,158.512213278,158.327792716,158.143319756,157.958794512,
+	157.774217097,157.589587623,157.404906201,157.220172944,157.035387963,
+	156.850551368,156.665663269,156.480723777,156.295733,156.110691048,
+	155.925598029,155.740454052,155.555259223,155.370013651,155.184717443,
+	154.999370704,154.813973541,154.62852606,154.443028365,154.257480563,
+	154.071882757,153.886235051,153.70053755,153.514790357,153.328993575,
+	153.143147306,152.957251652,152.771306717,152.5853126,152.399269404,
+	152.213177229,152.027036175,151.840846344,151.654607834,151.468320744,
+	151.281985175,151.095601225,150.909168991,150.722688573,150.536160067,
+	150.349583572,150.162959184,149.976287,149.789567117,149.60279963,
+	149.415984635,149.229122227,149.042212503,148.855255556,148.668251481,
+	148.481200372,148.294102323,148.106957428,147.919765781,147.732527473,
+	147.545242597,147.357911247,147.170533514,146.98310949,146.795639267,
+	146.608122935,146.420560586,146.232952311,146.045298199,145.857598342,
+	145.669852828,145.482061748,145.294225191,145.106343245,144.918416001,
+	144.730443545,144.542425968,144.354363356,144.166255797,143.97810338,
+	143.789906191,143.601664317,143.413377845,143.225046862,143.036671454,
+	142.848251708,142.659787708,142.471279541,142.282727292,142.094131047,
+	141.905490889,141.716806905,141.528079178,141.339307792,141.150492833,
+	140.961634383,140.772732527,140.583787347,140.394798927,140.20576735,
+	140.016692699,139.827575057,139.638414505,139.449211127,139.259965004,
+	139.070676217,138.88134485,138.691970983,138.502554697,138.313096073,
+	138.123595193,137.934052137,137.744466986,137.55483982,137.36517072,
+	137.175459765,136.985707035,136.79591261,136.60607657,136.416198993,
+	136.22627996,136.036319549,135.846317839,135.656274909,135.466190838,
+	135.276065704,135.085899585,134.895692559,134.705444705,134.5151561,
+	134.324826823,134.13445695,133.944046559,133.753595729,133.563104534,
+	133.372573054,133.182001365,132.991389543,132.800737666,132.61004581,
+	132.419314051,132.228542467,132.037731132,131.846880124,131.655989518,
+	131.46505939,131.274089817,131.083080873,130.892032635,130.700945177,
+	130.509818577,130.318652908,130.127448245,129.936204665,129.744922243,
+	129.553601052,129.362241169,129.170842668,128.979405623,128.78793011,
+	128.596416203,128.404863976,128.213273504,128.021644862,127.829978123,
+	127.638273363,127.446530654,127.254750072,127.062931691,126.871075583,
+	126.679181825,126.487250488,126.295281648,126.103275378,125.911231752,
+	125.719150844,125.527032727,125.334877475,125.142685163,124.950455862,
+	124.758189648,124.565886593,124.373546772,124.181170257,123.988757122,
+	123.796307442,123.603821288,123.411298735,123.218739857,123.026144726,
+	122.833513416,122.640846001,122.448142555,122.255403149,122.062627859,
+	121.869816757,121.676969918,121.484087414,121.291169319,121.098215706,
+	120.90522665,120.712202224,120.519142502,120.326047556,120.132917462,
+	119.939752292,119.746552121,119.553317022,119.360047069,119.166742336,
+	118.973402897,118.780028826,118.586620198,118.393177086,118.199699564,
+	118.006187707,117.81264159,117.619061286,117.42544687,117.231798417,
+	117.038116001,116.844399697,116.650649581,116.456865726,116.263048209,
+	116.069197103,115.875312486,115.68139443,115.487443014,115.293458311,
+	115.099440397,114.905389349,114.711305243,114.517188154,114.323038158,
+	114.128855333,113.934639754,113.740391499,113.546110644,113.351797266,
+	113.157451442,112.963073249,112.768662766,112.574220069,112.379745237,
+	112.185238347,111.990699479,111.796128709,111.601526117,111.406891782,
+	111.212225782,111.017528197,110.822799106,110.62803859,110.433246727,
+	110.238423599,110.043569285,109.848683866,109.653767423,109.458820038,
+	109.263841792,109.068832766,108.873793042,108.678722704,108.483621833,
+	108.288490512,108.093328825,107.898136855,107.702914687,107.507662403,
+	107.31238009,107.117067832,106.921725713,106.726353821,106.53095224,
+	106.335521058,106.14006036,105.944570235,105.749050771,105.553502054,
+	105.357924174,105.16231722,104.966681281,104.771016447,104.575322809,
+	104.379600457,104.183849483,103.98806998,103.792262038,103.596425752,
+	103.400561215,103.204668521,103.008747766,102.812799044,102.616822451,
+	102.420818085,102.224786042,102.028726421,101.832639321,101.63652484,
+	101.440383079,101.244214139,101.048018121,100.851795129,100.655545265,
+	100.459268634,100.26296534,100.06663549,99.8702791895,99.6738965474,
+	99.4774876719,99.2810526729,99.0845916608,98.8881047476,98.691592046,
+	98.4950536699,98.2984897344,98.1019003557,97.9052856512,97.7086457396,
+	97.5119807408,97.315290776,97.1185759679,96.9218364403,96.7250723187,
+	96.52828373,96.3314708025,96.1346336663,95.9377724527,95.7408872952,
+	95.5439783285,95.3470456894,95.1500895163,94.9531099497,94.7561071318,
+	94.5590812068,94.3620323212,94.1649606233,93.9678662638,93.7707493956,
+	93.5736101738,93.3764487561,93.1792653025,92.9820599756,92.7848329407,
+	92.5875843657,92.3903144214,92.1930232816,91.9957111228,91.7983781248,
+	91.6010244707,91.4036503465,91.2062559421,91.0088414506,90.8114070689,
+	90.6139529975,90.4164794409,90.2189866076,90.0214747103,89.823943966,
+	89.626394596,89.4288268263,89.2312408877,89.0336370159,88.8360154516,
+	88.6383764408,88.4407202349,88.243047091,88.045357272,87.8476510469,
+	87.6499286907,87.4521904852,87.2544367185,87.0566676858,86.8588836897,
+	86.6610850397,86.4632720534,86.2654450561,86.0676043814,85.8697503714,
+	85.6718833771,85.4740037586,85.2761118852,85.0782081364,84.8802929016,
+	84.6823665808,84.4844295847,84.2864823355,84.0885252669,83.8905588249,
+	83.6925834679,83.4945996672,83.2966079077,83.0986086881,82.9006025218,
+	82.7025899369,82.504571477,82.3065477019,82.1085191881,81.9104865291,
+	81.7124503365,81.5144112404,81.31636989,81.1183269543,80.9202831233,
+	80.7222391079,80.5241956415,80.3261534801,80.1281134038,79.9300762172,
+	79.7320427503,79.5340138598,79.3359904296,79.1379733722,78.9399636292,
+	78.7419621732,78.5439700078,78.3459881699,78.14801773,77.9500597938,
+	77.7521155034,77.5541860386,77.3562726184,77.1583765021,76.960498991,
+	76.7626414298,76.5648052081,76.3669917621,76.1692025763,75.971439185,
+	75.7737031742,75.5759961834,75.3783199075,75.1806760987,74.9830665686,
+	74.78549319,74.5879578994,74.3904626989,74.1930096588,73.9956009193,
+	73.7982386937,73.6009252702,73.4036630149,73.2064543742,73.0093018775,
+	72.8122081401,72.6151758657,72.4182078498,72.2213069825,72.0244762512,
+	71.8277187444,71.6310376545,71.4344362812,71.2379180349,71.0414864401,
+	70.8451451392,70.6488978956,70.4527485979,70.2567012634,70.0607600418,
+	69.8649292195,69.6692132231,69.4736166236,69.2781441408,69.0828006466,
+	68.8875911702,68.6925209014,68.4975951954,68.302819577,68.1081997447,
+	67.9137415753,67.7194511279,67.5253346485,67.3313985744,67.137649538,
+	66.9440943715,66.750740111,66.5575940006,66.3646634965,66.1719562709,
+	65.979480216,65.7872434478,65.5952543092,65.4035213744,65.2120534512,
+	65.0208595845,64.8299490593,64.6393314028,64.4490163873,64.2590140316,
+	64.0693346033,63.8799886194,63.6909868482,63.502340309,63.3140602728,
+	63.1261582616,62.9386460478,62.7515356528,62.5648393451,62.3785696378,
+	62.1927392856,62.0073612811,61.8224488501,61.6380154473,61.4540747498,
+	61.2706406511,61.0877272534,60.9053488602,60.7235199671,60.5422552522,
+	60.3615695659,60.1814779194,60.0019954732,59.8231375236,59.6449194893,
+	59.467356897,59.290465366,59.1142605922,58.9387583312,58.7639743808,
+	58.5899245626,58.4166247035,58.2440906157,58.0723380767,57.9013828089,
+	57.7312404584,57.5619265734,57.3934565824,57.2258457724,57.0591092663,
+	56.8932620005,56.7283187029,56.5642938699,56.4012017447,56.2390562951,
+	56.0778711918,55.9176597869,55.7584350933,55.6002097646,55.442996075,
+	55.2868059006,55.1316507015,54.9775415045,54.8244888866,54.67250296,
+	54.521593358,54.3717692215,54.2230391876,54.0754113787,53.928893393,
+	53.7834922966,53.6392146163,53.4960663344,53.3540528842,53.213179147,
+	53.0734494507,52.9348675694,52.7974367242,52.6611595853,52.5260382756,
+	52.392074375,52.2592689262,52.1276224411,51.9971349089,51.8678058046,
+	51.7396340988,51.6126182678,51.4867563052,51.3620457335,51.2384836172,
+	51.1160665754,50.9947907962,50.8746520501,50.7556457053,50.6377667424,
+	50.5210097692,50.4053690366,50.2908384541,50.177411605,50.0650817627,
+	49.953841906,49.8436847348,49.7346026858,49.626587948,49.5196324774,
+	49.4137280128,49.30886609,49.2050380567,49.1022350863,49.0004481925,
+	48.899668242,48.7998859685,48.7010919851,48.6032767968,48.5064308127,
+	48.4105443574,48.3156076826,48.2216109775,48.1285443795,48.0363979842,
+	47.9451618546,47.8548260307,47.7653805379,47.6768153954,47.5891206244,
+	47.5022862551,47.4163023342,47.3311589317,47.2468461468,47.1633541147,
+	47.0806730113,46.9987930595,46.9177045334,46.8373977633,46.7578631402,
+	46.6790911195,46.6010722248,46.5237970519,46.4472562712,46.3714406313,
+	46.2963409615,46.2219481742,46.1482532672,46.0752473257,46.0029215242,
+	45.9312671284,45.8602754958,45.789938078,45.7202464213,45.6511921675,
+	45.582767055,45.5149629195,45.4477716941,45.3811854103,45.3151961979,
+	45.249796285,45.1849779988,45.1207337645,45.0570561064,44.9939376466,
+	44.9313711053,44.8693493005,44.8078651471,44.746911657,44.686481938,
+	44.6265691936,44.567166722,44.5082679158,44.449866261,44.391955336,
+	44.3345288112,44.2775804481,44.2211040981,44.1650937017,44.1095432878,
+	44.0544469725,43.9997989584,43.9455935331,43.8918250688,43.8384880208,
+	43.7855769268,43.7330864057,43.6810111566,43.6293459579,43.5780856658,
+	43.5272252138,43.4767596114,43.426683943,43.3769933668,43.3276831139,
+	43.2787484874,43.230184861,43.181987678,43.1341524507,43.0866747587,
+	43.0395502487,42.9927746327,42.9463436875,42.9002532535,42.8544992337,
+	42.8090775929,42.7639843566,42.7192156101,42.6747674974,42.6306362206,
+	42.5868180387,42.5433092665,42.5001062744,42.4572054868,42.4146033815,
+	42.3722964889,42.3302813911,42.2885547209,42.2471131613,42.2059534443,
+	42.1650723503,42.1244667073,42.0841333903,42.0440693199,42.0042714625,
+	41.9647368285,41.9254624723,41.8864454915,41.8476830258,41.8091722568,
+	41.7709104067,41.7328947382,41.6951225536,41.6575911941,41.6202980392,
+	41.5832405061,41.5464160489,41.5098221582,41.4734563605,41.4373162174,
+	41.4013993251,41.3657033141,41.3302258481,41.294964624,41.2599173708,
+	41.2250818496,41.1904558528,41.1560372035,41.1218237553,41.0878133915,
+	41.0540040246,41.0203935961,40.9869800759,40.9537614617,40.9207357786,
+	40.8879010787,40.8552554409,40.8227969699,40.7905237962,40.7584340756,
+	40.7265259888,40.694797741,40.6632475612,40.6318737025,40.6006744409,
+	40.5696480755,40.5387929281,40.5081073423,40.477589684,40.4472383402,
+	40.4170517192,40.3870282502,40.3571663827,40.3274645866,40.2979213512,
+	40.2685351859,40.2393046187,40.210228197,40.1813044866,40.1525320716,
+	40.1239095543,40.0954355544,40.0671087095,40.0389276741,40.0108911199,
+	39.982997735,39.955246224,39.9276353079,39.9001637232,39.8728302225,
+	39.8456335736,39.8185725594,39.7916459781,39.7648526423,39.7381913793,
+	39.7116610306,39.6852604519,39.6589885127,39.6328440961,39.6068260988,
+	39.5809334306,39.5551650145,39.5295197862,39.5039966942,39.4785946995,
+	39.4533127753,39.4281499069,39.4031050918,39.3781773388,39.3533656688,
+	39.3286691137,39.304086717,39.2796175331,39.2552606273,39.2310150758,
+	39.2068799653,39.1828543931,39.1589374668,39.1351283041,39.1114260327,
+	39.0878297902,39.064338724,39.0409519911,39.0176687579,38.9944882003,
+	38.9714095031,38.9484318604,38.9255544753,38.9027765596,38.8800973337,
+	38.8575160268,38.8350318765,38.8126441286,38.7903520373,38.7681548648,
+	38.7460518814,38.7240423652,38.7021256022,38.6803008859,38.6585675176,
+	38.636924806,38.6153720669,38.5939086239,38.5725338073,38.5512469547,
+	38.5300474107,38.5089345267,38.4879076609,38.4669661783,38.4461094505,
+	38.4253368556,38.4046477781,38.384041609,38.3635177454,38.3430755908,
+	38.3227145546,38.3024340525,38.2822335058,38.2621123421,38.2420699944,
+	38.2221059018,38.2022195088,38.1824102656,38.1626776278,38.1430210566,
+	38.1234400185,38.1039339853,38.0845024341,38.065144847,38.0458607114,
+	38.0266495197,38.0075107692,37.9884439622,37.9694486057,37.9505242119,
+	37.9316702972,37.912886383,37.8941719953,37.8755266647,37.8569499261,
+	37.838441319,37.8200003873,37.8016266793,37.7833197474,37.7650791485,
+	37.7469044434,37.7287951972,37.7107509792,37.6927713625,37.6748559244,
+	37.6570042459,37.6392159121,37.621490512,37.6038276382,37.5862268871,
+	37.568687859,37.5512101577,37.5337933905,37.5164371687,37.4991411068,
+	37.4819048228,37.4647279384,37.4476100786,37.4305508715,37.4135499491,
+	37.3966069463,37.3797215014,37.3628932558,37.3461218542,37.3294069446,
+	37.3127481779,37.296145208,37.2795976922,37.2631052905,37.2466676661,
+	37.2302844849,37.2139554159,37.197680131,37.1814583048,37.1652896148,
+	37.1491737414,37.1331103675,37.1170991789,37.1011398641,37.0852321142,
+	37.069375623,37.0535700867,37.0378152045,37.0221106777,37.0064562103,
+	36.990851509,36.9752962825,36.9597902425,36.9443331026,36.9289245791,
+	36.9135643906,36.8982522581,36.8829879046,36.8677710558,36.8526014395,
+	36.8374787856,36.8224028263,36.8073732962,36.7923899319,36.7774524719,
+	36.7625606573,36.747714231,36.7329129381,36.7181565255,36.7034447426,
+	36.6887773404,36.6741540721,36.6595746928,36.6450389596,36.6305466316,
+	36.6160974695,36.6016912363,36.5873276967,36.5730066171,36.5587277661,
+	36.5444909137,36.530295832,36.5161422947,36.5020300775,36.4879589576,
+	36.473928714,36.4599391274,36.4459899804,36.4320810569,36.4182121427,
+	36.4043830253,36.3905934937,36.3768433384,36.3631323519,36.3494603278,
+	36.3358270615,36.32223235,36.3086759918,36.2951577868,36.2816775364,
+	36.2682350438,36.2548301133,36.2414625508,36.2281321637,36.2148387608,
+	36.2015821522,36.1883621497,36.1751785661,36.1620312159,36.1489199148,
+	36.1358444799,36.1228047297,36.1098004839,36.0968315636,36.0838977911,
+	36.0709989901,36.0581349856,36.0453056038,36.0325106721,36.0197500193,
+	36.0070234752,35.9943308711,35.9816720393,35.9690468132,35.9564550278,
+	35.9438965189,35.9313711235,35.9188786799,35.9064190275,35.8939920068,
+	35.8815974594,35.869235228,35.8569051565,35.8446070897,35.8323408738,
+	35.8201063558,35.8079033838,35.7957318069,35.7835914756,35.771482241,
+	35.7594039553,35.747356472,35.7353396454,35.7233533306,35.7113973841,
+	35.6994716631,35.6875760259,35.6757103316,35.6638744405,35.6520682136,
+	35.640291513,35.6285442016,35.6168261434,35.6051372032,35.5934772466,
+	35.5818461403,35.5702437517,35.5586699493,35.5471246023,35.5356075808,
+	35.5241187557,35.512657999,35.5012251833,35.489820182,35.4784428696,
+	35.4670931211,35.4557708126,35.4444758209,35.4332080234,35.4219672987,
+	35.4107535258,35.3995665848,35.3884063562,35.3772727218,35.3661655635,
+	35.3550847646,35.3440302088,35.3330017805,35.321999365,35.3110228483,
+	35.300072117,35.2891470586,35.2782475612,35.2673735136,35.2565248054,
+	35.2457013268,35.2349029688,35.2241296228,35.2133811812,35.2026575371,
+	35.1919585838,35.1812842159,35.1706343282,35.1600088162,35.1494075763,
+	35.1388305053,35.1282775008,35.1177484608,35.1072432842,35.0967618704,
+	35.0863041192,35.0758699315,35.0654592084,35.0550718516,35.0447077637,
+	35.0343668477,35.0240490072,35.0137541462,35.0034821697,34.9932329829,
+	34.9830064918,34.9728026027,34.9626212228,34.9524622596,34.9423256212,
+	34.9322112164,34.9221189543,34.9120487447,34.9020004979,34.8919741248,
+	34.8819695366,34.8719866453,34.8620253633,34.8520856033,34.842167279,
+	34.8322703041,34.8223945932,34.8125400611,34.8027066232,34.7928941955,
+	34.7831026943,34.7733320366,34.7635821397,34.7538529214,34.7441443,
+	34.7344561944,34.7247885237,34.7151412076,34.7055141664,34.6959073207,
+	34.6863205914,34.6767539002,34.6672071689,34.6576803201,34.6481732765,
+	34.6386859615,34.6292182987,34.6197702123,34.6103416268,34.6009324673,
+	34.5915426592,34.5821721282,34.5728208006,34.5634886031,34.5541754628,
+	34.544881307,34.5356060638,34.5263496612,34.517112028,34.5078930933,
+	34.4986927864,34.4895110373,34.4803477761,34.4712029334,34.4620764403,
+	34.4529682279,34.4438782282,34.4348063732,34.4257525953,34.4167168273,
+	34.4076990026,34.3986990546,34.3897169172,34.3807525248,34.3718058119,
+	34.3628767135,34.353965165,34.3450711019,34.3361944604,34.3273351768,
+	34.3184931877,34.3096684302,34.3008608417,34.2920703598,34.2832969226,
+	34.2745404684,34.2658009359,34.2570782641,34.2483723923,34.2396832601,
+	34.2310108075,34.2223549748,34.2137157025,34.2050929316,34.1964866032,
+	34.1878966587,34.1793230401,34.1707656894,34.1622245491,34.1536995617,
+	34.1451906704,34.1366978184,34.1282209493,34.1197600069,34.1113149355,
+	34.1028856794,34.0944721833,34.0860743924,34.0776922518,34.0693257072,
+	34.0609747043,34.0526391894,34.0443191087,34.0360144089,34.027725037,
+	34.0194509401,34.0111920657,34.0029483616,33.9947197757,33.9865062562,
+	33.9783077517,33.970124211,33.9619555829,33.9538018168,33.9456628623,
+	33.937538669,33.929429187,33.9213343666,33.9132541583,33.9051885128,
+	33.8971373811,33.8891007144,33.8810784643,33.8730705825,33.8650770208,
+	33.8570977314,33.8491326669,33.8411817798,33.833245023,33.8253223496,
+	33.8174137129,33.8095190666,33.8016383643,33.7937715601,33.7859186082,
+	33.7780794631,33.7702540793,33.7624424119,33.7546444159,33.7468600466,
+	33.7390892595,33.7313320104,33.7235882552,33.7158579501,33.7081410514,
+	33.7004375158,33.6927472999,33.6850703608,33.6774066556,33.6697561417,
+	33.6621187768,33.6544945186,33.646883325,33.6392851544,33.6316999649,
+	33.6241277153,33.6165683642,33.6090218706,33.6014881937,33.5939672928,
+	33.5864591274,33.5789636572,33.5714808422,33.5640106423,33.5565530179,
+	33.5491079294,33.5416753374,33.5342552028,33.5268474865,33.5194521497,
+	33.5120691538,33.5046984602,33.4973400307,33.489993827,33.4826598114,
+	33.475337946,33.4680281931,33.4607305153,33.4534448754,33.4461712362,
+	33.4389095608,33.4316598125,33.4244219546,33.4171959506,33.4099817644,
+	33.4027793597,33.3955887006,33.3884097513,33.3812424763,33.3740868399,
+	33.3669428069,33.3598103421,33.3526894105,33.3455799772,33.3384820076,
+	33.3313954671,33.3243203212,33.3172565359,33.3102040768,33.3031629102,
+	33.2961330022,33.2891143192,33.2821068276,33.2751104942,33.2681252856,
+	33.2611511689,33.254188111,33.2472360793,33.2402950411,33.2333649639,
+	33.2264458153,33.2195375632,33.2126401754,33.20575362,33.1988778652,
+	33.1920128793,33.1851586308,33.1783150883,33.1714822206,33.1646599965,
+	33.157848385,33.1510473553,33.1442568766,33.1374769184,33.1307074501,
+	33.1239484414,33.1171998621,33.1104616821,33.1037338714,33.0970164003,
+	33.090309239,33.0836123579,33.0769257276,33.0702493187,33.063583102,
+	33.0569270484,33.050281129,33.0436453148,33.0370195773,33.0304038877,
+	33.0237982176,33.0172025386,33.0106168224,33.004041041,32.9974751662,
+	32.9909191702,32.9843730252,32.9778367035,32.9713101775,32.9647934199,
+	32.9582864031,32.9517891002,32.9453014838,32.938823527,32.932355203,
+	32.9258964848,32.919447346,32.9130077598,32.9065776998,32.9001571398,
+	32.8937460533,32.8873444143,32.8809521968,32.8745693748,32.8681959225,
+	32.8618318142,32.8554770243,32.8491315272,32.8427952975,32.8364683099,
+	32.8301505393,32.8238419604,32.8175425484,32.8112522782,32.8049711251,
+	32.7986990644,32.7924360713,32.7861821216,32.7799371906,32.7737012541,
+	32.7674742879,32.7612562677,32.7550471697,32.7488469698,32.7426556442,
+	32.7364731692,32.730299521,32.7241346761,32.717978611,32.7118313024,
+	32.705692727,32.6995628615,32.6934416828,32.6873291679,32.6812252939,
+	32.6751300379,32.6690433772,32.6629652891,32.656895751,32.6508347404,
+	32.6447822349,32.6387382122,32.6327026501,32.6266755264,32.620656819,
+	32.614646506,32.6086445654,32.6026509754,32.5966657144,32.5906887606,
+	32.5847200926,32.5787596887,32.5728075277,32.5668635881,32.5609278488,
+	32.5550002886,32.5490808863,32.5431696211,32.537266472,32.5313714181,
+	32.5254844387,32.519605513,32.5137346206,32.5078717408,32.5020168532,
+	32.4961699374,32.4903309731,32.4844999401,32.4786768182,32.4728615874,
+	32.4670542276,32.4612547189,32.4554630416,32.4496791757,32.4439031016,
+	32.4381347996,32.4323742503,32.426621434,32.4208763314,32.4151389231,
+	32.4094091899,32.4036871126,32.3979726719,32.3922658489,32.3865666246,
+	32.38087498,32.3751908962,32.3695143546,32.3638453363,32.3581838227,
+	32.3525297952,32.3468832354,32.3412441247,32.3356124448,32.3299881773,
+	32.3243713041,32.3187618069,32.3131596676,32.3075648682,32.3019773906,
+	32.296397217,32.2908243294,32.2852587101,32.2797003414,32.2741492056,
+	32.268605285,32.2630685622,32.2575390196,32.2520166399,32.2465014056,
+	32.2409932995,32.2354923044,32.229998403,32.2245115783,32.2190318133,
+	32.2135590908,32.208093394,32.202634706,32.1971830101,32.1917382894,
+	32.1863005272,32.1808697069,32.175445812,32.170028826,32.1646187322,
+	32.1592155144,32.1538191563,32.1484296414,32.1430469536,32.1376710768,
+	32.1323019947,32.1269396913,32.1215841506,32.1162353567,32.1108932936,
+	32.1055579455,32.1002292966,32.0949073313,32.0895920337,32.0842833883,
+	32.0789813795,32.0736859917,32.0683972096,32.0631150177,32.0578394006,
+	32.052570343,32.0473078297,32.0420518455,32.0368023751,32.0315594036,
+	32.0263229158,32.0210928968,32.0158693316,32.0106522053,32.0054415031,
+	32.0002372101,31.9950393117,31.989847793,31.9846626396,31.9794838367,
+	31.9743113698,31.9691452245,31.9639853862,31.9588318406,31.9536845733,
+	31.9485435701,31.9434088165,31.9382802985,31.9331580018,31.9280419124,
+	31.9229320162,31.9178282991,31.9127307472,31.9076393466,31.9025540833,
+	31.8974749435,31.8924019134,31.8873349793,31.8822741275,31.8772193443,
+	31.8721706161,31.8671279293,31.8620912705,31.857060626,31.8520359826,
+	31.8470173268,31.8420046452,31.8369979246,31.8319971517,31.8270023133,
+	31.8220133962,31.8170303872,31.8120532733,31.8070820415,31.8021166787,
+	31.797157172,31.7922035084,31.7872556751,31.7823136593,31.7773774481,
+	31.7724470288,31.7675223886,31.762603515,31.7576903953,31.7527830168,
+	31.7478813671,31.7429854336,31.7380952039,31.7332106655,31.728331806,
+	31.7234586132,31.7185910746,31.713729178,31.7088729112,31.7040222619,
+	31.6991772181,31.6943377676,31.6895038984,31.6846755983,31.6798528554,
+	31.6750356577,31.6702239933,31.6654178504,31.660617217,31.6558220813,
+	31.6510324316,31.6462482561,31.6414695432,31.636696281,31.6319284582,
+	31.6271660629,31.6224090837,31.6176575091,31.6129113276,31.6081705277,
+	31.6034350979,31.5987050271,31.5939803036,31.5892609164,31.5845468541,
+	31.5798381054,31.5751346592,31.5704365043,31.5657436296,31.5610560239,
+	31.5563736762,31.5516965754,31.5470247107,31.5423580709,31.5376966452,
+	31.5330404227,31.5283893925,31.5237435438,31.5191028657,31.5144673476,
+	31.5098369787,31.5052117483,31.5005916457,31.4959766602,31.4913667814,
+	31.4867619986,31.4821623013,31.477567679,31.4729781212,31.4683936175,
+	31.4638141574,31.4592397306,31.4546703267,31.4501059355,31.4455465465,
+	31.4409921497,31.4364427347,31.4318982914,31.4273588096,31.4228242792,
+	31.4182946901,31.4137700321,31.4092502953,31.4047354697,31.4002255452,
+	31.395720512,31.39122036,31.3867250795,31.3822346605,31.3777490932,
+	31.3732683678,31.3687924745,31.3643214037,31.3598551455,31.3553936903,
+	31.3509370284,31.3464851502,31.3420380461,31.3375957065,31.3331581218,
+	31.3287252826,31.3242971794,31.3198738027,31.315455143,31.311041191,
+	31.3066319372,31.3022273724,31.2978274871,31.2934322722,31.2890417183,
+	31.2846558161,31.2802745565,31.2758979303,31.2715259284,31.2671585414,
+	31.2627957605,31.2584375764,31.2540839802,31.2497349627,31.245390515,
+	31.2410506282,31.2367152932,31.2323845011,31.228058243,31.2237365101,
+	31.2194192934,31.2151065843,31.2107983738,31.2064946532,31.2021954137,
+	31.1979006466,31.1936103433,31.189324495,31.1850430931,31.180766129,
+	31.176493594,31.1722254796,31.1679617772,31.1637024784,31.1594475745,
+	31.1551970572,31.1509509179,31.1467091483,31.1424717399,31.1382386843,
+	31.1340099732,31.1297855982,31.1255655511,31.1213498235,31.1171384071,
+	31.1129312938,31.1087284753,31.1045299434,31.1003356899,31.0961457067,
+	31.0919599856
+	};
+	
+tubetable_6C16_rtable_0(r) = (tubetable_6C16_0,r):rdtable;
+tubetable_6C16_rtable_1(r) = (tubetable_6C16_1,r):rdtable;
+
+// generated by ../../tools/tube_transfer.py
+// tube: 6DJ8
+// plate current function: triode
+// mu: 28
+// kx: 1.3
+// kg1: 330
+// kp: 320
+// kvb: 300
+
+tubetable_6DJ8_0 = waveform{
+	137.512728867,137.399223264,137.285690251,137.17212984,137.058542039,
+	136.944926859,136.831284308,136.717614396,136.603917133,136.490192528,
+	136.37644059,136.262661328,136.148854752,136.035020871,135.921159694,
+	135.80727123,135.693355487,135.579412475,135.465442203,135.351444679,
+	135.237419911,135.12336791,135.009288682,134.895182238,134.781048584,
+	134.66688773,134.552699684,134.438484454,134.324242049,134.209972477,
+	134.095675745,133.981351862,133.867000836,133.752622675,133.638217387,
+	133.523784979,133.40932546,133.294838836,133.180325116,133.065784308,
+	132.951216418,132.836621455,132.721999425,132.607350337,132.492674197,
+	132.377971012,132.263240791,132.148483539,132.033699265,131.918887974,
+	131.804049675,131.689184374,131.574292077,131.459372792,131.344426526,
+	131.229453284,131.114453074,130.999425902,130.884371775,130.769290699,
+	130.654182681,130.539047726,130.423885842,130.308697033,130.193481308,
+	130.078238671,129.962969128,129.847672686,129.732349351,129.616999128,
+	129.501622024,129.386218043,129.270787192,129.155329476,129.039844901,
+	128.924333473,128.808795197,128.693230078,128.577638121,128.462019333,
+	128.346373717,128.230701281,128.115002027,127.999275963,127.883523091,
+	127.767743419,127.65193695,127.536103689,127.420243641,127.304356811,
+	127.188443204,127.072502824,126.956535675,126.840541763,126.724521091,
+	126.608473664,126.492399486,126.376298562,126.260170896,126.144016492,
+	126.027835354,125.911627486,125.795392892,125.679131576,125.562843542,
+	125.446528794,125.330187335,125.213819169,125.0974243,124.981002732,
+	124.864554467,124.74807951,124.631577864,124.515049532,124.398494517,
+	124.281912824,124.165304454,124.048669411,123.932007699,123.815319319,
+	123.698604276,123.581862572,123.465094209,123.348299192,123.231477521,
+	123.114629201,122.997754234,122.880852622,122.763924367,122.646969473,
+	122.529987942,122.412979775,122.295944976,122.178883547,122.061795488,
+	121.944680804,121.827539496,121.710371565,121.593177014,121.475955845,
+	121.358708059,121.241433658,121.124132644,121.006805019,120.889450784,
+	120.772069941,120.654662491,120.537228435,120.419767776,120.302280513,
+	120.18476665,120.067226186,119.949659123,119.832065462,119.714445204,
+	119.596798349,119.4791249,119.361424857,119.24369822,119.12594499,
+	119.008165168,118.890358755,118.772525751,118.654666156,118.536779972,
+	118.418867198,118.300927835,118.182961883,118.064969342,117.946950213,
+	117.828904495,117.710832189,117.592733295,117.474607812,117.356455741,
+	117.238277081,117.120071832,117.001839993,116.883581565,116.765296547,
+	116.646984939,116.52864674,116.410281948,116.291890565,116.173472589,
+	116.055028019,115.936556854,115.818059094,115.699534738,115.580983784,
+	115.462406232,115.343802081,115.225171329,115.106513975,114.987830018,
+	114.869119456,114.750382289,114.631618514,114.51282813,114.394011136,
+	114.27516753,114.15629731,114.037400475,113.918477022,113.799526951,
+	113.680550258,113.561546942,113.442517002,113.323460434,113.204377236,
+	113.085267407,112.966130945,112.846967846,112.727778109,112.608561731,
+	112.489318709,112.370049041,112.250752725,112.131429757,112.012080135,
+	111.892703857,111.773300918,111.653871317,111.53441505,111.414932115,
+	111.295422508,111.175886226,111.056323266,110.936733624,110.817117298,
+	110.697474283,110.577804577,110.458108176,110.338385076,110.218635274,
+	110.098858766,109.979055549,109.859225617,109.739368969,109.619485599,
+	109.499575504,109.379638679,109.259675121,109.139684826,109.019667789,
+	108.899624005,108.779553471,108.659456182,108.539332134,108.419181322,
+	108.299003742,108.178799389,108.058568258,107.938310344,107.818025643,
+	107.697714149,107.577375859,107.457010766,107.336618867,107.216200154,
+	107.095754624,106.975282272,106.854783091,106.734257077,106.613704224,
+	106.493124526,106.372517979,106.251884576,106.131224312,106.010537181,
+	105.889823177,105.769082295,105.648314528,105.52751987,105.406698316,
+	105.28584986,105.164974495,105.044072215,104.923143013,104.802186884,
+	104.681203821,104.560193818,104.439156867,104.318092963,104.197002099,
+	104.075884268,103.954739463,103.833567678,103.712368905,103.591143138,
+	103.46989037,103.348610593,103.2273038,103.105969985,102.98460914,
+	102.863221257,102.74180633,102.62036435,102.498895311,102.377399205,
+	102.255876023,102.134325759,102.012748405,101.891143952,101.769512394,
+	101.647853721,101.526167926,101.404455002,101.282714939,101.16094773,
+	101.039153366,100.917331839,100.795483141,100.673607263,100.551704197,
+	100.429773934,100.307816465,100.185831783,100.063819877,99.9417807401,
+	99.8197143622,99.6976207349,99.575499849,99.4533516955,99.3311762653,
+	99.2089735491,99.0867435378,98.964486222,98.8422015924,98.7198896394,
+	98.5975503536,98.4751837255,98.3527897454,98.2303684035,98.1079196902,
+	97.9854435957,97.86294011,97.7404092232,97.6178509253,97.4952652063,
+	97.3726520559,97.250011464,97.1273434204,97.0046479148,96.8819249367,
+	96.7591744756,96.6363965212,96.5135910627,96.3907580897,96.2678975913,
+	96.1450095569,96.0220939755,95.8991508364,95.7761801285,95.6531818408,
+	95.5301559623,95.4071024818,95.2840213882,95.1609126701,95.0377763163,
+	94.9146123152,94.7914206556,94.6682013258,94.5449543144,94.4216796095,
+	94.2983771996,94.1750470729,94.0516892175,93.9283036216,93.8048902731,
+	93.6814491601,93.5579802705,93.4344835922,93.3109591128,93.1874068203,
+	93.0638267021,92.940218746,92.8165829395,92.6929192701,92.5692277251,
+	92.4455082919,92.3217609579,92.1979857102,92.0741825361,91.9503514226,
+	91.8264923567,91.7026053255,91.5786903159,91.4547473147,91.3307763088,
+	91.2067772848,91.0827502295,90.9586951294,90.8346119711,90.7105007411,
+	90.5863614258,90.4621940116,90.3379984848,90.2137748316,90.0895230382,
+	89.9652430908,89.8409349754,89.7165986779,89.5922341844,89.4678414807,
+	89.3434205527,89.218971386,89.0944939665,88.9699882796,88.8454543111,
+	88.7208920464,88.596301471,88.4716825703,88.3470353296,88.2223597342,
+	88.0976557693,87.9729234202,87.8481626718,87.7233735093,87.5985559176,
+	87.4737098817,87.3488353864,87.2239324165,87.0990009569,86.9740409921,
+	86.8490525069,86.7240354858,86.5989899134,86.4739157741,86.3488130523,
+	86.2236817325,86.0985217988,85.9733332355,85.8481160269,85.7228701571,
+	85.5975956101,85.47229237,85.3469604207,85.2215997461,85.0962103302,
+	84.9707921567,84.8453452094,84.719869472,84.5943649281,84.4688315614,
+	84.3432693553,84.2176782934,84.092058359,83.9664095357,83.8407318067,
+	83.7150251553,83.5892895648,83.4635250183,83.337731499,83.2119089899,
+	83.0860574742,82.9601769347,82.8342673545,82.7083287164,82.5823610033,
+	82.456364198,82.3303382832,82.2042832416,82.078199056,81.9520857088,
+	81.8259431828,81.6997714604,81.5735705241,81.4473403564,81.3210809396,
+	81.1947922561,81.0684742883,80.9421270183,80.8157504285,80.6893445011,
+	80.5629092181,80.4364445617,80.309950514,80.1834270571,80.0568741728,
+	79.9302918433,79.8036800504,79.677038776,79.550368002,79.4236677102,
+	79.2969378824,79.1701785004,79.0433895459,78.9165710006,78.7897228462,
+	78.6628450643,78.5359376366,78.4090005446,78.2820337698,78.1550372939,
+	78.0280110983,77.9009551645,77.7738694739,77.6467540081,77.5196087483,
+	77.3924336761,77.2652287728,77.1379940197,77.0107293981,76.8834348895,
+	76.756110475,76.6287561361,76.5013718539,76.3739576098,76.2465133849,
+	76.1190391605,75.9915349179,75.8640006383,75.7364363029,75.6088418928,
+	75.4812173894,75.3535627738,75.2258780272,75.0981631308,74.9704180658,
+	74.8426428134,74.7148373548,74.5870016713,74.459135744,74.3312395542,
+	74.203313083,74.0753563118,73.9473692218,73.8193517943,73.6913040105,
+	73.5632258517,73.4351172993,73.3069783346,73.178808939,73.0506090938,
+	72.9223787804,72.7941179804,72.6658266751,72.537504846,72.4091524748,
+	72.2807695429,72.1523560319,72.0239119235,71.8954371994,71.7669318413,
+	71.6383958309,71.5098291501,71.3812317808,71.2526037048,71.1239449041,
+	70.9952553608,70.866535057,70.7377839747,70.6090020962,70.4801894039,
+	70.3513458799,70.2224715068,70.0935662671,69.9646301433,69.835663118,
+	69.706665174,69.5776362942,69.4485764614,69.3194856586,69.190363869,
+	69.0612110757,68.932027262,68.8028124113,68.6735665071,68.544289533,
+	68.4149814728,68.2856423104,68.1562720296,68.0268706146,67.8974380496,
+	67.767974319,67.6384794072,67.508953299,67.379395979,67.2498074323,
+	67.1201876439,66.990536599,66.8608542831,66.7311406816,66.6013957805,
+	66.4716195655,66.3418120229,66.2119731387,66.0821028996,65.9522012923,
+	65.8222683035,65.6923039203,65.5623081301,65.4322809203,65.3022222787,
+	65.1721321933,65.0420106521,64.9118576437,64.7816731566,64.65145718,
+	64.5212097028,64.3909307146,64.2606202051,64.1302781642,63.9999045824,
+	63.86949945,63.7390627581,63.6085944978,63.4780946606,63.3475632383,
+	63.2170002231,63.0864056074,62.955779384,62.8251215463,62.6944320876,
+	62.563711002,62.4329582837,62.3021739275,62.1713579283,62.0405102818,
+	61.9096309838,61.7787200307,61.6477774192,61.5168031466,61.3857972106,
+	61.2547596093,61.1236903414,60.9925894061,60.8614568029,60.7302925321,
+	60.5990965942,60.4678689907,60.3366097231,60.205318794,60.0739962062,
+	59.9426419632,59.8112560693,59.6798385291,59.5483893481,59.4169085323,
+	59.2853960884,59.1538520239,59.0222763469,58.8906690661,58.7590301912,
+	58.6273597325,58.4956577011,58.3639241087,58.2321589683,58.1003622931,
+	57.9685340977,57.8366743971,57.7047832076,57.5728605462,57.4409064308,
+	57.3089208804,57.1769039148,57.0448555549,56.9127758226,56.7806647409,
+	56.6485223339,56.5163486267,56.3841436456,56.251907418,56.1196399725,
+	55.9873413389,55.8550115484,55.7226506333,55.5902586273,55.4578355654,
+	55.3253814839,55.1928964206,55.0603804149,54.9278335073,54.7952557401,
+	54.6626471571,54.5300078037,54.3973377269,54.2646369754,54.1319055996,
+	53.9991436517,53.8663511857,53.7335282574,53.6006749245,53.4677912468,
+	53.3348772861,53.2019331059,53.0689587724,52.9359543534,52.8029199192,
+	52.6698555425,52.5367612981,52.4036372633,52.2704835179,52.1373001442,
+	52.0040872271,51.8708448542,51.7375731158,51.6042721052,51.4709419183,
+	51.3375826542,51.204194415,51.070777306,50.9373314355,50.8038569154,
+	50.6703538609,50.5368223907,50.4032626271,50.2696746961,50.1360587275,
+	50.0024148551,49.8687432167,49.7350439541,49.6013172136,49.4675631456,
+	49.3337819053,49.1999736524,49.0661385513,48.9322767715,48.7983884873,
+	48.6644738783,48.5305331297,48.3965664318,48.2625739808,48.1285559787,
+	47.9945126336,47.8604441597,47.7263507774,47.592232714,47.4580902033,
+	47.3239234861,47.1897328106,47.0555184321,46.9212806137,46.7870196261,
+	46.6527357484,46.5184292679,46.3841004803,46.2497496903,46.1153772119,
+	45.9809833681,45.846568492,45.7121329263,45.5776770243,45.4432011498,
+	45.3087056776,45.1741909936,45.0396574956,44.9051055933,44.7705357088,
+	44.635948277,44.5013437459,44.3667225771,44.2320852465,44.0974322441,
+	43.962764075,43.8280812598,43.6933843349,43.5586738531,43.4239503843,
+	43.2892145156,43.1544668524,43.0197080186,42.8849386573,42.7501594316,
+	42.6153710249,42.4805741417,42.3457695087,42.2109578746,42.0761400117,
+	41.9413167163,41.8064888093,41.6716571374,41.5368225735,41.401986018,
+	41.2671483992,41.1323106748,40.9974738322,40.8626388899,40.7278068984,
+	40.5929789412,40.4581561358,40.3233396351,40.1885306281,40.0537303414,
+	39.9189400403,39.78416103,39.6493946568,39.5146423098,39.3799054219,
+	39.2451854712,39.1104839826,38.9758025293,38.8411427342,38.7065062715,
+	38.5718948684,38.4373103067,38.3027544245,38.1682291179,38.0337363429,
+	37.8992781174,37.7648565227,37.6304737057,37.4961318809,37.3618333323,
+	37.2275804158,37.093375561,36.9592212736,36.8251201375,36.6910748171,
+	36.55708806,36.4231626987,36.2893016539,36.1555079361,36.0217846488,
+	35.8881349906,35.7545622582,35.6210698488,35.4876612628,35.3543401068,
+	35.2211100958,35.0879750567,34.9549389303,34.822005775,34.6891797689,
+	34.556465213,34.4238665343,34.2913882882,34.1590351614,34.0268119754,
+	33.8947236884,33.7627753988,33.6309723478,33.499319922,33.3678236562,
+	33.236489236,33.1053225003,32.9743294439,32.8435162196,32.7128891409,
+	32.5824546835,32.4522194881,32.3221903615,32.1923742787,32.0627783842,
+	31.9334099937,31.8042765947,31.6753858474,31.5467455858,31.4183638174,
+	31.2902487238,31.1624086599,31.0348521538,30.9075879057,30.7806247864,
+	30.6539718359,30.5276382612,30.4016334335,30.275966886,30.1506483095,
+	30.0256875494,29.9010946007,29.7768796032,29.6530528365,29.5296247133,
+	29.4066057737,29.2840066773,29.1618381963,29.0401112068,28.9188366802,
+	28.7980256739,28.6776893212,28.557838821,28.4384854266,28.3196404341,
+	28.2013151706,28.083520981,27.9662692154,27.8495712153,27.7334382994,
+	27.6178817497,27.502912796,27.3885426015,27.274782247,27.1616427153,
+	27.0491348756,26.9372694673,26.8260570842,26.7155081583,26.605632944,
+	26.4964415017,26.3879436828,26.2801491135,26.1730671799,26.066707013,
+	25.9610774742,25.8561871411,25.7520442943,25.6486569043,25.5460326191,
+	25.4441787527,25.343102274,25.2428097972,25.1433075719,25.0446014749,
+	24.9466970027,24.8495992647,24.7533129776,24.6578424604,24.5631916308,
+	24.4693640021,24.3763626815,24.284190369,24.1928493573,24.102341533,
+	24.0126683781,23.9238309727,23.8358299992,23.7486657456,23.6623381119,
+	23.576846615,23.492190396,23.4083682275,23.3253785212,23.2432193369,
+	23.1618883911,23.0813830671,23.0017004246,22.9228372103,22.8447898684,
+	22.7675545521,22.6911271343,22.6155032194,22.5406781549,22.4666470431,
+	22.3934047528,22.3209459315,22.2492650165,22.1783562475,22.1082136777,
+	22.0388311858,21.9702024871,21.9023211449,21.8351805819,21.7687740907,
+	21.7030948443,21.6381359073,21.573890245,21.5103507342,21.4475101722,
+	21.3853612859,21.3238967417,21.2631091529,21.2029910891,21.1435350836,
+	21.0847336411,21.0265792455,20.9690643664,20.9121814661,20.8559230061,
+	20.800281453,20.7452492842,20.6908189936,20.6369830967,20.5837341354,
+	20.5310646827,20.4789673469,20.4274347758,20.3764596604,20.3260347384,
+	20.2761527978,20.2268066794,20.1779892802,20.1296935556,20.081912522,
+	20.034639259,19.9878669114,19.941588691,19.8957978783,19.8504878237,
+	19.8056519493,19.7612837498,19.7173767936,19.6739247233,19.6309212573,
+	19.5883601896,19.5462353909,19.5045408084,19.4632704669,19.4224184683,
+	19.3819789922,19.3419462957,19.3023147134,19.2630786571,19.2242326162,
+	19.1857711566,19.1476889213,19.109980629,19.0726410748,19.0356651289,
+	18.9990477362,18.9627839162,18.9268687619,18.8912974396,18.8560651877,
+	18.8211673166,18.7865992077,18.7523563125,18.7184341523,18.6848283169,
+	18.6515344643,18.6185483195,18.5858656739,18.5534823845,18.5213943728,
+	18.4895976244,18.4580881876,18.4268621732,18.3959157529,18.3652451591,
+	18.3348466836,18.3047166771,18.2748515479,18.2452477615,18.2159018395,
+	18.1868103586,18.1579699502,18.1293772992,18.1010291432,18.0729222719,
+	18.0450535259,18.0174197962,17.9900180234,17.9628451967,17.9358983531,
+	17.9091745768,17.8826709984,17.856384794,17.8303131846,17.804453435,
+	17.7788028537,17.7533587915,17.7281186413,17.7030798369,17.6782398529,
+	17.6535962035,17.629146442,17.60488816,17.5808189872,17.5569365901,
+	17.5332386719,17.5097229715,17.4863872631,17.4632293556,17.4402470917,
+	17.4174383478,17.3948010329,17.3723330884,17.3500324875,17.3278972343,
+	17.3059253639,17.2841149411,17.2624640605,17.2409708457,17.2196334488,
+	17.19845005,17.177418857,17.1565381047,17.1358060544,17.1152209936,
+	17.0947812357,17.0744851191,17.0543310071,17.0343172874,17.0144423714,
+	16.9947046944,16.9751027147,16.9556349131,16.9362997931,16.9170958798,
+	16.8980217202,16.8790758822,16.8602569547,16.8415635471,16.8229942888,
+	16.804547829,16.7862228364,16.7680179988,16.7499320229,16.7319636336,
+	16.714111574,16.6963746054,16.6787515061,16.661241072,16.6438421159,
+	16.6265534672,16.6093739717,16.5923024914,16.5753379039,16.5584791027,
+	16.5417249963,16.5250745085,16.5085265778,16.4920801573,16.4757342144,
+	16.4594877306,16.4433397013,16.4272891353,16.4113350551,16.3954764962,
+	16.3797125071,16.3640421492,16.3484644962,16.3329786343,16.3175836618,
+	16.3022786889,16.2870628377,16.2719352417,16.2568950459,16.2419414064,
+	16.2270734904,16.2122904759,16.1975915515,16.1829759164,16.1684427801,
+	16.1539913623,16.1396208926,16.1253306106,16.1111197655,16.0969876161,
+	16.0829334306,16.0689564863,16.0550560698,16.0412314765,16.0274820108,
+	16.0138069857,16.0002057227,15.9866775518,15.9732218113,15.9598378476,
+	15.9465250152,15.9332826765,15.9201102017,15.9070069688,15.8939723631,
+	15.8810057776,15.8681066125,15.8552742754,15.8425081808,15.8298077503,
+	15.8171724125,15.8046016028,15.7920947632,15.7796513423,15.7672707954,
+	15.754952584,15.7426961761,15.7305010459,15.7183666735,15.7062925455,
+	15.694278154,15.6823229973,15.6704265793,15.6585884097,15.6468080039,
+	15.6350848828,15.6234185725,15.611808605,15.6002545171,15.5887558512,
+	15.5773121548,15.5659229802,15.5545878851,15.543306432,15.5320781883,
+	15.5209027261,15.5097796223,15.4987084586,15.4876888213,15.476720301,
+	15.465802493,15.454934997,15.4441174172,15.4333493618,15.4226304434,
+	15.4119602788,15.4013384891,15.3907646991,15.3802385379,15.3697596385,
+	15.3593276378,15.3489421765,15.3386028993,15.3283094545,15.3180614942,
+	15.3078586739,15.2977006532,15.2875870947,15.277517665,15.267492034,
+	15.2575098748,15.2475708642,15.2376746822,15.2278210121,15.2180095404,
+	15.208239957,15.1985119547,15.1888252296,15.1791794809,15.1695744108,
+	15.1600097243,15.1504851298,15.1410003383,15.1315550638,15.1221490232,
+	15.1127819361,15.1034535249,15.094163515,15.0849116342,15.0756976132,
+	15.0665211851,15.057382086,15.0482800541,15.0392148306,15.030186159,
+	15.0211937853,15.012237458,15.003316928,14.9944319486,14.9855822755,
+	14.9767676668,14.9679878826,14.9592426857,14.950531841,14.9418551155,
+	14.9332122786,14.9246031017,14.9160273584,14.9074848247,14.8989752782,
+	14.8904984989,14.8820542689,14.8736423721,14.8652625946,14.8569147243,
+	14.8485985512,14.8403138672,14.832060466,14.8238381434,14.8156466968,
+	14.8074859258,14.7993556314,14.7912556167,14.7831856865,14.7751456474,
+	14.7671353076,14.7591544771,14.7512029678,14.7432805929,14.7353871675,
+	14.7275225084,14.7196864338,14.7118787638,14.7040993197,14.6963479248,
+	14.6886244037,14.6809285825,14.6732602889,14.6656193522,14.6580056031,
+	14.6504188737,14.6428589975,14.6353258098,14.6278191469,14.6203388467,
+	14.6128847485,14.6054566928,14.5980545218,14.5906780788,14.5833272083,
+	14.5760017565,14.5687015706,14.5614264991,14.554176392,14.5469511003,
+	14.5397504764,14.532574374,14.5254226477,14.5182951536,14.511191749,
+	14.5041122922,14.4970566428,14.4900246616,14.4830162103,14.476031152,
+	14.4690693508,14.4621306719,14.4552149818,14.4483221476,14.4414520381,
+	14.4346045227,14.427779472,14.4209767576,14.4141962524,14.4074378298,
+	14.4007013648,14.3939867329,14.3872938109,14.3806224764,14.3739726081,
+	14.3673440856,14.3607367896,14.3541506013,14.3475854034,14.3410410791,
+	14.3345175128,14.3280145895,14.3215321954,14.3150702174,14.3086285433,
+	14.3022070619,14.2958056626,14.2894242359,14.283062673,14.276720866,
+	14.2703987079,14.2640960923,14.2578129137,14.2515490676,14.24530445,
+	14.2390789579,14.232872489,14.2266849416,14.2205162152,14.2143662096,
+	14.2082348255,14.2021219646,14.1960275289,14.1899514215,14.1838935459,
+	14.1778538067,14.1718321088,14.165828358,14.1598424609,14.1538743246,
+	14.1479238569,14.1419909664,14.1360755623,14.1301775544,14.1242968532,
+	14.11843337,14.1125870164,14.106757705,14.1009453487,14.0951498615,
+	14.0893711574,14.0836091515,14.0778637594,14.0721348971,14.0664224814,
+	14.0607264296,14.0550466597,14.0493830902,14.0437356402,14.0381042293,
+	14.0324887777,14.0268892062,14.0213054361,14.0157373894,14.0101849885,
+	14.0046481563,13.9991268163,13.9936208926,13.9881303098,13.9826549929,
+	13.9771948675,13.9717498598,13.9663198964,13.9609049044,13.9555048114,
+	13.9501195456,13.9447490356,13.9393932105,13.9340519998,13.9287253336,
+	13.9234131425,13.9181153575,13.91283191,13.9075627319,13.9023077557,
+	13.8970669141,13.8918401405,13.8866273686,13.8814285326,13.876243567,
+	13.871072407,13.865914988,13.860771246,13.8556411172,13.8505245383,
+	13.8454214467,13.8403317797,13.8352554755,13.8301924725,13.8251427093,
+	13.8201061252,13.8150826598,13.8100722531,13.8050748454,13.8000903775,
+	13.7951187905,13.790160026,13.7852140259,13.7802807323,13.775360088,
+	13.7704520359,13.7655565194,13.7606734822,13.7558028685,13.7509446227,
+	13.7460986895,13.7412650141,13.7364435419,13.7316342189,13.7268369912,
+	13.7220518053,13.717278608,13.7125173466,13.7077679684,13.7030304215,
+	13.6983046538,13.693590614,13.6888882508,13.6841975133,13.679518351,
+	13.6748507136,13.6701945512,13.665549814,13.6609164529,13.6562944187,
+	13.6516836627,13.6470841366,13.6424957921,13.6379185813,13.6333524569,
+	13.6287973714,13.6242532779,13.6197201297,13.6151978803,13.6106864838,
+	13.6061858941,13.6016960656,13.5972169532,13.5927485117,13.5882906964,
+	13.5838434627,13.5794067665,13.5749805636,13.5705648106,13.5661594637,
+	13.5617644799,13.5573798162,13.5530054299,13.5486412786,13.54428732,
+	13.5399435123,13.5356098136,13.5312861826,13.526972578,13.5226689589,
+	13.5183752845,13.5140915142,13.5098176079,13.5055535255,13.5012992271,
+	13.4970546733,13.4928198245,13.4885946418,13.4843790862,13.4801731191,
+	13.4759767019,13.4717897965,13.4676123647,13.4634443689,13.4592857713,
+	13.4551365347,13.4509966219,13.4468659959,13.4427446199,13.4386324575,
+	13.4345294722,13.4304356279,13.4263508888,13.422275219,13.418208583,
+	13.4141509456,13.4101022715,13.4060625259,13.4020316739,13.3980096811,
+	13.393996513,13.3899921354,13.3859965145,13.3820096163,13.3780314073,
+	13.374061854,13.3701009232,13.3661485818,13.362204797,13.358269536,
+	13.3543427662,13.3504244554,13.3465145714,13.3426130821,13.3387199557,
+	13.3348351605,13.3309586652,13.3270904383,13.3232304487,13.3193786654,
+	13.3155350575,13.3116995946,13.3078722459,13.3040529813,13.3002417706,
+	13.2964385836,13.2926433907,13.2888561621,13.2850768682,13.2813054797,
+	13.2775419674,13.2737863022,13.2700384552,13.2662983976,13.2625661008,
+	13.2588415363,13.2551246758,13.2514154912,13.2477139545,13.2440200377,
+	13.2403337131,13.2366549531,13.2329837303,13.2293200174,13.2256637873,
+	13.2220150128,13.2183736671,13.2147397235,13.2111131554,13.2074939363,
+	13.2038820398,13.2002774397,13.19668011,13.1930900248,13.1895071582,
+	13.1859314845,13.1823629783,13.178801614,13.1752473665,13.1717002105,
+	13.168160121,13.1646270732,13.1611010422,13.1575820033,13.1540699321,
+	13.1505648041,13.1470665951,13.1435752808,13.1400908372,13.1366132404,
+	13.1331424666,13.1296784921,13.1262212933,13.1227708467,13.1193271291,
+	13.1158901171,13.1124597877,13.1090361179,13.1056190848,13.1022086655,
+	13.0988048375,13.0954075782,13.0920168651,13.0886326759,13.0852549884,
+	13.0818837805,13.0785190301,13.0751607154,13.0718088145,13.0684633057,
+	13.0651241676,13.0617913785,13.0584649171,13.0551447622,13.0518308925,
+	13.048523287,13.0452219246,13.0419267846,13.0386378462,13.0353550886,
+	13.0320784913,13.0288080338,13.0255436958,13.0222854569,13.019033297,
+	13.0157871959,13.0125471336,13.0093130904,13.0060850462,13.0028629815,
+	12.9996468766,12.9964367119,12.993232468,12.9900341256,12.9868416654,
+	12.9836550682,12.9804743149,12.9772993866,12.9741302643,12.9709669292,
+	12.9678093625,12.9646575458,12.9615114602,12.9583710875,12.9552364092,
+	12.9521074069,12.9489840625,12.9458663579,12.9427542749,12.9396477957,
+	12.9365469022,12.9334515768,12.9303618016,12.9272775591,12.9241988316,
+	12.9211256016,12.9180578519,12.9149955649,12.9119387235,12.9088873106,
+	12.9058413089,12.9028007015,12.8997654714,12.8967356018,12.8937110759,
+	12.8906918769,12.8876779882,12.8846693933,12.8816660756,12.8786680187,
+	12.8756752064,12.8726876222,12.86970525,12.8667280736,12.8637560771,
+	12.8607892443,12.8578275594,12.8548710066,12.8519195701,12.848973234,
+	12.8460319829,12.8430958011,12.8401646731,12.8372385835,12.8343175169,
+	12.831401458,12.8284903916,12.8255843025,12.8226831755,12.8197869957,
+	12.8168957481,12.8140094178,12.8111279898,12.8082514496,12.8053797822,
+	12.8025129731,12.7996510076,12.7967938713,12.7939415497,12.7910940284,
+	12.7882512929,12.7854133292,12.7825801228,12.7797516597,12.7769279257,
+	12.7741089069,12.7712945892,12.7684849587,12.7656800016,12.762879704,
+	12.7600840522,12.7572930325,12.7545066312,12.7517248349,12.74894763,
+	12.7461750029,12.7434069404,12.7406434291,12.7378844557,12.7351300068,
+	12.7323800695,12.7296346305,12.7268936767,12.7241571952,12.721425173,
+	12.7186975971,12.7159744547,12.7132557331,12.7105414194,12.7078315009,
+	12.7051259651,12.7024247993,12.699727991,12.6970355276,12.6943473968,
+	12.6916635861,12.6889840833,12.6863088759,12.6836379519,12.680971299,
+	12.678308905,12.6756507579,12.6729968456,12.6703471562,12.6677016776,
+	12.6650603981,12.6624233057,12.6597903887,12.6571616353,12.6545370337,
+	12.6519165725,12.6493002398,12.6466880242,12.6440799142,12.6414758982,
+	12.6388759649,12.6362801029,12.6336883008,12.6311005473,12.6285168312,
+	12.6259371414,12.6233614666,12.6207897957,12.6182221177,12.6156584215,
+	12.6130986962,12.6105429308,12.6079911145,12.6054432363,12.6028992855,
+	12.6003592512,12.5978231229,12.5952908898,12.5927625412,12.5902380665,
+	12.5877174553,12.585200697,12.582687781,12.580178697,12.5776734346,
+	12.5751719835,12.5726743332,12.5701804736,12.5676903943,12.5652040853,
+	12.5627215363,12.5602427373,12.5577676781,12.5552963487,12.5528287392,
+	12.5503648395,12.5479046397,12.54544813,12.5429953005,12.5405461414,
+	12.5381006428,12.5356587952,12.5332205887,12.5307860138,12.5283550607,
+	12.52592772,12.523503982,12.5210838372,12.5186672762,12.5162542895,
+	12.5138448677,12.5114390014,12.5090366814,12.5066378982,12.5042426426,
+	12.5018509054,12.4994626774,12.4970779493,12.4946967122,12.4923189569,
+	12.4899446743,12.4875738554,12.4852064912,12.4828425728,12.4804820912,
+	12.4781250374,12.4757714028,12.4734211784,12.4710743554,12.468730925,
+	12.4663908786,12.4640542075,12.4617209029,12.4593909562,12.4570643588,
+	12.4547411022,12.4524211778,12.4501045771,12.4477912916,12.4454813129,
+	12.4431746326,12.4408712422,12.4385711334,12.4362742979,12.4339807274,
+	12.4316904136,12.4294033483,12.4271195232,12.4248389303,12.4225615613,
+	12.4202874082,12.4180164628,12.4157487171,12.413484163,12.4112227927,
+	12.408964598,12.406709571,12.4044577039,12.4022089887,12.3999634176,
+	12.3977209827,12.3954816763,12.3932454906,12.3910124178,12.3887824501,
+	12.38655558,12.3843317998,12.3821111017,12.3798934782,12.3776789218,
+	12.3754674248,12.3732589797,12.371053579,12.3688512153,12.366651881,
+	12.3644555688,12.3622622713,12.3600719811,12.3578846908,12.3557003931,
+	12.3535190807,12.3513407464,12.3491653829,12.3469929829,12.3448235394,
+	12.342657045,12.3404934928,12.3383328755,12.336175186,12.3340204173,
+	12.3318685624,12.3297196142,12.3275735657,12.3254304099,12.3232901399,
+	12.3211527488,12.3190182296,12.3168865756,12.3147577797,12.3126318353,
+	12.3105087354,12.3083884733,12.3062710423,12.3041564356,12.3020446464,
+	12.2999356681,12.2978294941,12.2957261176,12.2936255321,12.2915277309,
+	12.2894327075,12.2873404553,12.2852509678,12.2831642384,12.2810802607,
+	12.2789990281,12.2769205344,12.2748447729,12.2727717373,12.2707014213,
+	12.2686338185,12.2665689225,12.2645067269,12.2624472256,12.2603904123,
+	12.2583362806,12.2562848243,12.2542360373,12.2521899133,12.2501464462,
+	12.2481056297,12.2460674579,12.2440319245,12.2419990234,12.2399687487,
+	12.2379410942,12.2359160539,12.2338936219,12.231873792,12.2298565583,
+	12.227841915,12.225829856,12.2238203754,12.2218134674,12.2198091261,
+	12.2178073455,12.2158081199,12.2138114435,12.2118173105,12.209825715,
+	12.2078366513,12.2058501137,12.2038660965,12.2018845939,12.1999056003,
+	12.1979291099,12.1959551172,12.1939836165,12.1920146022,12.1900480687,
+	12.1880840104,12.1861224218,12.1841632973,12.1822066314,12.1802524186,
+	12.1783006534,12.1763513304,12.174404444,12.1724599888,12.1705179595,
+	12.1685783507,12.1666411568,12.1647063727,12.1627739928,12.160844012,
+	12.1589164248,12.156991226,12.1550684103,12.1531479725,12.1512299072,
+	12.1493142093,12.1474008735,12.1454898947,12.1435812676,12.1416749871,
+	12.1397710481,12.1378694453,12.1359701738,12.1340732283,12.1321786038,
+	12.1302862953,12.1283962977,12.1265086058,12.1246232148,12.1227401197,
+	12.1208593153,12.1189807968,12.1171045592,12.1152305975,12.1133589068,
+	12.1114894822,12.1096223189,12.1077574118,12.1058947562,12.1040343472,
+	12.1021761799,12.1003202496,12.0984665514,12.0966150806,12.0947658323,
+	12.0929188017,12.0910739843,12.0892313751,12.0873909695,12.0855527628,
+	12.0837167503,12.0818829273,12.0800512891,12.0782218311,12.0763945487,
+	12.0745694373,12.0727464922,12.0709257088,12.0691070826,12.067290609,
+	12.0654762834
+	};
+
+tubetable_6DJ8_1 = waveform{
+	137.512728867,137.399223264,137.285690251,137.17212984,137.058542039,
+	136.944926859,136.831284308,136.717614396,136.603917133,136.490192528,
+	136.37644059,136.262661328,136.148854752,136.035020871,135.921159694,
+	135.80727123,135.693355487,135.579412475,135.465442203,135.351444679,
+	135.237419911,135.12336791,135.009288682,134.895182238,134.781048584,
+	134.66688773,134.552699684,134.438484454,134.324242049,134.209972477,
+	134.095675745,133.981351862,133.867000836,133.752622675,133.638217387,
+	133.523784979,133.40932546,133.294838836,133.180325116,133.065784308,
+	132.951216418,132.836621455,132.721999425,132.607350337,132.492674197,
+	132.377971012,132.263240791,132.148483539,132.033699265,131.918887974,
+	131.804049675,131.689184374,131.574292077,131.459372792,131.344426526,
+	131.229453284,131.114453074,130.999425902,130.884371775,130.769290699,
+	130.654182681,130.539047726,130.423885842,130.308697033,130.193481308,
+	130.078238671,129.962969128,129.847672686,129.732349351,129.616999128,
+	129.501622024,129.386218043,129.270787192,129.155329476,129.039844901,
+	128.924333473,128.808795197,128.693230078,128.577638121,128.462019333,
+	128.346373717,128.230701281,128.115002027,127.999275963,127.883523091,
+	127.767743419,127.65193695,127.536103689,127.420243641,127.304356811,
+	127.188443204,127.072502824,126.956535675,126.840541763,126.724521091,
+	126.608473664,126.492399486,126.376298562,126.260170896,126.144016492,
+	126.027835354,125.911627486,125.795392892,125.679131576,125.562843542,
+	125.446528794,125.330187335,125.213819169,125.0974243,124.981002732,
+	124.864554467,124.74807951,124.631577864,124.515049532,124.398494517,
+	124.281912824,124.165304454,124.048669411,123.932007699,123.815319319,
+	123.698604276,123.581862572,123.465094209,123.348299192,123.231477521,
+	123.114629201,122.997754234,122.880852622,122.763924367,122.646969473,
+	122.529987942,122.412979775,122.295944976,122.178883547,122.061795488,
+	121.944680804,121.827539496,121.710371565,121.593177014,121.475955845,
+	121.358708059,121.241433658,121.124132644,121.006805019,120.889450784,
+	120.772069941,120.654662491,120.537228435,120.419767776,120.302280513,
+	120.18476665,120.067226186,119.949659123,119.832065462,119.714445204,
+	119.596798349,119.4791249,119.361424857,119.24369822,119.12594499,
+	119.008165168,118.890358755,118.772525751,118.654666156,118.536779972,
+	118.418867198,118.300927835,118.182961883,118.064969342,117.946950213,
+	117.828904495,117.710832189,117.592733295,117.474607812,117.356455741,
+	117.238277081,117.120071832,117.001839993,116.883581565,116.765296548,
+	116.646984939,116.52864674,116.410281948,116.291890565,116.173472589,
+	116.055028019,115.936556854,115.818059094,115.699534738,115.580983784,
+	115.462406232,115.343802081,115.225171329,115.106513975,114.987830018,
+	114.869119456,114.750382289,114.631618514,114.51282813,114.394011136,
+	114.27516753,114.15629731,114.037400475,113.918477022,113.799526951,
+	113.680550258,113.561546942,113.442517002,113.323460434,113.204377236,
+	113.085267407,112.966130945,112.846967846,112.727778109,112.608561731,
+	112.489318709,112.370049041,112.250752725,112.131429757,112.012080135,
+	111.892703857,111.773300918,111.653871317,111.53441505,111.414932115,
+	111.295422508,111.175886226,111.056323266,110.936733624,110.817117298,
+	110.697474283,110.577804577,110.458108176,110.338385076,110.218635274,
+	110.098858766,109.979055549,109.859225618,109.739368969,109.619485599,
+	109.499575504,109.379638679,109.259675121,109.139684826,109.019667789,
+	108.899624005,108.779553471,108.659456182,108.539332134,108.419181322,
+	108.299003742,108.178799389,108.058568258,107.938310344,107.818025643,
+	107.69771415,107.577375859,107.457010766,107.336618867,107.216200154,
+	107.095754624,106.975282272,106.854783091,106.734257077,106.613704224,
+	106.493124526,106.372517979,106.251884576,106.131224312,106.010537181,
+	105.889823177,105.769082295,105.648314528,105.52751987,105.406698317,
+	105.28584986,105.164974495,105.044072215,104.923143013,104.802186884,
+	104.681203821,104.560193818,104.439156867,104.318092963,104.197002099,
+	104.075884268,103.954739463,103.833567678,103.712368905,103.591143138,
+	103.46989037,103.348610593,103.227303801,103.105969985,102.98460914,
+	102.863221258,102.74180633,102.620364351,102.498895311,102.377399205,
+	102.255876023,102.134325759,102.012748405,101.891143953,101.769512394,
+	101.647853721,101.526167927,101.404455002,101.282714939,101.16094773,
+	101.039153366,100.917331839,100.795483141,100.673607263,100.551704197,
+	100.429773934,100.307816466,100.185831783,100.063819878,99.9417807406,
+	99.8197143628,99.6976207354,99.5754998496,99.4533516961,99.3311762659,
+	99.2089735498,99.0867435385,98.9644862227,98.8422015931,98.7198896402,
+	98.5975503544,98.4751837263,98.3527897462,98.2303684044,98.1079196912,
+	97.9854435967,97.862940111,97.7404092242,97.6178509264,97.4952652074,
+	97.3726520571,97.2500114653,97.1273434217,97.0046479161,96.881924938,
+	96.759174477,96.6363965227,96.5135910643,96.3907580913,96.267897593,
+	96.1450095586,96.0220939773,95.8991508382,95.7761801304,95.6531818428,
+	95.5301559644,95.407102484,95.2840213905,95.1609126725,95.0377763187,
+	94.9146123178,94.7914206583,94.6682013286,94.5449543172,94.4216796125,
+	94.2983772027,94.1750470761,94.0516892209,93.9283036251,93.8048902767,
+	93.6814491639,93.5579802744,93.4344835962,93.3109591171,93.1874068247,
+	93.0638267067,92.9402187508,92.8165829445,92.6929192752,92.5692277304,
+	92.4455082975,92.3217609637,92.1979857163,92.0741825423,91.9503514291,
+	91.8264923635,91.7026053326,91.5786903232,91.4547473223,91.3307763167,
+	91.206777293,91.082750238,90.9586951383,90.8346119803,90.7105007507,
+	90.5863614358,90.462194022,90.3379984956,90.2137748429,90.0895230499,
+	89.965243103,89.840934988,89.7165986911,89.5922341981,89.467841495,
+	89.3434205675,89.2189714014,89.0944939825,88.9699882963,88.8454543284,
+	88.7208920644,88.5963014897,88.4716825897,88.3470353498,88.2223597552,
+	88.0976557912,87.9729234429,87.8481626954,87.7233735338,87.5985559431,
+	87.4737099082,87.3488354139,87.2239324452,87.0990009867,86.9740410231,
+	86.8490525391,86.7240355193,86.5989899482,86.4739158103,86.34881309,
+	86.2236817716,86.0985218395,85.9733332779,85.8481160709,85.7228702028,
+	85.5975956577,85.4722924194,85.3469604721,85.2215997996,85.0962103858,
+	84.9707922146,84.8453452696,84.7198695345,84.5943649931,84.4688316289,
+	84.3432694255,84.2176783664,84.092058435,83.9664096147,83.8407318888,
+	83.7150252407,83.5892896536,83.4635251106,83.3377315949,83.2119090897,
+	83.0860575779,82.9601770426,82.8342674667,82.708328833,82.5823611245,
+	82.456364324,82.3303384143,82.2042833779,82.0781991977,81.9520858562,
+	81.825943336,81.6997716197,81.5735706898,81.4473405286,81.3210811187,
+	81.1947924423,81.0684744819,80.9421272196,80.8157506378,80.6893447187,
+	80.5629094444,80.436444797,80.3099507586,80.1834273114,80.0568744373,
+	79.9302921182,79.8036803362,79.6770390732,79.550368311,79.4236680315,
+	79.2969382165,79.1701788478,79.0433899071,78.9165713762,78.7897232367,
+	78.6628454704,78.5359380588,78.4090009835,78.2820342262,78.1550377685,
+	78.0280115917,77.9009556775,77.7738700074,77.6467545627,77.519609325,
+	77.3924342757,77.2652293962,77.1379946679,77.0107300721,76.8834355903,
+	76.7561112037,76.6287568937,76.5013726416,76.3739584288,76.2465142365,
+	76.119040046,75.9915358386,75.8640015956,75.7364372982,75.6088429277,
+	75.4812184654,75.3535638926,75.2258791905,75.0981643403,74.9704193234,
+	74.842644121,74.7148387145,74.587003085,74.4591372139,74.3312410825,
+	74.2033146721,74.0753579641,73.9473709398,73.8193535805,73.6913058677,
+	73.5632277828,73.4351193072,73.3069804223,73.1788111097,73.0506113508,
+	72.9223811272,72.7941204204,72.6658292121,72.537507484,72.4091552176,
+	72.2807723947,72.1523589971,72.0239150066,71.8954404051,71.7669351744,
+	71.6383992966,71.5098327536,71.3812355275,71.2526076005,71.1239489547,
+	70.9952595725,70.8665394361,70.7377885279,70.6090068305,70.4801943263,
+	70.3513509981,70.2224768285,70.0935718004,69.9646358965,69.8356691,
+	69.7066713939,69.5776427614,69.4485831857,69.3194926503,69.1903711386,
+	69.0612186344,68.9320351212,68.802820583,68.6735750037,68.5442983675,
+	68.4149906585,68.2856518613,68.1562819603,68.0268809401,67.8974487857,
+	67.7679854819,67.638491014,67.5089653673,67.3794085272,67.2498204794,
+	67.1202012097,66.9905507042,66.8608689491,66.7311559309,66.601411636,
+	66.4716360515,66.3418291643,66.2119909618,66.0821214314,65.9522205608,
+	65.8222883382,65.6923247516,65.5623297897,65.4323034412,65.302245695,
+	65.1721565406,65.0420359675,64.9118839657,64.7817005253,64.6514856368,
+	64.5212392911,64.3909614794,64.2606521931,64.1303114242,63.9999391648,
+	63.8695354075,63.7391001453,63.6086333716,63.47813508,63.3476052649,
+	63.2170439207,63.0864510425,62.9558266257,62.8251706663,62.6944831608,
+	62.5637641059,62.4330134991,62.3022313383,62.1714176218,62.0405723488,
+	61.9096955186,61.7787871314,61.6478471879,61.5168756894,61.3858726377,
+	61.2548380355,61.1237718859,60.9926741928,60.8615449607,60.730384195,
+	60.5991919017,60.4679680876,60.3367127601,60.2054259277,60.0741075994,
+	59.9427577854,59.8113764964,59.6799637443,59.5485195417,59.4170439022,
+	59.2855368404,59.1539983719,59.0224285133,58.8908272824,58.7591946978,
+	58.6275307794,58.4958355482,58.3641090265,58.2323512377,58.1005622064,
+	57.9687419586,57.8368905217,57.7050079243,57.5730941965,57.4411493697,
+	57.3091734771,57.1771665531,57.0451286339,56.9130597573,56.7809599628,
+	56.6488292914,56.5166677863,56.3844754921,56.2522524556,56.1199987253,
+	55.9877143521,55.8553993885,55.7230538895,55.5906779121,55.4582715156,
+	55.3258347616,55.1933677144,55.0608704404,54.9283430087,54.7957854911,
+	54.6631979622,54.5305804991,54.3979331822,54.2652560946,54.1325493226,
+	53.9998129557,53.8670470866,53.7342518116,53.6014272301,53.4685734456,
+	53.3356905649,53.202778699,53.0698379626,52.9368684747,52.8038703584,
+	52.6708437413,52.5377887554,52.4047055373,52.2715942288,52.1384549761,
+	52.005287931,51.8720932505,51.7388710969,51.6056216384,51.4723450489,
+	51.3390415085,51.2057112034,51.0723543264,50.9389710768,50.8055616609,
+	50.6721262922,50.5386651916,50.4051785874,50.271666716,50.1381298218,
+	50.0045681577,49.8709819854,49.7373715755,49.6037372078,49.470079172,
+	49.3363977676,49.2026933043,49.0689661028,48.9352164944,48.8014448221,
+	48.6676514405,48.5338367167,48.40000103,48.2661447731,48.1322683519,
+	47.9983721867,47.8644567117,47.7305223766,47.5965696462,47.4625990014,
+	47.3286109398,47.1946059759,47.0605846422,46.9265474893,46.792495087,
+	46.6584280245,46.5243469117,46.3902523791,46.2561450792,46.122025687,
+	45.9878949008,45.853753443,45.7196020608,45.5854415275,45.4512726429,
+	45.3170962344,45.1829131581,45.0487242995,44.9145305749,44.7803329321,
+	44.6461323516,44.5119298478,44.3777264702,44.2435233043,44.1093214733,
+	43.9751221389,43.8409265029,43.7067358086,43.5725513419,43.4383744332,
+	43.3042064584,43.1700488409,43.0359030526,42.9017706161,42.7676531062,
+	42.6335521515,42.4994694361,42.3654067018,42.2313657496,42.0973484418,
+	41.9633567039,41.8293925267,41.6954579684,41.5615551566,41.4276862907,
+	41.293853644,41.1600595658,41.0263064842,40.8925969082,40.7589334302,
+	40.6253187286,40.4917555701,40.3582468127,40.2247954079,40.0914044039,
+	39.9580769478,39.8248162888,39.691625781,39.5585088858,39.4254691754,
+	39.2925103354,39.1596361679,39.0268505942,38.8941576581,38.7615615286,
+	38.6290665035,38.4966770114,38.3643976159,38.2322330175,38.1001880572,
+	37.9682677194,37.8364771346,37.7048215822,37.5733064936,37.4419374545,
+	37.3107202079,37.1796606565,37.0487648651,36.9180390628,36.7874896455,
+	36.6571231776,36.526946394,36.3969662016,36.2671896813,36.1376240885,
+	36.0082768545,35.8791555875,35.7502680727,35.6216222725,35.4932263267,
+	35.3650885517,35.23721744,35.1096216587,34.9823100482,34.8552916201,
+	34.7285755548,34.6021711986,34.4760880604,34.3503358077,34.2249242626,
+	34.0998633968,33.9751633259,33.8508343041,33.7268867171,33.6033310755,
+	33.4801780068,33.3574382475,33.2351226341,33.1132420942,32.9918076357,
+	32.8708303373,32.7503213367,32.6302918195,32.5107530067,32.3917161423,
+	32.2731924804,32.1551932711,32.037729747,31.9208131085,31.8044545095,
+	31.6886650419,31.5734557206,31.4588374679,31.3448210978,31.2314173004,
+	31.1186366258,31.0064894684,30.8949860509,30.7841364092,30.6739503761,
+	30.5644375666,30.455607363,30.3474688999,30.2400310502,30.1333024117,
+	30.0272912935,29.9220057037,29.8174533375,29.7136415657,29.6105774244,
+	29.5082676055,29.4067184471,29.3059359261,29.2059256507,29.1066928541,
+	29.0082423889,28.9105787231,28.8137059359,28.7176277156,28.6223473578,
+	28.5278677641,28.4341914432,28.3413205108,28.2492566924,28.1580013255,
+	28.0675553634,27.9779193796,27.8890935724,27.8010777713,27.7138714431,
+	27.6274736993,27.5418833035,27.4570986796,27.373117921,27.289938799,
+	27.2075587732,27.1259750009,27.0451843475,26.965183397,26.8859684628,
+	26.8075355984,26.7298806087,26.652999061,26.5768862962,26.5015374399,
+	26.426947414,26.3531109471,26.2800225865,26.2076767084,26.1360675291,
+	26.0651891153,25.9950353953,25.9256001685,25.8568771158,25.7888598095,
+	25.7215417227,25.6549162387,25.5889766601,25.5237162175,25.4591280777,
+	25.3952053525,25.331941106,25.2693283624,25.2073601134,25.1460293249,
+	25.0853289441,25.0252519052,24.9657911364,24.9069395648,24.8486901225,
+	24.7910357516,24.7339694092,24.677484072,24.6215727409,24.5662284448,
+	24.5114442449,24.4572132382,24.4035285609,24.3503833915,24.2977709541,
+	24.2456845208,24.1941174145,24.1430630113,24.0925147424,24.0424660964,
+	23.992910621,23.9438419248,23.8952536784,23.8471396162,23.7994935376,
+	23.7523093077,23.7055808586,23.6593021901,23.6134673704,23.5680705368,
+	23.5231058959,23.4785677245,23.4344503694,23.3907482481,23.3474558483,
+	23.3045677287,23.2620785186,23.2199829176,23.1782756959,23.1369516941,
+	23.0960058224,23.055433061,23.0152284591,22.9753871351,22.9359042758,
+	22.8967751359,22.8579950378,22.8195593706,22.7814635902,22.743703218,
+	22.7062738406,22.6691711094,22.6323907394,22.5959285091,22.5597802593,
+	22.5239418928,22.4884093734,22.4531787255,22.4182460329,22.3836074384,
+	22.3492591431,22.3151974054,22.2814185405,22.2479189191,22.2146949676,
+	22.1817431664,22.1490600496,22.1166422042,22.0844862693,22.0525889354,
+	22.0209469434,21.9895570842,21.9584161977,21.9275211724,21.896868944,
+	21.8664564954,21.8362808557,21.8063390992,21.7766283451,21.7471457566,
+	21.7178885402,21.6888539452,21.6600392626,21.631441825,21.6030590054,
+	21.5748882168,21.5469269116,21.5191725808,21.4916227535,21.4642749962,
+	21.4371269121,21.4101761408,21.3834203573,21.3568572718,21.3304846287,
+	21.3043002064,21.2783018166,21.2524873036,21.2268545441,21.2014014463,
+	21.1761259495,21.1510260236,21.1260996686,21.1013449141,21.0767598189,
+	21.0523424701,21.0280909831,21.004003501,20.9800781938,20.9563132586,
+	20.9327069183,20.9092574221,20.8859630443,20.8628220842,20.8398328657,
+	20.8169937368,20.7943030693,20.7717592581,20.7493607214,20.7271058996,
+	20.7049932554,20.6830212735,20.6611884598,20.6394933414,20.617934466,
+	20.5965104018,20.5752197372,20.5540610799,20.5330330574,20.512134316,
+	20.491363521,20.4707193559,20.4502005225,20.4298057403,20.4095337464,
+	20.3893832953,20.3693531584,20.3494421236,20.3296489955,20.3099725947,
+	20.2904117577,20.2709653368,20.2516321995,20.2324112284,20.2133013213,
+	20.1943013902,20.1754103619,20.1566271772,20.1379507909,20.1193801714,
+	20.1009143009,20.0825521747,20.0642928011,20.0461352015,20.0280784098,
+	20.0101214725,19.9922634483,19.9745034079,19.9568404342,19.9392736215,
+	19.9218020757,19.9044249141,19.8871412651,19.8699502683,19.8528510738,
+	19.8358428425,19.818924746,19.8020959659,19.7853556942,19.7687031328,
+	19.7521374934,19.7356579977,19.7192638768,19.702954371,19.6867287302,
+	19.6705862133,19.6545260883,19.6385476318,19.6226501296,19.6068328756,
+	19.5910951724,19.5754363311,19.5598556707,19.5443525186,19.5289262099,
+	19.5135760879,19.4983015033,19.4831018147,19.4679763881,19.4529245969,
+	19.4379458218,19.4230394509,19.4082048791,19.3934415084,19.3787487479,
+	19.3641260131,19.3495727265,19.3350883172,19.3206722206,19.3063238786,
+	19.2920427395,19.2778282577,19.263679894,19.2495971149,19.2355793932,
+	19.2216262073,19.2077370416,19.1939113861,19.1801487367,19.1664485945,
+	19.1528104664,19.1392338645,19.1257183064,19.1122633148,19.0988684177,
+	19.0855331483,19.0722570446,19.0590396499,19.0458805122,19.0327791844,
+	19.0197352243,19.0067481941,18.993817661,18.9809431967,18.9681243774,
+	18.9553607836,18.9426520006,18.9299976177,18.9173972287,18.9048504315,
+	18.8923568283,18.8799160254,18.8675276332,18.855191266,18.8429065421,
+	18.8306730839,18.8184905175,18.8063584728,18.7942765836,18.7822444873,
+	18.7702618249,18.7583282413,18.7464433847,18.734606907,18.7228184636,
+	18.7110777131,18.6993843177,18.6877379431,18.6761382579,18.6645849344,
+	18.6530776479,18.6416160769,18.6301999032,18.6188288114,18.6075024895,
+	18.5962206284,18.5849829221,18.5737890673,18.5626387639,18.5515317145,
+	18.5404676247,18.5294462029,18.5184671601,18.5075302104,18.4966350702,
+	18.4857814588,18.4749690983,18.4641977132,18.4534670307,18.4427767803,
+	18.4321266945,18.4215165079,18.4109459577,18.4004147836,18.3899227277,
+	18.3794695343,18.3690549502,18.3586787246,18.3483406089,18.3380403567,
+	18.327777724,18.3175524689,18.3073643518,18.2972131352,18.2870985837,
+	18.2770204641,18.2669785453,18.2569725982,18.2470023957,18.2370677129,
+	18.2271683268,18.2173040164,18.2074745625,18.1976797481,18.187919358,
+	18.1781931787,18.1685009989,18.1588426089,18.149217801,18.1396263691,
+	18.1300681091,18.1205428184,18.1110502966,18.1015903445,18.0921627649,
+	18.0827673623,18.0734039429,18.0640723142,18.0547722859,18.0455036688,
+	18.0362662756,18.0270599206,18.0178844194,18.0087395894,17.9996252494,
+	17.9905412198,17.9814873225,17.9724633808,17.9634692195,17.9545046649,
+	17.9455695447,17.9366636879,17.9277869252,17.9189390885,17.9101200109,
+	17.9013295273,17.8925674735,17.883833687,17.8751280064,17.8664502716,
+	17.857800324,17.849178006,17.8405831614,17.8320156354,17.8234752741,
+	17.8149619251,17.8064754372,17.7980156603,17.7895824455,17.7811756451,
+	17.7727951126,17.7644407026,17.7561122709,17.7478096744,17.7395327711,
+	17.7312814201,17.7230554816,17.714854817,17.7066792887,17.69852876,
+	17.6904030955,17.6823021608,17.6742258224,17.6661739479,17.6581464059,
+	17.6501430661,17.642163799,17.6342084763,17.6262769706,17.6183691553,
+	17.6104849049,17.6026240949,17.5947866017,17.5869723025,17.5791810756,
+	17.5714128001,17.5636673559,17.5559446241,17.5482444865,17.5405668256,
+	17.5329115251,17.5252784694,17.5176675436,17.510078634,17.5025116274,
+	17.4949664116,17.4874428751,17.4799409074,17.4724603986,17.4650012398,
+	17.4575633227,17.4501465398,17.4427507845,17.4353759509,17.4280219338,
+	17.4206886288,17.4133759324,17.4060837415,17.3988119541,17.3915604686,
+	17.3843291844,17.3771180014,17.3699268203,17.3627555424,17.35560407,
+	17.3484723057,17.341360153,17.3342675159,17.3271942994,17.3201404088,
+	17.3131057502,17.3060902305,17.2990937569,17.2921162377,17.2851575813,
+	17.2782176971,17.2712964951,17.2643938858,17.2575097803,17.2506440905,
+	17.2437967285,17.2369676075,17.2301566409,17.2233637429,17.2165888281,
+	17.2098318119,17.2030926101,17.1963711391,17.189667316,17.1829810581,
+	17.1763122836,17.1696609112,17.1630268599,17.1564100495,17.1498104003,
+	17.1432278329,17.1366622687,17.1301136294,17.1235818374,17.1170668156,
+	17.1105684871,17.1040867758,17.0976216062,17.0911729029,17.0847405913,
+	17.0783245972,17.0719248468,17.0655412669,17.0591737847,17.0528223279,
+	17.0464868247,17.0401672035,17.0338633936,17.0275753244,17.0213029259,
+	17.0150461285,17.008804863,17.0025790607,16.9963686535,16.9901735733,
+	16.9839937528,16.9778291251,16.9716796235,16.9655451818,16.9594257344,
+	16.9533212159,16.9472315614,16.9411567063,16.9350965866,16.9290511385,
+	16.9230202986,16.9170040041,16.9110021924,16.9050148013,16.8990417691,
+	16.8930830343,16.8871385358,16.8812082131,16.8752920059,16.8693898542,
+	16.8635016985,16.8576274795,16.8517671385,16.8459206169,16.8400878566,
+	16.8342687999,16.8284633893,16.8226715677,16.8168932783,16.8111284648,
+	16.8053770711,16.7996390414,16.7939143204,16.7882028529,16.7825045842,
+	16.7768194599,16.7711474258,16.7654884282,16.7598424137,16.7542093289,
+	16.7485891212,16.7429817379,16.7373871268,16.731805236,16.7262360139,
+	16.7206794092,16.7151353708,16.7096038479,16.7040847902,16.6985781476,
+	16.69308387,16.687601908,16.6821322124,16.676674734,16.6712294241,
+	16.6657962344,16.6603751165,16.6549660228,16.6495689054,16.6441837172,
+	16.6388104109,16.6334489397,16.6280992572,16.6227613169,16.617435073,
+	16.6121204796,16.6068174911,16.6015260624,16.5962461483,16.5909777043,
+	16.5857206857,16.5804750482,16.575240748,16.5700177411,16.5648059841,
+	16.5596054337,16.5544160468,16.5492377806,16.5440705926,16.5389144403,
+	16.5337692817,16.5286350749,16.5235117782,16.5183993502,16.5132977498,
+	16.5082069358,16.5031268677,16.4980575048,16.4929988068,16.4879507336,
+	16.4829132453,16.4778863024,16.4728698652,16.4678638946,16.4628683516,
+	16.4578831973,16.4529083931,16.4479439006,16.4429896815,16.438045698,
+	16.4331119121,16.4281882863,16.4232747832,16.4183713655,16.4134779963,
+	16.4085946388,16.4037212562,16.3988578123,16.3940042707,16.3891605954,
+	16.3843267505,16.3795027004,16.3746884096,16.3698838428,16.3650889649,
+	16.3603037408,16.3555281359,16.3507621156,16.3460056454,16.3412586913,
+	16.336521219,16.3317931948,16.3270745849,16.3223653558,16.3176654741,
+	16.3129749068,16.3082936207,16.303621583,16.298958761,16.2943051222,
+	16.2896606343,16.285025265,16.2803989824,16.2757817546,16.2711735499,
+	16.2665743366,16.2619840836,16.2574027594,16.2528303331,16.2482667737,
+	16.2437120505,16.2391661329,16.2346289903,16.2301005925,16.2255809094,
+	16.2210699108,16.2165675671,16.2120738484,16.2075887252,16.203112168,
+	16.1986441477,16.194184635,16.189733601,16.1852910168,16.1808568537,
+	16.1764310832,16.1720136768,16.1676046063,16.1632038434,16.1588113602,
+	16.1544271288,16.1500511214,16.1456833105,16.1413236685,16.1369721682,
+	16.1326287822,16.1282934836,16.1239662453,16.1196470405,16.1153358426,
+	16.1110326249,16.1067373611,16.1024500248,16.0981705898,16.0938990301,
+	16.0896353196,16.0853794327,16.0811313435,16.0768910266,16.0726584563,
+	16.0684336075,16.0642164549,16.0600069734,16.055805138,16.0516109239,
+	16.0474243062,16.0432452604,16.0390737619,16.0349097864,16.0307533095,
+	16.026604307,16.022462755,16.0183286294,16.0142019064,16.0100825622,
+	16.0059705733,16.0018659161,15.9977685672,15.9936785032,15.9895957011,
+	15.9855201377,15.98145179,15.9773906352,15.9733366504,15.9692898131,
+	15.9652501006,15.9612174904,15.9571919603,15.9531734879,15.949162051,
+	15.9451576277,15.941160196,15.9371697339,15.9331862197,15.9292096318,
+	15.9252399486,15.9212771486,15.9173212104,15.9133721128,15.9094298345,
+	15.9054943544,15.9015656517,15.8976437053,15.8937284944,15.8898199983,
+	15.8859181964,15.8820230682,15.8781345932,15.874252751,15.8703775214,
+	15.8665088841,15.8626468192,15.8587913065,15.8549423262,15.8510998585,
+	15.8472638835,15.8434343817,15.8396113335,15.8357947194,15.8319845199,
+	15.8281807158,15.8243832879,15.8205922169,15.8168074838,15.8130290697,
+	15.8092569556,15.8054911227,15.8017315522,15.7979782256,15.7942311241,
+	15.7904902294,15.7867555229,15.7830269864,15.7793046016,15.7755883502,
+	15.7718782142,15.7681741756,15.7644762164,15.7607843186,15.7570984646,
+	15.7534186365,15.7497448167,15.7460769876,15.7424151318,15.7387592317,
+	15.7351092701,15.7314652295,15.7278270929,15.7241948431,15.720568463,
+	15.7169479355,15.7133332439,15.7097243711,15.7061213004,15.7025240152,
+	15.6989324987,15.6953467343,15.6917667056,15.6881923961,15.6846237894,
+	15.6810608692,15.6775036193,15.6739520235,15.6704060657,15.6668657298,
+	15.6633309998,15.6598018599,15.6562782942,15.652760287,15.6492478224,
+	15.6457408848,15.6422394587,15.6387435286,15.6352530788,15.6317680941,
+	15.6282885592,15.6248144586,15.6213457773,15.6178825,15.6144246117,
+	15.6109720973,15.6075249419,15.6040831305,15.6006466483,15.5972154805,
+	15.5937896123,15.5903690291,15.5869537163,15.5835436592,15.5801388435,
+	15.5767392546,15.5733448782,15.5699556999,15.5665717054,15.5631928806,
+	15.5598192113,15.5564506833,15.5530872827,15.5497289954,15.5463758074,
+	15.543027705,15.5396846742,15.5363467014,15.5330137727,15.5296858744,
+	15.5263629931,15.5230451151,15.5197322269,15.5164243151,15.5131213662,
+	15.5098233669,15.5065303039,15.5032421639,15.4999589337,15.4966806003,
+	15.4934071504,15.4901385711,15.4868748494,15.4836159722,15.4803619267,
+	15.4771127001,15.4738682796,15.4706286523,15.4673938057,15.464163727,
+	15.4609384036,15.457717823,15.4545019727,15.4512908402,15.4480844132,
+	15.4448826791,15.4416856258,15.4384932409,15.4353055122,15.4321224276,
+	15.4289439748,15.4257701418,15.4226009166,15.4194362872,15.4162762415,
+	15.4131207678,15.409969854,15.4068234885,15.4036816594,15.400544355,
+	15.3974115636,15.3942832736,15.3911594733,15.3880401512,15.3849252958,
+	15.3818148956,15.3787089391,15.3756074151,15.3725103121,15.3694176188,
+	15.366329324,15.3632454164,15.3601658849,15.3570907183,15.3540199055,
+	15.3509534355,15.3478912972,15.3448334797,15.341779972,15.3387307632,
+	15.3356858425,15.3326451991,15.3296088221,15.3265767009,15.3235488246,
+	15.3205251828,15.3175057647,15.3144905597,15.3114795573,15.308472747,
+	15.3054701184,15.3024716609,15.2994773642,15.2964872179,15.2935012118,
+	15.2905193354,15.2875415787,15.2845679312,15.281598383,15.2786329238,
+	15.2756715436,15.2727142322,15.2697609796,15.2668117759,15.2638666111,
+	15.2609254752,15.2579883584,15.2550552508,15.2521261426,15.249201024,
+	15.2462798852,15.2433627166,15.2404495084,15.2375402511,15.2346349349,
+	15.2317335503,15.2288360878,15.2259425378,15.2230528908,15.2201671375,
+	15.2172852684,15.2144072741,15.2115331453,15.2086628726,15.2057964467,
+	15.2029338585,15.2000750986,15.197220158,15.1943690274,15.1915216977,
+	15.1886781598,15.1858384047,15.1830024233,15.1801702066,15.1773417457,
+	15.1745170316,15.1716960554,15.1688788083,15.1660652813,15.1632554657,
+	15.1604493526,15.1576469334,15.1548481993,15.1520531416,15.1492617516,
+	15.1464740206,15.1436899402,15.1409095017,15.1381326965,15.1353595161,
+	15.1325899521,15.1298239959,15.1270616392,15.1243028735,15.1215476904,
+	15.1187960816,15.1160480388,15.1133035537,15.1105626179,15.1078252234,
+	15.1050913618,15.1023610249,15.0996342047,15.0969108929,15.0941910815,
+	15.0914747624,15.0887619276,15.086052569,15.0833466786,15.0806442485,
+	15.0779452707,15.0752497372,15.0725576403,15.0698689721,15.0671837246,
+	15.0645018902,15.0618234609,15.0591484291,15.0564767869,15.0538085268,
+	15.051143641,15.0484821218,15.0458239617,15.0431691529,15.0405176879,
+	15.0378695592,15.0352247593,15.0325832805,15.0299451154,15.0273102566,
+	15.0246786966,15.022050428,15.0194254434,15.0168037355,15.0141852968,
+	15.0115701201,15.0089581981,15.0063495236,15.0037440891,15.0011418876,
+	14.9985429119,14.9959471547,14.9933546088,14.9907652673,14.9881791229,
+	14.9855961686,14.9830163972,14.9804398018,14.9778663754,14.9752961109,
+	14.9727290013,14.9701650398,14.9676042193,14.965046533,14.962491974,
+	14.9599405354,14.9573922104,14.9548469921,14.9523048738,14.9497658486,
+	14.9472299098,14.9446970507,14.9421672646,14.9396405447,14.9371168844,
+	14.9345962771,14.932078716,14.9295641947,14.9270527064,14.9245442447,
+	14.9220388029,14.9195363747,14.9170369533,14.9145405324,14.9120471055,
+	14.9095566662,14.9070692079,14.9045847244,14.9021032092,14.8996246559,
+	14.8971490582,14.8946764098,14.8922067044,14.8897399356,14.8872760973,
+	14.884815183,14.8823571867,14.8799021021,14.877449923,14.8750006433,
+	14.8725542567,14.8701107571,14.8676701385,14.8652323947,14.8627975196,
+	14.8603655072,14.8579363515,14.8555100463,14.8530865858,14.8506659638,
+	14.8482481745,14.8458332119,14.84342107,14.841011743,14.8386052248,
+	14.8362015098,14.8338005919,14.8314024654,14.8290071244,14.8266145631,
+	14.8242247756,14.8218377564,14.8194534995,14.8170719992,14.8146932498,
+	14.8123172457,14.809943981,14.8075734502,14.8052056476,14.8028405675,
+	14.8004782043,14.7981185525,14.7957616063,14.7934073604,14.791055809,
+	14.7887069467,14.7863607679,14.7840172671,14.7816764389,14.7793382777,
+	14.7770027781,14.7746699347,14.7723397421,14.7700121947,14.7676872873,
+	14.7653650145,14.7630453708,14.760728351,14.7584139497,14.7561021616,
+	14.7537929814,14.7514864038,14.7491824235,14.7468810354,14.7445822341,
+	14.7422860144,14.7399923711,14.7377012991,14.7354127931,14.733126848,
+	14.7308434587,14.72856262,14.7262843267,14.7240085739,14.7217353563,
+	14.719464669,14.7171965068,14.7149308648,14.7126677378,14.7104071209,
+	14.7081490091
+	};
+
+
+tubetable_6DJ8_rtable_0(r) = (tubetable_6DJ8_0,r):rdtable;
+tubetable_6DJ8_rtable_1(r) = (tubetable_6DJ8_1,r):rdtable;
+
+
+/*
+ * tube: 6V6
+ * */
+ 
+ tubetable_6V6_0 = waveform{
+	239.919843376,239.854937108,239.789738489,239.724247218,239.658462996,
+	239.592385535,239.526014546,239.459349752,239.392390878,239.325137654,
+	239.257589818,239.189747112,239.121609284,239.053176087,238.984447281,
+	238.91542263,238.846101903,238.776484877,238.706571332,238.636361055,
+	238.565853836,238.495049475,238.423947772,238.352548536,238.280851579,
+	238.208856722,238.136563787,238.063972604,237.991083007,237.917894835,
+	237.844407935,237.770622155,237.696537352,237.622153385,237.54747012,
+	237.472487429,237.397205186,237.321623273,237.245741575,237.169559984,
+	237.093078396,237.016296711,236.939214835,236.86183268,236.78415016,
+	236.706167196,236.627883714,236.549299644,236.470414921,236.391229484,
+	236.311743279,236.231956253,236.151868362,236.071479563,235.99078982,
+	235.9097991,235.828507376,235.746914624,235.665020826,235.582825967,
+	235.500330038,235.417533033,235.334434951,235.251035796,235.167335575,
+	235.083334301,234.999031988,234.914428659,234.829524337,234.744319051,
+	234.658812834,234.573005723,234.48689776,234.400488988,234.313779459,
+	234.226769224,234.13945834,234.05184687,233.963934876,233.875722429,
+	233.7872096,233.698396466,233.609283107,233.519869606,233.430156051,
+	233.340142534,233.249829147,233.159215991,233.068303166,232.977090779,
+	232.885578937,232.793767753,232.701657342,232.609247824,232.516539321,
+	232.423531959,232.330225867,232.236621177,232.142718023,232.048516546,
+	231.954016887,231.85921919,231.764123605,231.66873028,231.573039372,
+	231.477051037,231.380765434,231.284182727,231.187303082,231.090126667,
+	230.992653654,230.894884217,230.796818534,230.698456783,230.599799147,
+	230.500845813,230.401596966,230.302052798,230.202213502,230.102079273,
+	230.001650309,229.900926811,229.799908981,229.698597024,229.596991149,
+	229.495091566,229.392898486,229.290412124,229.187632698,229.084560426,
+	228.98119553,228.877538233,228.77358876,228.66934734,228.564814202,
+	228.459989578,228.354873701,228.249466808,228.143769136,228.037780925,
+	227.931502416,227.824933853,227.718075481,227.610927548,227.503490301,
+	227.395763992,227.287748873,227.179445197,227.070853221,226.961973202,
+	226.852805398,226.743350071,226.633607482,226.523577894,226.413261574,
+	226.302658786,226.1917698,226.080594885,225.969134311,225.857388351,
+	225.745357278,225.633041366,225.520440893,225.407556135,225.294387371,
+	225.180934881,225.067198945,224.953179846,224.838877868,224.724293293,
+	224.609426409,224.494277501,224.378846857,224.263134765,224.147141516,
+	224.030867399,223.914312706,223.79747773,223.680362764,223.562968102,
+	223.445294038,223.32734087,223.209108892,223.090598404,222.971809703,
+	222.852743088,222.733398858,222.613777314,222.493878757,222.373703489,
+	222.253251812,222.132524028,222.011520442,221.890241357,221.768687078,
+	221.64685791,221.524754159,221.402376131,221.279724132,221.15679847,
+	221.033599452,220.910127386,220.78638258,220.662365343,220.538075983,
+	220.413514811,220.288682136,220.163578268,220.038203517,219.912558193,
+	219.786642608,219.660457072,219.534001897,219.407277394,219.280283874,
+	219.15302165,219.025491033,218.897692335,218.769625868,218.641291945,
+	218.512690877,218.383822977,218.254688558,218.125287932,217.995621411,
+	217.865689308,217.735491935,217.605029605,217.47430263,217.343311321,
+	217.212055993,217.080536955,216.948754521,216.816709003,216.684400712,
+	216.551829959,216.418997057,216.285902317,216.152546049,216.018928564,
+	215.885050174,215.750911189,215.616511919,215.481852673,215.346933762,
+	215.211755495,215.076318182,214.94062213,214.804667649,214.668455047,
+	214.531984632,214.395256711,214.258271591,214.121029579,213.983530982,
+	213.845776106,213.707765256,213.569498737,213.430976855,213.292199913,
+	213.153168215,213.013882065,212.874341767,212.734547621,212.594499931,
+	212.454198998,212.313645122,212.172838605,212.031779746,211.890468845,
+	211.748906201,211.607092111,211.465026874,211.322710786,211.180144145,
+	211.037327247,210.894260386,210.750943858,210.607377956,210.463562975,
+	210.319499207,210.175186945,210.03062648,209.885818102,209.740762104,
+	209.595458773,209.449908399,209.30411127,209.158067675,209.011777899,
+	208.865242228,208.718460949,208.571434346,208.424162703,208.276646303,
+	208.128885428,207.980880361,207.832631382,207.684138772,207.53540281,
+	207.386423774,207.237201943,207.087737593,206.938031001,206.788082442,
+	206.637892191,206.487460522,206.336787708,206.185874021,206.034719731,
+	205.883325111,205.73169043,205.579815955,205.427701956,205.275348699,
+	205.122756451,204.969925477,204.816856041,204.663548407,204.510002838,
+	204.356219595,204.20219894,204.047941132,203.893446431,203.738715095,
+	203.583747381,203.428543545,203.273103843,203.117428529,202.961517858,
+	202.80537208,202.648991449,202.492376215,202.335526628,202.178442936,
+	202.021125388,201.86357423,201.705789708,201.547772068,201.389521553,
+	201.231038406,201.072322869,200.913375184,200.75419559,200.594784326,
+	200.435141631,200.275267741,200.115162893,199.954827322,199.794261261,
+	199.633464944,199.472438602,199.311182467,199.149696769,198.987981736,
+	198.826037597,198.663864578,198.501462905,198.338832802,198.175974495,
+	198.012888205,197.849574154,197.686032562,197.52226365,197.358267635,
+	197.194044735,197.029595166,196.864919145,196.700016884,196.534888597,
+	196.369534496,196.203954793,196.038149697,195.872119417,195.70586416,
+	195.539384134,195.372679544,195.205750595,195.03859749,194.871220431,
+	194.703619619,194.535795255,194.367747539,194.199476666,194.030982836,
+	193.862266242,193.69332708,193.524165544,193.354781825,193.185176116,
+	193.015348605,192.845299483,192.675028937,192.504537154,192.333824319,
+	192.162890617,191.991736232,191.820361346,191.648766139,191.476950793,
+	191.304915485,191.132660394,190.960185696,190.787491567,190.61457818,
+	190.44144571,190.268094328,190.094524205,189.92073551,189.746728413,
+	189.572503081,189.398059679,189.223398374,189.048519329,188.873422706,
+	188.698108668,188.522577375,188.346828986,188.17086366,187.994681553,
+	187.818282821,187.641667619,187.4648361,187.287788416,187.110524719,
+	186.933045159,186.755349884,186.577439042,186.399312779,186.220971241,
+	186.042414571,185.863642913,185.684656407,185.505455195,185.326039416,
+	185.146409208,184.966564707,184.78650605,184.606233371,184.425746802,
+	184.245046478,184.064132527,183.88300508,183.701664266,183.520110212,
+	183.338343043,183.156362885,182.974169862,182.791764095,182.609145707,
+	182.426314816,182.243271543,182.060016004,181.876548316,181.692868595,
+	181.508976953,181.324873504,181.14055836,180.95603163,180.771293424,
+	180.58634385,180.401183013,180.215811021,180.030227975,179.844433981,
+	179.658429138,179.472213549,179.285787311,179.099150523,178.912303282,
+	178.725245682,178.537977819,178.350499785,178.162811672,177.974913571,
+	177.78680557,177.598487758,177.409960222,177.221223046,177.032276316,
+	176.843120113,176.653754521,176.464179619,176.274395486,176.084402201,
+	175.894199839,175.703788477,175.513168189,175.322339047,175.131301123,
+	174.940054487,174.748599208,174.556935354,174.365062992,174.172982186,
+	173.980693001,173.788195499,173.595489741,173.402575787,173.209453697,
+	173.016123528,172.822585335,172.628839174,172.434885098,172.240723159,
+	172.046353409,171.851775896,171.65699067,171.461997778,171.266797264,
+	171.071389174,170.87577355,170.679950435,170.483919869,170.28768189,
+	170.091236537,169.894583847,169.697723853,169.500656591,169.303382093,
+	169.105900389,168.90821151,168.710315484,168.512212338,168.313902098,
+	168.115384789,167.916660433,167.717729053,167.518590668,167.319245298,
+	167.11969296,166.919933671,166.719967446,166.519794298,166.31941424,
+	166.118827282,165.918033434,165.717032704,165.515825098,165.314410622,
+	165.112789281,164.910961076,164.708926008,164.506684078,164.304235284,
+	164.101579623,163.898717091,163.695647681,163.492371386,163.288888199,
+	163.085198108,162.881301103,162.67719717,162.472886295,162.268368463,
+	162.063643656,161.858711857,161.653573044,161.448227196,161.242674291,
+	161.036914304,160.83094721,160.62477298,160.418391588,160.211803002,
+	160.005007191,159.798004121,159.590793759,159.383376069,159.175751012,
+	158.967918551,158.759878644,158.551631251,158.343176326,158.134513827,
+	157.925643705,157.716565915,157.507280405,157.297787126,157.088086025,
+	156.878177048,156.66806014,156.457735244,156.247202301,156.036461253,
+	155.825512036,155.614354589,155.402988847,155.191414744,154.979632212,
+	154.767641183,154.555441585,154.343033346,154.130416393,153.91759065,
+	153.704556041,153.491312486,153.277859907,153.064198221,152.850327345,
+	152.636247195,152.421957684,152.207458725,151.992750227,151.7778321,
+	151.562704251,151.347366586,151.131819009,150.916061423,150.700093728,
+	150.483915823,150.267527608,150.050928976,149.834119824,149.617100043,
+	149.399869526,149.182428161,148.964775837,148.746912439,148.528837853,
+	148.310551961,148.092054646,147.873345786,147.65442526,147.435292944,
+	147.215948713,146.99639244,146.776623997,146.556643254,146.336450078,
+	146.116044336,145.895425893,145.674594613,145.453550356,145.232292983,
+	145.010822352,144.789138319,144.567240739,144.345129466,144.122804351,
+	143.900265243,143.677511992,143.454544443,143.231362442,143.007965832,
+	142.784354453,142.560528148,142.336486752,142.112230104,141.887758038,
+	141.663070388,141.438166985,141.213047659,140.987712238,140.762160551,
+	140.536392421,140.310407672,140.084206127,139.857787605,139.631151926,
+	139.404298906,139.177228362,138.949940108,138.722433955,138.494709716,
+	138.266767199,138.038606213,137.810226563,137.581628056,137.352810494,
+	137.12377368,136.894517415,136.665041496,136.435345723,136.205429892,
+	135.975293798,135.744937235,135.514359995,135.283561869,135.052542648,
+	134.82130212,134.589840073,134.358156292,134.126250564,133.894122672,
+	133.661772399,133.429199528,133.19640384,132.963385115,132.730143131,
+	132.496677668,132.262988503,132.029075413,131.794938175,131.560576562,
+	131.325990352,131.091179317,130.856143233,130.620881872,130.385395008,
+	130.149682414,129.913743863,129.677579128,129.441187981,129.204570195,
+	128.967725544,128.730653801,128.493354739,128.255828133,128.018073758,
+	127.780091388,127.541880801,127.303441774,127.064774085,126.825877513,
+	126.58675184,126.347396848,126.107812322,125.867998046,125.627953809,
+	125.387679402,125.147174616,124.906439246,124.665473091,124.424275951,
+	124.18284763,123.941187934,123.699296676,123.457173669,123.214818733,
+	122.97223169,122.729412369,122.486360602,122.243076228,121.99955909,
+	121.755809038,121.511825927,121.26760962,121.023159987,120.778476904,
+	120.533560256,120.288409935,120.043025842,119.797407887,119.551555992,
+	119.305470084,119.059150105,118.812596006,118.565807749,118.318785311,
+	118.071528678,117.824037853,117.57631285,117.328353699,117.080160446,
+	116.831733152,116.583071896,116.334176775,116.085047901,115.835685411,
+	115.586089457,115.336260215,115.086197883,114.835902681,114.585374855,
+	114.334614673,114.083622432,113.832398456,113.580943098,113.329256739,
+	113.077339793,112.825192708,112.572815961,112.320210071,112.067375588,
+	111.814313105,111.561023251,111.307506702,111.053764172,110.799796425,
+	110.545604269,110.291188564,110.036550219,109.781690197,109.526609517,
+	109.271309257,109.015790552,108.760054603,108.504102673,108.247936094,
+	107.99155627,107.734964676,107.478162863,107.221152462,106.963935187,
+	106.706512834,106.448887292,106.191060538,105.933034646,105.674811791,
+	105.416394248,105.157784399,104.89898474,104.639997879,104.380826542,
+	104.121473582,103.861941977,103.602234839,103.342355417,103.082307103,
+	102.822093435,102.561718104,102.30118496,102.040498015,101.779661449,
+	101.518679619,101.25755706,100.996298495,100.734908838,100.473393204,
+	100.211756913,99.9500054931,99.6881446953,99.4261804934,99.1641190935,
+	98.9019669409,98.6397307266,98.3774173951,98.115034151,97.8525884667,
+	97.5900880897,97.32754105,97.0649556675,96.8023405592,96.5397046474,
+	96.2770571663,96.01440767,95.7517660395,95.4891424902,95.226547579,
+	94.9639922112,94.7014876479,94.4390455122,94.1766777957,93.9143968652,
+	93.6522154685,93.39014674,93.1282042061,92.8664017902,92.6047538171,
+	92.3432750174,92.0819805307,91.820885909,91.5600071186,91.2993605427,
+	91.0389629817,90.7788316539,90.5189841954,90.2594386585,90.0002135096,
+	89.7413276266,89.4828002945,89.2246512005,88.9669004284,88.709568451,
+	88.4526761221,88.196244667,87.940295672,87.6848510727,87.4299331406,
+	87.1755644693,86.9217679583,86.6685667964,86.4159844438,86.1640446119,
+	85.9127712432,85.6621884888,85.4123206855,85.163192331,84.914828058,
+	84.6672526082,84.4204908033,84.1745675171,83.9295076449,83.6853360732,
+	83.4420776478,83.1997571419,82.9583992232,82.7180284205,82.4786690901,
+	82.2403453816,82.0030812043,81.7669001925,81.5318256718,81.2978806254,
+	81.0650876604,80.8334689751,80.6030463265,80.373840999,80.1458737738,
+	79.9191648987,79.6937340602,79.469600356,79.2467822688,79.025297642,
+	78.8051636567,78.5863968102,78.3690128963,78.1530269874,77.9384534185,
+	77.7253057722,77.5135968673,77.3033387471,77.0945426718,76.8872191109,
+	76.6813777391,76.4770274327,76.274176269,76.0728315269,75.8729996892,
+	75.674686447,75.4778967059,75.2826345928,75.0889034655,74.896705923,
+	74.7060438173,74.5169182664,74.3293296689,74.1432777192,73.958761424,
+	73.7757791196,73.5943284902,73.4144065864,73.2360098455,73.0591341108,
+	72.8837746527,72.7099261894,72.5375829084,72.3667384877,72.1973861174,
+	72.0295185219,71.8631279807,71.698206351,71.5347450886,71.3727352695,
+	71.2121676108,71.0530324916,70.895319974,70.7390198224,70.5841215239,
+	70.4306143075,70.2784871629,70.127728859,69.9783279618,69.8302728517,
+	69.6835517406,69.5381526878,69.3940636164,69.251272328,69.1097665175,
+	68.9695337873,68.8305616607,68.692837595,68.556348994,68.4210832195,
+	68.2870276031,68.1541694565,68.0224960825,67.8919947839,67.7626528733,
+	67.6344576819,67.5073965675,67.3814569225,67.2566261813,67.132891827,
+	67.0102413984,66.8886624955,66.7681427857,66.6486700089,66.5302319826,
+	66.4128166063,66.2964118658,66.1810058376,66.0665866919,65.9531426963,
+	65.8406622188,65.7291337307,65.6185458088,65.5088871381,65.4001465135,
+	65.2923128418,65.1853751436,65.0793225539,64.9741443241,64.869829823,
+	64.7663685372,64.6637500722,64.5619641527,64.4610006235,64.3608494493,
+	64.261500715,64.1629446261,64.0651715079,63.9681718061,63.8719360861,
+	63.776455033,63.6817194506,63.5877202614,63.4944485058,63.4018953417,
+	63.3100520431,63.2189100002,63.1284607182,63.038695816,62.9496070262,
+	62.8611861931,62.7734252727,62.6863163309,62.5998515428,62.5140231916,
+	62.4288236674,62.344245466,62.2602811881,62.1769235376,62.094165321,
+	62.0119994454,61.9304189184,61.8494168459,61.7689864313,61.6891209743,
+	61.6098138696,61.5310586057,61.4528487634,61.3751780152,61.2980401233,
+	61.2214289391,61.1453384013,61.0697625353,60.9946954515,60.9201313444,
+	60.8460644913,60.772489251,60.699400063,60.6267914458,60.554657996,
+	60.4829943874,60.4117953693,60.3410557658,60.2707704748,60.2009344661,
+	60.1315427815,60.0625905326,59.9940729003,59.9259851339,59.8583225495,
+	59.7910805294,59.724254521,59.6578400356,59.5918326476,59.5262279936,
+	59.4610217712,59.3962097382,59.3317877115,59.2677515663,59.2040972355,
+	59.140820708,59.0779180285,59.0153852966,58.9532186654,58.8914143412,
+	58.8299685825,58.768877699,58.708138051,58.6477460488,58.5876981511,
+	58.5279908653,58.4686207459,58.4095843943,58.3508784577,58.2924996285,
+	58.2344446436,58.1767102838,58.119293373,58.0621907773,58.005399405,
+	57.948916205,57.892738167,57.8368623204,57.7812857339,57.7260055146,
+	57.6710188078,57.616322796,57.5619146987,57.5077917713,57.4539513053,
+	57.4003906269,57.3471070972,57.2940981111,57.241361097,57.1888935166,
+	57.1366928636,57.084756664,57.0330824751,56.9816678854,56.9305105136,
+	56.8796080089,56.8289580495,56.7785583433,56.7284066266,56.6785006639,
+	56.6288382478,56.5794171979,56.5302353612,56.4812906111,56.432580847,
+	56.3841039945,56.3358580041,56.2878408518,56.2400505378,56.1924850868,
+	56.1451425476,56.0980209921,56.0511185157,56.0044332366,55.9579632956,
+	55.9117068555,55.8656621011,55.8198272387,55.7742004958,55.7287801209,
+	55.6835643831,55.6385515716,55.5937399958,55.5491279849,55.5047138872,
+	55.4604960706,55.4164729216,55.3726428452,55.3290042651,55.2855556227,
+	55.2422953775,55.1992220065,55.1563340038,55.1136298808,55.0711081657,
+	55.0287674032,54.9866061544,54.9446229966,54.9028165229,54.8611853421,
+	54.8197280785,54.7784433715,54.7373298757,54.6963862605,54.6556112098,
+	54.6150034221,54.5745616098,54.5342844997,54.4941708323,54.4542193616,
+	54.4144288551,54.3747980937,54.3353258713,54.2960109948,54.2568522837,
+	54.2178485702,54.1789986988,54.1403015262,54.1017559213,54.0633607649,
+	54.0251149495,53.9870173791,53.9490669694,53.9112626471,53.8736033501,
+	53.8360880275,53.7987156391,53.7614851554,53.7243955574,53.6874458368,
+	53.6506349953,53.6139620448,53.5774260075,53.5410259151,53.5047608095,
+	53.4686297419,53.4326317732,53.3967659736,53.3610314227,53.3254272092,
+	53.2899524309,53.2546061945,53.2193876154,53.184295818,53.149329935,
+	53.1144891078,53.079772486,53.0451792278,53.0107084993,52.9763594747,
+	52.9421313363,52.9080232742,52.8740344864,52.8401641783,52.8064115633,
+	52.772775862,52.7392563025,52.7058521203,52.672562558,52.6393868653,
+	52.6063242993,52.5733741236,52.5405356091,52.5078080332,52.4751906802,
+	52.442682841,52.4102838131,52.3779929004,52.3458094133,52.3137326685,
+	52.281761989,52.2498967038,52.2181361484,52.1864796639,52.1549265977,
+	52.123476303,52.0921281387,52.0608814697,52.0297356664,51.998690105,
+	51.9677441672,51.9368972401,51.9061487165,51.8754979942,51.8449444767,
+	51.8144875727,51.7841266957,51.7538612649,51.7236907043,51.6936144428,
+	51.6636319146,51.6337425585,51.6039458184,51.5742411427,51.544627985,
+	51.5151058032,51.4856740601,51.4563322228,51.4270797633,51.3979161578,
+	51.3688408872,51.3398534365,51.3109532954,51.2821399576,51.2534129212,
+	51.2247716884,51.1962157658,51.1677446638,51.1393578971,51.1110549843,
+	51.0828354481,51.0546988151,51.0266446158,50.9986723845,50.9707816593,
+	50.9429719823,50.9152428991,50.8875939591,50.8600247153,50.8325347244,
+	50.8051235466,50.7777907458,50.7505358892,50.7233585476,50.6962582952,
+	50.6692347097,50.6422873719,50.6154158663,50.5886197804,50.5618987051,
+	50.5352522345,50.5086799659,50.4821814997,50.4557564396,50.4294043921,
+	50.4031249672,50.3769177775,50.3507824389,50.3247185701,50.2987257929,
+	50.2728037319,50.2469520147,50.2211702716,50.1954581358,50.1698152434,
+	50.1442412332,50.1187357466,50.0932984281,50.0679289244,50.0426268854,
+	50.0173919631,49.9922238125,49.967122091,49.9420864588,49.9171165783,
+	49.8922121146,49.8673727353,49.8425981105,49.8178879127,49.7932418167,
+	49.7686594998,49.7441406417,49.7196849244,49.6952920323,49.670961652,
+	49.6466934725,49.622487185,49.5983424828,49.5742590617,49.5502366195,
+	49.5262748563,49.5023734741,49.4785321775,49.4547506727,49.4310286684,
+	49.4073658752,49.3837620058,49.3602167748,49.336729899,49.3133010971,
+	49.28993009,49.2666166002,49.2433603524,49.2201610732,49.197018491,
+	49.1739323363,49.1509023413,49.12792824,49.1050097686,49.0821466646,
+	49.0593386678,49.0365855194,49.0138869628,48.9912427428,48.968652606,
+	48.9461163009,48.9236335776,48.901204188,48.8788278855,48.8565044252,
+	48.8342335641,48.8120150606,48.7898486748,48.7677341684,48.7456713047,
+	48.7236598486,48.7016995666,48.6797902266,48.6579315983,48.6361234527,
+	48.6143655624,48.5926577015,48.5709996457,48.5493911719,48.5278320588,
+	48.5063220864,48.484861036,48.4634486905,48.4420848342,48.4207692528,
+	48.3995017333,48.3782820642,48.3571100353,48.3359854377,48.314908064,
+	48.2938777081,48.272894165,48.2519572313,48.2310667048,48.2102223845,
+	48.1894240707,48.1686715652,48.1479646707,48.1273031914,48.1066869326,
+	48.0861157009,48.0655893041,48.0451075513,48.0246702526,48.0042772194,
+	47.9839282643,47.963623201,47.9433618444,47.9231440105,47.9029695165,
+	47.8828381808,47.8627498227,47.8427042628,47.8227013227,47.8027408252,
+	47.7828225941,47.7629464542,47.7431122316,47.7233197533,47.7035688473,
+	47.6838593428,47.6641910699,47.6445638598,47.6249775446,47.6054319576,
+	47.5859269331,47.5664623061,47.5470379129,47.5276535906,47.5083091774,
+	47.4890045124,47.4697394356,47.450513788,47.4313274116,47.4121801493,
+	47.3930718448,47.3740023428,47.3549714891,47.3359791301,47.3170251133,
+	47.2981092869,47.2792315003,47.2603916035,47.2415894475,47.2228248841,
+	47.2040977659,47.1854079466,47.1667552804,47.1481396226,47.1295608293,
+	47.1110187573,47.0925132644,47.0740442089,47.0556114503,47.0372148487,
+	47.0188542649,47.0005295607,46.9822405986,46.9639872418,46.9457693543,
+	46.9275868009,46.9094394473,46.8913271597,46.8732498052,46.8552072516,
+	46.8371993674,46.8192260219,46.8012870852,46.7833824279,46.7655119216,
+	46.7476754383,46.7298728509,46.712104033,46.6943688588,46.6766672034,
+	46.6589989423,46.6413639518,46.6237621091,46.6061932917,46.5886573779,
+	46.5711542468,46.5536837781,46.5362458519,46.5188403494,46.501467152,
+	46.4841261421,46.4668172024,46.4495402166,46.4322950687,46.4150816434,
+	46.3978998262,46.3807495031,46.3636305605,46.3465428857,46.3294863665,
+	46.3124608912,46.2954663489,46.2785026291,46.261569622,46.2446672182,
+	46.2277953091,46.2109537865,46.1941425428,46.1773614712,46.1606104651,
+	46.1438894186,46.1271982264,46.1105367837,46.0939049864,46.0773027305,
+	46.0607299131,46.0441864315,46.0276721836,46.0111870677,45.9947309829,
+	45.9783038286,45.9619055047,45.9455359118,45.9291949509,45.9128825234,
+	45.8965985314,45.8803428774,45.8641154643,45.8479161957,45.8317449755,
+	45.8156017082,45.7994862988,45.7833986526,45.7673386755,45.751306274,
+	45.7353013548,45.7193238253,45.7033735933,45.6874505668,45.6715546547,
+	45.6556857661,45.6398438106,45.6240286981,45.6082403393,45.5924786449,
+	45.5767435264,45.5610348956,45.5453526646,45.5296967462,45.5140670535,
+	45.4984635,45.4828859995,45.4673344665,45.4518088158,45.4363089625,
+	45.4208348222,45.4053863109,45.3899633451,45.3745658416,45.3591937176,
+	45.3438468908,45.328525279,45.3132288009,45.297957375,45.2827109208,
+	45.2674893576,45.2522926056,45.2371205849,45.2219732164,45.2068504212,
+	45.1917521207,45.1766782368,45.1616286916,45.1466034078,45.1316023084,
+	45.1166253165,45.101672356,45.0867433507,45.0718382252,45.0569569041,
+	45.0420993126,45.027265376,45.0124550203,44.9976681714,44.9829047559,
+	44.9681647005,44.9534479326,44.9387543794,44.924083969,44.9094366294,
+	44.8948122891,44.8802108769,44.865632322,44.8510765539,44.8365435024,
+	44.8220330976,44.8075452698,44.7930799499,44.778637069,44.7642165583,
+	44.7498183497,44.735442375,44.7210885667,44.7067568573,44.6924471798,
+	44.6781594673,44.6638936534,44.6496496719,44.6354274569,44.6212269429,
+	44.6070480645,44.5928907568,44.578754955,44.5646405947,44.5505476118,
+	44.5364759423,44.5224255228,44.50839629,44.4943881808,44.4804011325,
+	44.4664350827,44.4524899692,44.43856573,44.4246623036,44.4107796285,
+	44.3969176438,44.3830762885,44.369255502,44.3554552242,44.341675395,
+	44.3279159545,44.3141768433,44.3004580021,44.2867593719,44.2730808939,
+	44.2594225098,44.2457841612,44.2321657901,44.2185673388,44.2049887499,
+	44.191429966,44.1778909302,44.1643715857,44.150871876,44.1373917448,
+	44.1239311362,44.1104899942,44.0970682634,44.0836658884,44.0702828141,
+	44.0569189857,44.0435743485,44.0302488482,44.0169424307,44.0036550418,
+	43.990386628,43.9771371358,43.9639065119,43.9506947033,43.9375016571,
+	43.9243273208,43.911171642,43.8980345685,43.8849160484,43.8718160299,
+	43.8587344616,43.8456712922,43.8326264705,43.8195999457,43.8065916671,
+	43.7936015843,43.780629647,43.7676758052,43.7547400091,43.7418222089,
+	43.7289223553,43.7160403991,43.7031762912,43.6903299827,43.6775014252,
+	43.66469057,43.6518973691,43.6391217743,43.6263637378,43.613623212,
+	43.6009001494,43.5881945027,43.5755062248,43.5628352689,43.5501815883,
+	43.5375451365,43.524925867,43.5123237339,43.499738691,43.4871706927,
+	43.4746196934,43.4620856476,43.4495685102,43.437068236,43.4245847802,
+	43.4121180981,43.3996681453,43.3872348772,43.3748182499,43.3624182192,
+	43.3500347414,43.3376677729,43.32531727,43.3129831897,43.3006654886,
+	43.2883641239,43.2760790527,43.2638102324,43.2515576206,43.2393211749,
+	43.2271008533,43.2148966136,43.2027084142,43.1905362133,43.1783799696,
+	43.1662396416,43.1541151882,43.1420065683,43.1299137412,43.1178366661,
+	43.1057753025,43.0937296101,43.0816995485,43.0696850777,43.0576861577,
+	43.0457027489,43.0337348116,43.0217823063,43.0098451938,42.9979234347,
+	42.9860169902,42.9741258213,42.9622498893,42.9503891557,42.938543582,
+	42.9267131299,42.9148977612,42.9030974381,42.8913121225,42.8795417768,
+	42.8677863635,42.856045845,42.8443201841,42.8326093436,42.8209132865,
+	42.809231976,42.7975653752,42.7859134476,42.7742761567,42.7626534662,
+	42.7510453398,42.7394517416,42.7278726355,42.7163079857,42.7047577566,
+	42.6932219127,42.6817004185,42.6701932388,42.6587003383,42.6472216822,
+	42.6357572354,42.6243069633,42.6128708311,42.6014488044,42.5900408488,
+	42.57864693,42.5672670139,42.5559010665,42.5445490538,42.5332109421,
+	42.5218866978,42.5105762873,42.4992796772,42.4879968343,42.4767277253,
+	42.4654723173,42.4542305773,42.4430024724,42.4317879701,42.4205870377,
+	42.4093996427,42.3982257529,42.3870653359,42.3759183598,42.3647847924,
+	42.3536646019,42.3425577565,42.3314642245,42.3203839745,42.309316975,
+	42.2982631946,42.2872226021,42.2761951665,42.2651808567,42.2541796418,
+	42.2431914911,42.2322163739,42.2212542596,42.2103051178,42.1993689181,
+	42.1884456302,42.1775352242,42.1666376698,42.1557529372,42.1448809965,
+	42.1340218181,42.1231753722,42.1123416295,42.1015205604,42.0907121357,
+	42.0799163261,42.0691331025,42.058362436,42.0476042976,42.0368586585,
+	42.0261254899,42.0154047634,42.0046964503,41.9940005222,41.9833169508,
+	41.972645708,41.9619867655,41.9513400953,41.9407056694,41.9300834602,
+	41.9194734397,41.9088755803,41.8982898545,41.8877162349,41.8771546939,
+	41.8666052044,41.8560677391,41.845542271,41.8350287731,41.8245272183,
+	41.81403758,41.8035598313,41.7930939457,41.7826398964,41.7721976572,
+	41.7617672016,41.7513485032,41.740941536,41.7305462738,41.7201626905,
+	41.7097907601,41.699430457,41.6890817552,41.6787446291,41.668419053,
+	41.6581050015,41.6478024491,41.6375113705,41.6272317404,41.6169635335,
+	41.6067067249,41.5964612895,41.5862272023,41.5760044385,41.5657929734,
+	41.5555927821,41.5454038401,41.535226123,41.5250596061,41.5149042652,
+	41.5047600759,41.4946270141,41.4845050556,41.4743941762,41.4642943522,
+	41.4542055595,41.4441277743,41.4340609729,41.4240051315,41.4139602267,
+	41.4039262349,41.3939031326,41.3838908964,41.3738895031,41.3638989294,
+	41.3539191523,41.3439501485,41.3339918952,41.3240443693,41.3141075481,
+	41.3041814088,41.2942659286,41.2843610849,41.2744668552,41.2645832169,
+	41.2547101477,41.2448476251,41.234995627,41.225154131,41.2153231151,
+	41.2055025572,41.1956924352,41.1858927273,41.1761034116,41.1663244663,
+	41.1565558696,41.1467976,41.1370496357,41.1273119554,41.1175845375,
+	41.1078673606,41.0981604035,41.0884636448,41.0787770634,41.0691006382,
+	41.059434348,41.049778172,41.0401320891,41.0304960786,41.0208701195,
+	41.0112541912,41.0016482731,40.9920523444,40.9824663846,40.9728903734,
+	40.9633242901,40.9537681146,40.9442218265,40.9346854055,40.9251588316,
+	40.9156420845,40.9061351443,40.8966379909,40.8871506045,40.8776729651,
+	40.868205053,40.8587468484,40.8492983317,40.8398594831,40.8304302833,
+	40.8210107125,40.8116007515,40.8022003807,40.792809581,40.7834283329,
+	40.7740566174,40.7646944152,40.7553417072,40.7459984744,40.7366646979,
+	40.7273403586,40.7180254378,40.7087199165,40.6994237762,40.6901369979,
+	40.6808595632,40.6715914533,40.6623326499,40.6530831343,40.6438428882,
+	40.6346118932,40.625390131,40.6161775833,40.6069742319,40.5977800587,
+	40.5885950455,40.5794191744,40.5702524272,40.5610947862,40.5519462333,
+	40.5428067507,40.5336763208,40.5245549257,40.5154425477,40.5063391692,
+	40.4972447727,40.4881593407,40.4790828555,40.4700152999,40.4609566565,
+	40.4519069079,40.4428660369,40.4338340262,40.4248108587,40.4157965172,
+	40.4067909847,40.3977942441,40.3888062786,40.3798270711,40.3708566047,
+	40.3618948628,40.3529418284,40.3439974848,40.3350618154,40.3261348035,
+	40.3172164326,40.3083066861,40.2994055475,40.2905130003,40.2816290283,
+	40.2727536149,40.2638867439,40.2550283991,40.2461785643,40.2373372232,
+	40.2285043598,40.219679958,40.2108640017,40.202056475,40.1932573619,
+	40.1844666466,40.1756843131,40.1669103458,40.1581447288,40.1493874464,
+	40.1406384829,40.1318978228,40.1231654504,40.1144413503,40.1057255068,
+	40.0970179046
+	};
+ tubetable_6V6_1 = waveform{
+	239.919843376,239.854937108,239.789738489,239.724247218,239.658462996,
+	239.592385535,239.526014546,239.459349752,239.392390878,239.325137654,
+	239.257589818,239.189747112,239.121609284,239.053176087,238.984447281,
+	238.91542263,238.846101903,238.776484877,238.706571332,238.636361055,
+	238.565853836,238.495049475,238.423947772,238.352548536,238.280851579,
+	238.208856722,238.136563787,238.063972604,237.991083007,237.917894835,
+	237.844407935,237.770622155,237.696537352,237.622153385,237.54747012,
+	237.472487429,237.397205186,237.321623273,237.245741575,237.169559984,
+	237.093078396,237.016296711,236.939214835,236.86183268,236.78415016,
+	236.706167196,236.627883714,236.549299644,236.470414921,236.391229484,
+	236.311743279,236.231956253,236.151868362,236.071479563,235.99078982,
+	235.9097991,235.828507376,235.746914624,235.665020826,235.582825967,
+	235.500330038,235.417533033,235.334434951,235.251035796,235.167335575,
+	235.083334301,234.999031988,234.914428659,234.829524337,234.744319051,
+	234.658812834,234.573005723,234.48689776,234.400488988,234.313779459,
+	234.226769224,234.13945834,234.05184687,233.963934876,233.875722429,
+	233.7872096,233.698396466,233.609283107,233.519869606,233.430156051,
+	233.340142534,233.249829147,233.159215991,233.068303166,232.977090779,
+	232.885578937,232.793767753,232.701657342,232.609247824,232.516539321,
+	232.423531959,232.330225867,232.236621177,232.142718023,232.048516546,
+	231.954016887,231.85921919,231.764123605,231.66873028,231.573039372,
+	231.477051037,231.380765434,231.284182727,231.187303082,231.090126667,
+	230.992653654,230.894884217,230.796818534,230.698456783,230.599799147,
+	230.500845813,230.401596966,230.302052798,230.202213502,230.102079273,
+	230.001650309,229.900926811,229.799908981,229.698597024,229.596991149,
+	229.495091566,229.392898486,229.290412124,229.187632698,229.084560426,
+	228.98119553,228.877538233,228.77358876,228.66934734,228.564814202,
+	228.459989578,228.354873701,228.249466808,228.143769136,228.037780925,
+	227.931502416,227.824933853,227.718075481,227.610927548,227.503490301,
+	227.395763992,227.287748873,227.179445197,227.070853221,226.961973202,
+	226.852805398,226.743350071,226.633607482,226.523577894,226.413261574,
+	226.302658786,226.1917698,226.080594885,225.969134311,225.857388351,
+	225.745357278,225.633041366,225.520440893,225.407556135,225.294387371,
+	225.180934881,225.067198945,224.953179846,224.838877868,224.724293293,
+	224.609426409,224.494277501,224.378846857,224.263134765,224.147141516,
+	224.030867399,223.914312706,223.79747773,223.680362764,223.562968102,
+	223.445294038,223.32734087,223.209108892,223.090598404,222.971809703,
+	222.852743088,222.733398858,222.613777314,222.493878757,222.373703489,
+	222.253251812,222.132524028,222.011520442,221.890241357,221.768687078,
+	221.64685791,221.524754159,221.402376131,221.279724132,221.15679847,
+	221.033599452,220.910127386,220.78638258,220.662365343,220.538075983,
+	220.413514811,220.288682136,220.163578268,220.038203517,219.912558193,
+	219.786642608,219.660457072,219.534001897,219.407277394,219.280283874,
+	219.15302165,219.025491033,218.897692335,218.769625868,218.641291945,
+	218.512690877,218.383822977,218.254688558,218.125287932,217.995621411,
+	217.865689308,217.735491935,217.605029605,217.47430263,217.343311321,
+	217.212055993,217.080536955,216.948754521,216.816709003,216.684400712,
+	216.551829959,216.418997057,216.285902317,216.152546049,216.018928564,
+	215.885050174,215.750911189,215.616511919,215.481852673,215.346933762,
+	215.211755495,215.076318182,214.94062213,214.804667649,214.668455047,
+	214.531984632,214.395256711,214.258271591,214.121029579,213.983530982,
+	213.845776106,213.707765256,213.569498737,213.430976855,213.292199913,
+	213.153168215,213.013882066,212.874341767,212.734547621,212.594499931,
+	212.454198998,212.313645123,212.172838605,212.031779747,211.890468845,
+	211.748906201,211.607092111,211.465026874,211.322710786,211.180144146,
+	211.037327247,210.894260386,210.750943858,210.607377956,210.463562975,
+	210.319499207,210.175186945,210.03062648,209.885818102,209.740762104,
+	209.595458773,209.449908399,209.304111271,209.158067675,209.011777899,
+	208.865242229,208.71846095,208.571434346,208.424162703,208.276646303,
+	208.128885429,207.980880362,207.832631383,207.684138772,207.53540281,
+	207.386423774,207.237201943,207.087737593,206.938031001,206.788082442,
+	206.637892192,206.487460523,206.336787708,206.185874021,206.034719732,
+	205.883325112,205.73169043,205.579815956,205.427701956,205.2753487,
+	205.122756451,204.969925477,204.816856041,204.663548407,204.510002838,
+	204.356219596,204.202198941,204.047941133,203.893446432,203.738715096,
+	203.583747382,203.428543546,203.273103844,203.11742853,202.961517859,
+	202.805372081,202.64899145,202.492376216,202.335526629,202.178442938,
+	202.021125389,201.863574231,201.70578971,201.547772069,201.389521554,
+	201.231038407,201.072322871,200.913375185,200.754195591,200.594784328,
+	200.435141633,200.275267743,200.115162895,199.954827324,199.794261263,
+	199.633464946,199.472438604,199.31118247,199.149696771,198.987981739,
+	198.826037599,198.66386458,198.501462908,198.338832806,198.175974498,
+	198.012888208,197.849574157,197.686032566,197.522263653,197.358267639,
+	197.194044739,197.029595171,196.864919149,196.700016888,196.534888602,
+	196.369534501,196.203954798,196.038149702,195.872119422,195.705864166,
+	195.53938414,195.372679551,195.205750602,195.038597496,194.871220438,
+	194.703619627,194.535795263,194.367747547,194.199476675,194.030982844,
+	193.862266251,193.69332709,193.524165554,193.354781836,193.185176127,
+	193.015348617,192.845299495,192.675028949,192.504537166,192.333824332,
+	192.162890631,191.991736246,191.820361361,191.648766155,191.476950809,
+	191.304915502,191.132660411,190.960185714,190.787491586,190.6145782,
+	190.441445731,190.268094349,190.094524227,189.920735533,189.746728437,
+	189.572503106,189.398059705,189.223398401,189.048519357,188.873422736,
+	188.698108699,188.522577407,188.34682902,188.170863695,187.994681589,
+	187.818282858,187.641667658,187.46483614,187.287788459,187.110524763,
+	186.933045205,186.755349932,186.577439092,186.399312831,186.220971295,
+	186.042414627,185.863642971,185.684656468,185.505455258,185.326039482,
+	185.146409276,184.966564778,184.786506124,184.606233447,184.425746882,
+	184.245046561,184.064132614,183.883005171,183.70166436,183.52011031,
+	183.338343145,183.156362991,182.974169972,182.79176421,182.609145826,
+	182.426314941,182.243271672,182.060016139,181.876548456,181.69286874,
+	181.508977105,181.324873662,181.140558524,180.956031801,180.771293602,
+	180.586344035,180.401183206,180.215811221,180.030228184,179.844434198,
+	179.658429365,179.472213784,179.285787556,179.099150778,178.912303547,
+	178.725245958,178.537978106,178.350500084,178.162811983,177.974913895,
+	177.786805907,177.598488109,177.409960587,177.221223426,177.032276711,
+	176.843120525,176.653754949,176.464180064,176.274395949,176.084402683,
+	175.894200341,175.703788999,175.513168732,175.322339612,175.131301711,
+	174.940055099,174.748599845,174.556936017,174.365063682,174.172982904,
+	173.980693748,173.788196276,173.59549055,173.402576629,173.209454574,
+	173.01612444,172.822586284,172.628840161,172.434886125,172.240724228,
+	172.046354521,171.851777054,171.656991875,171.461999032,171.266798569,
+	171.071390532,170.875774963,170.679951906,170.483921399,170.287683483,
+	170.091238194,169.894585571,169.697725648,169.500658458,169.303384036,
+	169.105902411,168.908213614,168.710317673,168.512214616,168.313904469,
+	168.115387256,167.916663,167.717731724,167.518593448,167.31924819,
+	167.11969597,166.919936804,166.719970706,166.51979769,166.319417769,
+	166.118830954,165.918037255,165.71703668,165.515829236,165.314414928,
+	165.112793761,164.910965738,164.70893086,164.506689127,164.304240538,
+	164.10158509,163.898722779,163.6956536,163.492377545,163.288894608,
+	163.085204777,162.881308042,162.677204391,162.472893809,162.268376282,
+	162.063651792,161.858720322,161.653581853,161.448236362,161.242683829,
+	161.036924229,160.830957537,160.624783727,160.41840277,160.211814637,
+	160.005019298,159.79801672,159.590806869,159.38338971,159.175765206,
+	158.967933321,158.759894013,158.551647242,158.343192966,158.134531141,
+	157.925661722,157.716584662,157.507299912,157.297807424,157.088107145,
+	156.878199025,156.668083008,156.457759039,156.247227061,156.036487016,
+	155.825538844,155.614382484,155.403017872,155.191444946,154.979663638,
+	154.767673882,154.55547561,154.34306875,154.130453232,153.917628982,
+	153.704595926,153.491353989,153.277903091,153.064243155,152.850374101,
+	152.636295846,152.422008306,152.207511398,151.992805035,151.777889129,
+	151.562763591,151.347428331,151.131883256,150.916128273,150.700163287,
+	150.483988202,150.267602919,150.051007339,149.834201362,149.617184885,
+	149.399957805,149.182520017,148.964871415,148.74701189,148.528941333,
+	148.310659634,148.092166681,147.873462361,147.654546557,147.435419156,
+	147.216080038,146.996529086,146.776766179,146.556791196,146.336604013,
+	146.116204508,145.895592554,145.674768025,145.453730794,145.23248073,
+	145.011017705,144.789341586,144.56745224,144.345349535,144.123033334,
+	143.900503503,143.677759903,143.454802397,143.231630845,143.008245106,
+	142.784645041,142.560830506,142.336801358,142.112557454,141.888098647,
+	141.663424793,141.438535745,141.213431356,140.988111477,140.76257596,
+	140.536824656,140.310857414,140.084674085,139.858274517,139.631658559,
+	139.40482606,139.177776866,138.950510827,138.72302779,138.495327601,
+	138.267410109,138.039275161,137.810922605,137.582352287,137.353564057,
+	137.124557761,136.89533325,136.665890372,136.436228977,136.206348916,
+	135.976250041,135.745932202,135.515395255,135.284639054,135.053663455,
+	134.822468314,134.591053492,134.359418849,134.127564247,133.895489551,
+	133.663194629,133.430679348,133.197943581,132.964987203,132.73181009,
+	132.498412124,132.264793187,132.030953168,131.796891958,131.562609451,
+	131.328105548,131.093380151,130.85843317,130.623264518,130.387874115,
+	130.152261884,129.916427758,129.680371672,129.444093571,129.207593404,
+	128.970871129,128.733926713,128.496760129,128.259371358,128.021760393,
+	127.783927234,127.545871891,127.307594385,127.069094748,126.830373023,
+	126.591429265,126.352263542,126.112875935,125.873266537,125.633435457,
+	125.393382821,125.153108766,124.91261345,124.671897045,124.430959742,
+	124.189801752,123.948423304,123.706824648,123.465006057,123.222967823,
+	122.980710263,122.738233721,122.495538562,122.252625181,122.009493998,
+	121.766145463,121.522580057,121.278798292,121.034800711,120.790587894,
+	120.546160453,120.30151904,120.056664344,119.811597095,119.566318064,
+	119.320828067,119.075127963,118.82921866,118.583101115,118.336776335,
+	118.090245381,117.84350937,117.596569475,117.349426929,117.102083029,
+	116.854539134,116.606796673,116.358857143,116.110722114,115.862393231,
+	115.613872218,115.365160881,115.116261108,114.867174879,114.61790426,
+	114.368451414,114.118818604,113.86900819,113.619022642,113.368864537,
+	113.118536565,112.868041535,112.617382378,112.366562149,112.115584036,
+	111.864451361,111.613167587,111.361736321,111.11016132,110.858446499,
+	110.60659593,110.354613852,110.102504677,109.850272992,109.597923569,
+	109.345461366,109.09289154,108.840219447,108.587450649,108.334590925,
+	108.081646272,107.828622915,107.575527312,107.322366164,107.069146415,
+	106.815875267,106.562560181,106.309208889,106.055829395,105.802429989,
+	105.549019247,105.295606044,105.042199559,104.78880928,104.535445014,
+	104.282116893,104.028835379,103.775611272,103.522455718,103.26938021,
+	103.016396602,102.763517107,102.510754307,102.258121157,102.00563099,
+	101.75329752,101.501134848,101.249157464,100.997380252,100.74581849,
+	100.494487852,100.243404412,99.9925846399,99.7420454065,99.4918039784,
+	99.2418780182,98.992285581,98.7430451111,98.4941754376,98.2456957684,
+	97.9976256841,97.7499851301,97.5027944079,97.2560741654,97.0098453854,
+	96.764129374,96.5189477467,96.2743224139,96.030275565,95.7868296514,
+	95.5440073677,95.3018316327,95.0603255681,94.8195124769,94.5794158196,
+	94.3400591904,94.1014662917,93.8636609074,93.6266668754,93.3905080596,
+	93.1552083202,92.9207914838,92.687281313,92.4547014744,92.2230755076,
+	91.9924267924,91.7627785162,91.5341536421,91.3065748752,91.0800646308,
+	90.8546450013,90.6303377244,90.4071641513,90.1851452154,89.9643014023,
+	89.7446527197,89.5262186689,89.309018217,89.0930697707,88.8783911506,
+	88.6649995678,88.452911601,88.2421431758,88.0327095454,87.8246252726,
+	87.6179042144,87.4125595073,87.2086035549,87.0060480178,86.8049038042,
+	86.6051810635,86.4068891809,86.2100367742,86.0146316924,85.820681016,
+	85.6281910588,85.4371673718,85.2476147483,85.059537231,84.8729381203,
+	84.6878199835,84.5041846669,84.3220333071,84.1413663453,83.9621835415,
+	83.78448399,83.6082661365,83.4335277947,83.2602661648,83.088477852,
+	82.918158886,82.7493047404,82.581910353,82.4159701465,82.2514780484,
+	82.0884275127,81.9268115401,81.7666226995,81.6078531484,81.450494654,
+	81.2945386136,81.1399760753,80.9867977578,80.8349940706,80.6845551334,
+	80.5354707951,80.387730653,80.2413240706,80.0962401958,79.9524679782,
+	79.8099961858,79.668813422,79.5289081407,79.3902686621,79.2528831875,
+	79.1167398133,78.9818265451,78.8481313104,78.7156419717,78.5843463383,
+	78.4542321781,78.3252872283,78.1974992063,78.0708558196,77.9453447751,
+	77.8209537885,77.6976705926,77.5754829453,77.4543786377,77.3343455008,
+	77.2153714125,77.097444304,76.9805521656,76.8646830525,76.7498250897,
+	76.6359664772,76.5230954944,76.411200504,76.3002699564,76.1902923926,
+	76.081256448,75.9731508553,75.865964447,75.7596861581,75.6543050282,
+	75.5498102036,75.446190939,75.3434365993,75.2415366608,75.1404807122,
+	75.0402584562,74.94085971,74.8422744057,74.7444925918,74.6475044324,
+	74.5513002088,74.4558703183,74.3612052756,74.2672957116,74.1741323741,
+	74.0817061269,73.9900079501,73.8990289392,73.8087603045,73.7191933711,
+	73.630319578,73.542130477,73.4546177327,73.3677731209,73.2815885286,
+	73.1960559524,73.1111674979,73.0269153786,72.943291915,72.8602895336,
+	72.7779007657,72.6961182464,72.6149347136,72.5343430066,72.4543360653,
+	72.3749069287,72.296048734,72.2177547155,72.140018203,72.062832621,
+	71.9861914875,71.9100884125,71.834517097,71.7594713319,71.6849449967,
+	71.6109320582,71.5374265695,71.4644226687,71.3919145776,71.3198966008,
+	71.2483631244,71.1773086147,71.1067276173,71.0366147558,70.9669647305,
+	70.8977723176,70.829032368,70.7607398058,70.692889628,70.6254769025,
+	70.5584967677,70.491944431,70.4258151681,70.3601043217,70.2948073007,
+	70.2299195789,70.1654366943,70.1013542477,70.0376679022,69.974373382,
+	69.9114664714,69.848943014,69.7867989115,69.7250301233,69.663632665,
+	69.6026026079,69.5419360781,69.4816292553,69.4216783727,69.3620797151,
+	69.302829619,69.2439244713,69.1853607088,69.127134817,69.0692433298,
+	69.0116828285,68.9544499408,68.8975413407,68.8409537471,68.7846839236,
+	68.7287286773,68.6730848588,68.6177493608,68.5627191177,68.5079911053,
+	68.4535623394,68.399429876,68.3455908099,68.2920422747,68.238781442,
+	68.1858055204,68.1331117557,68.0806974294,68.0285598591,67.9766963971,
+	67.9251044304,67.8737813799,67.8227247,67.7719318779,67.7214004334,
+	67.671127918,67.6211119148,67.5713500377,67.521839931,67.4725792692,
+	67.4235657562,67.3747971248,67.3262711367,67.2779855816,67.2299382769,
+	67.1821270675,67.1345498251,67.0872044479,67.0400888603,66.9932010121,
+	66.9465388788,66.9001004606,66.8538837821,66.8078868926,66.7621078646,
+	66.7165447945,66.6711958016,66.626059028,66.5811326384,66.5364148192,
+	66.491903779,66.4475977476,66.4034949759,66.3595937358,66.3158923195,
+	66.2723890395,66.2290822282,66.1859702377,66.1430514394,66.1003242235,
+	66.0577869994,66.0154381946,65.9732762552,65.9312996451,65.8895068457,
+	65.8478963563,65.806466693,65.7652163892,65.7241439947,65.6832480761,
+	65.642527216,65.6019800131,65.5616050819,65.5214010526,65.4813665705,
+	65.4415002962,65.4018009052,65.3622670877,65.3228975484,65.2836910063,
+	65.2446461946,65.2057618602,65.1670367641,65.1284696804,65.0900593968,
+	65.0518047142,65.0137044463,64.9757574197,64.9379624738,64.9003184602,
+	64.8628242429,64.825478698,64.7882807137,64.7512291898,64.7143230378,
+	64.6775611809,64.6409425534,64.6044661009,64.5681307798,64.5319355578,
+	64.4958794131,64.4599613344,64.4241803212,64.388535383,64.3530255396,
+	64.317649821,64.282407267,64.2472969272,64.2123178609,64.1774691369,
+	64.1427498335,64.1081590383,64.0736958481,64.0393593686,64.0051487146,
+	63.9710630098,63.9371013865,63.9032629857,63.8695469568,63.8359524576,
+	63.8024786545,63.7691247216,63.7358898415,63.7027732045,63.669774009,
+	63.636891461,63.6041247743,63.5714731704,63.5389358781,63.5065121337,
+	63.4742011808,63.4420022703,63.4099146602,63.3779376154,63.3460704081,
+	63.3143123171,63.2826626281,63.2511206336,63.2196856325,63.1883569306,
+	63.1571338399,63.1260156789,63.0950017724,63.0640914515,63.0332840535,
+	63.0025789217,62.9719754055,62.9414728602,62.9110706472,62.8807681334,
+	62.8505646917,62.8204597006,62.7904525442,62.7605426122,62.7307292997,
+	62.7010120074,62.6713901411,62.6418631122,62.6124303372,62.5830912378,
+	62.5538452407,62.5246917779,62.4956302862,62.4666602075,62.4377809884,
+	62.4089920806,62.3802929404,62.3516830289,62.3231618119,62.2947287596,
+	62.2663833472,62.238125054,62.2099533641,62.1818677657,62.1538677518,
+	62.1259528192,62.0981224695,62.0703762081,62.0427135449,62.0151339937,
+	61.9876370727,61.9602223038,61.9328892131,61.9056373307,61.8784661904,
+	61.8513753301,61.8243642916,61.7974326202,61.7705798651,61.7438055793,
+	61.7171093194,61.6904906456,61.6639491218,61.6374843153,61.6110957971,
+	61.5847831416,61.5585459265,61.5323837333,61.5062961465,61.4802827541,
+	61.4543431474,61.4284769208,61.4026836724,61.376963003,61.3513145168,
+	61.3257378211,61.3002325264,61.2747982461,61.2494345967,61.2241411979,
+	61.1989176721,61.1737636448,61.1486787445,61.1236626024,61.0987148526,
+	61.0738351323,61.049023081,61.0242783416,60.9996005592,60.9749893819,
+	60.9504444605,60.9259654483,60.9015520014,60.8772037785,60.8529204409,
+	60.8287016523,60.8045470791,60.7804563903,60.7564292571,60.7324653534,
+	60.7085643554,60.6847259419,60.660949794,60.637235595,60.6135830308,
+	60.5899917896,60.5664615617,60.5429920399,60.5195829191,60.4962338965,
+	60.4729446717,60.4497149461,60.4265444237,60.4034328102,60.3803798139,
+	60.357385145,60.3344485156,60.3115696402,60.2887482352,60.2659840191,
+	60.2432767122,60.2206260372,60.1980317183,60.1754934821,60.1530110568,
+	60.1305841728,60.1082125622,60.0858959592,60.0636340995,60.041426721,
+	60.0192735634,59.9971743681,59.9751288783,59.9531368392,59.9311979974,
+	59.9093121016,59.8874789021,59.865698151,59.8439696018,59.8222930102,
+	59.8006681332,59.7790947295,59.7575725597,59.7361013857,59.7146809713,
+	59.6933110816,59.6719914837,59.6507219459,59.6295022382,59.6083321322,
+	59.587211401,59.5661398192,59.5451171629,59.5241432098,59.5032177389,
+	59.4823405308,59.4615113675,59.4407300325,59.4199963107,59.3993099884,
+	59.3786708534,59.3580786947,59.3375333029,59.3170344698,59.2965819887,
+	59.2761756541,59.2558152619,59.2355006095,59.2152314953,59.1950077192,
+	59.1748290824,59.1546953873,59.1346064375,59.1145620381,59.0945619952,
+	59.0746061163,59.05469421,59.0348260863,59.0150015562,58.9952204321,
+	58.9754825273,58.9557876566,58.9361356358,58.9165262819,58.896959413,
+	58.8774348483,58.8579524084,58.8385119146,58.8191131897,58.7997560573,
+	58.7804403424,58.7611658707,58.7419324694,58.7227399664,58.7035881909,
+	58.684476973,58.665406144,58.6463755361,58.6273849825,58.6084343176,
+	58.5895233766,58.5706519958,58.5518200125,58.533027265,58.5142735925,
+	58.4955588353,58.4768828345,58.4582454322,58.4396464715,58.4210857965,
+	58.402563252,58.384078684,58.3656319393,58.3472228655,58.3288513112,
+	58.310517126,58.2922201602,58.2739602651,58.2557372929,58.2375510965,
+	58.2194015299,58.2012884478,58.1832117056,58.16517116,58.1471666681,
+	58.129198088,58.1112652786,58.0933680997,58.0755064118,58.0576800761,
+	58.039888955,58.0221329113,58.0044118086,57.9867255116,57.9690738855,
+	57.9514567963,57.9338741109,57.9163256968,57.8988114223,57.8813311564,
+	57.8638847691,57.8464721308,57.8290931127,57.8117475869,57.7944354261,
+	57.7771565037,57.7599106939,57.7426978714,57.7255179118,57.7083706914,
+	57.691256087,57.6741739762,57.6571242374,57.6401067494,57.6231213918,
+	57.6061680451,57.58924659,57.5723569081,57.5554988818,57.5386723939,
+	57.5218773279,57.505113568,57.488380999,57.4716795062,57.4550089757,
+	57.4383692942,57.4217603489,57.4051820278,57.3886342192,57.3721168123,
+	57.3556296967,57.3391727627,57.3227459011,57.3063490034,57.2899819617,
+	57.2736446684,57.2573370167,57.2410589004,57.2248102138,57.2085908517,
+	57.1924007095,57.1762396831,57.1601076691,57.1440045645,57.127930267,
+	57.1118846745,57.0958676858,57.0798792,57.063919117,57.0479873368,
+	57.0320837602,57.0162082886,57.0003608236,56.9845412676,56.9687495233,
+	56.952985494,56.9372490836,56.9215401962,56.9058587367,56.8902046103,
+	56.8745777228,56.8589779803,56.8434052895,56.8278595578,56.8123406926,
+	56.796848602,56.7813831948,56.7659443798,56.7505320667,56.7351461652,
+	56.719786586,56.7044532397,56.6891460378,56.6738648919,56.6586097143,
+	56.6433804175,56.6281769146,56.6129991191,56.597846945,56.5827203065,
+	56.5676191185,56.5525432961,56.537492755,56.5224674112,56.507467181,
+	56.4924919814,56.4775417297,56.4626163434,56.4477157406,56.4328398399,
+	56.41798856,56.4031618202,56.3883595402,56.37358164,56.35882804,
+	56.3440986611,56.3293934243,56.3147122514,56.3000550642,56.2854217851,
+	56.2708123367,56.2562266421,56.2416646249,56.2271262086,56.2126113176,
+	56.1981198764,56.1836518097,56.1692070429,56.1547855016,56.1403871117,
+	56.1260117995,56.1116594916,56.097330115,56.0830235971,56.0687398656,
+	56.0544788483,56.0402404738,56.0260246706,56.0118313678,55.9976604948,
+	55.9835119812,55.969385757,55.9552817525,55.9411998985,55.9271401258,
+	55.9131023657,55.89908655,55.8850926104,55.8711204792,55.8571700891,
+	55.8432413727,55.8293342633,55.8154486945,55.8015845998,55.7877419134,
+	55.7739205698,55.7601205035,55.7463416495,55.7325839431,55.7188473199,
+	55.7051317156,55.6914370665,55.677763309,55.6641103798,55.6504782158,
+	55.6368667544,55.6232759331,55.6097056897,55.5961559624,55.5826266896,
+	55.5691178099,55.5556292623,55.542160986,55.5287129205,55.5152850055,
+	55.501877181,55.4884893873,55.475121565,55.4617736549,55.448445598,
+	55.4351373357,55.4218488095,55.4085799613,55.3953307332,55.3821010675,
+	55.3688909069,55.3557001941,55.3425288723,55.3293768848,55.3162441752,
+	55.3031306873,55.2900363653,55.2769611534,55.2639049962,55.2508678385,
+	55.2378496253,55.2248503018,55.2118698137,55.1989081067,55.1859651266,
+	55.1730408198,55.1601351326,55.1472480117,55.134379404,55.1215292566,
+	55.1086975168,55.0958841322,55.0830890507,55.0703122201,55.0575535887,
+	55.0448131049,55.0320907175,55.0193863752,55.0067000272,54.9940316227,
+	54.9813811114,54.9687484428,54.956133567,54.943536434,54.9309569943,
+	54.9183951983,54.9058509969,54.893324341,54.8808151818,54.8683234706,
+	54.8558491591,54.8433921989,54.8309525421,54.8185301409,54.8061249475,
+	54.7937369146,54.7813659949,54.7690121413,54.7566753071,54.7443554455,
+	54.73205251,54.7197664544,54.7074972325,54.6952447985,54.6830091066,
+	54.6707901112,54.6585877671,54.646402029,54.634232852,54.6220801911,
+	54.6099440019,54.5978242398,54.5857208606,54.5736338202,54.5615630746,
+	54.5495085801,54.5374702932,54.5254481704,54.5134421685,54.5014522444,
+	54.4894783554,54.4775204586,54.4655785116,54.4536524719,54.4417422974,
+	54.429847946,54.4179693758,54.4061065451,54.3942594124,54.3824279364,
+	54.3706120757,54.3588117893,54.3470270364,54.3352577761,54.323503968,
+	54.3117655715,54.3000425465,54.2883348527,54.2766424504,54.2649652996,
+	54.2533033607,54.2416565943,54.2300249609,54.2184084215,54.206806937,
+	54.1952204684,54.1836489771,54.1720924245,54.1605507722,54.1490239817,
+	54.1375120151,54.1260148343,54.1145324014,54.1030646788,54.0916116288,
+	54.0801732141,54.0687493974,54.0573401415,54.0459454094,54.0345651643,
+	54.0231993694,54.0118479883,54.0005109843,53.9891883213,53.977879963,
+	53.9665858734,53.9553060167,53.944040357,53.9327888587,53.9215514863,
+	53.9103282045,53.8991189781,53.8879237718,53.8767425508,53.8655752802,
+	53.8544219253,53.8432824515,53.8321568244,53.8210450096,53.8099469729,
+	53.7988626803,53.7877920977,53.7767351915,53.7656919278,53.7546622731,
+	53.7436461939,53.7326436569,53.721654629,53.7106790769,53.6997169678,
+	53.6887682688,53.6778329471,53.6669109702,53.6560023055,53.6451069207,
+	53.6342247836,53.6233558619,53.6125001237,53.6016575371,53.5908280702,
+	53.5800116914,53.5692083692,53.558418072,53.5476407686,53.5368764276,
+	53.5261250181,53.5153865089,53.5046608693,53.4939480683,53.4832480754,
+	53.47256086,53.4618863916,53.4512246399,53.4405755746,53.4299391657,
+	53.419315383,53.4087041967,53.398105577,53.3875194941,53.3769459184,
+	53.3663848205,53.355836171,53.3452999404,53.3347760998,53.3242646199,
+	53.3137654719,53.3032786267,53.2928040557,53.2823417301,53.2718916214,
+	53.261453701,53.2510279406,53.240614312,53.2302127868,53.2198233371,
+	53.2094459348,53.1990805521,53.1887271611,53.1783857341,53.1680562435,
+	53.1577386619,53.1474329617,53.1371391157,53.1268570966,53.1165868773,
+	53.1063284308,53.09608173,53.0858467482,53.0756234586,53.0654118344,
+	53.0552118491,53.0450234762,53.0348466893,53.0246814621,53.0145277683,
+	53.0043855819,52.9942548766,52.9841356267,52.9740278062,52.9639313893,
+	52.9538463503,52.9437726636,52.9337103037,52.9236592451,52.9136194624,
+	52.9035909305,52.8935736241,52.883567518,52.8735725874,52.8635888072,
+	52.8536161525,52.8436545987,52.833704121,52.8237646948,52.8138362956,
+	52.8039188989,52.7940124804,52.7841170158,52.7742324808,52.7643588514,
+	52.7544961035,52.7446442132,52.7348031565,52.7249729097,52.7151534489,
+	52.7053447507,52.6955467913,52.6857595473,52.6759829952,52.6662171118,
+	52.6564618738,52.6467172578,52.636983241,52.6272598001,52.6175469122,
+	52.6078445544,52.598152704,52.5884713381,52.5788004341,52.5691399694,
+	52.5594899214,52.5498502678,52.5402209861,52.5306020539,52.5209934492,
+	52.5113951496,52.5018071332,52.4922293778,52.4826618616,52.4731045626,
+	52.463557459,52.4540205291,52.4444937512,52.4349771037,52.425470565,
+	52.4159741138,52.4064877284,52.3970113878,52.3875450705,52.3780887554,
+	52.3686424213,52.3592060472,52.3497796121,52.340363095,52.3309564751,
+	52.3215597316,52.3121728436,52.3027957907,52.293428552,52.2840711072,
+	52.2747234357,52.2653855171,52.2560573311,52.2467388573,52.2374300756,
+	52.2281309658,52.2188415077,52.2095616814,52.2002914668,52.1910308441,
+	52.1817797934,52.1725382949,52.1633063289,52.1540838757,52.1448709156,
+	52.1356674293,52.1264733971,52.1172887997,52.1081136176,52.0989478315,
+	52.0897914223,52.0806443707,52.0715066576,52.0623782639,52.0532591707,
+	52.0441493588,52.0350488095,52.0259575039,52.0168754232,52.0078025486,
+	51.9987388616,51.9896843435,51.9806389757,51.9716027398,51.9625756172,
+	51.9535575896,51.9445486387,51.9355487462,51.9265578938,51.9175760635,
+	51.908603237,51.8996393962,51.8906845233,51.8817386003,51.8728016091,
+	51.8638735321,51.8549543514,51.8460440492,51.8371426079,51.8282500099,
+	51.8193662375,51.8104912732,51.8016250996,51.7927676992,51.7839190547,
+	51.7750791486,51.7662479639,51.7574254831,51.7486116892,51.7398065651,
+	51.7310100936,51.7222222578,51.7134430406,51.7046724253,51.6959103948,
+	51.6871569323,51.6784120212,51.6696756447,51.660947786,51.6522284287,
+	51.643517556,51.6348151515,51.6261211987,51.6174356812,51.6087585825,
+	51.6000898864,51.5914295766,51.5827776367,51.5741340507,51.5654988023,
+	51.5568718755,51.5482532542,51.5396429225,51.5310408642,51.5224470636,
+	51.5138615047,51.5052841718,51.496715049,51.4881541206,51.4796013709,
+	51.4710567843,51.4625203452,51.453992038,51.4454718472,51.4369597573,
+	51.428455753,51.4199598188,51.4114719394,51.4029920995,51.3945202839,
+	51.3860564773,51.3776006646,51.3691528308,51.3607129606,51.352281039,
+	51.3438570512,51.3354409821,51.3270328167,51.3186325404,51.3102401382,
+	51.3018555953,51.293478897,51.2851100286,51.2767489755,51.268395723,
+	51.2600502566,51.2517125617,51.2433826238,51.2350604285,51.2267459613,
+	51.218439208,51.210140154,51.2018487853,51.1935650874,51.1852890462,
+	51.1770206476,51.1687598773,51.1605067213,51.1522611655,51.1440231959,
+	51.1357927985,51.1275699594,51.1193546647,51.1111469005,51.1029466529,
+	51.0947539083,51.0865686527,51.0783908726,51.0702205543,51.062057684,
+	51.0539022483,51.0457542335,51.0376136261,51.0294804127,51.0213545797,
+	51.0132361137
+	};
+
+
+tubetable_6V6_rtable_0(r) = (tubetable_6V6_0,r):rdtable;
+tubetable_6V6_rtable_1(r) = (tubetable_6V6_1,r):rdtable;
+
+// generated by ../../tools/tube_transfer.py
+// tube: 12AT7
+// plate current function: triode
+// mu: 60
+// kx: 1.35
+// kg1: 460
+// kp: 300
+// kvb: 300
+
+tubetable_12AT7_0 = waveform{
+	223.484971051,223.38189846,223.278606859,223.175096438,223.071367386,
+	222.967419894,222.863254153,222.758870355,222.654268692,222.549449358,
+	222.444412546,222.339158451,222.233687268,222.127999193,222.022094421,
+	221.915973151,221.809635579,221.703081904,221.596312324,221.489327039,
+	221.382126248,221.274710152,221.167078951,221.059232846,220.951172041,
+	220.842896736,220.734407134,220.62570344,220.516785857,220.407654588,
+	220.298309839,220.188751814,220.078980719,219.96899676,219.858800143,
+	219.748391075,219.637769762,219.526936413,219.415891235,219.304634436,
+	219.193166225,219.081486809,218.9695964,218.857495205,218.745183435,
+	218.6326613,218.519929009,218.406986775,218.293834807,218.180473316,
+	218.066902515,217.953122614,217.839133825,217.724936362,217.610530435,
+	217.495916257,217.381094042,217.266064002,217.150826349,217.035381299,
+	216.919729063,216.803869855,216.68780389,216.571531381,216.455052541,
+	216.338367587,216.22147673,216.104380187,215.987078171,215.869570897,
+	215.75185858,215.633941434,215.515819675,215.397493517,215.278963175,
+	215.160228865,215.041290801,214.922149198,214.802804272,214.683256238,
+	214.563505311,214.443551707,214.32339564,214.203037325,214.082476979,
+	213.961714816,213.840751051,213.719585899,213.598219576,213.476652297,
+	213.354884277,213.232915731,213.110746873,212.988377919,212.865809083,
+	212.74304058,212.620072625,212.496905433,212.373539217,212.249974193,
+	212.126210573,212.002248574,211.878088408,211.75373029,211.629174433,
+	211.504421051,211.379470357,211.254322565,211.128977889,211.003436541,
+	210.877698734,210.751764681,210.625634594,210.499308686,210.37278717,
+	210.246070256,210.119158158,209.992051086,209.864749253,209.737252869,
+	209.609562146,209.481677294,209.353598524,209.225326046,209.096860071,
+	208.968200809,208.839348469,208.710303261,208.581065394,208.451635077,
+	208.322012519,208.192197928,208.062191513,207.931993481,207.801604041,
+	207.671023398,207.540251762,207.409289338,207.278136334,207.146792955,
+	207.015259407,206.883535897,206.75162263,206.61951981,206.487227642,
+	206.354746332,206.222076083,206.089217099,205.956169583,205.82293374,
+	205.689509771,205.555897879,205.422098267,205.288111136,205.153936688,
+	205.019575125,204.885026646,204.750291453,204.615369746,204.480261724,
+	204.344967587,204.209487534,204.073821763,203.937970474,203.801933864,
+	203.66571213,203.52930547,203.392714081,203.255938159,203.1189779,
+	202.9818335,202.844505154,202.706993058,202.569297405,202.43141839,
+	202.293356206,202.155111047,202.016683105,201.878072574,201.739279645,
+	201.60030451,201.46114736,201.321808386,201.182287779,201.042585728,
+	200.902702422,200.762638052,200.622392806,200.481966872,200.341360438,
+	200.200573691,200.059606819,199.918460008,199.777133444,199.635627312,
+	199.493941798,199.352077087,199.210033363,199.067810809,198.92540961,
+	198.782829948,198.640072006,198.497135966,198.354022009,198.210730316,
+	198.067261068,197.923614446,197.779790629,197.635789796,197.491612126,
+	197.347257797,197.202726987,197.058019875,196.913136635,196.768077446,
+	196.622842482,196.477431919,196.331845933,196.186084697,196.040148386,
+	195.894037174,195.747751232,195.601290734,195.454655852,195.307846758,
+	195.160863622,195.013706614,194.866375906,194.718871667,194.571194065,
+	194.423343269,194.275319448,194.127122768,193.978753398,193.830211503,
+	193.681497249,193.532610803,193.383552329,193.234321992,193.084919955,
+	192.935346382,192.785601437,192.635685281,192.485598078,192.335339987,
+	192.18491117,192.034311788,191.883542,191.732601966,191.581491845,
+	191.430211795,191.278761974,191.127142539,190.975353646,190.823395453,
+	190.671268115,190.518971788,190.366506625,190.213872781,190.061070409,
+	189.908099664,189.754960697,189.60165366,189.448178705,189.294535983,
+	189.140725644,188.986747838,188.832602715,188.678290424,188.523811112,
+	188.369164928,188.214352019,188.059372531,187.904226611,187.748914404,
+	187.593436056,187.43779171,187.281981512,187.126005604,186.96986413,
+	186.813557231,186.65708505,186.500447728,186.343645406,186.186678223,
+	186.029546321,185.872249837,185.71478891,185.55716368,185.399374282,
+	185.241420854,185.083303532,184.925022452,184.766577751,184.607969561,
+	184.449198018,184.290263255,184.131165406,183.971904602,183.812480977,
+	183.652894661,183.493145785,183.33323448,183.173160876,183.012925102,
+	182.852527286,182.691967557,182.531246043,182.37036287,182.209318165,
+	182.048112054,181.886744663,181.725216116,181.563526537,181.401676051,
+	181.239664781,181.077492849,180.915160377,180.752667487,180.590014299,
+	180.427200936,180.264227515,180.101094157,179.93780098,179.774348102,
+	179.610735642,179.446963716,179.283032441,179.118941932,178.954692305,
+	178.790283676,178.625716158,178.460989865,178.29610491,178.131061407,
+	177.965859466,177.8004992,177.634980719,177.469304135,177.303469556,
+	177.137477092,176.971326852,176.805018943,176.638553475,176.471930553,
+	176.305150284,176.138212774,175.971118129,175.803866452,175.63645785,
+	175.468892424,175.301170279,175.133291517,174.965256239,174.797064548,
+	174.628716544,174.460212328,174.291551999,174.122735656,173.953763399,
+	173.784635325,173.615351532,173.445912117,173.276317175,173.106566804,
+	172.936661098,172.766600153,172.596384061,172.426012917,172.255486814,
+	172.084805844,171.9139701,171.742979672,171.571834651,171.400535128,
+	171.229081192,171.057472933,170.885710438,170.713793796,170.541723094,
+	170.36949842,170.197119859,170.024587497,169.851901419,169.679061711,
+	169.506068455,169.332921736,169.159621635,168.986168237,168.812561622,
+	168.638801872,168.464889067,168.290823288,168.116604613,167.942233123,
+	167.767708895,167.593032007,167.418202536,167.24322056,167.068086154,
+	166.892799395,166.717360356,166.541769112,166.366025738,166.190130307,
+	166.014082891,165.837883563,165.661532395,165.485029456,165.308374819,
+	165.131568552,164.954610726,164.777501409,164.60024067,164.422828575,
+	164.245265193,164.06755059,163.889684831,163.711667983,163.533500109,
+	163.355181276,163.176711545,162.998090981,162.819319646,162.640397602,
+	162.46132491,162.282101632,162.102727828,161.923203558,161.743528881,
+	161.563703855,161.383728539,161.20360299,161.023327265,160.842901421,
+	160.662325513,160.481599598,160.300723728,160.11969796,159.938522345,
+	159.757196938,159.57572179,159.394096954,159.212322481,159.030398422,
+	158.848324827,158.666101745,158.483729225,158.301207317,158.118536068,
+	157.935715525,157.752745735,157.569626745,157.3863586,157.202941345,
+	157.019375024,156.835659683,156.651795363,156.467782109,156.283619962,
+	156.099308963,155.914849155,155.730240578,155.545483271,155.360577274,
+	155.175522626,154.990319366,154.80496753,154.619467157,154.433818283,
+	154.248020943,154.062075174,153.87598101,153.689738486,153.503347636,
+	153.316808491,153.130121087,152.943285453,152.756301622,152.569169625,
+	152.381889493,152.194461254,152.006884938,151.819160575,151.631288191,
+	151.443267815,151.255099474,151.066783193,150.878318999,150.689706918,
+	150.500946973,150.312039189,150.122983589,149.933780197,149.744429035,
+	149.554930124,149.365283487,149.175489143,148.985547114,148.795457417,
+	148.605220074,148.414835102,148.224302518,148.033622341,147.842794587,
+	147.651819272,147.460696413,147.269426023,147.078008117,146.88644271,
+	146.694729815,146.502869444,146.31086161,146.118706324,145.926403598,
+	145.733953442,145.541355866,145.348610879,145.15571849,144.962678708,
+	144.76949154,144.576156994,144.382675075,144.18904579,143.995269144,
+	143.801345143,143.60727379,143.413055089,143.218689043,143.024175656,
+	142.829514928,142.634706862,142.439751458,142.244648717,142.049398638,
+	141.854001221,141.658456465,141.462764367,141.266924924,141.070938135,
+	140.874803995,140.678522501,140.482093647,140.285517428,140.088793838,
+	139.891922871,139.694904521,139.497738779,139.300425637,139.102965087,
+	138.905357119,138.707601724,138.509698892,138.311648611,138.113450871,
+	137.915105658,137.716612961,137.517972767,137.319185062,137.120249831,
+	136.921167061,136.721936735,136.522558838,136.323033353,136.123360263,
+	135.923539552,135.7235712,135.52345519,135.323191502,135.122780116,
+	134.922221012,134.72151417,134.520659568,134.319657184,134.118506996,
+	133.917208981,133.715763115,133.514169375,133.312427735,133.110538172,
+	132.908500658,132.706315168,132.503981676,132.301500154,132.098870574,
+	131.896092908,131.693167128,131.490093204,131.286871106,131.083500803,
+	130.879982266,130.676315463,130.472500361,130.268536929,130.064425133,
+	129.860164941,129.655756317,129.451199229,129.24649364,129.041639516,
+	128.836636821,128.631485518,128.426185571,128.220736941,128.015139592,
+	127.809393485,127.603498581,127.397454841,127.191262225,126.984920693,
+	126.778430205,126.57179072,126.365002195,126.158064589,125.950977859,
+	125.743741963,125.536356858,125.328822499,125.121138842,124.913305843,
+	124.705323458,124.497191639,124.288910343,124.080479522,123.87189913,
+	123.66316912,123.454289445,123.245260057,123.036080908,122.82675195,
+	122.617273133,122.407644409,122.197865728,121.987937041,121.777858298,
+	121.567629447,121.357250439,121.146721222,120.936041745,120.725211957,
+	120.514231806,120.30310124,120.091820207,119.880388654,119.668806528,
+	119.457073777,119.245190347,119.033156186,118.82097124,118.608635455,
+	118.396148777,118.183511154,117.970722531,117.757782854,117.544692069,
+	117.331450122,117.118056958,116.904512525,116.690816767,116.476969631,
+	116.262971063,116.048821008,115.834519413,115.620066224,115.405461388,
+	115.19070485,114.975796559,114.76073646,114.545524502,114.330160631,
+	114.114644796,113.898976945,113.683157025,113.467184988,113.25106078,
+	113.034784354,112.818355658,112.601774644,112.385041264,112.168155469,
+	111.951117213,111.733926449,111.516583131,111.299087215,111.081438657,
+	110.863637413,110.645683442,110.427576702,110.209317154,109.990904759,
+	109.772339479,109.553621277,109.334750119,109.115725972,108.896548803,
+	108.677218581,108.457735278,108.238098866,108.01830932,107.798366617,
+	107.578270734,107.358021653,107.137619356,106.917063827,106.696355055,
+	106.475493028,106.25447774,106.033309184,105.81198736,105.590512267,
+	105.36888391,105.147102295,104.925167434,104.703079339,104.480838028,
+	104.258443522,104.035895848,103.813195034,103.590341113,103.367334124,
+	103.14417411,102.920861118,102.697395202,102.473776418,102.250004831,
+	102.02608051,101.802003529,101.577773971,101.353391923,101.128857479,
+	100.904170741,100.679331818,100.454340825,100.229197888,100.003903138,
+	99.778456717,99.5528587734,99.3271094667,99.1012089653,98.8751574477,
+	98.6489551024,98.4226021292,98.1960987386,97.969445153,97.7426416069,
+	97.5156883471,97.2885856338,97.0613337405,96.833932955,96.6063835797,
+	96.3786859321,96.1508403457,95.9228471705,95.6947067733,95.4664195391,
+	95.2379858709,95.0094061912,94.7806809423,94.5518105871,94.3227956102,
+	94.0936365183,93.8643338415,93.6348881337,93.405299974,93.1755699676,
+	92.9456987464,92.7156869704,92.4855353287,92.2552445406,92.0248153569,
+	91.7942485605,91.5635449686,91.3327054332,91.1017308426,90.8706221232,
+	90.6393802404,90.4080062002,90.1765010512,89.9448658855,89.7131018408,
+	89.4812101019,89.2491919027,89.0170485276,88.784781314,88.5523916537,
+	88.3198809952,88.0872508458,87.8545027735,87.6216384098,87.3886594513,
+	87.1555676628,86.9223648793,86.6890530085,86.4556340339,86.2221100172,
+	85.9884831011,85.7547555124,85.5209295646,85.2870076616,85.0529923004,
+	84.8188860745,84.5846916773,84.3504119056,84.1160496633,83.8816079647,
+	83.647089939,83.4124988332,83.1778380171,82.9431109867,82.7083213689,
+	82.4734729256,82.2385695581,82.0036153116,81.7686143804,81.5335711119,
+	81.2984900118,81.0633757495,80.8282331624,80.5930672616,80.3578832372,
+	80.1226864634,79.8874825043,79.6522771191,79.417076268,79.1818861179,
+	78.946713048,78.7115636561,78.4764447639,78.2413634234,78.0063269226,
+	77.7713427919,77.5364188098,77.3015630089,77.0667836823,76.832089389,
+	76.5974889606,76.3629915064,76.1286064198,75.8943433838,75.6602123765,
+	75.4262236766,75.1923878688,74.9587158488,74.7252188281,74.4919083386,
+	74.2587962373,74.0258947099,73.7932162747,73.5607737859,73.3285804366,
+	73.0966497613,72.8649956377,72.6336322885,72.4025742822,72.1718365333,
+	71.9414343025,71.7113831952,71.4816991604,71.2523984878,71.0234978052,
+	70.7950140739,70.5669645844,70.3393669505,70.1122391024,69.8855992793,
+	69.659466021,69.4338581579,69.2087948004,68.9842953275,68.7603793738,
+	68.5370668156,68.3143777559,68.0923325085,67.8709515808,67.6502556556,
+	67.4302655713,67.2110023025,66.9924869376,66.7747406569,66.5577847094,
+	66.341640388,66.1263290049,65.9118718655,65.6982902415,65.485605344,
+	65.2738382953,65.0630101007,64.8531416195,64.644253536,64.4363663304,
+	64.2295002488,64.0236752742,63.8189110973,63.6152270868,63.4126422611,
+	63.2111752599,63.0108443162,62.8116672294,62.613661339,62.4168434988,
+	62.2212300529,62.026836812,61.8336790312,61.6417713894,61.4511279693,
+	61.2617622392,61.0736870367,60.8869145531,60.7014563202,60.5173231979,
+	60.3345253642,60.1530723064,59.9729728143,59.7942349746,59.6168661678,
+	59.4408730656,59.2662616311,59.0930371202,58.9212040837,58.7507663728,
+	58.5817271438,58.4140888665,58.2478533317,58.0830216621,57.9195943226,
+	57.757571133,57.5969512811,57.437733337,57.2799152681,57.1234944552,
+	56.9684677091,56.8148312878,56.6625809145,56.5117117958,56.3622186407,
+	56.2140956792,56.0673366819,55.9219349798,55.777883483,55.6351747015,
+	55.4938007636,55.3537534367,55.2150241456,55.0776039925,54.9414837759,
+	54.8066540091,54.6731049389,54.5408265635,54.4098086506,54.2800407545,
+	54.1515122329,54.0242122639,53.8981298612,53.7732538906,53.6495730842,
+	53.5270760555,53.4057513131,53.2855872745,53.166572279,53.0486945999,
+	52.9319424571,52.816304028,52.7017674586,52.5883208741,52.4759523889,
+	52.3646501157,52.2544021747,52.1451967025,52.0370218595,51.9298658379,
+	51.8237168688,51.718563229,51.6143932475,51.5111953109,51.4089578697,
+	51.3076694432,51.2073186239,51.1078940829,51.0093845734,50.9117789348,
+	50.815066096,50.7192350793,50.6242750025,50.5301750825,50.4369246372,
+	50.3445130879,50.2529299611,50.1621648909,50.0722076197,49.9830480004,
+	49.894675997,49.8070816859,49.7202552566,49.6341870125,49.5488673716,
+	49.4642868666,49.3804361451,49.2973059702,49.2148872203,49.1331708887,
+	49.052148084,48.9718100296,48.892148063,48.8131536359,48.7348183134,
+	48.6571337734,48.5800918059,48.5036843125,48.4279033056,48.3527409073,
+	48.2781893488,48.2042409693,48.1308882153,48.0581236393,47.9859398991,
+	47.9143297565,47.8432860762,47.772801825,47.7028700705,47.6334839797,
+	47.5646368183,47.4963219495,47.4285328322,47.3612630208,47.2945061629,
+	47.2282559993,47.1625063616,47.0972511721,47.0324844415,46.9682002687,
+	46.9043928391,46.8410564231,46.7781853756,46.7157741343,46.6538172188,
+	46.5923092291,46.5312448446,46.4706188231,46.4104259995,46.3506612843,
+	46.2913196632,46.2323961953,46.1738860123,46.1157843173,46.0580863839,
+	46.0007875547,45.9438832405,45.8873689195,45.8312401357,45.7754924981,
+	45.7201216798,45.665123417,45.6104935076,45.5562278108,45.5023222456,
+	45.4487727904,45.3955754813,45.3427264119,45.2902217321,45.238057647,
+	45.1862304162,45.1347363532,45.0835718238,45.0327332461,44.982217089,
+	44.9320198716,44.8821381626,44.8325685792,44.7833077865,44.7343524964,
+	44.6856994674,44.6373455033,44.5892874528,44.5415222087,44.4940467071,
+	44.4468579267,44.3999528883,44.3533286537,44.3069823257,44.2609110467,
+	44.2151119985,44.1695824018,44.124319515,44.0793206341,44.034583092,
+	43.9901042576,43.9458815358,43.9019123661,43.8581942231,43.8147246147,
+	43.7715010829,43.728521202,43.6857825789,43.6432828524,43.6010196926,
+	43.5589908004,43.5171939069,43.4756267733,43.4342871901,43.3931729766,
+	43.3522819807,43.3116120784,43.2711611731,43.2309271955,43.1909081027,
+	43.1511018785,43.1115065323,43.0721200993,43.0329406393,42.9939662373,
+	42.9551950023,42.9166250673,42.878254589,42.8400817471,42.8021047443,
+	42.7643218057,42.7267311786,42.6893311322,42.6521199569,42.6150959646,
+	42.5782574877,42.5416028795,42.5051305131,42.4688387817,42.4327260982,
+	42.3967908945,42.3610316219,42.32544675,42.2900347672,42.2547941799,
+	42.2197235125,42.184821307,42.1500861227,42.1155165361,42.0811111406,
+	42.0468685461,42.0127873789,41.9788662816,41.9451039126,41.9114989459,
+	41.8780500709,41.8447559925,41.8116154303,41.7786271187,41.7457898069,
+	41.7131022583,41.6805632504,41.6481715748,41.6159260367,41.5838254549,
+	41.5518686617,41.5200545023,41.4883818353,41.4568495316,41.4254564751,
+	41.394201562,41.3630837008,41.3321018122,41.3012548286,41.2705416944,
+	41.2399613655,41.2095128092,41.1791950042,41.1490069403,41.1189476183,
+	41.0890160496,41.0592112567,41.0295322723,40.9999781396,40.970547912,
+	40.9412406531,40.9120554366,40.8829913457,40.8540474735,40.8252229228,
+	40.7965168056,40.7679282435,40.7394563671,40.7111003161,40.6828592393,
+	40.6547322942,40.626718647,40.5988174728,40.5710279548,40.5433492849,
+	40.5157806631,40.4883212976,40.4609704049,40.433727209,40.4065909422,
+	40.3795608443,40.3526361629,40.3258161531,40.2991000774,40.2724872058,
+	40.2459768155,40.2195681909,40.1932606236,40.1670534118,40.1409458612,
+	40.114937284,40.089026999,40.063214332,40.0374986152,40.0118791874,
+	39.9863553935,39.9609265851,39.9355921199,39.9103513619,39.8852036809,
+	39.8601484532,39.8351850605,39.8103128908,39.7855313379,39.7608398011,
+	39.7362376854,39.7117244017,39.6872993662,39.6629620004,39.6387117317,
+	39.6145479924,39.5904702202,39.5664778582,39.5425703542,39.5187471617,
+	39.4950077387,39.4713515484,39.447778059,39.4242867434,39.4008770793,
+	39.3775485493,39.3543006404,39.3311328446,39.3080446582,39.2850355821,
+	39.2621051218,39.2392527869,39.2164780918,39.193780555,39.1711596991,
+	39.1486150512,39.1261461426,39.1037525085,39.0814336882,39.0591892253,
+	39.0370186672,39.0149215651,38.9928974745,38.9709459543,38.9490665676,
+	38.9272588811,38.9055224652,38.883856894,38.8622617454,38.8407366006,
+	38.8192810448,38.7978946663,38.7765770572,38.7553278128,38.7341465321,
+	38.7130328173,38.6919862739,38.6710065108,38.6500931402,38.6292457774,
+	38.608464041,38.5877475528,38.5670959377,38.5465088236,38.5259858415,
+	38.5055266257,38.485130813,38.4647980436,38.4445279604,38.4243202094,
+	38.4041744393,38.3840903017,38.3640674511,38.3441055447,38.3242042424,
+	38.3043632069,38.2845821037,38.2648606009,38.2451983691,38.2255950817,
+	38.2060504147,38.1865640465,38.1671356581,38.1477649333,38.1284515578,
+	38.1091952204,38.0899956119,38.0708524256,38.0517653574,38.0327341052,
+	38.0137583696,37.9948378534,37.9759722615,37.9571613012,37.9384046823,
+	37.9197021164,37.9010533177,37.8824580021,37.8639158882,37.8454266964,
+	37.8269901493,37.8086059716,37.7902738901,37.7719936336,37.753764933,
+	37.7355875212,37.717461133,37.6993855054,37.6813603772,37.6633854891,
+	37.6454605838,37.6275854059,37.6097597018,37.59198322,37.5742557106,
+	37.5565769256,37.5389466189,37.521364546,37.5038304645,37.4863441334,
+	37.4689053137,37.4515137681,37.4341692609,37.4168715581,37.3996204275,
+	37.3824156386,37.3652569623,37.3481441714,37.3310770401,37.3140553445,
+	37.297078862,37.2801473717,37.2632606542,37.2464184918,37.2296206681,
+	37.2128669684,37.1961571795,37.1794910896,37.1628684884,37.1462891671,
+	37.1297529184,37.1132595362,37.0968088162,37.0804005552,37.0640345515,
+	37.0477106048,37.0314285162,37.0151880881,36.9989891244,36.9828314301,
+	36.9667148116,36.9506390768,36.9346040347,36.9186094956,36.9026552713,
+	36.8867411745,36.8708670195,36.8550326217,36.8392377978,36.8234823655,
+	36.807766144,36.7920889536,36.7764506158,36.7608509532,36.7452897896,
+	36.7297669502,36.714282261,36.6988355493,36.6834266436,36.6680553734,
+	36.6527215694,36.6374250634,36.6221656883,36.606943278,36.5917576675,
+	36.5766086929,36.5614961915,36.5464200014,36.5313799619,36.5163759132,
+	36.5014076967,36.4864751547,36.4715781305,36.4567164685,36.4418900139,
+	36.4270986131,36.4123421134,36.3976203629,36.382933211,36.3682805076,
+	36.353662104,36.3390778522,36.324527605,36.3100112165,36.2955285412,
+	36.2810794351,36.2666637545,36.252281357,36.237932101,36.2236158457,
+	36.2093324512,36.1950817784,36.1808636892,36.1666780462,36.152524713,
+	36.1384035538,36.1243144338,36.1102572191,36.0962317763,36.0822379733,
+	36.0682756782,36.0543447604,36.0404450898,36.0265765373,36.0127389743,
+	35.9989322732,35.9851563071,35.9714109499,35.957696076,35.944011561,
+	35.9303572808,35.9167331123,35.903138933,35.8895746213,35.8760400561,
+	35.8625351171,35.8490596847,35.8356136401,35.822196865,35.808809242,
+	35.7954506543,35.7821209857,35.7688201207,35.7555479447,35.7423043434,
+	35.7290892035,35.715902412,35.7027438569,35.6896134267,35.6765110104,
+	35.663436498,35.6503897796,35.6373707465,35.6243792901,35.6114153029,
+	35.5984786777,35.5855693079,35.5726870876,35.5598319116,35.5470036751,
+	35.534202274,35.5214276048,35.5086795644,35.4959580506,35.4832629614,
+	35.4705941957,35.4579516528,35.4453352325,35.4327448353,35.4201803622,
+	35.4076417148,35.3951287951,35.3826415057,35.3701797498,35.3577434311,
+	35.3453324539,35.3329467228,35.3205861432,35.3082506207,35.2959400619,
+	35.2836543733,35.2713934625,35.2591572371,35.2469456055,35.2347584766,
+	35.2225957595,35.2104573643,35.198343201,35.1862531805,35.174187214,
+	35.1621452133,35.1501270905,35.1381327583,35.1261621298,35.1142151186,
+	35.1022916388,35.0903916048,35.0785149317,35.0666615348,35.0548313299,
+	35.0430242335,35.0312401621,35.0194790329,35.0077407637,34.9960252724,
+	34.9843324774,34.9726622977,34.9610146526,34.9493894618,34.9377866455,
+	34.9262061242,34.9146478189,34.903111651,34.8915975423,34.880105415,
+	34.8686351915,34.8571867951,34.845760149,34.8343551769,34.8229718032,
+	34.8116099522,34.800269549,34.7889505189,34.7776527876,34.7663762811,
+	34.7551209259,34.7438866488,34.732673377,34.7214810381,34.7103095599,
+	34.6991588708,34.6880288994,34.6769195746,34.665830826,34.654762583,
+	34.6437147759,34.632687335,34.6216801911,34.6106932752,34.5997265188,
+	34.5887798536,34.5778532119,34.5669465259,34.5560597285,34.5451927529,
+	34.5343455323,34.5235180007,34.5127100921,34.5019217408,34.4911528817,
+	34.4804034497,34.4696733802,34.458962609,34.4482710719,34.4375987053,
+	34.4269454458,34.4163112303,34.405695996,34.3950996804,34.3845222213,
+	34.373963557,34.3634236256,34.3529023661,34.3423997173,34.3319156186,
+	34.3214500095,34.3110028299,34.30057402,34.2901635202,34.2797712711,
+	34.2693972139,34.2590412897,34.2487034402,34.2383836071,34.2280817325,
+	34.2177977589,34.2075316288,34.1972832853,34.1870526713,34.1768397305,
+	34.1666444064,34.1564666431,34.1463063848,34.1361635759,34.1260381613,
+	34.1159300859,34.1058392949,34.0957657339,34.0857093486,34.075670085,
+	34.0656478894,34.0556427083,34.0456544884,34.0356831767,34.0257287205,
+	34.0157910671,34.0058701643,33.9959659601,33.9860784026,33.9762074403,
+	33.9663530217,33.9565150959,33.9466936118,33.9368885189,33.9270997666,
+	33.9173273049,33.9075710837,33.8978310533,33.8881071641,33.8783993668,
+	33.8687076124,33.8590318519,33.8493720367,33.8397281184,33.8301000487,
+	33.8204877797,33.8108912635,33.8013104526,33.7917452996,33.7821957572,
+	33.7726617786,33.763143317,33.7536403258,33.7441527588,33.7346805697,
+	33.7252237126,33.7157821418,33.7063558118,33.6969446771,33.6875486927,
+	33.6781678136,33.6688019951,33.6594511925,33.6501153616,33.6407944581,
+	33.631488438,33.6221972577,33.6129208733,33.6036592416,33.5944123194,
+	33.5851800634,33.575962431,33.5667593793,33.5575708659,33.5483968486,
+	33.539237285,33.5300921334,33.5209613518,33.5118448987,33.5027427327,
+	33.4936548125,33.484581097,33.4755215454,33.4664761168,33.4574447707,
+	33.4484274668,33.4394241647,33.4304348245,33.4214594063,33.4124978703,
+	33.403550177,33.3946162869,33.3856961609,33.3767897599,33.367897045,
+	33.3590179775,33.3501525187,33.3413006302,33.3324622739,33.3236374115,
+	33.3148260051,33.3060280169,33.2972434094,33.2884721449,33.2797141863,
+	33.2709694962,33.2622380377,33.2535197739,33.2448146681,33.2361226837,
+	33.2274437842,33.2187779335,33.2101250953,33.2014852337,33.1928583128,
+	33.184244297,33.1756431507,33.1670548384,33.158479325,33.1499165753,
+	33.1413665542,33.1328292271,33.124304559,33.1157925156,33.1072930624,
+	33.098806165,33.0903317894,33.0818699015,33.0734204674,33.0649834534,
+	33.0565588258,33.0481465513,33.0397465963,33.0313589278,33.0229835126,
+	33.0146203178,33.0062693106,32.9979304582,32.989603728,32.9812890877,
+	32.972986505,32.9646959476,32.9564173834,32.9481507806,32.9398961073,
+	32.9316533318,32.9234224226,32.9152033482,32.9069960773,32.8988005787,
+	32.8906168214,32.8824447742,32.8742844065,32.8661356875,32.8579985866,
+	32.8498730732,32.8417591171,32.833656688,32.8255657557,32.8174862902,
+	32.8094182617,32.8013616402,32.7933163962,32.7852825001,32.7772599223,
+	32.7692486337,32.7612486048,32.7532598067,32.7452822103,32.7373157867,
+	32.7293605071,32.7214163428,32.7134832652,32.705561246,32.6976502567,
+	32.689750269,32.6818612548,32.6739831862,32.666116035,32.6582597736,
+	32.6504143741,32.6425798089,32.6347560506,32.6269430716,32.6191408447,
+	32.6113493427,32.6035685384,32.5957984048,32.588038915,32.5802900421,
+	32.5725517595,32.5648240406,32.5571068587,32.5494001875,32.5417040007,
+	32.5340182719,32.5263429752,32.5186780844,32.5110235735,32.5033794168,
+	32.4957455885,32.4881220628,32.4805088143,32.4729058175,32.4653130469,
+	32.4577304774,32.4501580835,32.4425958404,32.4350437229,32.4275017061,
+	32.4199697652,32.4124478754,32.404936012,32.3974341505,32.3899422665,
+	32.3824603354,32.374988333,32.3675262351,32.3600740175,32.3526316561,
+	32.3451991271,32.3377764065,32.3303634705,32.3229602955,32.3155668577,
+	32.3081831337,32.3008091,32.2934447331,32.2860900099,32.2787449071,
+	32.2714094015,32.2640834702,32.2567670901,32.2494602383,32.2421628922,
+	32.2348750288,32.2275966256,32.22032766,32.2130681096,32.2058179518,
+	32.1985771644,32.1913457251,32.1841236118,32.1769108022,32.1697072745,
+	32.1625130066,32.1553279767,32.148152163,32.1409855437,32.1338280972,
+	32.126679802,32.1195406365,32.1124105793,32.1052896091,32.0981777045,
+	32.0910748445,32.0839810077,32.0768961733,32.0698203201,32.0627534273,
+	32.0556954741,32.0486464396,32.0416063031,32.0345750441,32.0275526419,
+	32.020539076,32.0135343261,32.0065383718,31.9995511928,31.9925727688,
+	31.9856030797,31.9786421055,31.9716898261,31.9647462215,31.957811272,
+	31.9508849576,31.9439672587,31.9370581555,31.9301576284,31.9232656579,
+	31.9163822245,31.9095073088,31.9026408914,31.895782953,31.8889334744,
+	31.8820924364,31.87525982,31.8684356061,31.8616197757,31.8548123099,
+	31.8480131899,31.8412223968,31.834439912,31.8276657168,31.8208997926,
+	31.8141421208,31.8073926829,31.8006514606,31.7939184355,31.7871935893,
+	31.7804769038,31.7737683607,31.7670679419,31.7603756294,31.7536914052,
+	31.7470152514,31.74034715,31.7336870832,31.7270350332,31.7203909824,
+	31.7137549131,31.7071268077,31.7005066486,31.6938944183,31.6872900995,
+	31.6806936748,31.6741051267,31.6675244382,31.6609515919,31.6543865707,
+	31.6478293576,31.6412799354,31.6347382873,31.6282043961,31.6216782452,
+	31.6151598176,31.6086490966,31.6021460655,31.5956507075,31.5891630062,
+	31.5826829449,31.576210507,31.5697456763,31.5632884362,31.5568387704,
+	31.5503966626,31.5439620966,31.5375350561,31.5311155251,31.5247034874,
+	31.5182989269,31.5119018277,31.5055121739,31.4991299494,31.4927551386,
+	31.4863877255,31.4800276945,31.4736750299,31.4673297159,31.4609917371,
+	31.4546610778,31.4483377225,31.4420216558,31.4357128623,31.4294113266,
+	31.4231170334,31.4168299674,31.4105501135,31.4042774564,31.398011981,
+	31.3917536723,31.3855025152,31.3792584947,31.3730215959,31.3667918039,
+	31.3605691038,31.3543534809,31.3481449203,31.3419434074,31.3357489276,
+	31.329561466,31.3233810083,31.3172075399,31.3110410462,31.3048815128,
+	31.2987289254,31.2925832695,31.2864445309,31.2803126952,31.2741877483,
+	31.2680696759,31.261958464,31.2558540983,31.249756565,31.2436658498,
+	31.2375819389,31.2315048184,31.2254344742,31.2193708927,31.2133140599,
+	31.2072639622,31.2012205857,31.1951839169,31.189153942,31.1831306474,
+	31.1771140197,31.1711040452,31.1651007105,31.1591040022,31.1531139068,
+	31.1471304109,31.1411535014,31.1351831648,31.1292193879,31.1232621575,
+	31.1173114605,31.1113672838,31.1054296141,31.0994984385,31.0935737441,
+	31.0876555177,31.0817437464,31.0758384175,31.0699395179,31.0640470349,
+	31.0581609557,31.0522812675,31.0464079577,31.0405410135,31.0346804223,
+	31.0288261716,31.0229782487,31.0171366411,31.0113013363,31.0054723219,
+	30.9996495855,30.9938331146,30.988022897,30.9822189203,30.9764211722,
+	30.9706296405,30.9648443129,30.9590651774,30.9532922218,30.9475254339,
+	30.9417648017
+	};
+
+tubetable_12AT7_1 = waveform{
+	223.484971051,223.38189846,223.278606859,223.175096438,223.071367386,
+	222.967419894,222.863254153,222.758870355,222.654268692,222.549449358,
+	222.444412546,222.339158451,222.233687268,222.127999193,222.022094421,
+	221.915973151,221.809635579,221.703081904,221.596312324,221.489327039,
+	221.382126248,221.274710152,221.167078951,221.059232846,220.951172041,
+	220.842896736,220.734407134,220.62570344,220.516785857,220.407654588,
+	220.298309839,220.188751814,220.078980719,219.96899676,219.858800143,
+	219.748391075,219.637769762,219.526936413,219.415891235,219.304634436,
+	219.193166225,219.081486809,218.9695964,218.857495205,218.745183435,
+	218.6326613,218.519929009,218.406986775,218.293834807,218.180473316,
+	218.066902515,217.953122614,217.839133825,217.724936362,217.610530435,
+	217.495916257,217.381094042,217.266064002,217.150826349,217.035381299,
+	216.919729063,216.803869855,216.68780389,216.571531381,216.455052541,
+	216.338367587,216.22147673,216.104380187,215.987078171,215.869570897,
+	215.75185858,215.633941434,215.515819675,215.397493517,215.278963175,
+	215.160228865,215.041290801,214.922149198,214.802804272,214.683256238,
+	214.563505311,214.443551707,214.32339564,214.203037325,214.082476979,
+	213.961714816,213.840751051,213.719585899,213.598219576,213.476652297,
+	213.354884277,213.232915731,213.110746873,212.988377919,212.865809083,
+	212.74304058,212.620072625,212.496905433,212.373539217,212.249974193,
+	212.126210573,212.002248574,211.878088408,211.75373029,211.629174433,
+	211.504421051,211.379470357,211.254322565,211.128977889,211.003436541,
+	210.877698734,210.751764681,210.625634594,210.499308686,210.37278717,
+	210.246070256,210.119158158,209.992051086,209.864749253,209.737252869,
+	209.609562146,209.481677294,209.353598524,209.225326046,209.096860071,
+	208.968200809,208.839348469,208.710303261,208.581065394,208.451635077,
+	208.322012519,208.192197928,208.062191513,207.931993481,207.801604041,
+	207.671023398,207.540251762,207.409289338,207.278136334,207.146792955,
+	207.015259407,206.883535897,206.75162263,206.61951981,206.487227642,
+	206.354746332,206.222076083,206.089217099,205.956169583,205.82293374,
+	205.689509771,205.555897879,205.422098267,205.288111136,205.153936688,
+	205.019575125,204.885026646,204.750291453,204.615369746,204.480261724,
+	204.344967587,204.209487534,204.073821763,203.937970474,203.801933864,
+	203.66571213,203.52930547,203.392714081,203.255938159,203.1189779,
+	202.9818335,202.844505154,202.706993058,202.569297405,202.43141839,
+	202.293356206,202.155111047,202.016683105,201.878072574,201.739279645,
+	201.60030451,201.46114736,201.321808386,201.182287779,201.042585728,
+	200.902702422,200.762638052,200.622392806,200.481966872,200.341360438,
+	200.200573692,200.059606819,199.918460008,199.777133444,199.635627312,
+	199.493941798,199.352077087,199.210033363,199.067810809,198.92540961,
+	198.782829948,198.640072006,198.497135966,198.354022009,198.210730316,
+	198.067261068,197.923614446,197.779790629,197.635789796,197.491612126,
+	197.347257797,197.202726987,197.058019875,196.913136635,196.768077446,
+	196.622842482,196.477431919,196.331845933,196.186084697,196.040148386,
+	195.894037174,195.747751232,195.601290734,195.454655852,195.307846758,
+	195.160863622,195.013706614,194.866375906,194.718871667,194.571194065,
+	194.423343269,194.275319448,194.127122768,193.978753398,193.830211503,
+	193.681497249,193.532610803,193.383552329,193.234321992,193.084919955,
+	192.935346382,192.785601437,192.635685281,192.485598078,192.335339987,
+	192.18491117,192.034311788,191.883542,191.732601966,191.581491845,
+	191.430211795,191.278761974,191.127142539,190.975353646,190.823395454,
+	190.671268116,190.518971788,190.366506625,190.213872781,190.06107041,
+	189.908099664,189.754960697,189.60165366,189.448178705,189.294535983,
+	189.140725644,188.986747838,188.832602716,188.678290424,188.523811112,
+	188.369164928,188.214352019,188.059372531,187.904226611,187.748914404,
+	187.593436056,187.43779171,187.281981512,187.126005604,186.96986413,
+	186.813557231,186.65708505,186.500447728,186.343645406,186.186678223,
+	186.029546321,185.872249837,185.714788911,185.55716368,185.399374282,
+	185.241420854,185.083303532,184.925022453,184.766577751,184.607969561,
+	184.449198018,184.290263255,184.131165406,183.971904603,183.812480977,
+	183.652894661,183.493145785,183.333234481,183.173160876,183.012925102,
+	182.852527286,182.691967558,182.531246043,182.37036287,182.209318165,
+	182.048112055,181.886744663,181.725216116,181.563526538,181.401676052,
+	181.239664781,181.077492849,180.915160377,180.752667487,180.5900143,
+	180.427200936,180.264227516,180.101094157,179.937800981,179.774348103,
+	179.610735643,179.446963717,179.283032441,179.118941933,178.954692306,
+	178.790283677,178.625716159,178.460989866,178.296104912,178.131061408,
+	177.965859467,177.800499201,177.634980721,177.469304136,177.303469557,
+	177.137477093,176.971326853,176.805018945,176.638553477,176.471930555,
+	176.305150286,176.138212776,175.971118131,175.803866455,175.636457852,
+	175.468892427,175.301170281,175.133291519,174.965256242,174.797064551,
+	174.628716547,174.460212331,174.291552002,174.12273566,173.953763402,
+	173.784635329,173.615351536,173.44591212,173.276317179,173.106566808,
+	172.936661103,172.766600157,172.596384066,172.426012922,172.255486819,
+	172.084805849,171.913970105,171.742979677,171.571834657,171.400535134,
+	171.229081198,171.057472939,170.885710445,170.713793803,170.541723102,
+	170.369498428,170.197119867,170.024587505,169.851901428,169.67906172,
+	169.506068464,169.332921745,169.159621646,168.986168248,168.812561633,
+	168.638801884,168.464889079,168.2908233,168.116604626,167.942233136,
+	167.767708909,167.593032021,167.418202552,167.243220576,167.068086171,
+	166.892799412,166.717360374,166.541769131,166.366025758,166.190130327,
+	166.014082912,165.837883585,165.661532417,165.48502948,165.308374843,
+	165.131568578,164.954610753,164.777501437,164.600240698,164.422828605,
+	164.245265224,164.067550622,163.889684865,163.711668018,163.533500146,
+	163.355181313,163.176711584,162.998091022,162.819319688,162.640397646,
+	162.461324957,162.28210168,162.102727878,161.92320361,161.743528935,
+	161.563703911,161.383728597,161.203603051,161.023327328,160.842901487,
+	160.662325582,160.481599669,160.300723803,160.119698037,159.938522426,
+	159.757197022,159.575721877,159.394097045,159.212322576,159.03039852,
+	158.848324929,158.666101851,158.483729336,158.301207432,158.118536187,
+	157.935715649,157.752745864,157.569626879,157.38635874,157.20294149,
+	157.019375176,156.83565984,156.651795527,156.467782279,156.283620139,
+	156.099309148,155.914849347,155.730240777,155.545483478,155.36057749,
+	155.175522851,154.9903196,154.804967774,154.61946741,154.433818546,
+	154.248021217,154.062075459,153.875981307,153.689738795,153.503347956,
+	153.316808825,153.130121434,152.943285814,152.756301998,152.569170017,
+	152.3818899,152.194461677,152.006885379,151.819161033,151.631288668,
+	151.443268311,151.25509999,151.06678373,150.878319558,150.689707498,
+	150.500947577,150.312039817,150.122984243,149.933780877,149.744429742,
+	149.55493086,149.365284253,149.17548994,148.985547943,148.79545828,
+	148.605220971,148.414836035,148.224303489,148.033623351,147.842795638,
+	147.651820366,147.46069755,147.269427206,147.078009348,146.886443991,
+	146.694731147,146.50287083,146.310863051,146.118707824,145.926405158,
+	145.733955065,145.541357554,145.348612635,145.155720318,144.962680609,
+	144.769493518,144.576159051,144.382677215,144.189048016,143.995271461,
+	143.801347552,143.607276296,143.413057696,143.218691756,143.024178478,
+	142.829517864,142.634709916,142.439754635,142.244652022,142.049402077,
+	141.854004798,141.658460186,141.462768238,141.266928951,141.070942324,
+	140.874808353,140.678527034,140.482098363,140.285522334,140.088798942,
+	139.891928181,139.694910044,139.497744525,139.300431614,139.102971305,
+	138.905363588,138.707608454,138.509705892,138.311655894,138.113458446,
+	137.915113539,137.71662116,137.517981296,137.319193934,137.120259061,
+	136.921176662,136.721946723,136.522569228,136.323044162,136.123371508,
+	135.923551249,135.723583369,135.523467849,135.32320467,135.122793815,
+	134.922235263,134.721528995,134.52067499,134.319673227,134.118523685,
+	133.917226342,133.715781176,133.514188163,133.31244728,133.110558503,
+	132.908521808,132.70633717,132.504004564,132.301523963,132.098895342,
+	131.896118674,131.693193931,131.490121086,131.286900111,131.083530977,
+	130.880013655,130.676348115,130.472534329,130.268572264,130.064461891,
+	129.860203179,129.655796095,129.451240608,129.246536686,129.041684295,
+	128.836683403,128.631533975,128.426235979,128.220789379,128.015194141,
+	127.80945023,127.603557611,127.397516247,127.191326104,126.984987144,
+	126.778499331,126.571862629,126.365076999,126.158142404,125.951058808,
+	125.74382617,125.536444455,125.328913622,125.121233634,124.913404451,
+	124.705426035,124.497298346,124.289021346,124.080594993,123.87201925,
+	123.663294075,123.45441943,123.245395274,123.036221568,122.826898272,
+	122.617425345,122.407802748,122.198030441,121.988108384,121.778036537,
+	121.567814861,121.357443316,121.146921862,120.936250462,120.725429075,
+	120.514457662,120.303336187,120.09206461,119.880642893,119.669071,
+	119.457348893,119.245476537,119.033453894,118.821280929,118.608957608,
+	118.396483896,118.18385976,117.971085166,117.758160083,117.545084479,
+	117.331858324,117.118481589,116.904954244,116.691276262,116.477447617,
+	116.263468283,116.049338237,115.835057456,115.620625918,115.406043603,
+	115.191310494,114.976426573,114.761391825,114.546206237,114.330869797,
+	114.115382497,113.899744328,113.683955284,113.468015365,113.251924567,
+	113.035682894,112.819290349,112.60274694,112.386052677,112.169207573,
+	111.952211643,111.735064908,111.517767389,111.300319114,111.082720112,
+	110.864970417,110.647070067,110.429019104,110.210817576,109.992465532,
+	109.77396303,109.55531013,109.336506899,109.117553408,108.898449735,
+	108.679195963,108.459792182,108.240238489,108.020534985,107.800681781,
+	107.580678994,107.360526749,107.140225178,106.919774422,106.69917463,
+	106.478425962,106.257528585,106.036482676,105.815288423,105.593946025,
+	105.372455689,105.150817638,104.929032102,104.707099327,104.48501957,
+	104.262793102,104.040420207,103.817901185,103.595236351,103.372426033,
+	103.149470578,102.926370349,102.703125726,102.479737108,102.256204914,
+	102.032529581,101.808711566,101.58475135,101.360649435,101.136406344,
+	100.912022628,100.687498859,100.462835637,100.23803359,100.013093371,
+	99.7880156641,99.5628011832,99.3374506734,99.1119649126,98.8863447123,
+	98.6605909195,98.4347044173,98.2086861271,97.9825370096,97.7562580661,
+	97.5298503407,97.3033149214,97.076652942,96.8498655839,96.6229540776,
+	96.3959197048,96.1687638004,95.9414877543,95.7140930135,95.4865810843,
+	95.2589535346,95.0312119958,94.8033581658,94.5753938109,94.3473207683,
+	94.1191409492,93.8908563411,93.6624690106,93.4339811063,93.205394862,
+	92.9767125993,92.7479367311,92.5190697648,92.2901143054,92.0610730592,
+	91.8319488373,91.602744559,91.373463256,91.1441080758,90.9146822859,
+	90.6851892779,90.4556325714,90.2260158187,89.9963428088,89.7666174721,
+	89.536843885,89.3070262745,89.0771690233,88.8472766741,88.6173539356,
+	88.3874056866,88.1574369818,87.9274530572,87.697459335,87.4674614297,
+	87.237465153,87.0074765201,86.7775017551,86.5475472965,86.3176198036,
+	86.087726162,85.8578734896,85.6280691424,85.3983207206,85.1686360744,
+	84.9390233102,84.7094907959,84.4800471675,84.2507013342,84.0214624844,
+	83.7923400915,83.5633439187,83.334484025,83.1057707701,82.8772148192,
+	82.6488271479,82.4206190466,82.1926021248,81.9647883147,81.7371898752,
+	81.5098193947,81.282689794,81.0558143286,80.8292065906,80.6028805099,
+	80.3768503551,80.1511307336,79.9257365914,79.7006832114,79.4759862124,
+	79.2516615459,79.0277254929,78.80419466,78.5810859742,78.3584166771,
+	78.1362043179,77.914466746,77.6932221017,77.4724888073,77.2522855555,
+	77.0326312982,76.8135452334,76.5950467914,76.3771556195,76.1598915665,
+	75.943274665,75.7273251137,75.5120632578,75.297509569,75.0836846242,
+	74.8706090831,74.6583036656,74.4467891271,74.2360862344,74.0262157397,
+	73.8171983546,73.609054723,73.4018053941,73.195470794,72.9900711983,
+	72.7856267028,72.5821571954,72.3796823271,72.1782214839,71.9777937575,
+	71.7784179177,71.5801123841,71.3828951991,71.1867840008,70.9917959968,
+	70.7979479394,70.6052561006,70.413736249,70.2234036275,70.0342729319,
+	69.8463582915,69.6596732499,69.4742307486,69.2900431108,69.1071220272,
+	68.925478544,68.7451230512,68.5660652733,68.3883142621,68.2118783899,
+	68.0367653452,67.8629821298,67.6905350579,67.5194297558,67.349671164,
+	67.1812635406,67.0142104662,66.8485148499,66.6841789368,66.5212043171,
+	66.359591936,66.1993421046,66.0404545127,65.8829282415,65.7267617781,
+	65.5719530301,65.4184993417,65.2663975098,65.1156438011,64.9662339694,
+	64.8181632736,64.6714264963,64.5260179616,64.3819315545,64.2391607398,
+	64.0976985804,63.9575377573,63.8186705879,63.6810890449,63.5447847755,
+	63.4097491195,63.2759731279,63.1434475806,63.0121630047,62.8821096914,
+	62.7532777134,62.6256569412,62.4992370596,62.3740075834,62.2499578725,
+	62.1270771474,62.0053545027,61.8847789218,61.7653392897,61.6470244065,
+	61.5298229991,61.4137237339,61.2987152275,61.1847860581,61.0719247757,
+	60.9601199122,60.8493599906,60.7396335345,60.630929076,60.5232351645,
+	60.4165403737,60.3108333094,60.2061026159,60.1023369826,59.9995251502,
+	59.8976559158,59.7967181389,59.6967007458,59.5975927344,59.4993831786,
+	59.4020612319,59.3056161312,59.2100372005,59.1153138535,59.0214355966,
+	58.9283920315,58.8361728577,58.7447678742,58.6541669817,58.5643601843,
+	58.4753375907,58.3870894158,58.2996059815,58.2128777181,58.1268951645,
+	58.0416489694,57.9571298914,57.8733287998,57.7902366743,57.7078446055,
+	57.6261437948,57.5451255545,57.4647813073,57.3851025863,57.3060810344,
+	57.2277084041,57.1499765569,57.0728774627,56.9964031993,56.9205459515,
+	56.8452980105,56.7706517731,56.6965997408,56.6231345189,56.5502488157,
+	56.4779354416,56.4061873078,56.3349974256,56.2643589053,56.1942649551,
+	56.12470888,56.0556840808,55.9871840529,55.9192023854,55.8517327594,
+	55.7847689478,55.7183048131,55.6523343072,55.5868514695,55.5218504263,
+	55.4573253892,55.3932706543,55.3296806009,55.2665496903,55.2038724646,
+	55.1416435458,55.0798576345,55.0185095087,54.9575940229,54.8971061066,
+	54.8370407637,54.7773930709,54.718158177,54.6593313016,54.6009077341,
+	54.5428828326,54.4852520229,54.4280107972,54.3711547138,54.3146793951,
+	54.2585805273,54.2028538591,54.147495201,54.092500424,54.0378654587,
+	53.9835862945,53.9296589787,53.8760796154,53.8228443647,53.7699494418,
+	53.7173911161,53.6651657104,53.6132695999,53.5616992114,53.5104510228,
+	53.4595215617,53.408907405,53.358605178,53.3086115536,53.2589232516,
+	53.2095370379,53.1604497237,53.1116581648,53.0631592611,53.0149499554,
+	52.9670272332,52.9193881217,52.8720296893,52.8249490449,52.7781433372,
+	52.7316097539,52.6853455215,52.6393479043,52.5936142039,52.5481417587,
+	52.5029279432,52.4579701673,52.4132658761,52.3688125489,52.3246076991,
+	52.2806488732,52.2369336506,52.193459643,52.1502244938,52.1072258777,
+	52.0644615,52.0219290964,51.9796264325,51.9375513029,51.8957015313,
+	51.8540749699,51.8126694984,51.7714830245,51.7305134827,51.6897588342,
+	51.6492170664,51.6088861928,51.568764252,51.5288493078,51.4891394485,
+	51.4496327869,51.4103274594,51.3712216261,51.3323134703,51.2936011979,
+	51.2550830374,51.2167572394,51.1786220761,51.1406758414,51.1029168502,
+	51.065343438,51.0279539611,50.9907467956,50.9537203379,50.9168730035,
+	50.8802032274,50.8437094637,50.8073901849,50.7712438821,50.7352690645,
+	50.6994642591,50.6638280107,50.6283588811,50.5930554497,50.5579163121,
+	50.522940081,50.4881253853,50.4534708698,50.4189751955,50.3846370388,
+	50.3504550916,50.3164280609,50.2825546688,50.2488336522,50.2152637622,
+	50.1818437647,50.1485724393,50.1154485799,50.0824709937,50.0496385019,
+	50.0169499386,49.9844041515,49.9520000008,49.9197363597,49.8876121142,
+	49.8556261623,49.8237774146,49.7920647936,49.7604872338,49.7290436813,
+	49.6977330941,49.6665544412,49.6355067033,49.6045888718,49.5737999493,
+	49.5431389491,49.5126048954,49.4821968226,49.4519137756,49.4217548096,
+	49.3917189898,49.3618053914,49.3320130994,49.3023412085,49.2727888229,
+	49.2433550565,49.2140390322,49.1848398821,49.1557567476,49.1267887789,
+	49.0979351349,49.0691949835,49.040567501,49.0120518721,48.9836472901,
+	48.9553529564,48.9271680807,48.8990918806,48.8711235817,48.8432624174,
+	48.815507629,48.7878584653,48.7603141827,48.732874045,48.7055373233,
+	48.6783032962,48.6511712493,48.6241404752,48.5972102736,48.5703799512,
+	48.5436488213,48.517016204,48.4904814261,48.464043821,48.4377027285,
+	48.4114574948,48.3853074723,48.35925202,48.3332905028,48.3074222917,
+	48.2816467637,48.2559633019,48.2303712951,48.204870138,48.179459231,
+	48.1541379801,48.1289057971,48.103762099,48.0787063085,48.0537378537,
+	48.0288561678,48.0040606896,47.9793508627,47.9547261362,47.9301859641,
+	47.9057298055,47.8813571243,47.8570673896,47.832860075,47.8087346591,
+	47.7846906251,47.7607274611,47.7368446597,47.7130417179,47.6893181375,
+	47.6656734245,47.6421070895,47.6186186475,47.5952076176,47.5718735233,
+	47.5486158923,47.5254342566,47.5023281519,47.4792971185,47.4563407004,
+	47.4334584457,47.4106499063,47.3879146382,47.3652522011,47.3426621586,
+	47.3201440779,47.2976975301,47.27532209,47.2530173358,47.2307828496,
+	47.2086182168,47.1865230265,47.1644968713,47.142539347,47.1206500531,
+	47.0988285923,47.0770745708,47.0553875978,47.033767286,47.0122132513,
+	46.9907251128,46.9693024927,46.9479450163,46.926652312,46.9054240114,
+	46.884259749,46.8631591622,46.8421218916,46.8211475806,46.8002358755,
+	46.7793864255,46.7585988825,46.7378729014,46.7172081399,46.6966042582,
+	46.6760609195,46.6555777895,46.6351545368,46.6147908322,46.5944863497,
+	46.5742407654,46.5540537582,46.5339250095,46.5138542031,46.4938410254,
+	46.4738851652,46.4539863139,46.434144165,46.4143584145,46.394628761,
+	46.374954905,46.3553365498,46.3357734005,46.3162651648,46.2968115526,
+	46.2774122759,46.258067049,46.2387755882,46.2195376123,46.200352842,
+	46.181221,46.1621418113,46.143115003,46.124140304,46.1052174456,
+	46.0863461607,46.0675261845,46.0487572541,46.0300391084,46.0113714885,
+	45.9927541372,45.9741867993,45.9556692215,45.9372011522,45.9187823419,
+	45.9004125427,45.8820915086,45.8638189954,45.8455947607,45.8274185639,
+	45.8092901659,45.7912093296,45.7731758195,45.7551894018,45.7372498443,
+	45.7193569166,45.7015103899,45.683710037,45.6659556324,45.648246952,
+	45.6305837735,45.6129658761,45.5953930405,45.5778650491,45.5603816856,
+	45.5429427354,45.5255479853,45.5081972237,45.4908902404,45.4736268266,
+	45.4564067751,45.4392298799,45.4220959367,45.4050047424,45.3879560955,
+	45.3709497956,45.3539856439,45.3370634429,45.3201829964,45.3033441096,
+	45.286546589,45.2697902423,45.2530748788,45.2364003088,45.2197663439,
+	45.2031727971,45.1866194827,45.170106216,45.1536328136,45.1371990936,
+	45.120804875,45.1044499781,45.0881342244,45.0718574366,45.0556194386,
+	45.0394200553,45.0232591129,45.0071364388,44.9910518613,44.97500521,
+	44.9589963155,44.9430250097,44.9270911254,44.9111944966,44.8953349582,
+	44.8795123463,44.8637264982,44.8479772519,44.8322644468,44.816587923,
+	44.8009475218,44.7853430856,44.7697744577,44.7542414822,44.7387440046,
+	44.7232818711,44.7078549288,44.6924630261,44.677106012,44.6617837367,
+	44.6464960512,44.6312428075,44.6160238584,44.6008390578,44.5856882605,
+	44.570571322,44.5554880988,44.5404384485,44.5254222292,44.5104393001,
+	44.4954895213,44.4805727536,44.4656888589,44.4508376997,44.4360191394,
+	44.4212330422,44.4064792734,44.3917576987,44.3770681849,44.3624105996,
+	44.347784811,44.3331906883,44.3186281014,44.3040969209,44.2895970184,
+	44.2751282661,44.2606905369,44.2462837046,44.2319076438,44.2175622296,
+	44.2032473381,44.188962846,44.1747086307,44.1604845704,44.1462905441,
+	44.1321264312,44.1179921121,44.1038874679,44.0898123802,44.0757667314,
+	44.0617504046,44.0477632835,44.0338052526,44.0198761971,44.0059760025,
+	43.9921045555,43.978261743,43.9644474528,43.9506615732,43.9369039933,
+	43.9231746028,43.9094732918,43.8957999513,43.8821544728,43.8685367485,
+	43.854946671,43.8413841338,43.8278490309,43.8143412567,43.8008607064,
+	43.7874072758,43.7739808611,43.7605813594,43.747208668,43.733862685,
+	43.720543309,43.7072504393,43.6939839756,43.6807438181,43.6675298677,
+	43.6543420258,43.6411801944,43.628044276,43.6149341734,43.6018497904,
+	43.5887910309,43.5757577997,43.5627500017,43.5497675426,43.5368103287,
+	43.5238782665,43.5109712632,43.4980892264,43.4852320645,43.4723996859,
+	43.459592,43.4468089162,43.4340503448,43.4213161963,43.4086063818,
+	43.395920813,43.3832594017,43.3706220606,43.3580087026,43.3454192411,
+	43.33285359,43.3203116637,43.3077933769,43.2952986449,43.2828273833,
+	43.2703795084,43.2579549366,43.2455535849,43.2331753709,43.2208202124,
+	43.2084880276,43.1961787354,43.1838922548,43.1716285054,43.1593874071,
+	43.1471688805,43.1349728462,43.1227992256,43.1106479402,43.0985189119,
+	43.0864120634,43.0743273173,43.0622645969,43.0502238257,43.0382049278,
+	43.0262078276,43.0142324497,43.0022787194,42.9903465622,42.9784359039,
+	42.9665466709,42.9546787897,42.9428321874,42.9310067914,42.9192025293,
+	42.9074193294,42.89565712,42.88391583,42.8721953886,42.8604957252,
+	42.8488167698,42.8371584525,42.825520704,42.8139034551,42.8023066371,
+	42.7907301817,42.7791740206,42.7676380862,42.7561223111,42.7446266282,
+	42.7331509707,42.7216952722,42.7102594667,42.6988434883,42.6874472716,
+	42.6760707514,42.664713863,42.6533765417,42.6420587235,42.6307603444,
+	42.6194813408,42.6082216494,42.5969812074,42.5857599519,42.5745578207,
+	42.5633747516,42.5522106829,42.5410655531,42.529939301,42.5188318657,
+	42.5077431866,42.4966732034,42.485621856,42.4745890847,42.4635748299,
+	42.4525790326,42.4416016337,42.4306425747,42.4197017972,42.4087792431,
+	42.3978748545,42.3869885739,42.3761203441,42.365270108,42.3544378088,
+	42.3436233901,42.3328267957,42.3220479695,42.3112868559,42.3005433995,
+	42.2898175449,42.2791092374,42.2684184221,42.2577450447,42.2470890509,
+	42.2364503869,42.2258289989,42.2152248334,42.2046378373,42.1940679577,
+	42.1835151416,42.1729793368,42.1624604909,42.1519585519,42.1414734681,
+	42.1310051879,42.1205536599,42.1101188331,42.0997006567,42.08929908,
+	42.0789140527,42.0685455244,42.0581934454,42.0478577658,42.0375384362,
+	42.0272354073,42.0169486299,42.0066780553,41.9964236349,41.9861853201,
+	41.9759630629,41.9657568151,41.955566529,41.9453921571,41.935233652,
+	41.9250909665,41.9149640537,41.9048528668,41.8947573593,41.8846774848,
+	41.8746131972,41.8645644507,41.8545311993,41.8445133977,41.8345110004,
+	41.8245239623,41.8145522385,41.8045957842,41.7946545548,41.784728506,
+	41.7748175936,41.7649217736,41.7550410021,41.7451752356,41.7353244307,
+	41.725488544,41.7156675325,41.7058613534,41.696069964,41.6862933217,
+	41.6765313841,41.6667841092,41.657051455,41.6473333796,41.6376298415,
+	41.6279407991,41.6182662112,41.6086060367,41.5989602347,41.5893287644,
+	41.5797115852,41.5701086567,41.5605199386,41.5509453909,41.5413849736,
+	41.531838647,41.5223063714,41.5127881076,41.5032838162,41.493793458,
+	41.4843169943,41.4748543861,41.4654055949,41.4559705822,41.4465493097,
+	41.4371417393,41.427747833,41.4183675529,41.4090008614,41.3996477209,
+	41.3903080941,41.3809819438,41.3716692328,41.3623699242,41.3530839814,
+	41.3438113676,41.3345520464,41.3253059814,41.3160731366,41.3068534757,
+	41.2976469631,41.2884535628,41.2792732394,41.2701059573,41.2609516812,
+	41.251810376,41.2426820066,41.2335665381,41.2244639357,41.2153741649,
+	41.2062971912,41.1972329801,41.1881814975,41.1791427094,41.1701165817,
+	41.1611030807,41.1521021727,41.1431138241,41.1341380016,41.1251746718,
+	41.1162238016,41.1072853581,41.0983593082,41.0894456193,41.0805442586,
+	41.0716551938,41.0627783924,41.0539138221,41.0450614508,41.0362212466,
+	41.0273931776,41.0185772119,41.0097733179,41.0009814642,40.9922016194,
+	40.9834337521,40.9746778312,40.9659338257,40.9572017046,40.9484814373,
+	40.9397729929,40.931076341,40.9223914511,40.9137182928,40.905056836,
+	40.8964070505,40.8877689064,40.8791423738,40.8705274229,40.8619240242,
+	40.853332148,40.8447517649,40.8361828457,40.8276253611,40.8190792821,
+	40.8105445796,40.8020212248,40.7935091889,40.7850084433,40.7765189594,
+	40.7680407088,40.7595736631,40.7511177941,40.7426730737,40.7342394738,
+	40.7258169666,40.7174055242,40.7090051189,40.7006157231,40.6922373093,
+	40.68386985,40.6755133181,40.6671676862,40.6588329272,40.6505090143,
+	40.6421959203,40.6338936187,40.6256020825,40.6173212853,40.6090512004,
+	40.6007918016,40.5925430624,40.5843049567,40.5760774582,40.567860541,
+	40.5596541792,40.5514583468,40.5432730181,40.5350981675,40.5269337693,
+	40.5187797982,40.5106362286,40.5025030354,40.4943801934,40.4862676773,
+	40.4781654622,40.4700735231,40.4619918353,40.4539203738,40.4458591142,
+	40.4378080318,40.429767102,40.4217363005,40.4137156031,40.4057049853,
+	40.3977044232,40.3897138925,40.3817333695,40.37376283,40.3658022505,
+	40.357851607,40.3499108761,40.3419800341,40.3340590575,40.3261479229,
+	40.3182466072,40.3103550869,40.302473339,40.2946013404,40.2867390681,
+	40.2788864992,40.2710436109,40.2632103804,40.2553867851,40.2475728023,
+	40.2397684096,40.2319735845,40.2241883047,40.2164125479,40.2086462918,
+	40.2008895143,40.1931421935,40.1854043073,40.1776758338,40.1699567512,
+	40.1622470377,40.1545466718,40.1468556316,40.1391738959,40.131501443,
+	40.1238382516,40.1161843004,40.1085395682,40.1009040337,40.093277676,
+	40.0856604739,40.0780524066,40.0704534531,40.0628635927,40.0552828046,
+	40.0477110681,40.0401483626,40.0325946677,40.0250499628,40.0175142275,
+	40.0099874416,40.0024695847,39.9949606367,39.9874605775,39.979969387,
+	39.9724870452,39.9650135322,39.9575488282,39.9500929133,39.9426457678,
+	39.9352073722,39.9277777067,39.9203567518,39.9129444882,39.9055408964,
+	39.898145957,39.8907596508,39.8833819586,39.8760128612,39.8686523396,
+	39.8613003748,39.8539569477,39.8466220395,39.8392956313,39.8319777044,
+	39.8246682402,39.8173672198,39.8100746247,39.8027904365,39.7955146366,
+	39.7882472066,39.7809881283,39.7737373832,39.7664949532,39.75926082,
+	39.7520349657,39.7448173721,39.7376080212,39.7304068951,39.7232139759,
+	39.7160292458,39.708852687,39.7016842819,39.6945240127,39.6873718619,
+	39.6802278119,39.6730918453,39.6659639446,39.6588440925,39.6517322716,
+	39.6446284646,39.6375326544,39.6304448239,39.6233649558,39.6162930333,
+	39.6092290392,39.6021729567,39.5951247688,39.5880844588,39.5810520098,
+	39.5740274052,39.5670106282,39.5600016623,39.5530004909,39.5460070974,
+	39.5390214655,39.5320435786,39.5250734205,39.5181109748,39.5111562253,
+	39.5042091557,39.4972697499,39.4903379919,39.4834138654,39.4764973546,
+	39.4695884435,39.4626871162,39.4557933567,39.4489071494,39.4420284784,
+	39.435157328,39.4282936826,39.4214375266,39.4145888443,39.4077476203,
+	39.4009138391,39.3940874853,39.3872685434,39.3804569982,39.3736528344,
+	39.3668560367,39.36006659,39.353284479,39.3465096888,39.3397422042,
+	39.3329820103,39.3262290921,39.3194834346,39.3127450231,39.3060138426,
+	39.2992898784,39.2925731158,39.2858635401,39.2791611366,39.2724658907,
+	39.2657777879,39.2590968136,39.2524229534,39.2457561929,39.2390965176,
+	39.2324439132,39.2257983655,39.2191598602,39.212528383,39.2059039198,
+	39.1992864564,39.1926759788,39.186072473,39.1794759249,39.1728863205,
+	39.166303646,39.1597278875,39.153159031,39.1465970629,39.1400419694,
+	39.1334937368,39.1269523513,39.1204177994,39.1138900674,39.1073691419,
+	39.1008550092,39.094347656,39.0878470687,39.081353234,39.0748661385,
+	39.068385769,39.0619121121,39.0554451545,39.0489848832,39.0425312849,
+	39.0360843464,39.0296440548,39.023210397,39.0167833599,39.0103629306,
+	39.0039490962,38.9975418437,38.9911411603,38.9847470331,38.9783594495,
+	38.9719783965,38.9656038616,38.959235832,38.9528742952,38.9465192384,
+	38.9401706492,38.933828515,38.9274928232,38.9211635616,38.9148407175,
+	38.9085242787,38.9022142328,38.8959105674,38.8896132703,38.8833223293,
+	38.877037732,38.8707594665,38.8644875204,38.8582218817,38.8519625383,
+	38.8457094782,38.8394626894,38.8332221598,38.8269878777,38.8207598309,
+	38.8145380078,38.8083223964,38.802112985,38.7959097617,38.7897127148,
+	38.7835218327,38.7773371036,38.7711585159,38.7649860581,38.7588197184,
+	38.7526594855,38.7465053477,38.7403572936,38.7342153118,38.7280793908,
+	38.7219495192,38.7158256858,38.7097078791,38.7035960879,38.697490301,
+	38.691390507,38.6852966949,38.6792088534,38.6731269715,38.667051038,
+	38.6609810418
+	};
+
+
+tubetable_12AT7_rtable_0(r) = (tubetable_12AT7_0,r):rdtable;
+tubetable_12AT7_rtable_1(r) = (tubetable_12AT7_1,r):rdtable;
+
+
+// generated by ../../tools/tube_transfer.py
+// tube: 12AU7
+// plate current function: pentode
+// mu: 21.5
+// kx: 1.3
+// kg1: 1180
+// kp: 84
+// kvb: 300
+
+
+tubetable_12AU7_0 = waveform{ 127.202255052,127.144735521,127.087208545,127.029674135,126.972132303,
+	126.914583061,126.857026422,126.799462397,126.741890998,126.684312237,
+	126.626726127,126.569132679,126.511531906,126.45392382,126.396308434,
+	126.338685759,126.281055807,126.223418592,126.165774125,126.108122418,
+	126.050463485,125.992797338,125.935123988,125.877443449,125.819755734,
+	125.762060854,125.704358822,125.646649651,125.588933353,125.531209942,
+	125.473479429,125.415741829,125.357997152,125.300245413,125.242486624,
+	125.184720797,125.126947947,125.069168085,125.011381225,124.953587379,
+	124.895786561,124.837978784,124.780164061,124.722342404,124.664513828,
+	124.606678345,124.548835968,124.490986711,124.433130587,124.375267609,
+	124.317397791,124.259521146,124.201637688,124.143747429,124.085850383,
+	124.027946564,123.970035986,123.912118661,123.854194604,123.796263828,
+	123.738326347,123.680382175,123.622431324,123.56447381,123.506509646,
+	123.448538845,123.390561421,123.332577389,123.274586763,123.216589556,
+	123.158585782,123.100575455,123.04255859,122.984535201,122.926505301,
+	122.868468905,122.810426027,122.752376682,122.694320883,122.636258645,
+	122.578189982,122.520114909,122.46203344,122.40394559,122.345851372,
+	122.287750803,122.229643895,122.171530664,122.113411125,122.055285291,
+	121.997153178,121.939014801,121.880870174,121.822719312,121.76456223,
+	121.706398942,121.648229465,121.590053812,121.531871999,121.47368404,
+	121.415489952,121.357289748,121.299083444,121.240871056,121.182652598,
+	121.124428085,121.066197534,121.007960959,120.949718376,120.891469799,
+	120.833215245,120.77495473,120.716688268,120.658415874,120.600137566,
+	120.541853358,120.483563266,120.425267305,120.366965492,120.308657843,
+	120.250344372,120.192025096,120.133700031,120.075369193,120.017032598,
+	119.958690261,119.900342199,119.841988428,119.783628965,119.725263824,
+	119.666893023,119.608516578,119.550134505,119.49174682,119.433353539,
+	119.37495468,119.316550259,119.258140292,119.199724795,119.141303785,
+	119.08287728,119.024445295,118.966007847,118.907564953,118.84911663,
+	118.790662894,118.732203763,118.673739253,118.615269382,118.556794165,
+	118.498313621,118.439827767,118.381336619,118.322840194,118.26433851,
+	118.205831585,118.147319435,118.088802077,118.03027953,117.97175181,
+	117.913218935,117.854680922,117.796137789,117.737589554,117.679036234,
+	117.620477847,117.56191441,117.503345942,117.444772459,117.386193981,
+	117.327610524,117.269022108,117.210428748,117.151830465,117.093227275,
+	117.034619197,116.97600625,116.91738845,116.858765817,116.800138368,
+	116.741506123,116.682869099,116.624227315,116.565580789,116.50692954,
+	116.448273586,116.389612947,116.330947639,116.272277683,116.213603098,
+	116.1549239,116.096240111,116.037551747,115.97885883,115.920161376,
+	115.861459406,115.802752938,115.744041992,115.685326586,115.62660674,
+	115.567882473,115.509153805,115.450420754,115.39168334,115.332941582,
+	115.274195501,115.215445115,115.156690443,115.097931507,115.039168325,
+	114.980400916,114.921629302,114.862853501,114.804073533,114.745289419,
+	114.686501178,114.62770883,114.568912395,114.510111894,114.451307346,
+	114.392498772,114.333686192,114.274869626,114.216049094,114.157224618,
+	114.098396216,114.039563911,113.980727722,113.92188767,113.863043775,
+	113.804196059,113.745344542,113.686489244,113.627630187,113.568767392,
+	113.509900879,113.451030669,113.392156784,113.333279244,113.274398071,
+	113.215513286,113.156624909,113.097732963,113.038837469,112.979938447,
+	112.92103592,112.862129909,112.803220436,112.744307521,112.685391187,
+	112.626471456,112.567548349,112.508621887,112.449692094,112.39075899,
+	112.331822598,112.272882939,112.213940036,112.154993911,112.096044586,
+	112.037092083,111.978136425,111.919177633,111.860215731,111.801250739,
+	111.742282682,111.683311582,111.624337461,111.565360341,111.506380246,
+	111.447397198,111.38841122,111.329422335,111.270430566,111.211435936,
+	111.152438467,111.093438183,111.034435107,110.975429263,110.916420672,
+	110.857409359,110.798395347,110.73937866,110.68035932,110.621337352,
+	110.562312778,110.503285623,110.44425591,110.385223663,110.326188906,
+	110.267151662,110.208111956,110.149069811,110.090025251,110.030978301,
+	109.971928984,109.912877325,109.853823348,109.794767077,109.735708537,
+	109.676647751,109.617584745,109.558519543,109.49945217,109.440382649,
+	109.381311006,109.322237266,109.263161453,109.204083592,109.145003709,
+	109.085921827,109.026837972,108.96775217,108.908664445,108.849574822,
+	108.790483327,108.731389985,108.672294822,108.613197862,108.554099132,
+	108.494998657,108.435896462,108.376792573,108.317687016,108.258579817,
+	108.199471001,108.140360595,108.081248624,108.022135114,107.963020092,
+	107.903903583,107.844785615,107.785666212,107.726545401,107.667423209,
+	107.608299663,107.549174788,107.490048611,107.430921159,107.371792458,
+	107.312662535,107.253531418,107.194399132,107.135265705,107.076131164,
+	107.016995535,106.957858847,106.898721125,106.839582398,106.780442692,
+	106.721302034,106.662160454,106.603017976,106.54387463,106.484730443,
+	106.425585442,106.366439655,106.30729311,106.248145835,106.188997857,
+	106.129849205,106.070699906,106.011549989,105.952399482,105.893248413,
+	105.83409681,105.774944701,105.715792116,105.656639082,105.597485627,
+	105.538331781,105.479177572,105.420023029,105.360868181,105.301713056,
+	105.242557683,105.183402091,105.124246309,105.065090367,105.005934293,
+	104.946778117,104.887621867,104.828465574,104.769309266,104.710152973,
+	104.650996725,104.591840551,104.532684481,104.473528544,104.41437277,
+	104.35521719,104.296061832,104.236906727,104.177751906,104.118597397,
+	104.059443232,104.00028944,103.941136051,103.881983097,103.822830607,
+	103.763678612,103.704527143,103.64537623,103.586225903,103.527076194,
+	103.467927133,103.408778751,103.34963108,103.290484149,103.231337991,
+	103.172192635,103.113048115,103.05390446,102.994761702,102.935619872,
+	102.876479002,102.817339124,102.758200268,102.699062467,102.639925752,
+	102.580790156,102.521655709,102.462522444,102.403390393,102.344259588,
+	102.285130061,102.226001843,102.166874968,102.107749468,102.048625375,
+	101.989502721,101.930381539,101.871261862,101.812143721,101.753027151,
+	101.693912183,101.634798851,101.575687186,101.516577224,101.457468995,
+	101.398362534,101.339257873,101.280155047,101.221054087,101.161955028,
+	101.102857902,101.043762744,100.984669587,100.925578465,100.86648941,
+	100.807402458,100.748317642,100.689234995,100.630154552,100.571076347,
+	100.512000413,100.452926786,100.393855498,100.334786586,100.275720082,
+	100.216656021,100.157594438,100.098535367,100.039478843,99.9804249014,
+	99.9213735758,99.8623249014,99.8032789131,99.7442356459,99.6851951348,
+	99.626157415,99.5671225215,99.5080904897,99.4490613547,99.390035152,
+	99.3310119171,99.2719916853,99.2129744923,99.1539603737,99.0949493652,
+	99.0359415025,98.9769368215,98.9179353582,98.8589371484,98.7999422282,
+	98.7409506337,98.681962401,98.6229775665,98.5639961663,98.5050182369,
+	98.4460438148,98.3870729363,98.3281056381,98.2691419569,98.2101819292,
+	98.151225592,98.092272982,98.0333241361,97.9743790913,97.9154378847,
+	97.8565005533,97.7975671344,97.7386376651,97.6797121827,97.6207907248,
+	97.5618733286,97.5029600316,97.4440508716,97.3851458861,97.3262451127,
+	97.2673485894,97.2084563538,97.149568444,97.0906848979,97.0318057536,
+	96.972931049,96.9140608226,96.8551951123,96.7963339567,96.737477394,
+	96.6786254626,96.6197782012,96.5609356482,96.5020978424,96.4432648223,
+	96.3844366268,96.3256132947,96.2667948649,96.2079813764,96.1491728683,
+	96.0903693795,96.0315709494,95.9727776171,95.9139894219,95.8552064032,
+	95.7964286005,95.7376560531,95.6788888008,95.6201268831,95.5613703397,
+	95.5026192104,95.443873535,95.3851333534,95.3263987056,95.2676696315,
+	95.2089461714,95.1502283653,95.0915162534,95.0328098761,94.9741092737,
+	94.9154144866,94.8567255554,94.7980425205,94.7393654225,94.6806943022,
+	94.6220292003,94.5633701577,94.5047172151,94.4460704135,94.387429794,
+	94.3287953976,94.2701672655,94.2115454388,94.1529299589,94.094320867,
+	94.0357182045,93.977122013,93.918532334,93.859949209,93.8013726797,
+	93.7428027879,93.6842395753,93.6256830838,93.5671333553,93.5085904318,
+	93.4500543553,93.391525168,93.3330029121,93.2744876298,93.2159793634,
+	93.1574781553,93.098984048,93.0404970839,92.9820173057,92.923544756,
+	92.8650794774,92.8066215128,92.7481709051,92.689727697,92.6312919317,
+	92.572863652,92.5144429013,92.4560297225,92.397624159,92.3392262541,
+	92.2808360511,92.2224535935,92.1640789248,92.1057120886,92.0473531285,
+	91.9890020883,91.9306590116,91.8723239425,91.8139969247,91.7556780023,
+	91.6973672194,91.63906462,91.5807702484,91.5224841489,91.4642063657,
+	91.4059369434,91.3476759263,91.289423359,91.2311792862,91.1729437526,
+	91.1147168029,91.0564984821,90.9982888349,90.9400879065,90.8818957418,
+	90.8237123861,90.7655378846,90.7073722826,90.6492156254,90.5910679586,
+	90.5329293276,90.4747997782,90.4166793559,90.3585681067,90.3004660764,
+	90.2423733109,90.1842898562,90.1262157586,90.0681510643,90.0100958195,
+	89.9520500706,89.8940138642,89.8359872468,89.7779702652,89.719962966,
+	89.6619653962,89.6039776027,89.5459996326,89.4880315331,89.4300733515,
+	89.3721251352,89.3141869316,89.2562587884,89.1983407533,89.1404328741,
+	89.0825351988,89.0246477754,88.9667706523,88.9089038776,88.8510474998,
+	88.7932015676,88.7353661296,88.6775412346,88.6197269318,88.5619232702,
+	88.5041302991,88.446348068,88.3885766264,88.3308160242,88.2730663111,
+	88.2153275374,88.1575997532,88.099883009,88.0421773555,87.9844828434,
+	87.9267995237,87.8691274477,87.8114666667,87.7538172323,87.6961791964,
+	87.6385526111,87.5809375286,87.5233340014,87.4657420824,87.4081618245,
+	87.350593281,87.2930365055,87.2354915517,87.1779584739,87.1204373264,
+	87.062928164,87.0054310416,86.9479460146,86.8904731388,86.8330124701,
+	86.775564065,86.7181279803,86.6607042731,86.6032930011,86.545894222,
+	86.4885079945,86.4311343773,86.3737734298,86.3164252117,86.2590897832,
+	86.2017672053,86.1444575392,86.0871608467,86.0298771904,85.9726066331,
+	85.9153492385,85.858105071,85.8008741953,85.743656677,85.6864525825,
+	85.6292619788,85.5720849335,85.5149215154,85.4577717937,85.4006358386,
+	85.3435137212,85.2864055135,85.2293112884,85.1722311199,85.1151650827,
+	85.058113253,85.0010757077,84.9440525249,84.8870437842,84.830049566,
+	84.7730699521,84.7161050257,84.6591548713,84.6022195749,84.5452992237,
+	84.4883939067,84.4315037144,84.3746287389,84.317769074,84.2609248154,
+	84.2040960603,84.1472829082,84.0904854603,84.03370382,83.9769380928,
+	83.9201883863,83.8634548107,83.8067374781,83.7500365035,83.6933520043,
+	83.6366841005,83.580032915,83.5233985736,83.4667812049,83.4101809407,
+	83.3535979161,83.2970322693,83.2404841423,83.1839536804,83.1274410328,
+	83.0709463526,83.0144697967,82.9580115264,82.9015717072,82.8451505094,
+	82.7887481075,82.7323646812,82.676000415,82.619655499,82.5633301282,
+	82.5070245037,82.4507388321,82.3944733263,82.3382282053,82.2820036947,
+	82.2258000269,82.1696174413,82.1134561847,82.0573165111,82.0011986828,
+	81.9451029699,81.8890296512,81.8329790139,81.7769513547,81.7209469793,
+	81.6649662036,81.6090093531,81.5530767642,81.4971687841,81.4412857711,
+	81.3854280954,81.3295961391,81.2737902971,81.2180109771,81.1622586004,
+	81.1065336021,81.0508364319,80.9951675546,80.9395274501,80.8839166148,
+	80.8283355615,80.7727848202,80.7172649388,80.6617764836,80.60632004,
+	80.550896213,80.4955056283,80.4401489323,80.3848267936,80.3295399031,
+	80.2742889753,80.2190747483,80.1638979857,80.1087594762,80.0536600356,
+	79.9986005067,79.9435817607,79.8886046981,79.8336702492,79.7787793757,
+	79.7239330709,79.6691323614,79.6143783076,79.5596720049,79.5050145846,
+	79.4504072153,79.3958511034,79.3413474946,79.2868976751,79.232502972,
+	79.1781647554,79.1238844387,79.0696634799,79.0155033833,78.9614056998,
+	78.9073720286,78.8534040181,78.7995033671,78.745671826,78.6919111977,
+	78.6382233388,78.5846101608,78.5310736309,78.4776157733,78.4242386699,
+	78.3709444615,78.3177353487,78.2646135927,78.2115815159,78.1586415033,
+	78.1057960025,78.0530475247,78.0003986452,77.947852004,77.8954103058,
+	77.8430763209,77.7908528846,77.738742898,77.6867493276,77.6348752053,
+	77.5831236277,77.5314977563,77.4800008163,77.4286360961,77.3774069467,
+	77.3263167799,77.2753690679,77.2245673409,77.1739151864,77.1234162467,
+	77.0730742172,77.0228928441,76.9728759219,76.9230272907,76.8733508334,
+	76.8238504726,76.7745301674,76.7253939097,76.6764457203,76.6276896455,
+	76.5791297525,76.530770125,76.4826148588,76.4346680573,76.3869338259,
+	76.3394162677,76.2921194775,76.245047537,76.1982045089,76.1515944315,
+	76.1052213127,76.0590891244,76.0132017967,75.9675632117,75.9221771979,
+	75.8770475238,75.8321778926,75.787571936,75.7432332085,75.6991651814,
+	75.6553712381,75.6118546675,75.5686186599,75.5256663009,75.4830005672,
+	75.4406243218,75.3985403095,75.3567511527,75.3152593478,75.2740672612,
+	75.2331771266,75.1925910414,75.1523109648,75.1123387149,75.0726759671,
+	75.0333242522,74.9942849556,74.9555593161,74.9171484253,74.8790532275,
+	74.84127452,74.8038129532,74.7666690316,74.729843115,74.6933354196,
+	74.6571460201,74.6212748514,74.5857217107,74.5504862605,74.5155680309,
+	74.4809664224,74.4466807098,74.4127100446,74.3790534589,74.3457098694,
+	74.3126780802,74.2799567878,74.2475445842,74.2154399613,74.183641315,
+	74.1521469494,74.1209550808,74.0900638421,74.0594712869,74.0291753936,
+	73.9991740699,73.9694651566,73.940046432,73.9109156157,73.8820703727,
+	73.8535083174,73.8252270172,73.7972239966,73.7694967405,73.7420426981,
+	73.7148592861,73.6879438923,73.6612938788,73.6349065851,73.608779331,
+	73.5829094199,73.5572941414,73.5319307741,73.5068165879,73.481948847,
+	73.4573248118,73.4329417415,73.408796896,73.3848875381,73.3612109353,
+	73.337764362,73.3145451007,73.2915504439,73.2687776959,73.2462241737,
+	73.2238872088,73.2017641484,73.1798523562,73.1581492141,73.1366521227,
+	73.1153585028,73.0942657956,73.073371464,73.0526729932,73.0321678913,
+	73.01185369,72.9917279452,72.9717882373,72.9520321718,72.9324573797,
+	72.9130615179,72.8938422692,72.8747973428,72.8559244746,72.8372214272,
+	72.8186859901,72.8003159797,72.7821092396,72.7640636405,72.7461770802,
+	72.7284474836,72.7108728027,72.6934510167,72.6761801314,72.6590581798,
+	72.6420832213,72.6252533423,72.6085666551,72.5920212986,72.5756154379,
+	72.5593472636,72.5432149922,72.5272168657,72.5113511511,72.4956161407,
+	72.4800101513,72.4645315244,72.4491786254,72.433949844,72.4188435934,
+	72.4038583105,72.388992455,72.3742445097,72.3596129798,72.3450963931,
+	72.3306932992,72.3164022693,72.3022218964,72.2881507943,72.2741875978,
+	72.2603309624,72.2465795636,72.232932097,72.2193872781,72.2059438415,
+	72.192600541,72.1793561494,72.1662094579,72.1531592761,72.1402044315,
+	72.1273437694,72.1145761524,72.1019004605,72.0893155905,72.0768204558,
+	72.0644139862,72.0520951278,72.0398628423,72.0277161072,72.0156539153,
+	72.0036752745,71.9917792075,71.9799647519,71.9682309594,71.956576896,
+	71.9450016415,71.9335042896,71.9220839473,71.9107397349,71.8994707857,
+	71.888276246,71.8771552744,71.8661070421,71.8551307324,71.8442255407,
+	71.8333906741,71.8226253513,71.8119288024,71.8013002686,71.7907390024,
+	71.7802442669,71.7698153359,71.7594514938,71.7491520351,71.7389162647,
+	71.7287434971,71.718633057,71.7085842785,71.6985965052,71.6886690901,
+	71.6788013952,71.6689927918,71.6592426597,71.6495503876,71.6399153729,
+	71.6303370213,71.6208147466,71.6113479711,71.6019361248,71.592578646,
+	71.5832749802,71.574024581,71.5648269093,71.5556814334,71.5465876288,
+	71.5375449783,71.5285529715,71.5196111052,71.5107188828,71.5018758143,
+	71.4930814165,71.4843352126,71.4756367321,71.4669855107,71.4583810906,
+	71.4498230196,71.4413108518,71.432844147,71.424422471,71.416045395,
+	71.407712496,71.3994233563,71.3911775639,71.3829747119,71.3748143987,
+	71.366696228,71.3586198085,71.3505847537,71.3425906823,71.3346372179,
+	71.3267239885,71.3188506271,71.3110167714,71.3032220633,71.2954661496,
+	71.2877486811,71.2800693133,71.2724277058,71.2648235225,71.2572564313,
+	71.2497261043,71.2422322176,71.2347744514,71.2273524895,71.2199660198,
+	71.212614734,71.2052983272,71.1980164986,71.1907689508,71.18355539,
+	71.1763755258,71.1692290714,71.1621157434,71.1550352617,71.1479873495,
+	71.1409717334,71.133988143,71.1270363112,71.1201159739,71.1132268703,
+	71.1063687424,71.0995413353,71.0927443969,71.0859776782,71.0792409329,
+	71.0725339177,71.0658563918,71.0592081174,71.0525888592,71.0459983846,
+	71.0394364638,71.0329028693,71.0263973764,71.0199197628,71.0134698085,
+	71.0070472963,71.0006520112,70.9942837405,70.9879422739,70.9816274037,
+	70.9753389239,70.9690766313,70.9628403246,70.9566298047,70.9504448748,
+	70.94428534,70.9381510078,70.9320416875,70.9259571906,70.9198973305,
+	70.9138619226,70.9078507843,70.901863735,70.8959005958,70.8899611899,
+	70.8840453422,70.8781528795,70.8722836304,70.8664374253,70.8606140963,
+	70.8548134773,70.8490354038,70.8432797131,70.8375462442,70.8318348376,
+	70.8261453356,70.8204775819,70.814831422,70.8092067028,70.8036032728,
+	70.7980209821,70.7924596821,70.7869192259,70.7813994679,70.7759002642,
+	70.7704214719,70.7649629499,70.7595245583,70.7541061588,70.748707614,
+	70.7433287883,70.7379695473,70.7326297578,70.7273092879,70.722008007,
+	70.7167257859,70.7114624965,70.7062180119,70.7009922065,70.6957849559,
+	70.6905961368,70.6854256272,70.6802733061,70.6751390538,70.6700227516,
+	70.664924282,70.6598435285,70.6547803759,70.6497347097,70.6447064169,
+	70.6396953852,70.6347015035,70.6297246618,70.6247647509,70.6198216628,
+	70.6148952904,70.6099855275,70.6050922689,70.6002154106,70.5953548492,
+	70.5905104824,70.5856822089,70.580869928,70.5760735403,70.5712929469,
+	70.5665280502,70.5617787532,70.5570449596,70.5523265745,70.5476235032,
+	70.5429356523,70.5382629289,70.5336052413,70.5289624981,70.5243346092,
+	70.5197214849,70.5151230364,70.5105391758,70.5059698158,70.5014148699,
+	70.4968742524,70.4923478781,70.4878356629,70.4833375231,70.4788533759,
+	70.4743831391,70.4699267312,70.4654840714,70.4610550798,70.4566396767,
+	70.4522377835,70.447849322,70.4434742148,70.439112385,70.4347637566,
+	70.4304282539,70.426105802,70.4217963266,70.4174997541,70.4132160112,
+	70.4089450256,70.4046867254,70.4004410391,70.3962078961,70.3919872262,
+	70.3877789598,70.3835830278,70.3793993618,70.3752278939,70.3710685566,
+	70.3669212831,70.3627860071,70.3586626627,70.3545511847,70.3504515084,
+	70.3463635694,70.3422873042,70.3382226493,70.3341695421,70.3301279203,
+	70.3260977221,70.3220788863,70.3180713521,70.314075059,70.3100899473,
+	70.3061159575,70.3021530306,70.2982011081,70.2942601321,70.2903300448,
+	70.2864107891,70.2825023083,70.278604546,70.2747174464,70.270840954,
+	70.2669750137,70.263119571,70.2592745716,70.2554399617,70.2516156878,
+	70.2478016971,70.2439979368,70.2402043547,70.2364208989,70.2326475181,
+	70.2288841612,70.2251307773,70.2213873163,70.2176537281,70.2139299631,
+	70.2102159721,70.2065117062,70.2028171169,70.1991321561,70.1954567758,
+	70.1917909286,70.1881345674,70.1844876454,70.180850116,70.1772219332,
+	70.1736030512,70.1699934245,70.1663930079,70.1628017565,70.159219626,
+	70.155646572,70.1520825507,70.1485275185,70.1449814321,70.1414442485,
+	70.1379159251,70.1343964195,70.1308856895,70.1273836935,70.1238903898,
+	70.1204057374,70.1169296952,70.1134622226,70.1100032792,70.1065528249,
+	70.10311082,70.0996772248,70.0962520002,70.0928351069,70.0894265065,
+	70.0860261602,70.08263403,70.0792500778,70.0758742659,70.072506557,
+	70.0691469136,70.065795299,70.0624516764,70.0591160093,70.0557882615,
+	70.052468397,70.0491563801,70.0458521752,70.0425557471,70.0392670607,
+	70.0359860812,70.032712774,70.0294471048,70.0261890395,70.022938544,
+	70.0196955847,70.0164601282,70.0132321412,70.0100115905,70.0067984435,
+	70.0035926675,70.0003942301,69.997203099,69.9940192423,69.9908426281,
+	69.987673225,69.9845110014,69.9813559263,69.9782079686,69.9750670975,
+	69.9719332824,69.968806493,69.9656866989,69.9625738702,69.9594679771,
+	69.9563689898,69.9532768789,69.9501916152,69.9471131695,69.9440415128,
+	69.9409766166,69.9379184521,69.934866991,69.9318222051,69.9287840663,
+	69.9257525469,69.922727619,69.9197092551,69.916697428,69.9136921103,
+	69.9106932751,69.9077008955,69.9047149448,69.9017353964,69.898762224,
+	69.8957954014,69.8928349024,69.8898807013,69.8869327721,69.8839910894,
+	69.8810556276,69.8781263615,69.875203266,69.872286316,69.8693754867,
+	69.8664707534,69.8635720915,69.8606794767,69.8577928846,69.8549122911,
+	69.8520376723,69.8491690042,69.8463062633,69.843449426,69.8405984687,
+	69.8377533682,69.8349141014,69.8320806452,69.8292529768,69.8264310733,
+	69.8236149122,69.820804471,69.8179997272,69.8152006587,69.8124072433,
+	69.809619459,69.806837284,69.8040606966,69.8012896751,69.798524198,
+	69.7957642439,69.7930097917,69.7902608201,69.7875173082,69.7847792351,
+	69.7820465799,69.7793193221,69.7765974411,69.7738809164,69.7711697277,
+	69.7684638549,69.7657632778,69.7630679764,69.760377931,69.7576931216,
+	69.7550135287,69.7523391328,69.7496699143,69.747005854,69.7443469326,
+	69.741693131,69.7390444302,69.7364008113,69.7337622555,69.731128744,
+	69.7285002583,69.7258767798,69.7232582901,69.720644771,69.7180362043,
+	69.7154325717,69.7128338553,69.7102400373,69.7076510997,69.7050670248,
+	69.702487795,69.6999133929,69.6973438008,69.6947790015,69.6922189777,
+	69.6896637122,69.6871131881,69.6845673881,69.6820262956,69.6794898936,
+	69.6769581654,69.6744310945,69.6719086642,69.669390858,69.6668776597,
+	69.6643690529,69.6618650215,69.6593655492,69.65687062,69.6543802181,
+	69.6518943274,69.6494129323,69.646936017,69.6444635658,69.6419955633,
+	69.6395319939,69.6370728423,69.6346180932,69.6321677312,69.6297217413,
+	69.6272801083,69.6248428174,69.6224098534,69.6199812016,69.6175568472,
+	69.6151367755,69.6127209718,69.6103094217,69.6079021105,69.605499024,
+	69.6031001477,69.6007054674,69.5983149688,69.595928638,69.5935464607,
+	69.5911684231,69.5887945111,69.586424711,69.5840590089,69.5816973912,
+	69.5793398442,69.5769863543,69.5746369081,69.5722914919,69.5699500926,
+	69.5676126967,69.565279291,69.5629498624,69.5606243976,69.5583028837,
+	69.5559853076,69.5536716564,69.5513619173,69.5490560774,69.546754124,
+	69.5444560444,69.542161826,69.5398714561,69.5375849224,69.5353022123,
+	69.5330233135,69.5307482137,69.5284769005,69.5262093618,69.5239455854,
+	69.5216855592,69.5194292712,69.5171767094,69.5149278619,69.5126827168,
+	69.5104412624,69.5082034867,69.5059693782,69.5037389252,69.5015121161,
+	69.4992889393,69.4970693835,69.4948534371,69.4926410887,69.4904323271,
+	69.488227141,69.4860255191,69.4838274503,69.4816329235,69.4794419275,
+	69.4772544515,69.4750704843,69.4728900152,69.4707130332,69.4685395275,
+	69.4663694874,69.4642029021,69.462039761,69.4598800535,69.4577237689,
+	69.4555708968,69.4534214266,69.451275348,69.4491326506,69.446993324,
+	69.444857358,69.4427247423,69.4405954667,69.438469521,69.4363468952,
+	69.4342275792,69.4321115629,69.4299988365,69.42788939,69.4257832134,
+	69.4236802971,69.421580631,69.4194842056,69.4173910112,69.4153010379,
+	69.4132142763,69.4111307167,69.4090503496,69.4069731655,69.404899155,
+	69.4028283086,69.400760617,69.3986960708,69.3966346607,69.3945763775,
+	69.392521212,69.390469155,69.3884201974,69.3863743301,69.384331544,
+	69.3822918302,69.3802551795,69.3782215832,69.3761910323,69.374163518,
+	69.3721390314,69.3701175638,69.3680991063,69.3660836504,69.3640711872,
+	69.3620617083,69.360055205,69.3580516687,69.3560510909,69.3540534631,
+	69.3520587769,69.3500670239,69.3480781956,69.3460922837,69.34410928,
+	69.3421291761,69.3401519637,69.3381776348,69.3362061811,69.3342375944,
+	69.3322718667,69.3303089899,69.328348956,69.3263917569,69.3244373848,
+	69.3224858315,69.3205370893,69.3185911503,69.3166480066,69.3147076504,
+	69.312770074,69.3108352696,69.3089032295,69.306973946,69.3050474114,
+	69.3031236182,69.3012025588,69.2992842255,69.297368611,69.2954557076,
+	69.293545508,69.2916380046,69.2897331902,69.2878310572,69.2859315985,
+	69.2840348066,69.2821406742,69.2802491942,69.2783603593,69.2764741623,
+	69.274590596,69.2727096534,69.2708313271,69.2689556103,69.2670824959,
+	69.2652119768,69.263344046,69.2614786965,69.2596159215,69.2577557139,
+	69.255898067,69.2540429739,69.2521904276,69.2503404215,69.2484929487,
+	69.2466480025,69.2448055761,69.2429656629,69.2411282562,69.2392933493,
+	69.2374609357,69.2356310086,69.2338035617,69.2319785882,69.2301560817,
+	69.2283360358,69.2265184438,69.2247032995,69.2228905963,69.2210803279,
+	69.2192724879,69.21746707,69.2156640679,69.2138634751,69.2120652856,
+	69.210269493,69.2084760912,69.2066850738,69.2048964348,69.203110168,
+	69.2013262672,69.1995447265,69.1977655395,69.1959887005,69.1942142031,
+	69.1924420416,69.1906722099,69.1889047019,69.1871395119,69.1853766338,
+	69.1836160617,69.1818577899,69.1801018123,69.1783481232,69.1765967169,
+	69.1748475874,69.173100729,69.171356136,69.1696138026,69.1678737232,
+	69.1661358921,69.1644003035,69.162666952,69.1609358317,69.1592069373,
+	69.157480263,69.1557558033,69.1540335526,69.1523135056,69.1505956566,
+	69.1488800002,69.1471665309,69.1454552434,69.1437461321,69.1420391917,
+	69.1403344169,69.1386318022,69.1369313423,69.1352330319,69.1335368658,
+	69.1318428385,69.130150945,69.1284611799,69.126773538,69.1250880141,
+	69.1234046031,69.1217232997,69.1200440988,69.1183669953,69.1166919841,
+	69.1150190601,69.1133482182,69.1116794534,69.1100127607,69.1083481349,
+	69.1066855712,69.1050250645,69.1033666098,69.1017102023,69.100055837,
+	69.098403509,69.0967532133,69.0951049452,69.0934586997,69.0918144721,
+	69.0901722574,69.0885320509,69.0868938478,69.0852576434,69.0836234328,
+	69.0819912113,69.0803609742,69.0787327168,69.0771064344,69.0754821223,
+	69.0738597759,69.0722393905,69.0706209615,69.0690044844,69.0673899544,
+	69.065777367,69.0641667177,69.0625580019,69.0609512151,69.0593463528,
+	69.0577434105,69.0561423836,69.0545432678,69.0529460585,69.0513507514,
+	69.049757342,69.0481658259,69.0465761987,69.0449884561,69.0434025936,
+	69.041818607,69.0402364919,69.0386562439,69.0370778589,69.0355013325,
+	69.0339266603,69.0323538383,69.0307828621,69.0292137275,69.0276464302,
+	69.0260809661,69.0245173311,69.0229555208,69.0213955313,69.0198373582,
+	69.0182809975,69.0167264451,69.0151736969,69.0136227488,69.0120735967,
+	69.0105262365,69.0089806642,69.0074368758,69.0058948672,69.0043546345,
+	69.0028161736,69.0012794806,68.9997445515,68.9982113823,68.9966799691,
+	68.995150308,68.993622395,68.9920962263,68.990571798,68.9890491061,
+	68.9875281469,68.9860089165,68.984491411,68.9829756266,68.9814615595,
+	68.9799492059,68.978438562,68.976929624,68.9754223882,68.9739168508,
+	68.9724130081,68.9709108564,68.9694103919,68.9679116109,68.9664145098,
+	68.9649190848,68.9634253323,68.9619332487,68.9604428303,68.9589540734,
+	68.9574669745,68.95598153,68.9544977362,68.9530155895,68.9515350864,
+	68.9500562234,68.9485789968,68.9471034032,68.945629439,68.9441571007,
+	68.9426863847,68.9412172877,68.9397498061,68.9382839364,68.9368196752,
+	68.935357019,68.9338959644,68.932436508,68.9309786463,68.929522376,
+	68.9280676936,68.9266145957,68.9251630791,68.9237131402,68.9222647759,
+	68.9208179827,68.9193727572,68.9179290963,68.9164869965,68.9150464545,
+	68.9136074672,68.9121700311,68.9107341431,68.9092997998,68.907866998,
+	68.9064357345,68.9050060061,68.9035778095,68.9021511415,68.9007259989,
+	68.8993023786,68.8978802773,68.8964596919,68.8950406192,68.8936230561,
+	68.8922069994,68.890792446,68.8893793928,68.8879678367,68.8865577745,
+	68.8851492032,68.8837421197,68.8823365209,68.8809324038,68.8795297653,
+	68.8781286023,68.8767289119,68.8753306909,68.8739339364,68.8725386454,
+	68.8711448149,68.8697524418,68.8683615232,68.8669720562,68.8655840377,
+	68.8641974648,68.8628123346,68.8614286441,68.8600463904,68.8586655705,
+	68.8572861817,68.8559082209,68.8545316853,68.853156572,68.8517828781,
+	68.8504106007,68.8490397371,68.8476702843,68.8463022395,68.8449355998,
+	68.8435703625,68.8422065248,68.8408440837,68.8394830366,68.8381233807,
+	68.836765113,68.835408231,68.8340527318,68.8326986126,68.8313458707,
+	68.8299945034,68.8286445079,68.8272958816,68.8259486216,68.8246027253,
+	68.8232581899,68.8219150129,68.8205731915,68.8192327229,68.8178936047,
+	68.816555834,68.8152194082,68.8138843248,68.812550581,68.8112181742,
+	68.8098871018,68.8085573612,68.8072289498,68.8059018649,68.804576104,
+	68.8032516645,68.8019285438,68.8006067394,68.7992862487,68.797967069,
+	68.796649198,68.795332633,68.7940173715,68.7927034109,68.7913907488,
+	68.7900793827,68.78876931,68.7874605283,68.786153035,68.7848468276,
+	68.7835419038
+	};
+
+tubetable_12AU7_1 = waveform{
+	127.202255052,127.144735521,127.087208545,127.029674135,126.972132303,
+	126.914583061,126.857026422,126.799462397,126.741890998,126.684312237,
+	126.626726127,126.569132679,126.511531906,126.45392382,126.396308434,
+	126.338685759,126.281055807,126.223418592,126.165774125,126.108122418,
+	126.050463485,125.992797338,125.935123988,125.877443449,125.819755734,
+	125.762060854,125.704358822,125.646649651,125.588933353,125.531209942,
+	125.473479429,125.415741829,125.357997152,125.300245413,125.242486624,
+	125.184720797,125.126947947,125.069168085,125.011381225,124.953587379,
+	124.895786561,124.837978784,124.780164061,124.722342404,124.664513828,
+	124.606678345,124.548835968,124.490986711,124.433130587,124.375267609,
+	124.317397791,124.259521146,124.201637688,124.143747429,124.085850383,
+	124.027946564,123.970035986,123.912118661,123.854194604,123.796263828,
+	123.738326347,123.680382175,123.622431324,123.56447381,123.506509646,
+	123.448538845,123.390561421,123.332577389,123.274586763,123.216589556,
+	123.158585782,123.100575455,123.04255859,122.984535201,122.926505301,
+	122.868468905,122.810426027,122.752376682,122.694320883,122.636258645,
+	122.578189982,122.520114909,122.46203344,122.40394559,122.345851372,
+	122.287750803,122.229643895,122.171530664,122.113411125,122.055285291,
+	121.997153178,121.939014801,121.880870174,121.822719312,121.76456223,
+	121.706398942,121.648229465,121.590053812,121.531871999,121.47368404,
+	121.415489952,121.357289748,121.299083444,121.240871056,121.182652598,
+	121.124428085,121.066197534,121.007960959,120.949718376,120.891469799,
+	120.833215245,120.77495473,120.716688268,120.658415874,120.600137566,
+	120.541853358,120.483563266,120.425267305,120.366965492,120.308657843,
+	120.250344372,120.192025096,120.133700031,120.075369193,120.017032598,
+	119.958690261,119.900342199,119.841988428,119.783628965,119.725263824,
+	119.666893023,119.608516578,119.550134505,119.49174682,119.433353539,
+	119.37495468,119.316550259,119.258140292,119.199724795,119.141303786,
+	119.08287728,119.024445295,118.966007847,118.907564953,118.84911663,
+	118.790662894,118.732203763,118.673739253,118.615269382,118.556794165,
+	118.498313621,118.439827767,118.381336619,118.322840194,118.26433851,
+	118.205831585,118.147319435,118.088802077,118.03027953,117.97175181,
+	117.913218935,117.854680922,117.796137789,117.737589554,117.679036234,
+	117.620477847,117.56191441,117.503345942,117.444772459,117.386193981,
+	117.327610524,117.269022108,117.210428748,117.151830465,117.093227275,
+	117.034619197,116.97600625,116.91738845,116.858765817,116.800138368,
+	116.741506123,116.682869099,116.624227315,116.565580789,116.50692954,
+	116.448273586,116.389612947,116.330947639,116.272277683,116.213603098,
+	116.1549239,116.096240111,116.037551747,115.97885883,115.920161376,
+	115.861459406,115.802752938,115.744041992,115.685326586,115.62660674,
+	115.567882473,115.509153805,115.450420754,115.39168334,115.332941582,
+	115.274195501,115.215445115,115.156690443,115.097931507,115.039168325,
+	114.980400916,114.921629302,114.862853501,114.804073533,114.745289419,
+	114.686501178,114.62770883,114.568912395,114.510111894,114.451307346,
+	114.392498772,114.333686192,114.274869626,114.216049094,114.157224618,
+	114.098396216,114.039563911,113.980727722,113.92188767,113.863043775,
+	113.804196059,113.745344542,113.686489244,113.627630188,113.568767392,
+	113.509900879,113.451030669,113.392156784,113.333279244,113.274398071,
+	113.215513286,113.156624909,113.097732963,113.038837469,112.979938447,
+	112.92103592,112.862129909,112.803220436,112.744307521,112.685391187,
+	112.626471456,112.567548349,112.508621888,112.449692094,112.39075899,
+	112.331822598,112.272882939,112.213940037,112.154993911,112.096044586,
+	112.037092083,111.978136425,111.919177633,111.860215731,111.80125074,
+	111.742282682,111.683311582,111.624337461,111.565360341,111.506380246,
+	111.447397198,111.38841122,111.329422336,111.270430566,111.211435936,
+	111.152438467,111.093438183,111.034435107,110.975429263,110.916420672,
+	110.857409359,110.798395347,110.73937866,110.68035932,110.621337352,
+	110.562312778,110.503285623,110.44425591,110.385223663,110.326188906,
+	110.267151662,110.208111956,110.149069811,110.090025251,110.030978301,
+	109.971928984,109.912877325,109.853823348,109.794767077,109.735708537,
+	109.676647752,109.617584746,109.558519543,109.49945217,109.440382649,
+	109.381311006,109.322237266,109.263161453,109.204083593,109.145003709,
+	109.085921827,109.026837973,108.96775217,108.908664445,108.849574822,
+	108.790483327,108.731389986,108.672294822,108.613197863,108.554099132,
+	108.494998657,108.435896462,108.376792573,108.317687016,108.258579817,
+	108.199471001,108.140360595,108.081248624,108.022135115,107.963020092,
+	107.903903584,107.844785615,107.785666212,107.726545402,107.66742321,
+	107.608299663,107.549174788,107.490048611,107.430921159,107.371792458,
+	107.312662536,107.253531418,107.194399133,107.135265706,107.076131165,
+	107.016995536,106.957858848,106.898721126,106.839582398,106.780442692,
+	106.721302035,106.662160454,106.603017977,106.543874631,106.484730444,
+	106.425585443,106.366439656,106.307293111,106.248145836,106.188997858,
+	106.129849206,106.070699908,106.011549991,105.952399484,105.893248414,
+	105.834096811,105.774944703,105.715792117,105.656639083,105.597485629,
+	105.538331783,105.479177574,105.420023031,105.360868183,105.301713058,
+	105.242557685,105.183402093,105.124246312,105.065090369,105.005934295,
+	104.946778119,104.88762187,104.828465577,104.769309269,104.710152976,
+	104.650996728,104.591840554,104.532684484,104.473528547,104.414372774,
+	104.355217194,104.296061836,104.236906732,104.17775191,104.118597402,
+	104.059443236,104.000289445,103.941136056,103.881983102,103.822830613,
+	103.763678618,103.704527149,103.645376236,103.586225909,103.527076201,
+	103.46792714,103.408778759,103.349631087,103.290484157,103.231337999,
+	103.172192644,103.113048124,103.053904469,102.994761711,102.935619882,
+	102.876479012,102.817339134,102.758200279,102.699062479,102.639925765,
+	102.580790168,102.521655722,102.462522458,102.403390407,102.344259603,
+	102.285130076,102.226001859,102.166874985,102.107749485,102.048625393,
+	101.989502739,101.930381558,101.871261882,101.812143742,101.753027172,
+	101.693912205,101.634798874,101.575687211,101.516577249,101.457469021,
+	101.398362561,101.339257902,101.280155076,101.221054117,101.161955059,
+	101.102857935,101.043762779,100.984669623,100.925578502,100.866489449,
+	100.807402498,100.748317684,100.689235038,100.630154597,100.571076394,
+	100.512000462,100.452926836,100.393855551,100.33478664,100.275720138,
+	100.21665608,100.157594499,100.098535431,100.03947891,99.9804249704,
+	99.9213736475,99.8623249759,99.8032789906,99.7442357264,99.6851952186,
+	99.626157502,99.567122612,99.5080905837,99.4490614525,99.3900352536,
+	99.3310120227,99.2719917951,99.2129746064,99.1539604923,99.0949494884,
+	99.0359416307,98.9769369548,98.9179354966,98.8589372923,98.7999423778,
+	98.7409507892,98.6819625626,98.6229777345,98.563996341,98.5050184185,
+	98.4460440035,98.3870731325,98.328105842,98.2691421688,98.2101821495,
+	98.151225821,98.09227322,98.0333243835,97.9743793485,97.915438152,
+	97.8565008311,97.7975674231,97.7386379652,97.6797124948,97.6207910491,
+	97.5618736657,97.5029603821,97.4440512358,97.3851462647,97.3262455062,
+	97.2673489984,97.208456779,97.149568886,97.0906853573,97.031806231,
+	96.9729315454,96.9140613384,96.8551956486,96.7963345141,96.7374779733,
+	96.6786260648,96.6197788271,96.5609362988,96.5020985186,96.4432655252,
+	96.3844373574,96.3256140541,96.2667956543,96.2079821969,96.1491737211,
+	96.090370266,96.0315718708,95.9727785748,95.9139904174,95.8552074379,
+	95.796429676,95.737657171,95.6788899628,95.6201280909,95.5613715951,
+	95.5026205153,95.4438748913,95.3851347632,95.3264001709,95.2676711546,
+	95.2089477545,95.1502300108,95.0915179637,95.0328116538,94.9741111215,
+	94.9154164072,94.8567275516,94.7980445954,94.7393675792,94.6806965439,
+	94.6220315304,94.5633725795,94.5047197323,94.44607303,94.3874325135,
+	94.3287982243,94.2701702035,94.2115484926,94.152933133,94.0943241661,
+	94.0357216337,93.9771255772,93.9185360386,93.8599530596,93.801376682,
+	93.7428069478,93.684243899,93.6256875779,93.5671380264,93.5085952869,
+	93.4500594017,93.3915304132,93.3330083638,93.2744932962,93.215985253,
+	93.1574842769,93.0989904107,93.0405036972,92.9820241794,92.9235519003,
+	92.8650869031,92.806629231,92.7481789271,92.689736035,92.631300598,
+	92.5728726596,92.5144522635,92.4560394534,92.397634273,92.3392367663,
+	92.2808469772,92.2224649498,92.1640907283,92.1057243567,92.0473658796,
+	91.9890153414,91.9306727865,91.8723382596,91.8140118055,91.7556934689,
+	91.6973832947,91.6390813282,91.5807876143,91.5225021983,91.4642251255,
+	91.4059564416,91.3476961919,91.2894444223,91.2312011785,91.1729665065,
+	91.1147404523,91.0565230622,90.9983143824,90.9401144593,90.8819233396,
+	90.8237410699,90.7655676971,90.7074032682,90.6492478303,90.5911014307,
+	90.5329641168,90.4748359361,90.4167169366,90.3586071659,90.3005066723,
+	90.242415504,90.1843337093,90.1262613369,90.0681984356,90.0101450544,
+	89.9521012424,89.8940670489,89.8360425236,89.7780277163,89.7200226769,
+	89.6620274557,89.6040421032,89.54606667,89.4881012072,89.4301457658,
+	89.3722003975,89.3142651538,89.2563400868,89.1984252488,89.1405206923,
+	89.0826264704,89.0247426361,88.966869243,88.9090063449,88.8511539961,
+	88.7933122511,88.7354811649,88.6776607928,88.6198511904,88.5620524139,
+	88.5042645199,88.4464875652,88.3887216073,88.3309667042,88.2732229142,
+	88.2154902961,88.1577689093,88.1000588138,88.04236007,87.9846727391,
+	87.9269968825,87.8693325627,87.8116798425,87.7540387854,87.6964094557,
+	87.6387919184,87.5811862391,87.5235924843,87.4660107213,87.408441018,
+	87.3508834435,87.2933380675,87.2358049606,87.1782841946,87.1207758422,
+	87.0632799768,87.0057966733,86.9483260074,86.8908680562,86.8334228976,
+	86.7759906111,86.7185712772,86.661164978,86.6037717966,86.5463918178,
+	86.4890251277,86.4316718142,86.3743319664,86.3170056754,86.2596930337,
+	86.2023941359,86.145109078,86.0878379584,86.0305808771,85.9733379363,
+	85.9161092405,85.8588948961,85.8016950119,85.7445096993,85.687339072,
+	85.6301832461,85.5730423407,85.5159164775,85.4588057811,85.4017103791,
+	85.3446304022,85.2875659842,85.2305172625,85.1734843777,85.1164674741,
+	85.0594666999,85.0024822069,84.945514151,84.8885626925,84.8316279957,
+	84.7747102297,84.717809568,84.6609261892,84.6040602768,84.5472120195,
+	84.4903816116,84.4335692527,84.3767751485,84.3199995108,84.2632425574,
+	84.2065045129,84.1497856085,84.0930860825,84.0364061805,83.9797461556,
+	83.9231062687,83.866486789,83.809887994,83.75331017,83.6967536122,
+	83.6402186255,83.5837055244,83.5272146335,83.470746288,83.4143008337,
+	83.3578786281,83.3014800399,83.2451054504,83.1887552531,83.1324298546,
+	83.0761296751,83.0198551485,82.9636067233,82.9073848632,82.8511900471,
+	82.79502277,82.7388835436,82.682772897,82.6266913768,82.5706395482,
+	82.5146179955,82.4586273228,82.4026681544,82.346741136,82.290846935,
+	82.2349862413,82.1791597684,82.1233682537,82.0676124596,82.0118931742,
+	81.9562112123,81.9005674161,81.844962656,81.7893978318,81.7338738734,
+	81.6783917418,81.6229524301,81.5675569644,81.5122064049,81.456901847,
+	81.4016444219,81.3464352983,81.291275683,81.2361668221,81.1811100021,
+	81.1261065514,81.0711578405,81.0162652843,80.9614303422,80.90665452,
+	80.8519393705,80.7972864951,80.7426975448,80.6881742212,80.6337182778,
+	80.579331521,80.5250158115,80.470773065,80.4166052536,80.3625144069,
+	80.3085026127,80.2545720181,80.2007248309,80.1469633197,80.0932898155,
+	80.0397067122,79.9862164673,79.9328216025,79.8795247049,79.8263284265,
+	79.7732354857,79.7202486668,79.6673708208,79.6146048653,79.5619537845,
+	79.5094206291,79.4570085162,79.4047206287,79.352560215,79.3005305881,
+	79.2486351248,79.1968772648,79.1452605095,79.0937884205,79.042464618,
+	78.9912927792,78.9402766362,78.8894199741,78.838726628,78.7882004811,
+	78.7378454614,78.6876655389,78.6376647223,78.5878470553,78.5382166134,
+	78.4887774995,78.4395338398,78.3904897799,78.3416494797,78.2930171091,
+	78.2445968429,78.1963928557,78.1484093165,78.1006503837,78.053120199,
+	78.0058228821,77.958762525,77.9119431858,77.8653688829,77.819043589,
+	77.7729712253,77.7271556551,77.6816006782,77.6363100247,77.591287349,
+	77.5465362241,77.5020601362,77.4578624787,77.4139465467,77.3703155323,
+	77.3269725192,77.2839204776,77.2411622604,77.1987005979,77.1565380947,
+	77.1146772253,77.0731203307,77.0318696155,76.990927145,76.9502948426,
+	76.909974488,76.8699677149,76.8302760101,76.7909007119,76.7518430099,
+	76.7131039444,76.6746844061,76.636585137,76.5988067306,76.5613496329,
+	76.5242141439,76.4874004191,76.4509084712,76.4147381725,76.3788892573,
+	76.3433613242,76.3081538394,76.2732661397,76.2386974356,76.2044468146,
+	76.1705132456,76.1368955816,76.1035925643,76.070602828,76.0379249031,
+	76.0055572212,75.9734981182,75.9417458394,75.9102985434,75.8791543063,
+	75.848311126,75.8177669265,75.7875195623,75.7575668221,75.7279064333,
+	75.6985360662,75.6694533373,75.6406558142,75.6121410187,75.5839064308,
+	75.5559494925,75.5282676111,75.5008581629,75.4737184964,75.4468459357,
+	75.4202377835,75.3938913241,75.3678038265,75.3419725471,75.3163947322,
+	75.291067621,75.2659884475,75.2411544433,75.2165628397,75.1922108698,
+	75.1680957703,75.1442147838,75.1205651605,75.0971441596,75.0739490514,
+	75.0509771182,75.0282256564,75.0056919772,74.9833734085,74.9612672952,
+	74.9393710013,74.9176819098,74.8961974247,74.874914971,74.8538319958,
+	74.8329459692,74.8122543847,74.7917547597,74.7714446366,74.7513215823,
+	74.7313831897,74.7116270773,74.6920508898,74.6726522985,74.6534290013,
+	74.634378723,74.6154992156,74.5967882581,74.578243657,74.5598632461,
+	74.5416448865,74.5235864667,74.5056859027,74.4879411377,74.470350142,
+	74.4529109135,74.4356214765,74.4184798829,74.4014842108,74.3846325653,
+	74.3679230776,74.3513539054,74.3349232322,74.3186292676,74.3024702466,
+	74.2864444294,74.2705501017,74.2547855738,74.2391491806,74.2236392814,
+	74.2082542598,74.1929925227,74.177852501,74.1628326486,74.1479314424,
+	74.133147382,74.1184789894,74.1039248086,74.0894834054,74.0751533673,
+	74.0609333028,74.0468218415,74.0328176334,74.0189193491,74.0051256791,
+	73.9914353336,73.9778470424,73.9643595544,73.9509716375,73.937682078,
+	73.9244896808,73.9113932687,73.8983916822,73.8854837795,73.8726684358,
+	73.8599445434,73.8473110113,73.8347667649,73.8223107457,73.8099419111,
+	73.7976592344,73.785461704,73.7733483235,73.7613181117,73.7493701016,
+	73.737503341,73.7257168917,73.7140098296,73.7023812443,73.6908302387,
+	73.6793559292,73.6679574452,73.6566339291,73.6453845356,73.6342084321,
+	73.6231047982,73.6120728253,73.6011117169,73.590220688,73.579398965,
+	73.5686457855,73.5579603984,73.547342063,73.5367900498,73.5263036396,
+	73.5158821233,73.5055248024,73.495230988,73.4850000013,73.474831173,
+	73.4647238434,73.4546773621,73.4446910879,73.4347643887,73.4248966411,
+	73.4150872306,73.4053355513,73.3956410057,73.3860030047,73.3764209671,
+	73.3668943202,73.3574224987,73.3480049456,73.3386411111,73.3293304532,
+	73.3200724372,73.3108665357,73.3017122285,73.2926090024,73.2835563511,
+	73.2745537752,73.2656007821,73.2566968855,73.2478416058,73.2390344699,
+	73.2302750107,73.2215627675,73.2128972856,73.2042781163,73.1957048168,
+	73.1871769501,73.178694085,73.1702557957,73.1618616621,73.1535112694,
+	73.1452042084,73.1369400749,73.12871847,73.1205389999,73.1124012759,
+	73.104304914,73.0962495354,73.0882347658,73.0802602359,73.0723255807,
+	73.0644304401,73.0565744583,73.0487572841,73.0409785705,73.0332379747,
+	73.0255351586,73.0178697878,73.0102415321,73.0026500655,72.9950950659,
+	72.9875762151,72.9800931987,72.9726457062,72.9652334309,72.9578560697,
+	72.950513323,72.9432048951,72.9359304935,72.9286898295,72.9214826175,
+	72.9143085755,72.9071674247,72.9000588896,72.8929826981,72.885938581,
+	72.8789262723,72.8719455093,72.8649960321,72.8580775839,72.8511899108,
+	72.844332762,72.8375058893,72.8307090475,72.8239419941,72.8172044895,
+	72.8104962966,72.8038171811,72.7971669113,72.7905452582,72.7839519951,
+	72.7773868982,72.7708497458,72.764340319,72.757858401,72.7514037776,
+	72.7449762369,72.7385755693,72.7322015676,72.7258540266,72.7195327435,
+	72.7132375179,72.7069681511,72.7007244468,72.694506211,72.6883132513,
+	72.6821453778,72.6760024024,72.6698841391,72.6637904036,72.6577210139,
+	72.6516757897,72.6456545528,72.6396571265,72.6336833363,72.6277330094,
+	72.6218059746,72.6159020628,72.6100211064,72.6041629397,72.5983273985,
+	72.5925143204,72.5867235447,72.5809549122,72.5752082655,72.5694834485,
+	72.5637803071,72.5580986883,72.5524384409,72.5467994152,72.5411814629,
+	72.5355844373,72.530008193,72.5244525861,72.5189174741,72.5134027161,
+	72.5079081723,72.5024337044,72.4969791754,72.4915444497,72.4861293931,
+	72.4807338724,72.475357756,72.4700009133,72.4646632153,72.4593445339,
+	72.4540447423,72.448763715,72.4435013277,72.4382574572,72.4330319815,
+	72.4278247797,72.4226357321,72.4174647202,72.4123116263,72.4071763341,
+	72.4020587284,72.3969586948,72.3918761201,72.3868108923,72.3817629002,
+	72.3767320336,72.3717181837,72.3667212421,72.3617411019,72.3567776569,
+	72.3518308019,72.3469004328,72.3419864461,72.3370887397,72.332207212,
+	72.3273417625,72.3224922916,72.3176587005,72.3128408914,72.3080387673,
+	72.3032522319,72.2984811901,72.2937255474,72.2889852101,72.2842600854,
+	72.2795500813,72.2748551066,72.2701750709,72.2655098845,72.2608594586,
+	72.2562237051,72.2516025367,72.2469958667,72.2424036093,72.2378256794,
+	72.2332619927,72.2287124653,72.2241770145,72.2196555578,72.2151480137,
+	72.2106543013,72.2061743404,72.2017080515,72.1972553556,72.1928161746,
+	72.1883904309,72.1839780475,72.1795789482,72.1751930572,72.1708202995,
+	72.1664606008,72.1621138871,72.1577800852,72.1534591226,72.1491509271,
+	72.1448554274,72.1405725526,72.1363022322,72.1320443967,72.1277989769,
+	72.123565904,72.1193451101,72.1151365275,72.1109400894,72.1067557292,
+	72.1025833809,72.0984229793,72.0942744593,72.0901377566,72.0860128072,
+	72.0818995479,72.0777979156,72.073707848,72.0696292831,72.0655621596,
+	72.0615064164,72.0574619931,72.0534288296,72.0494068663,72.0453960442,
+	72.0413963045,72.0374075891,72.0334298402,72.0294630004,72.0255070128,
+	72.0215618211,72.017627369,72.0137036011,72.009790462,72.0058878971,
+	72.0019958519,71.9981142724,71.9942431051,71.9903822968,71.9865317947,
+	71.9826915465,71.9788615,71.9750416037,71.9712318063,71.967432057,
+	71.9636423053,71.959862501,71.9560925943,71.9523325359,71.9485822768,
+	71.9448417681,71.9411109616,71.9373898094,71.9336782636,71.9299762771,
+	71.9262838028,71.9226007941,71.9189272048,71.9152629889,71.9116081006,
+	71.9079624947,71.9043261262,71.9006989504,71.8970809229,71.8934719996,
+	71.8898721369,71.8862812912,71.8826994194,71.8791264786,71.8755624264,
+	71.8720072205,71.8684608189,71.8649231799,71.8613942621,71.8578740245,
+	71.8543624263,71.8508594268,71.8473649859,71.8438790635,71.8404016199,
+	71.8369326157,71.8334720117,71.8300197691,71.826575849,71.8231402132,
+	71.8197128235,71.816293642,71.8128826312,71.8094797536,71.806084972,
+	71.8026982497,71.79931955,71.7959488366,71.7925860731,71.7892312238,
+	71.785884253,71.7825451252,71.7792138052,71.775890258,71.7725744489,
+	71.7692663434,71.7659659071,71.762673106,71.7593879063,71.7561102742,
+	71.7528401764,71.7495775796,71.746322451,71.7430747576,71.7398344669,
+	71.7366015466,71.7333759644,71.7301576886,71.7269466872,71.7237429288,
+	71.7205463819,71.7173570156,71.7141747987,71.7109997006,71.7078316906,
+	71.7046707384,71.7015168139,71.698369887,71.6952299278,71.6920969069,
+	71.6889707947,71.685851562,71.6827391798,71.679633619,71.676534851,
+	71.6734428473,71.6703575795,71.6672790193,71.6642071389,71.6611419102,
+	71.6580833057,71.6550312978,71.6519858592,71.6489469627,71.6459145813,
+	71.6428886881,71.6398692565,71.6368562598,71.6338496718,71.6308494663,
+	71.6278556171,71.6248680983,71.6218868843,71.6189119494,71.6159432682,
+	71.6129808154,71.6100245659,71.6070744946,71.6041305767,71.6011927875,
+	71.5982611025,71.5953354972,71.5924159474,71.589502429,71.5865949179,
+	71.5836933903,71.5807978225,71.577908191,71.5750244723,71.5721466431,
+	71.5692746802,71.5664085606,71.5635482615,71.56069376,71.5578450334,
+	71.5550020594,71.5521648155,71.5493332795,71.5465074292,71.5436872426,
+	71.5408726979,71.5380637733,71.5352604472,71.532462698,71.5296705045,
+	71.5268838452,71.5241026992,71.5213270452,71.5185568625,71.5157921303,
+	71.5130328278,71.5102789345,71.5075304299,71.5047872938,71.5020495058,
+	71.4993170459,71.4965898941,71.4938680305,71.4911514352,71.4884400887,
+	71.4857339713,71.4830330636,71.4803373463,71.4776468,71.4749614057,
+	71.4722811443,71.4696059969,71.4669359446,71.4642709687,71.4616110506,
+	71.4589561717,71.4563063136,71.453661458,71.4510215867,71.4483866814,
+	71.4457567242,71.4431316972,71.4405115824,71.4378963621,71.4352860186,
+	71.4326805345,71.4300798922,71.4274840743,71.4248930635,71.4223068427,
+	71.4197253947,71.4171487025,71.4145767492,71.412009518,71.409446992,
+	71.4068891546,71.4043359893,71.4017874795,71.3992436089,71.3967043611,
+	71.3941697198,71.3916396689,71.3891141924,71.3865932742,71.3840768985,
+	71.3815650494,71.3790577112,71.3765548681,71.3740565047,71.3715626054,
+	71.3690731547,71.3665881374,71.3641075382,71.3616313418,71.3591595332,
+	71.3566920973,71.3542290191,71.3517702838,71.3493158765,71.3468657825,
+	71.3444199871,71.3419784758,71.3395412339,71.3371082471,71.334679501,
+	71.3322549813,71.3298346737,71.3274185641,71.3250066384,71.3225988825,
+	71.3201952826,71.3177958246,71.3154004948,71.3130092795,71.3106221649,
+	71.3082391374,71.3058601835,71.3034852898,71.3011144427,71.2987476289,
+	71.2963848352,71.2940260482,71.2916712549,71.2893204422,71.286973597,
+	71.2846307063,71.2822917573,71.279956737,71.2776256327,71.2752984317,
+	71.2729751214,71.270655689,71.2683401221,71.2660284081,71.2637205347,
+	71.2614164895,71.2591162602,71.2568198345,71.2545272002,71.2522383453,
+	71.2499532575,71.247671925,71.2453943357,71.2431204777,71.2408503393,
+	71.2385839085,71.2363211736,71.234062123,71.2318067451,71.2295550282,
+	71.2273069608,71.2250625314,71.2228217287,71.2205845412,71.2183509577,
+	71.2161209669,71.2138945576,71.2116717186,71.2094524388,71.2072367071,
+	71.2050245127,71.2028158444,71.2006106914,71.1984090428,71.1962108879,
+	71.1940162159,71.191825016,71.1896372776,71.1874529901,71.1852721429,
+	71.1830947256,71.1809207276,71.1787501385,71.176582948,71.1744191456,
+	71.1722587212,71.1701016646,71.1679479654,71.1657976135,71.163650599,
+	71.1615069116,71.1593665414,71.1572294785,71.1550957128,71.1529652346,
+	71.1508380339,71.1487141011,71.1465934263,71.1444759999,71.1423618121,
+	71.1402508534,71.1381431141,71.1360385848,71.133937256,71.1318391181,
+	71.1297441618,71.1276523777,71.1255637565,71.1234782889,71.1213959656,
+	71.1193167774,71.1172407152,71.1151677698,71.1130979321,71.1110311931,
+	71.1089675437,71.106906975,71.1048494781,71.102795044,71.1007436639,
+	71.098695329,71.0966500304,71.0946077595,71.0925685075,71.0905322657,
+	71.0884990255,71.0864687783,71.0844415156,71.0824172287,71.0803959093,
+	71.0783775489,71.0763621389,71.0743496712,71.0723401372,71.0703335287,
+	71.0683298374,71.066329055,71.0643311734,71.0623361844,71.0603440798,
+	71.0583548515,71.0563684914,71.0543849915,71.0524043438,71.0504265403,
+	71.048451573,71.0464794341,71.0445101156,71.0425436098,71.0405799088,
+	71.0386190048,71.03666089,71.0347055568,71.0327529975,71.0308032044,
+	71.0288561699,71.0269118863,71.0249703462,71.023031542,71.0210954661,
+	71.0191621112,71.0172314698,71.0153035344,71.0133782977,71.0114557523,
+	71.009535891,71.0076187064,71.0057041912,71.0037923382,71.0018831403,
+	70.9999765902,70.9980726807,70.9961714049,70.9942727555,70.9923767255,
+	70.9904833079,70.9885924957,70.9867042819,70.9848186595,70.9829356216,
+	70.9810551613,70.9791772718,70.9773019462,70.9754291776,70.9735589594,
+	70.9716912847,70.9698261468,70.9679635389,70.9661034545,70.9642458868,
+	70.9623908292,70.9605382751,70.958688218,70.9568406512,70.9549955682,
+	70.9531529626,70.9513128279,70.9494751575,70.9476399451,70.9458071843,
+	70.9439768687,70.9421489919,70.9403235476,70.9385005294,70.9366799312,
+	70.9348617467,70.9330459695,70.9312325936,70.9294216127,70.9276130206,
+	70.9258068113,70.9240029785,70.9222015163,70.9204024184,70.918605679,
+	70.9168112919,70.9150192512,70.9132295508,70.9114421849,70.9096571474,
+	70.9078744325,70.9060940343,70.904315947,70.9025401645,70.9007666812,
+	70.8989954913,70.8972265889,70.8954599683,70.8936956238,70.8919335496,
+	70.89017374,70.8884161894,70.8866608922,70.8849078426,70.8831570351,
+	70.8814084641,70.879662124,70.8779180092,70.8761761143,70.8744364337,
+	70.8726989619,70.8709636935,70.869230623,70.867499745,70.865771054,
+	70.8640445448,70.8623202118,70.8605980499,70.8588780535,70.8571602175,
+	70.8554445365,70.8537310053,70.8520196185,70.850310371,70.8486032576,
+	70.846898273,70.8451954121,70.8434946697,70.8417960407,70.8400995199,
+	70.8384051023,70.8367127827,70.8350225561,70.8333344174,70.8316483616,
+	70.8299643837,70.8282824787,70.8266026417,70.8249248675,70.8232491514,
+	70.8215754884,70.8199038735,70.8182343019,70.8165667687,70.8149012691,
+	70.8132377981,70.8115763511,70.8099169231,70.8082595094,70.8066041053,
+	70.8049507059,70.8032993065,70.8016499024,70.8000024889,70.7983570614,
+	70.796713615,70.7950721452,70.7934326474,70.7917951169,70.7901595491,
+	70.7885259394,70.7868942832,70.785264576,70.7836368132,70.7820109903,
+	70.7803871028,70.7787651462,70.777145116,70.7755270077,70.7739108169,
+	70.7722965391,70.77068417,70.769073705,70.7674651399,70.7658584703,
+	70.7642536917,70.7626507999,70.7610497905,70.7594506591,70.7578534016,
+	70.7562580136,70.7546644907,70.7530728289,70.7514830237,70.7498950711,
+	70.7483089667,70.7467247064,70.745142286,70.7435617013,70.7419829481,
+	70.7404060224,70.7388309199,70.7372576365,70.7356861682,70.7341165109,
+	70.7325486605,70.7309826128,70.729418364,70.7278559098,70.7262952464,
+	70.7247363697,70.7231792756,70.7216239603,70.7200704198,70.71851865,
+	70.716968647,70.715420407,70.713873926,70.7123292001,70.7107862253,
+	70.7092449979,70.707705514,70.7061677696,70.704631761,70.7030974843,
+	70.7015649357,70.7000341115,70.6985050077,70.6969776207,70.6954519467,
+	70.6939279818,70.6924057225,70.6908851648,70.6893663052,70.68784914,
+	70.6863336653,70.6848198776,70.6833077731,70.6817973482,70.6802885993,
+	70.6787815228,70.6772761149,70.6757723721,70.6742702908,70.6727698674,
+	70.6712710983,70.66977398,70.6682785089,70.6667846814,70.6652924941,
+	70.6638019434,70.6623130257,70.6608257377,70.6593400758,70.6578560365,
+	70.6563736163,70.6548928119,70.6534136197,70.6519360364,70.6504600585,
+	70.6489856826,70.6475129053,70.6460417232,70.6445721329,70.6431041311,
+	70.6416377145,70.6401728795,70.638709623,70.6372479416,70.635787832,
+	70.6343292908,70.6328723148,70.6314169007,70.6299630452,70.6285107451,
+	70.6270599971,70.6256107979,70.6241631443,70.6227170332,70.6212724612,
+	70.6198294252,70.618387922,70.6169479483,70.6155095011,70.6140725771,
+	70.6126371732,70.6112032863,70.6097709132,70.6083400508,70.6069106959,
+	70.6054828456,70.6040564965,70.6026316458,70.6012082902,70.5997864268,
+	70.5983660524,70.5969471641,70.5955297587,70.5941138333,70.5926993847,
+	70.5912864101,70.5898749064,70.5884648705,70.5870562996,70.5856491906,
+	70.5842435406,70.5828393466,70.5814366056,70.5800353147,70.578635471,
+	70.5772370716,70.5758401135,70.5744445938,70.5730505096,70.5716578581,
+	70.5702666363,70.5688768414,70.5674884705,70.5661015208,70.5647159894,
+	70.5633318734,70.5619491701,70.5605678767,70.5591879902,70.5578095079,
+	70.5564324271,70.5550567448,70.5536824584,70.552309565,70.550938062,
+	70.5495679464,70.5481992157,70.546831867,70.5454658977,70.5441013049,
+	70.542738086,70.5413762383,70.5400157591,70.5386566456,70.5372988952,
+	70.5359425053,70.534587473,70.5332337959,70.5318814712,70.5305304963,
+	70.5291808686,70.5278325853,70.526485644,70.5251400419,70.5237957765,
+	70.5224528452,70.5211112453,70.5197709744,70.5184320297,70.5170944088,
+	70.5157581091,70.514423128,70.513089463,70.5117571115,70.510426071,
+	70.5090963391,70.507767913,70.5064407904,70.5051149688,70.5037904455,
+	70.5024672183,70.5011452845,70.4998246417,70.4985052874,70.4971872192,
+	70.4958704345,70.494554931,70.4932407063,70.4919277578,70.4906160832,
+	70.48930568,70.4879965458,70.4866886782,70.4853820748,70.4840767332,
+	70.4827726511,70.481469826,70.4801682555,70.4788679374,70.4775688692,
+	70.4762710486,70.4749744732,70.4736791407,70.4723850488,70.4710921952,
+	70.4698005774,70.4685101933,70.4672210404,70.4659331165,70.4646464193,
+	70.4633609466
+	};
+
+tubetable_12AU7_rtable_0(r) = (tubetable_12AU7_0,r):rdtable;
+tubetable_12AU7_rtable_1(r) = (tubetable_12AU7_1,r):rdtable;
+
+
+// generated by ../../tools/tube_transfer.py
+// tube: 12AX7
+// plate current function: triode
+// mu: 100
+// kx: 1.4
+// kg1: 1060
+// kp: 600
+// kvb: 300
+
+tubetable_12AX7_0 = waveform{
+	249.98706929,249.986851225,249.986629489,249.986404021,249.986174757,
+	249.985941635,249.985704589,249.985463554,249.985218463,249.984969247,
+	249.984715838,249.984458166,249.984196158,249.983929743,249.983658846,
+	249.983383392,249.983103306,249.982818508,249.982528921,249.982234464,
+	249.981935056,249.981630613,249.981321052,249.981006287,249.98068623,
+	249.980360793,249.980029887,249.979693419,249.979351296,249.979003424,
+	249.978649708,249.978290048,249.977924346,249.9775525,249.977174409,
+	249.976789967,249.976399069,249.976001606,249.97559747,249.975186548,
+	249.974768727,249.974343893,249.973911927,249.973472711,249.973026125,
+	249.972572044,249.972110345,249.9716409,249.971163579,249.970678252,
+	249.970184785,249.969683043,249.969172887,249.968654177,249.968126772,
+	249.967590526,249.967045292,249.96649092,249.965927258,249.965354153,
+	249.964771446,249.964178978,249.963576587,249.962964107,249.962341372,
+	249.961708211,249.96106445,249.960409914,249.959744424,249.959067797,
+	249.95837985,249.957680393,249.956969237,249.956246188,249.955511048,
+	249.954763616,249.95400369,249.953231063,249.952445523,249.951646857,
+	249.950834849,249.950009276,249.949169916,249.94831654,249.947448916,
+	249.946566809,249.945669979,249.944758184,249.943831177,249.942888706,
+	249.941930516,249.940956349,249.93996594,249.938959023,249.937935324,
+	249.936894568,249.935836475,249.934760758,249.933667127,249.932555289,
+	249.931424944,249.930275788,249.929107511,249.9279198,249.926712337,
+	249.925484796,249.92423685,249.922968162,249.921678394,249.9203672,
+	249.91903423,249.917679127,249.916301529,249.914901069,249.913477372,
+	249.912030061,249.910558748,249.909063042,249.907542547,249.905996856,
+	249.904425561,249.902828244,249.901204482,249.899553844,249.897875894,
+	249.896170188,249.894436274,249.892673696,249.890881989,249.889060679,
+	249.887209288,249.885327328,249.883414305,249.881469716,249.879493052,
+	249.877483793,249.875441414,249.87336538,249.87125515,249.869110171,
+	249.866929885,249.864713724,249.86246111,249.860171458,249.857844173,
+	249.855478652,249.853074281,249.850630438,249.848146491,249.845621799,
+	249.843055711,249.840447565,249.837796689,249.835102404,249.832364016,
+	249.829580824,249.826752115,249.823877166,249.820955243,249.8179856,
+	249.81496748,249.811900117,249.80878273,249.80561453,249.802394713,
+	249.799122465,249.795796959,249.792417358,249.788982809,249.785492449,
+	249.781945403,249.778340779,249.774677678,249.770955183,249.767172365,
+	249.763328284,249.759421981,249.75545249,249.751418824,249.747319988,
+	249.743154968,249.738922738,249.734622257,249.730252468,249.725812301,
+	249.72130067,249.716716471,249.712058589,249.70732589,249.702517225,
+	249.697631429,249.692667321,249.687623703,249.682499361,249.677293063,
+	249.672003562,249.666629592,249.661169871,249.655623098,249.649987954,
+	249.644263106,249.638447197,249.632538857,249.626536694,249.620439299,
+	249.614245244,249.607953082,249.601561346,249.59506855,249.588473189,
+	249.581773739,249.574968653,249.568056367,249.561035295,249.553903831,
+	249.546660348,249.5393032,249.531830718,249.524241211,249.516532969,
+	249.508704259,249.500753327,249.492678397,249.48447767,249.476149326,
+	249.467691521,249.459102391,249.450380046,249.441522576,249.432528047,
+	249.423394501,249.414119957,249.404702411,249.395139834,249.385430176,
+	249.37557136,249.365561287,249.355397831,249.345078845,249.334602156,
+	249.323965565,249.313166851,249.302203767,249.291074039,249.27977537,
+	249.268305439,249.256661896,249.244842368,249.232844458,249.220665739,
+	249.208303762,249.195756051,249.183020104,249.170093394,249.156973366,
+	249.143657441,249.130143014,249.116427453,249.102508098,249.088382267,
+	249.074047249,249.059500307,249.044738677,249.029759572,249.014560175,
+	248.999137645,248.983489114,248.967611688,248.951502446,248.935158442,
+	248.918576704,248.901754233,248.884688005,248.867374969,248.84981205,
+	248.831996145,248.813924127,248.795592843,248.776999115,248.75813974,
+	248.739011488,248.719611106,248.699935316,248.679980814,248.659744274,
+	248.639222342,248.618411645,248.597308781,248.575910327,248.554212837,
+	248.532212841,248.509906845,248.487291335,248.464362771,248.441117595,
+	248.417552224,248.393663055,248.369446462,248.344898801,248.320016406,
+	248.29479559,248.269232647,248.243323852,248.217065459,248.190453706,
+	248.163484811,248.136154974,248.108460379,248.080397191,248.05196156,
+	248.02314962,247.993957487,247.964381265,247.934417041,247.904060889,
+	247.87330887,247.84215703,247.810601403,247.778638011,247.746262866,
+	247.713471967,247.680261303,247.646626855,247.612564592,247.578070476,
+	247.543140461,247.507770494,247.471956513,247.435694453,247.398980241,
+	247.3618098,247.32417905,247.286083906,247.247520279,247.208484082,
+	247.168971222,247.128977607,247.088499146,247.047531747,247.00607132,
+	246.964113777,246.921655031,246.878691002,246.835217611,246.791230785,
+	246.746726457,246.701700566,246.656149058,246.610067887,246.563453015,
+	246.516300414,246.468606066,246.420365964,246.371576111,246.322232524,
+	246.272331232,246.221868279,246.170839722,246.119241634,246.067070104,
+	246.014321237,245.960991157,245.907076004,245.852571939,245.79747514,
+	245.74178181,245.685488167,245.628590455,245.571084939,245.512967907,
+	245.454235672,245.394884569,245.334910961,245.274311236,245.213081807,
+	245.151219115,245.08871963,245.02557985,244.9617963,244.897365536,
+	244.832284146,244.766548747,244.700155987,244.633102547,244.565385141,
+	244.497000515,244.427945449,244.358216758,244.287811291,244.216725932,
+	244.144957602,244.072503257,243.999359889,243.92552453,243.850994248,
+	243.775766147,243.699837372,243.623205106,243.545866572,243.467819032,
+	243.389059786,243.309586179,243.229395592,243.148485449,243.066853216,
+	242.984496398,242.901412546,242.817599248,242.733054138,242.647774892,
+	242.561759227,242.475004906,242.387509732,242.299271553,242.210288262,
+	242.120557793,242.030078124,241.938847279,241.846863324,241.754124371,
+	241.660628575,241.566374134,241.471359294,241.375582341,241.279041608,
+	241.181735472,241.083662355,240.984820721,240.885209081,240.784825989,
+	240.683670043,240.581739885,240.479034203,240.375551726,240.271291229,
+	240.166251531,240.060431493,239.95383002,239.846446061,239.738278607,
+	239.629326695,239.5195894,239.409065844,239.29775519,239.185656641,
+	239.072769446,238.959092892,238.84462631,238.729369072,238.61332059,
+	238.496480317,238.378847747,238.260422414,238.141203892,238.021191795,
+	237.900385775,237.778785524,237.656390773,237.533201291,237.409216884,
+	237.284437398,237.158862715,237.032492753,236.905327469,236.777366855,
+	236.648610938,236.519059783,236.388713489,236.257572188,236.125636051,
+	235.992905278,235.859380107,235.725060807,235.58994768,235.454041062,
+	235.31734132,235.179848852,235.041564089,234.902487493,234.762619556,
+	234.6219608,234.480511776,234.338273067,234.195245283,234.051429062,
+	233.906825072,233.761434008,233.615256591,233.468293572,233.320545726,
+	233.172013855,233.022698786,232.872601372,232.721722492,232.570063047,
+	232.417623965,232.264406196,232.110410713,231.955638512,231.800090614,
+	231.643768059,231.48667191,231.328803251,231.170163188,231.010752847,
+	230.850573373,230.689625933,230.527911712,230.365431915,230.202187764,
+	230.0381805,229.873411384,229.707881693,229.541592719,229.374545774,
+	229.206742186,229.038183299,228.868870471,228.698805078,228.527988509,
+	228.356422169,228.184107477,228.011045867,227.837238785,227.662687692,
+	227.487394061,227.311359378,227.134585141,226.957072863,226.778824064,
+	226.59984028,226.420123056,226.239673947,226.058494521,225.876586355,
+	225.693951036,225.510590161,225.326505336,225.141698178,224.956170309,
+	224.769923365,224.582958985,224.39527882,224.206884527,224.017777772,
+	223.827960226,223.637433569,223.446199487,223.254259674,223.061615828,
+	222.868269655,222.674222866,222.479477179,222.284034315,222.087896002,
+	221.891063973,221.693539966,221.495325721,221.296422987,221.096833513,
+	220.896559053,220.695601367,220.493962216,220.291643365,220.088646583,
+	219.884973642,219.680626315,219.475606381,219.269915618,219.063555809,
+	218.856528737,218.64883619,218.440479954,218.231461819,218.021783577,
+	217.811447019,217.600453941,217.388806137,217.176505402,216.963553533,
+	216.749952328,216.535703584,216.3208091,216.105270675,215.889090106,
+	215.672269193,215.454809735,215.23671353,215.017982376,214.798618071,
+	214.578622412,214.357997196,214.136744219,213.914865275,213.692362159,
+	213.469236664,213.245490582,213.021125704,212.796143819,212.570546714,
+	212.344336178,212.117513994,211.890081946,211.662041815,211.433395383,
+	211.204144425,210.97429072,210.74383604,210.512782158,210.281130844,
+	210.048883865,209.816042987,209.582609974,209.348586585,209.113974579,
+	208.878775712,208.642991738,208.406624407,208.169675468,207.932146665,
+	207.694039743,207.455356441,207.216098496,206.976267643,206.735865613,
+	206.494894135,206.253354936,206.011249738,205.76858026,205.52534822,
+	205.281555332,205.037203306,204.792293851,204.54682867,204.300809466,
+	204.054237936,203.807115776,203.559444679,203.311226332,203.062462422,
+	202.813154631,202.563304638,202.312914121,202.06198475,201.810518197,
+	201.558516128,201.305980206,201.05291209,200.799313438,200.545185904,
+	200.290531137,200.035350786,199.779646493,199.5234199,199.266672645,
+	199.009406363,198.751622683,198.493323236,198.234509646,197.975183536,
+	197.715346523,197.455000226,197.194146256,196.932786223,196.670921736,
+	196.408554398,196.145685811,195.882317572,195.618451279,195.354088524,
+	195.089230896,194.823879985,194.558037374,194.291704646,194.024883381,
+	193.757575156,193.489781546,193.221504124,192.952744459,192.68350412,
+	192.413784672,192.143587679,191.872914702,191.601767301,191.330147033,
+	191.058055454,190.785494118,190.512464577,190.238968382,189.965007082,
+	189.690582224,189.415695355,189.14034802,188.864541763,188.588278126,
+	188.311558653,188.034384883,187.756758358,187.478680617,187.200153199,
+	186.921177645,186.641755492,186.36188828,186.081577548,185.800824834,
+	185.519631679,185.237999622,184.955930205,184.673424969,184.390485457,
+	184.107113213,183.823309782,183.539076713,183.254415552,182.969327853,
+	182.683815168,182.397879052,182.111521065,181.824742767,181.537545724,
+	181.249931504,180.961901678,180.673457823,180.384601519,180.095334351,
+	179.805657909,179.515573788,179.225083588,178.934188917,178.642891387,
+	178.351192617,178.059094236,177.766597877,177.473705181,177.1804178,
+	176.886737393,176.592665628,176.298204182,176.003354745,175.708119016,
+	175.412498704,175.116495531,174.820111234,174.523347558,174.226206264,
+	173.92868913,173.630797944,173.332534512,173.033900658,172.734898219,
+	172.435529055,172.13579504,171.835698069,171.53524006,171.234422948,
+	170.933248694,170.631719279,170.32983671,170.027603019,169.725020263,
+	169.422090529,169.118815931,168.815198611,168.511240746,168.206944541,
+	167.902312237,167.597346111,167.292048474,166.986421676,166.680468107,
+	166.374190197,166.06759042,165.760671293,165.453435381,165.145885296,
+	164.8380237,164.529853307,164.221376886,163.912597261,163.603517315,
+	163.294139991,162.984468296,162.674505303,162.36425415,162.05371805,
+	161.742900285,161.431804217,161.120433284,160.808791007,160.496880994,
+	160.184706939,159.872272629,159.559581944,159.246638866,158.933447477,
+	158.620011964,158.306336627,157.992425878,157.678284247,157.363916386,
+	157.049327076,156.734521226,156.419503883,156.104280235,155.788855613,
+	155.473235502,155.15742554,154.841431529,154.525259436,154.2089154,
+	153.89240574,153.575736958,153.258915746,152.941948993,152.624843791,
+	152.307607442,151.990247462,151.672771591,151.3551878,151.037504296,
+	150.719729528,150.4018722,150.083941272,149.765945972,149.4478958,
+	149.129800541,148.811670267,148.493515348,148.17534646,147.857174591,
+	147.539011052,147.220867482,146.90275586,146.584688509,146.266678104,
+	145.948737684,145.630880657,145.313120806,144.995472301,144.677949704,
+	144.360567975,144.043342481,143.726289002,143.409423738,143.092763314,
+	142.776324787,142.46012565,142.144183838,141.828517734,141.513146167,
+	141.198088421,140.883364237,140.56899381,140.254997798,139.941397314,
+	139.628213931,139.31546968,139.003187046,138.691388964,138.380098818,
+	138.069340432,137.759138065,137.449516402,137.140500548,136.832116012,
+	136.524388701,136.217344903,135.911011273,135.605414819,135.300582882,
+	134.99654312,134.693323486,134.390952204,134.089457749,133.788868823,
+	133.489214324,133.190523322,132.89282503,132.596148773,132.300523955,
+	132.005980028,131.712546456,131.420252683,131.129128093,130.839201977,
+	130.550503492,130.263061625,129.97690515,129.692062595,129.408562198,
+	129.126431866,128.845699141,128.566391153,128.288534586,128.012155639,
+	127.737279983,127.463932729,127.19213839,126.921920841,126.653303293,
+	126.386308253,126.120957494,125.857272028,125.595272075,125.334977038,
+	125.076405477,124.819575089,124.564502686,124.311204176,124.059694549,
+	123.809987864,123.562097233,123.316034816,123.071811813,122.829438459,
+	122.588924021,122.3502768,122.113504129,121.878612383,121.645606978,
+	121.414492385,121.185272137,120.957948844,120.732524201,120.508999009,
+	120.287373188,120.067645798,119.849815055,119.633878355,119.419832294,
+	119.207672691,118.997394612,118.788992394,118.582459671,118.377789395,
+	118.174973871,117.974004772,117.774873176,117.577569586,117.382083958,
+	117.188405731,116.996523847,116.806426787,116.618102586,116.431538869,
+	116.246722869,116.063641457,115.882281163,115.702628206,115.524668508,
+	115.348387726,115.173771271,115.000804328,114.82947188,114.659758727,
+	114.491649506,114.325128711,114.160180708,113.996789759,113.834940032,
+	113.674615621,113.515800563,113.358478849,113.20263444,113.048251282,
+	112.895313317,112.743804495,112.593708787,112.445010196,112.297692766,
+	112.151740591,112.007137828,111.863868702,111.721917517,111.581268659,
+	111.441906608,111.303815943,111.166981347,111.031387613,110.897019652,
+	110.763862493,110.63190129,110.501121329,110.371508026,110.243046933,
+	110.115723745,109.989524294,109.864434561,109.740440669,109.617528892,
+	109.495685656,109.374897534,109.255151254,109.1364337,109.018731905,
+	108.902033061,108.786324515,108.671593767,108.557828476,108.445016453,
+	108.333145667,108.222204241,108.112180452,108.003062732,107.894839664,
+	107.787499986,107.681032587,107.575426505,107.470670928,107.366755194,
+	107.263668787,107.161401337,107.059942619,106.959282552,106.859411195,
+	106.760318751,106.661995559,106.564432098,106.467618982,106.37154696,
+	106.276206914,106.181589858,106.087686935,105.994489418,105.901988705,
+	105.81017632,105.719043911,105.628583246,105.538786217,105.44964483,
+	105.361151211,105.273297602,105.186076356,105.09947994,105.013500931,
+	104.928132016,104.843365988,104.759195746,104.675614294,104.592614738,
+	104.510190286,104.428334244,104.347040018,104.266301109,104.186111115,
+	104.106463726,104.027352725,103.948771984,103.870715468,103.793177227,
+	103.716151398,103.639632204,103.563613952,103.48809103,103.41305791,
+	103.33850914,103.26443935,103.190843246,103.117715611,103.045051301,
+	102.972845249,102.901092457,102.829788,102.758927024,102.688504742,
+	102.618516438,102.54895746,102.479823222,102.411109205,102.342810952,
+	102.274924068,102.207444221,102.140367139,102.07368861,102.007404481,
+	101.941510654,101.876003092,101.810877811,101.746130883,101.681758433,
+	101.617756641,101.554121738,101.490850007,101.427937781,101.365381444,
+	101.303177428,101.241322214,101.179812331,101.118644352,101.057814898,
+	100.997320637,100.937158279,100.877324577,100.817816329,100.758630377,
+	100.6997636,100.641212922,100.582975306,100.525047756,100.467427312,
+	100.410111057,100.353096108,100.296379621,100.23995879,100.183830844,
+	100.127993045,100.072442696,100.017177128,99.9621937113,99.9074898464,
+	99.8530629679,99.7989105427,99.7450300696,99.6914190787,99.6380751312,
+	99.5849958187,99.5321787628,99.4796216147,99.4273220547,99.3752777916,
+	99.3234865625,99.2719461323,99.2206542933,99.1696088648,99.1188076924,
+	99.0682486481,99.0179296296,98.9678485599,98.918003387,98.8683920837,
+	98.8190126467,98.769863097,98.7209414788,98.6722458598,98.6237743302,
+	98.5755250031,98.5274960135,98.4796855184,98.4320916962,98.3847127468,
+	98.3375468908,98.2905923695,98.2438474444,98.1973103972,98.1509795293,
+	98.1048531614,98.0589296337,98.013207305,97.9676845528,97.922359773,
+	97.8772313798,97.8322978049,97.7875574979,97.7430089255,97.6986505718,
+	97.6544809376,97.6104985402,97.5667019136,97.5230896077,97.4796601886,
+	97.4364122381,97.3933443532,97.3504551465,97.3077432458,97.2652072933,
+	97.2228459464,97.1806578767,97.1386417702,97.0967963268,97.0551202605,
+	97.0136122989,96.9722711833,96.931095668,96.8900845209,96.8492365225,
+	96.8085504664,96.7680251586,96.7276594179,96.687452075,96.6474019731,
+	96.6075079673,96.5677689244,96.528183723,96.4887512533,96.4494704166,
+	96.4103401258,96.3713593045,96.3325268876,96.2938418206,96.2553030595,
+	96.2169095712,96.1786603327,96.1405543314,96.1025905648,96.0647680402,
+	96.0270857751,95.9895427965,95.9521381411,95.9148708551,95.8777399941,
+	95.840744623,95.8038838156,95.767156655,95.7305622332,95.6940996508,
+	95.6577680174,95.621566451,95.5854940781,95.5495500336,95.5137334607,
+	95.4780435108,95.4424793434,95.4070401257,95.3717250333,95.3365332491,
+	95.3014639639,95.2665163763,95.231689692,95.1969831244,95.1623958942,
+	95.1279272293,95.0935763647,95.0593425426,95.0252250121,94.9912230293,
+	94.957335857,94.9235627648,94.889903029,94.8563559325,94.8229207646,
+	94.7895968211,94.7563834042,94.7232798225,94.6902853904,94.6573994289,
+	94.6246212649,94.5919502312,94.5593856666,94.5269269159,94.4945733296,
+	94.4623242638,94.4301790804,94.398137147,94.3661978366,94.3343605276,
+	94.3026246041,94.2709894553,94.2394544758,94.2080190654,94.1766826291,
+	94.145444577,94.1143043243,94.0832612913,94.052314903,94.0214645895,
+	93.9907097857,93.9600499313,93.9294844707,93.899012853,93.8686345319,
+	93.8383489659,93.8081556177,93.7780539548,93.7480434489,93.7181235762,
+	93.6882938173,93.658553657,93.6289025843,93.5993400927,93.5698656795,
+	93.5404788464,93.5111790989,93.4819659468,93.4528389037,93.4237974873,
+	93.3948412191,93.3659696245,93.3371822327,93.3084785767,93.2798581933,
+	93.2513206229,93.2228654096,93.1944921013,93.1662002492,93.1379894083,
+	93.109859137,93.0818089971,93.0538385542,93.0259473769,92.9981350374,
+	92.9704011112,92.9427451771,92.9151668171,92.8876656167,92.8602411644,
+	92.8328930518,92.8056208739,92.7784242286,92.7513027171,92.7242559433,
+	92.6972835146,92.670385041,92.6435601356,92.6168084145,92.5901294966,
+	92.5635230038,92.5369885607,92.5105257949,92.4841343366,92.4578138189,
+	92.4315638777,92.4053841514,92.3792742812,92.353233911,92.3272626873,
+	92.3013602592,92.2755262785,92.2497603994,92.2240622787,92.1984315757,
+	92.1728679522,92.1473710724,92.1219406032,92.0965762136,92.0712775751,
+	92.0460443617,92.0208762495,91.9957729173,91.9707340457,91.9457593182,
+	91.9208484199,91.8960010388,91.8712168645,91.8464955894,91.8218369075,
+	91.7972405155,91.7727061118,91.7482333973,91.7238220746,91.6994718488,
+	91.6751824268,91.6509535176,91.6267848322,91.6026760837,91.5786269871,
+	91.5546372594,91.5307066197,91.5068347888,91.4830214895,91.4592664466,
+	91.4355693866,91.4119300382,91.3883481315,91.3648233988,91.3413555741,
+	91.3179443931,91.2945895935,91.2712909146,91.2480480975,91.224860885,
+	91.2017290219,91.1786522542,91.1556303301,91.1326629992,91.1097500128,
+	91.086891124,91.0640860873,91.041334659,91.0186365969,90.9959916605,
+	90.9733996109,90.9508602106,90.9283732238,90.9059384162,90.883555555,
+	90.8612244091,90.8389447485,90.8167163451,90.7945389721,90.7724124041,
+	90.7503364174,90.7283107894,90.7063352991,90.6844097271,90.6625338551,
+	90.6407074663,90.6189303453,90.5972022781,90.5755230521,90.5538924558,
+	90.5323102793,90.510776314,90.4892903525,90.4678521887,90.4464616179,
+	90.4251184365,90.4038224425,90.3825734349,90.3613712139,90.3402155812,
+	90.3191063395,90.2980432928,90.2770262463,90.2560550065,90.2351293809,
+	90.2142491783,90.1934142087,90.1726242833,90.1518792142,90.131178815,
+	90.1105229001,90.0899112853,90.0693437874,90.0488202242,90.0283404148,
+	90.0079041793,89.9875113389,89.9671617157,89.9468551333,89.9265914158,
+	89.9063703888,89.8861918787,89.866055713,89.8459617203,89.82590973,
+	89.8058995729,89.7859310803,89.7660040849,89.7461184202,89.7262739206,
+	89.7064704218,89.68670776,89.6669857728,89.6473042984,89.6276631762,
+	89.6080622464,89.5885013501,89.5689803294,89.5494990274,89.5300572878,
+	89.5106549554,89.491291876,89.4719678961,89.4526828632,89.4334366256,
+	89.4142290324,89.3950599338,89.3759291805,89.3568366244,89.3377821181,
+	89.3187655149,89.2997866691,89.2808454357,89.2619416708,89.2430752308,
+	89.2242459734,89.2054537569,89.1866984403,89.1679798835,89.1492979471,
+	89.1306524926,89.1120433823,89.0934704789,89.0749336464,89.056432749,
+	89.0379676522,89.0195382218,89.0011443245,88.9827858277,88.9644625997,
+	88.9461745092,88.927921426,88.9097032202,88.8915197629,88.8733709258,
+	88.8552565813,88.8371766024,88.8191308631,88.8011192377,88.7831416014,
+	88.7651978299,88.7472877998,88.7294113881,88.7115684728,88.6937589321,
+	88.6759826453,88.658239492,88.6405293526,88.6228521081,88.6052076402,
+	88.5875958312,88.5700165638,88.5524697217,88.5349551889,88.5174728501,
+	88.5000225908,88.4826042968,88.4652178545,88.4478631513,88.4305400746,
+	88.413248513,88.3959883551,88.3787594905,88.3615618091,88.3443952016,
+	88.3272595591,88.3101547733,88.2930807364,88.2760373414,88.2590244815,
+	88.2420420507,88.2250899434,88.2081680546,88.1912762799,88.1744145152,
+	88.1575826573,88.1407806031,88.1240082504,88.1072654973,88.0905522424,
+	88.0738683849,88.0572138245,88.0405884613,88.0239921962,88.0074249301,
+	87.9908865649,87.9743770026,87.9578961459,87.941443898,87.9250201625,
+	87.9086248434,87.8922578454,87.8759190734,87.859608433,87.8433258301,
+	87.8270711713,87.8108443633,87.7946453135,87.7784739298,87.7623301204,
+	87.746213794,87.7301248597,87.7140632271,87.6980288064,87.6820215078,
+	87.6660412424,87.6500879215,87.6341614567,87.6182617604,87.6023887451,
+	87.5865423238,87.57072241,87.5549289176,87.5391617608,87.5234208543,
+	87.5077061131,87.4920174528,87.4763547894,87.4607180389,87.4451071183,
+	87.4295219444,87.4139624349,87.3984285076,87.3829200807,87.3674370729,
+	87.3519794032,87.3365469909,87.321139756,87.3057576185,87.2904004989,
+	87.2750683183,87.2597609977,87.2444784589,87.2292206238,87.2139874149,
+	87.1987787547,87.1835945665,87.1684347736,87.1532992998,87.1381880693,
+	87.1231010065,87.1080380363,87.0929990838,87.0779840746,87.0629929344,
+	87.0480255896,87.0330819666,87.0181619923,87.0032655939,86.988392699,
+	86.9735432353,86.9587171311,86.9439143149,86.9291347155,86.914378262,
+	86.899644884,86.8849345112,86.8702470737,86.855582502,86.8409407267,
+	86.8263216789,86.81172529,86.7971514915,86.7826002155,86.7680713942,
+	86.7535649602,86.7390808462,86.7246189855,86.7101793115,86.695761758,
+	86.681366259,86.6669927487,86.6526411619,86.6383114334,86.6240034983,
+	86.6097172923,86.5954527509,86.5812098103,86.5669884067,86.5527884768,
+	86.5386099573,86.5244527855,86.5103168987,86.4962022346,86.4821087312,
+	86.4680363266,86.4539849594,86.4399545682,86.4259450922,86.4119564705,
+	86.3979886428,86.3840415487,86.3701151284,86.356209322,86.3423240703,
+	86.328459314,86.3146149941,86.3007910521,86.2869874293,86.2732040677,
+	86.2594409093,86.2456978963,86.2319749714,86.2182720773,86.204589157,
+	86.1909261539,86.1772830113,86.1636596731,86.1500560831,86.1364721857,
+	86.1229079253,86.1093632464,86.0958380941,86.0823324135,86.0688461498,
+	86.0553792488,86.0419316561,86.0285033179,86.0150941804,86.0017041901,
+	85.9883332936,85.9749814379,85.9616485701,85.9483346376,85.935039588,
+	85.9217633689,85.9085059285,85.8952672149,85.8820471765,85.868845762,
+	85.8556629201,85.8424986001,85.829352751,85.8162253223,85.8031162638,
+	85.7900255253,85.7769530568,85.7638988086,85.7508627312,85.7378447752,
+	85.7248448915,85.7118630312,85.6988991455,85.6859531858,85.6730251039,
+	85.6601148515,85.6472223807,85.6343476437,85.6214905929,85.608651181,
+	85.5958293606,85.5830250847,85.5702383066,85.5574689796,85.5447170572,
+	85.531982493,85.5192652411,85.5065652554,85.4938824903,85.4812169001,
+	85.4685684394,85.4559370631,85.4433227262,85.4307253837,85.4181449909,
+	85.4055815034,85.3930348768,85.380505067,85.36799203,85.3554957218,
+	85.3430160989,85.3305531178,85.3181067352,85.3056769079,85.2932635929,
+	85.2808667474,85.2684863287,85.2561222943,85.243774602,85.2314432095,
+	85.2191280748,85.2068291561,85.1945464117,85.1822798,85.1700292797,
+	85.1577948095,85.1455763484,85.1333738555,85.1211872901,85.1090166115,
+	85.0968617793,85.0847227531,85.0725994929,85.0604919587,85.0484001106,
+	85.036323909,85.0242633142,85.0122182869,85.0001887879,84.988174778,
+	84.9761762183,84.96419307,84.9522252944,84.940272853,84.9283357074,
+	84.9164138193,84.9045071507,84.8926156637,84.8807393203,84.8688780829,
+	84.8570319141,84.8452007763,84.8333846323,84.821583445,84.8097971775,
+	84.7980257927,84.7862692541,84.7745275251,84.7628005691,84.7510883499,
+	84.7393908313,84.7277079772,84.7160397517,84.704386119,84.6927470434,
+	84.6811224894,84.6695124216,84.6579168048,84.6463356037,84.6347687833,
+	84.6232163088,84.6116781453,84.6001542582,84.588644613,84.5771491752,
+	84.5656679107,84.5542007852,84.5427477647,84.5313088153,84.5198839031,
+	84.5084729946,84.4970760562,84.4856930544,84.4743239558,84.4629687275,
+	84.4516273361,84.4402997488,84.4289859327,84.4176858551,84.4063994834,
+	84.395126785,84.3838677277,84.372622279,84.3613904068,84.3501720791,
+	84.338967264,84.3277759297,84.3165980443,84.3054335763,84.2942824943,
+	84.2831447667,84.2720203625,84.2609092503,84.2498113991,84.238726778,
+	84.2276553561,84.2165971027,84.2055519872,84.194519979,84.1835010476,
+	84.1724951629,84.1615022946,84.1505224125,84.1395554866,84.1286014871,
+	84.1176603842,84.1067321481,84.0958167492,84.0849141581,84.0740243453,
+	84.0631472816,84.0522829378,84.0414312847,84.0305922934,84.0197659349,
+	84.0089521804,83.9981510014,83.987362369,83.9765862548,83.9658226305,
+	83.9550714676,83.944332738,83.9336064135,83.922892466,83.9121908677,
+	83.9015015907,83.8908246072,83.8801598895,83.8695074102,83.8588671416,
+	83.8482390564,83.8376231274,83.8270193272,83.8164276289,83.8058480053,
+	83.7952804295,83.7847248747,83.774181314,83.763649721,83.7531300688,
+	83.7426223311,83.7321264815,83.7216424936,83.7111703411,83.700709998,
+	83.6902614382,83.6798246356,83.6693995644,83.6589861988,83.648584513,
+	83.6381944814,83.6278160785,83.6174492788,83.6070940568,83.5967503873,
+	83.586418245,83.5760976048,83.5657884417,83.5554907305,83.5452044465,
+	83.5349295648,83.5246660606,83.5144139094,83.5041730864,83.4939435673,
+	83.4837253275,83.4735183427,83.4633225887,83.4531380413,83.4429646763,
+	83.4328024696,83.4226513974,83.4125114358,83.4023825609,83.392264749,
+	83.3821579764,83.3720622196,83.361977455,83.3519036592,83.3418408089,
+	83.3317888807,83.3217478514,83.3117176979,83.3016983972,83.2916899262,
+	83.281692262,83.2717053817,83.2617292627,83.251763882,83.2418092172,
+	83.2318652457,83.2219319449,83.2120092924,83.2020972659,83.1921958431,
+	83.1823050018,83.1724247198,83.162554975,83.1526957454,83.1428470091,
+	83.1330087443,83.123180929,83.1133635416,83.1035565603,83.0937599636,
+	83.08397373,83.0741978379,83.064432266,83.0546769929,83.0449319973,
+	83.035197258,83.0254727539,83.0157584639,83.006054367,82.9963604422,
+	82.9866766686,82.9770030254,82.9673394918,82.9576860472,82.9480426709,
+	82.9384093423,82.9287860409,82.9191727463,82.9095694381,82.8999760959,
+	82.8903926995,82.8808192286,82.8712556633,82.8617019832,82.8521581685,
+	82.8426241992,82.8331000553,82.8235857171,82.8140811647,82.8045863785,
+	82.7951013386,82.7856260257,82.77616042,82.7667045022,82.7572582527,
+	82.7478216522,82.7383946815,82.7289773211,82.719569552,82.710171355,
+	82.700782711,82.6914036009,82.6820340059,82.6726739069,82.6633232851,
+	82.6539821217,82.644650398,82.6353280953,82.6260151948,82.6167116781,
+	82.6074175266,82.5981327217,82.5888572452,82.5795910786,82.5703342036,
+	82.5610866019,82.5518482554,82.5426191458,82.5333992551,82.5241885652,
+	82.5149870582,82.505794716,82.4966115208,82.4874374547,82.4782724999,
+	82.4691166388,82.4599698535,82.4508321266,82.4417034403,82.4325837772,
+	82.4234731197,82.4143714505,82.4052787521,82.3961950073,82.3871201986,
+	82.378054309,82.3689973211,82.3599492179,82.3509099823,82.3418795973,
+	82.3328580457,82.3238453108,82.3148413756,82.3058462233,82.296859837,
+	82.2878822
+	};
+
+tubetable_12AX7_1 = waveform{
+	249.98706929,249.986851225,249.986629489,249.986404021,249.986174757,
+	249.985941635,249.985704589,249.985463554,249.985218463,249.984969247,
+	249.984715838,249.984458166,249.984196158,249.983929743,249.983658846,
+	249.983383392,249.983103306,249.982818508,249.982528921,249.982234464,
+	249.981935056,249.981630613,249.981321052,249.981006287,249.98068623,
+	249.980360793,249.980029887,249.979693419,249.979351296,249.979003424,
+	249.978649708,249.978290048,249.977924346,249.9775525,249.977174409,
+	249.976789967,249.976399069,249.976001606,249.97559747,249.975186548,
+	249.974768727,249.974343893,249.973911927,249.973472711,249.973026125,
+	249.972572044,249.972110345,249.9716409,249.971163579,249.970678252,
+	249.970184785,249.969683043,249.969172887,249.968654177,249.968126772,
+	249.967590526,249.967045292,249.96649092,249.965927258,249.965354153,
+	249.964771446,249.964178978,249.963576587,249.962964107,249.962341372,
+	249.961708211,249.96106445,249.960409914,249.959744424,249.959067797,
+	249.95837985,249.957680393,249.956969237,249.956246188,249.955511048,
+	249.954763616,249.95400369,249.953231063,249.952445523,249.951646857,
+	249.950834849,249.950009276,249.949169916,249.94831654,249.947448916,
+	249.946566809,249.945669979,249.944758184,249.943831177,249.942888706,
+	249.941930516,249.940956349,249.93996594,249.938959023,249.937935324,
+	249.936894568,249.935836475,249.934760758,249.933667127,249.932555289,
+	249.931424944,249.930275788,249.929107511,249.9279198,249.926712337,
+	249.925484796,249.92423685,249.922968162,249.921678394,249.9203672,
+	249.91903423,249.917679127,249.916301529,249.914901069,249.913477372,
+	249.912030061,249.910558748,249.909063042,249.907542547,249.905996856,
+	249.904425561,249.902828244,249.901204482,249.899553844,249.897875894,
+	249.896170188,249.894436274,249.892673696,249.890881989,249.889060679,
+	249.887209288,249.885327328,249.883414305,249.881469716,249.879493052,
+	249.877483793,249.875441414,249.87336538,249.87125515,249.869110171,
+	249.866929885,249.864713724,249.86246111,249.860171458,249.857844173,
+	249.855478652,249.853074281,249.850630438,249.848146491,249.845621799,
+	249.843055711,249.840447565,249.837796689,249.835102404,249.832364016,
+	249.829580824,249.826752115,249.823877166,249.820955243,249.8179856,
+	249.81496748,249.811900117,249.80878273,249.80561453,249.802394713,
+	249.799122465,249.795796959,249.792417358,249.788982809,249.785492449,
+	249.781945403,249.778340779,249.774677678,249.770955183,249.767172365,
+	249.763328284,249.759421981,249.75545249,249.751418824,249.747319988,
+	249.743154968,249.738922738,249.734622257,249.730252468,249.725812301,
+	249.72130067,249.716716471,249.712058589,249.70732589,249.702517225,
+	249.697631429,249.692667321,249.687623703,249.682499361,249.677293063,
+	249.672003562,249.666629592,249.661169871,249.655623098,249.649987954,
+	249.644263106,249.638447197,249.632538857,249.626536694,249.620439299,
+	249.614245244,249.607953082,249.601561346,249.59506855,249.588473189,
+	249.581773739,249.574968653,249.568056367,249.561035295,249.553903831,
+	249.546660348,249.5393032,249.531830718,249.524241211,249.516532969,
+	249.508704259,249.500753327,249.492678397,249.48447767,249.476149326,
+	249.467691521,249.459102391,249.450380046,249.441522576,249.432528047,
+	249.423394501,249.414119957,249.404702411,249.395139834,249.385430176,
+	249.37557136,249.365561287,249.355397831,249.345078845,249.334602156,
+	249.323965565,249.313166851,249.302203767,249.291074039,249.27977537,
+	249.268305439,249.256661896,249.244842368,249.232844458,249.220665739,
+	249.208303762,249.195756051,249.183020104,249.170093394,249.156973366,
+	249.143657441,249.130143014,249.116427453,249.102508098,249.088382267,
+	249.074047249,249.059500307,249.044738677,249.029759572,249.014560175,
+	248.999137645,248.983489114,248.967611688,248.951502446,248.935158442,
+	248.918576704,248.901754233,248.884688005,248.867374969,248.84981205,
+	248.831996145,248.813924127,248.795592843,248.776999115,248.75813974,
+	248.739011488,248.719611106,248.699935316,248.679980814,248.659744274,
+	248.639222342,248.618411645,248.597308781,248.575910327,248.554212837,
+	248.532212841,248.509906845,248.487291335,248.464362771,248.441117595,
+	248.417552224,248.393663055,248.369446462,248.344898801,248.320016406,
+	248.29479559,248.269232647,248.243323852,248.217065459,248.190453706,
+	248.163484811,248.136154974,248.108460379,248.080397191,248.05196156,
+	248.02314962,247.993957487,247.964381265,247.934417041,247.90406089,
+	247.87330887,247.84215703,247.810601403,247.778638011,247.746262866,
+	247.713471967,247.680261304,247.646626855,247.612564592,247.578070476,
+	247.543140462,247.507770494,247.471956513,247.435694453,247.398980241,
+	247.361809801,247.32417905,247.286083906,247.24752028,247.208484082,
+	247.168971222,247.128977608,247.088499147,247.047531748,247.006071321,
+	246.964113777,246.921655032,246.878691002,246.835217611,246.791230786,
+	246.746726458,246.701700567,246.656149059,246.610067888,246.563453016,
+	246.516300415,246.468606067,246.420365965,246.371576112,246.322232525,
+	246.272331233,246.22186828,246.170839723,246.119241635,246.067070105,
+	246.014321238,245.960991158,245.907076005,245.85257194,245.797475142,
+	245.741781811,245.685488168,245.628590456,245.57108494,245.512967909,
+	245.454235673,245.394884571,245.334910963,245.274311238,245.213081809,
+	245.151219118,245.088719633,245.025579852,244.961796302,244.897365539,
+	244.832284149,244.76654875,244.70015599,244.633102551,244.565385144,
+	244.497000518,244.427945453,244.358216762,244.287811295,244.216725936,
+	244.144957607,244.072503262,243.999359895,243.925524536,243.850994253,
+	243.775766153,243.699837378,243.623205113,243.545866579,243.467819039,
+	243.389059794,243.309586187,243.2293956,243.148485458,243.066853225,
+	242.984496408,242.901412556,242.817599259,242.733054149,242.647774903,
+	242.561759239,242.475004919,242.387509745,242.299271568,242.210288277,
+	242.120557808,242.03007814,241.938847296,241.846863343,241.75412439,
+	241.660628595,241.566374155,241.471359316,241.375582364,241.279041632,
+	241.181735498,241.083662381,240.984820749,240.88520911,240.78482602,
+	240.683670075,240.581739919,240.479034238,240.375551763,240.271291268,
+	240.166251571,240.060431535,239.953830064,239.846446107,239.738278656,
+	239.629326745,239.519589453,239.4090659,239.297755248,239.185656702,
+	239.072769509,238.959092958,238.84462638,238.729369145,238.613320666,
+	238.496480396,238.37884783,238.260422501,238.141203983,238.02119189,
+	237.900385875,237.778785628,237.656390882,237.533201405,237.409217004,
+	237.284437524,237.158862846,237.03249289,236.905327613,236.777367005,
+	236.648611095,236.519059947,236.38871366,236.257572368,236.125636239,
+	235.992905475,235.859380313,235.725061022,235.589947905,235.454041297,
+	235.317341565,235.179849108,235.041564357,234.902487774,234.762619849,
+	234.621961106,234.480512096,234.338273402,234.195245633,234.051429428,
+	233.906825454,233.761434407,233.615257009,233.468294009,233.320546182,
+	233.172014331,233.022699284,232.872601892,232.721723035,232.570063615,
+	232.417624559,232.264406816,232.110411361,231.955639189,231.800091321,
+	231.643768797,231.486672681,231.328804057,231.17016403,231.010753726,
+	230.850574292,230.689626893,230.527912715,230.365432962,230.202188857,
+	230.038181642,229.873412577,229.707882938,229.541594019,229.374547132,
+	229.206743604,229.038184779,228.868872017,228.698806692,228.527990194,
+	228.356423928,228.184109314,228.011047785,227.837240787,227.662689782,
+	227.487396243,227.311361655,227.134587519,226.957075345,226.778826655,
+	226.599842984,226.420125878,226.239676893,226.058497596,225.876589564,
+	225.693954385,225.510593656,225.326508984,225.141701984,224.956174281,
+	224.769927509,224.58296331,224.395283333,224.206889237,224.017782686,
+	223.827965353,223.637438918,223.446205069,223.254265497,223.061621903,
+	222.868275994,222.674229479,222.479484077,222.284041512,222.08790351,
+	221.891071805,221.693548135,221.495334244,221.296431876,221.096842785,
+	220.896568725,220.695611455,220.493972738,220.29165434,220.08865803,
+	219.88498558,219.680638766,219.475619366,219.269929161,219.063569932,
+	218.856543466,218.648851549,218.440495971,218.231478522,218.021800994,
+	217.811465182,217.60047288,217.388825884,217.176525993,216.963575003,
+	216.749974714,216.535726925,216.320833437,216.105296048,215.88911656,
+	215.672296774,215.45483849,215.236743508,215.018013629,214.798650652,
+	214.578656378,214.358032605,214.136781131,213.914903754,213.692402271,
+	213.469278477,213.245534168,213.021171136,212.796191175,212.570596077,
+	212.344387629,212.117567622,211.890137843,211.662100076,211.433456105,
+	211.204207714,210.974356681,210.743904787,210.512853806,210.281205515,
+	210.048961685,209.816124088,209.582694492,209.348674664,209.114066368,
+	208.878871366,208.643091418,208.406728281,208.169783711,207.93225946,
+	207.694157278,207.455478915,207.216226114,206.97640062,206.736004172,
+	206.49503851,206.253505367,206.011406477,205.768743571,205.525518376,
+	205.281732618,205.037388018,204.792486297,204.547029172,204.301018358,
+	204.054455568,203.80734251,203.559680893,203.31147242,203.062718793,
+	202.813421712,202.563582874,202.313203973,202.062286701,201.810832747,
+	201.558843799,201.306321542,201.053267658,200.799683826,200.545571726,
+	200.290933032,200.035769418,199.780082556,199.523874114,199.26714576,
+	199.00989916,198.752135977,198.493857873,198.235066508,197.97576354,
+	197.715950626,197.455629421,197.19480158,196.933468754,196.671632596,
+	196.409294756,196.146456882,195.883120624,195.619287629,195.354959544,
+	195.090138015,194.824824689,194.559021212,194.292729229,194.025950385,
+	193.758686328,193.490938703,193.222709157,192.953999338,192.684810894,
+	192.415145475,192.145004731,191.874390314,191.603303879,191.331747082,
+	191.059721579,190.787229033,190.514271105,190.240849462,189.966965773,
+	189.69262171,189.417818949,189.14255917,188.866844059,188.590675304,
+	188.314054599,188.036983645,187.759464146,187.481497813,187.203086365,
+	186.924231527,186.64493503,186.365198614,186.085024028,185.804413028,
+	185.523367379,185.241888858,184.95997925,184.677640352,184.394873972,
+	184.11168193,183.828066057,183.544028199,183.259570217,182.974693983,
+	182.689401387,182.403694334,182.117574747,181.831044563,181.544105742,
+	181.25676026,180.969010115,180.680857324,180.392303929,180.103351992,
+	179.814003602,179.524260869,179.234125934,178.943600962,178.652688148,
+	178.361389716,178.069707923,177.777645057,177.485203439,177.192385426,
+	176.899193414,176.605629834,176.311697159,176.017397903,175.722734622,
+	175.42770992,175.132326446,174.836586898,174.540494025,174.244050629,
+	173.947259568,173.650123755,173.352646164,173.054829832,172.756677859,
+	172.458193411,172.159379726,171.860240112,171.560777954,171.260996712,
+	170.960899932,170.660491239,170.359774348,170.058753063,169.757431286,
+	169.455813011,169.153902337,168.851703468,168.549220714,168.246458503,
+	167.943421374,167.640113993,167.336541149,167.032707762,166.728618886,
+	166.424279716,166.119695592,165.814872003,165.509814594,165.204529171,
+	164.899021704,164.593298336,164.287365388,163.981229364,163.674896958,
+	163.36837506,163.061670761,162.754791362,162.447744379,162.140537551,
+	161.833178847,161.525676469,161.218038867,160.91027474,160.602393044,
+	160.294403003,159.986314114,159.678136154,159.369879193,159.061553594,
+	158.753170027,158.444739474,158.13627324,157.827782957,157.519280595,
+	157.21077847,156.90228925,156.593825964,156.285402011,155.977031166,
+	155.668727586,155.360505823,155.052380826,154.744367948,154.436482957,
+	154.128742038,153.821161801,153.513759285,153.206551968,152.899557763,
+	152.592795032,152.286282581,151.980039672,151.674086016,151.368441781,
+	151.063127591,150.758164527,150.453574123,150.149378371,149.84559971,
+	149.542261029,149.239385659,148.936997368,148.635120356,148.333779243,
+	148.032999061,147.732805244,147.433223619,147.134280384,146.836002101,
+	146.538415678,146.241548349,145.945427656,145.650081429,145.355537765,
+	145.061825,144.768971689,144.477006578,144.185958573,143.895856717,
+	143.606730155,143.318608101,143.031519811,142.745494544,142.460561528,
+	142.176749925,141.894088794,141.612607053,141.33233344,141.053296478,
+	140.775524432,140.499045269,140.223886626,139.950075761,139.677639521,
+	139.406604303,139.13699601,138.86884002,138.602161147,138.336983605,
+	138.073330973,137.811226163,137.550691387,137.291748127,137.034417106,
+	136.778718261,136.524670718,136.272292766,136.021601842,135.772614503,
+	135.525346418,135.279812345,135.036026122,134.79400066,134.553747926,
+	134.315278945,134.078603792,133.843731591,133.610670518,133.379427799,
+	133.150009719,132.922421627,132.696667945,132.472752176,132.25067692,
+	132.030443888,131.812053912,131.595506968,131.380802191,131.167937895,
+	130.956911595,130.747720026,130.540359167,130.334824266,130.13110986,
+	129.929209804,129.729117294,129.53082489,129.334324549,129.139607641,
+	128.946664984,128.755486867,128.566063074,128.378382911,128.192435235,
+	128.008208475,127.82569066,127.644869442,127.465732122,127.288265674,
+	127.112456765,126.938291784,126.765756859,126.594837879,126.425520519,
+	126.257790258,126.091632396,125.92703208,125.763974314,125.602443985,
+	125.442425874,125.283904673,125.126865007,124.971291439,124.817168494,
+	124.664480664,124.51321243,124.363348265,124.214872655,124.067770102,
+	123.922025141,123.777622345,123.634546339,123.492781803,123.352313488,
+	123.213126215,123.075204892,122.938534511,122.803100162,122.668887034,
+	122.535880424,122.404065739,122.273428504,122.143954363,122.015629084,
+	121.888438563,121.76236883,121.637406044,121.513536504,121.390746648,
+	121.269023054,121.148352444,121.028721683,120.910117783,120.792527903,
+	120.675939349,120.560339577,120.445716191,120.332056945,120.219349742,
+	120.107582636,119.996743831,119.886821679,119.777804682,119.669681491,
+	119.562440905,119.45607187,119.350563481,119.245904975,119.142085739,
+	119.039095299,118.936923328,118.835559639,118.734994187,118.635217064,
+	118.536218503,118.437988872,118.340518677,118.243798555,118.147819277,
+	118.052571748,117.958046998,117.864236189,117.771130609,117.678721671,
+	117.587000912,117.495959991,117.405590688,117.315884902,117.226834649,
+	117.138432063,117.050669391,116.963538993,116.87703334,116.791145014,
+	116.705866704,116.621191207,116.537111424,116.453620361,116.370711124,
+	116.288376922,116.206611062,116.125406949,116.044758083,115.964658061,
+	115.885100572,115.806079397,115.727588408,115.649621564,115.572172916,
+	115.495236596,115.418806826,115.342877908,115.267444229,115.192500255,
+	115.118040534,115.04405969,114.970552425,114.89751352,114.824937826,
+	114.752820271,114.681155856,114.60993965,114.539166794,114.4688325,
+	114.398932045,114.329460774,114.260414097,114.191787491,114.123576494,
+	114.055776708,113.988383796,113.921393483,113.854801553,113.788603846,
+	113.722796265,113.657374766,113.592335361,113.527674118,113.463387161,
+	113.399470663,113.335920853,113.27273401,113.209906463,113.147434593,
+	113.085314829,113.023543648,112.962117574,112.901033179,112.840287082,
+	112.779875944,112.719796474,112.660045423,112.600619585,112.541515797,
+	112.482730939,112.42426193,112.36610573,112.308259341,112.250719802,
+	112.19348419,112.136549623,112.079913253,112.023572271,111.967523904,
+	111.911765414,111.856294098,111.801107289,111.746202353,111.691576689,
+	111.637227729,111.583152939,111.529349816,111.475815888,111.422548715,
+	111.369545886,111.316805023,111.264323773,111.212099817,111.160130862,
+	111.108414643,111.056948924,111.005731497,110.954760178,110.904032814,
+	110.853547274,110.803301456,110.75329328,110.703520696,110.653981674,
+	110.60467421,110.555596324,110.50674606,110.458121485,110.409720688,
+	110.361541782,110.313582902,110.265842202,110.218317863,110.171008082,
+	110.123911081,110.077025099,110.030348399,109.983879261,109.937615986,
+	109.891556896,109.845700329,109.800044645,109.754588221,109.709329453,
+	109.664266754,109.619398556,109.57472331,109.530239481,109.485945553,
+	109.441840028,109.397921423,109.354188272,109.310639125,109.267272548,
+	109.224087122,109.181081447,109.138254133,109.095603809,109.053129118,
+	109.010828717,108.968701278,108.926745487,108.884960045,108.843343665,
+	108.801895077,108.760613021,108.719496253,108.67854354,108.637753663,
+	108.597125417,108.556657609,108.516349056,108.476198591,108.436205057,
+	108.39636731,108.356684217,108.317154657,108.277777521,108.238551712,
+	108.199476141,108.160549735,108.121771427,108.083140165,108.044654905,
+	108.006314614,107.96811827,107.930064861,107.892153386,107.854382852,
+	107.816752278,107.77926069,107.741907128,107.704690637,107.667610274,
+	107.630665104,107.593854203,107.557176653,107.520631548,107.48421799,
+	107.447935087,107.41178196,107.375757736,107.339861549,107.304092545,
+	107.268449875,107.2329327,107.197540188,107.162271514,107.127125864,
+	107.092102428,107.057200405,107.022419004,106.987757437,106.953214926,
+	106.9187907,106.884483995,106.850294054,106.816220127,106.78226147,
+	106.748417348,106.714687031,106.681069796,106.647564927,106.614171713,
+	106.580889453,106.547717448,106.514655009,106.48170145,106.448856093,
+	106.416118267,106.383487304,106.350962545,106.318543335,106.286229026,
+	106.254018974,106.221912543,106.189909101,106.158008021,106.126208684,
+	106.094510473,106.06291278,106.031414999,106.000016532,105.968716784,
+	105.937515166,105.906411094,105.87540399,105.844493279,105.813678393,
+	105.782958766,105.752333841,105.721803061,105.691365878,105.661021745,
+	105.630770122,105.600610472,105.570542264,105.540564971,105.51067807,
+	105.480881041,105.451173372,105.421554551,105.392024073,105.362581436,
+	105.333226143,105.3039577,105.274775617,105.245679411,105.216668597,
+	105.1877427,105.158901246,105.130143764,105.101469788,105.072878857,
+	105.04437051,105.015944294,104.987599757,104.959336451,104.931153932,
+	104.903051759,104.875029495,104.847086706,104.819222962,104.791437835,
+	104.763730902,104.736101743,104.708549941,104.681075081,104.653676754,
+	104.626354551,104.599108068,104.571936905,104.544840663,104.517818946,
+	104.490871364,104.463997527,104.437197048,104.410469545,104.383814638,
+	104.357231948,104.330721102,104.304281728,104.277913457,104.251615922,
+	104.225388761,104.199231613,104.173144119,104.147125925,104.121176677,
+	104.095296026,104.069483624,104.043739125,104.018062189,103.992452474,
+	103.966909643,103.941433361,103.916023296,103.890679118,103.865400498,
+	103.840187112,103.815038637,103.789954751,103.764935137,103.739979478,
+	103.715087461,103.690258774,103.665493107,103.640790154,103.616149609,
+	103.59157117,103.567054536,103.542599408,103.51820549,103.493872487,
+	103.469600108,103.445388062,103.42123606,103.397143817,103.373111047,
+	103.34913747,103.325222804,103.301366771,103.277569095,103.253829501,
+	103.230147716,103.206523469,103.182956493,103.159446518,103.13599328,
+	103.112596516,103.089255964,103.065971363,103.042742456,103.019568986,
+	102.996450698,102.97338734,102.950378659,102.927424406,102.904524334,
+	102.881678195,102.858885746,102.836146742,102.813460943,102.790828108,
+	102.768247999,102.74572038,102.723245015,102.700821671,102.678450115,
+	102.656130116,102.633861446,102.611643877,102.589477183,102.567361139,
+	102.545295522,102.523280109,102.501314681,102.479399019,102.457532905,
+	102.435716122,102.413948457,102.392229695,102.370559624,102.348938035,
+	102.327364716,102.305839461,102.284362062,102.262932314,102.241550013,
+	102.220214956,102.198926941,102.177685768,102.156491237,102.135343152,
+	102.114241314,102.093185529,102.072175603,102.051211342,102.030292555,
+	102.009419051,101.98859064,101.967807134,101.947068347,101.926374091,
+	101.905724182,101.885118436,101.864556671,101.844038704,101.823564356,
+	101.803133447,101.782745799,101.762401235,101.742099578,101.721840653,
+	101.701624287,101.681450305,101.661318537,101.641228811,101.621180958,
+	101.601174808,101.581210193,101.561286947,101.541404903,101.521563896,
+	101.501763763,101.482004341,101.462285466,101.442606979,101.422968719,
+	101.403370526,101.383812242,101.36429371,101.344814774,101.325375276,
+	101.305975064,101.286613983,101.267291879,101.248008601,101.228763999,
+	101.20955792,101.190390216,101.171260738,101.152169339,101.133115871,
+	101.114100189,101.095122146,101.076181599,101.057278403,101.038412416,
+	101.019583497,101.000791503,100.982036294,100.96331773,100.944635673,
+	100.925989984,100.907380526,100.888807163,100.870269758,100.851768177,
+	100.833302284,100.814871947,100.796477033,100.778117409,100.759792944,
+	100.741503507,100.723248969,100.705029199,100.68684407,100.668693453,
+	100.650577222,100.632495249,100.614447409,100.596433577,100.578453629,
+	100.56050744,100.542594887,100.524715848,100.506870202,100.489057826,
+	100.471278601,100.453532406,100.435819123,100.418138632,100.400490816,
+	100.382875557,100.365292739,100.347742246,100.330223961,100.312737771,
+	100.29528356,100.277861215,100.260470623,100.243111672,100.225784249,
+	100.208488243,100.191223543,100.17399004,100.156787623,100.139616184,
+	100.122475614,100.105365804,100.088286649,100.07123804,100.054219871,
+	100.037232038,100.020274434,100.003346955,99.9864494965,99.9695819554,
+	99.9527442284,99.935936213,99.9191578071,99.9024089092,99.8856894183,
+	99.8689992338,99.8523382559,99.8357063851,99.8191035222,99.8025295689,
+	99.7859844271,99.7694679993,99.7529801885,99.7365208981,99.7200900321,
+	99.7036874949,99.6873131914,99.6709670269,99.6546489073,99.6383587388,
+	99.6220964281,99.6058618826,99.5896550097,99.5734757178,99.5573239152,
+	99.5411995111,99.5251024148,99.5090325364,99.492989786,99.4769740745,
+	99.460985313,99.4450234132,99.4290882872,99.4131798474,99.3972980067,
+	99.3814426785,99.3656137764,99.3498112147,99.3340349078,99.3182847708,
+	99.3025607191,99.2868626683,99.2711905347,99.2555442348,99.2399236857,
+	99.2243288047,99.2087595095,99.1932157183,99.1776973497,99.1622043225,
+	99.146736556,99.1312939699,99.1158764842,99.1004840195,99.0851164964,
+	99.0697738362,99.0544559603,99.0391627907,99.0238942497,99.0086502598,
+	98.993430744,98.9782356258,98.9630648287,98.9479182768,98.9327958945,
+	98.9176976065,98.902623338,98.8875730143,98.8725465613,98.857543905,
+	98.8425649718,98.8276096887,98.8126779826,98.7977697811,98.7828850119,
+	98.7680236031,98.7531854831,98.7383705808,98.7235788251,98.7088101455,
+	98.6940644717,98.6793417336,98.6646418617,98.6499647867,98.6353104394,
+	98.6206787511,98.6060696534,98.5914830783,98.5769189578,98.5623772246,
+	98.5478578113,98.533360651,98.5188856772,98.5044328236,98.490002024,
+	98.4755932127,98.4612063243,98.4468412937,98.4324980559,98.4181765464,
+	98.4038767009,98.3895984552,98.3753417457,98.361106509,98.3468926817,
+	98.332700201,98.3185290043,98.3043790291,98.2902502134,98.2761424952,
+	98.2620558131,98.2479901058,98.2339453121,98.2199213714,98.205918223,
+	98.1919358068,98.1779740627,98.164032931,98.1501123522,98.136212267,
+	98.1223326165,98.108473342,98.0946343849,98.080815687,98.0670171904,
+	98.0532388372,98.03948057,98.0257423315,98.0120240648,97.9983257129,
+	97.9846472195,97.9709885281,97.9573495827,97.9437303276,97.930130707,
+	97.9165506656,97.9029901484,97.8894491003,97.8759274667,97.8624251931,
+	97.8489422254,97.8354785095,97.8220339916,97.8086086182,97.795202336,
+	97.7818150918,97.7684468328,97.7550975062,97.7417670596,97.7284554407,
+	97.7151625976,97.7018884783,97.6886330313,97.6753962052,97.6621779488,
+	97.648978211,97.6357969412,97.6226340887,97.6094896032,97.5963634346,
+	97.5832555327,97.570165848,97.5570943308,97.5440409318,97.5310056019,
+	97.5179882919,97.5049889533,97.4920075374,97.4790439958,97.4660982804,
+	97.4531703431,97.4402601362,97.427367612,97.4144927232,97.4016354224,
+	97.3887956627,97.3759733971,97.3631685791,97.350381162,97.3376110997,
+	97.3248583459,97.3121228548,97.2994045805,97.2867034775,97.2740195003,
+	97.2613526038,97.2487027429,97.2360698727,97.2234539485,97.2108549257,
+	97.1982727601,97.1857074075,97.1731588237,97.1606269651,97.1481117878,
+	97.1356132485,97.1231313037,97.1106659104,97.0982170254,97.0857846061,
+	97.0733686096,97.0609689935,97.0485857155,97.0362187333,97.0238680049,
+	97.0115334885,96.9992151424,96.9869129251,96.974626795,96.9623567111,
+	96.9501026322,96.9378645174,96.925642326,96.9134360174,96.901245551,
+	96.8890708866,96.8769119841,96.8647688034,96.8526413048,96.8405294484,
+	96.8284331947,96.8163525044,96.8042873382,96.792237657,96.7802034217,
+	96.7681845937,96.7561811342,96.7441930046,96.7322201667,96.7202625821,
+	96.7083202128,96.6963930208,96.6844809683,96.6725840175,96.660702131,
+	96.6488352713,96.6369834012,96.6251464835,96.6133244813,96.6015173576,
+	96.5897250758,96.5779475993,96.5661848916,96.5544369164,96.5427036375,
+	96.5309850188,96.5192810244,96.5075916186,96.4959167655,96.4842564298,
+	96.472610576,96.4609791688,96.449362173,96.4377595536,96.4261712758,
+	96.4145973047,96.4030376057,96.3914921443,96.379960886,96.3684437966,
+	96.3569408419,96.3454519879,96.3339772007,96.3225164464,96.3110696914,
+	96.2996369022,96.2882180452,96.2768130873,96.2654219951,96.2540447357,
+	96.242681276,96.2313315832,96.2199956245,96.2086733674,96.1973647793,
+	96.1860698279,96.1747884809,96.1635207061,96.1522664715,96.1410257451,
+	96.1297984951,96.1185846898,96.1073842976,96.096197287,96.0850236266,
+	96.0738632851,96.0627162315,96.0515824345,96.0404618634,96.0293544871,
+	96.018260275,96.0071791965,95.9961112211,95.9850563182,95.9740144577,
+	95.9629856092,95.9519697427,95.9409668282,95.9299768358,95.9189997356,
+	95.908035498,95.8970840934,95.8861454923,95.8752196653,95.8643065831,
+	95.8534062165,95.8425185365,95.8316435139,95.82078112,95.8099313258,
+	95.7990941028,95.7882694223,95.7774572558,95.7666575748,95.7558703512,
+	95.7450955566,95.7343331628,95.723583142,95.7128454661,95.7021201073,
+	95.6914070379,95.6807062301,95.6700176564,95.6593412894,95.6486771016,
+	95.6380250658,95.6273851547,95.6167573413,95.6061415985,95.5955378994,
+	95.5849462171,95.5743665249,95.5637987962,95.5532430042,95.5426991226,
+	95.532167125,95.521646985,95.5111386764,95.500642173,95.4901574488,
+	95.4796844778,95.4692232342,95.4587736921,95.4483358257,95.4379096096,
+	95.4274950181,95.4170920257,95.406700607,95.3963207368,95.3859523898,
+	95.375595541,95.3652501651,95.3549162373,95.3445937326,95.3342826263,
+	95.3239828935,95.3136945097,95.3034174503,95.2931516907,95.2828972066,
+	95.2726539735,95.2624219673,95.2522011637,95.2419915386,95.231793068,
+	95.221605728,95.2114294947,95.2012643442,95.1911102528,95.1809671969,
+	95.1708351529,95.1607140973,95.1506040066,95.1405048576,95.1304166269,
+	95.1203392913,95.1102728277,95.100217213,95.0901724243,95.0801384386,
+	95.070115233,95.0601027849,95.0501010715,95.0401100701,95.0301297583,
+	95.0201601135,95.0102011132,95.0002527353,94.9903149573,94.9803877571,
+	94.9704711125,94.9605650015,94.950669402,94.9407842921,94.93090965,
+	94.9210454538,94.9111916818,94.9013483124,94.8915153239,94.8816926948,
+	94.8718804037,94.8620784292,94.8522867499,94.8425053445,94.8327341919,
+	94.8229732709,94.8132225604,94.8034820394,94.793751687,94.7840314824,
+	94.7743214046,94.7646214329,94.7549315467,94.7452517252,94.7355819481,
+	94.7259221946,94.7162724445,94.7066326773,94.6970028726,94.6873830104,
+	94.6777730702,94.6681730321,94.658582876,94.6490025817,94.6394321295,
+	94.6298714993,94.6203206714,94.610779626,94.6012483433,94.5917268037,
+	94.5822149877,94.5727128756,94.563220448,94.5537376855,94.5442645687,
+	94.5348010783,94.525347195,94.5159028997,94.5064681732,94.4970429965,
+	94.4876273505,94.4782212162,94.4688245748,94.4594374074,94.4500596952,
+	94.4406914195,94.4313325615,94.4219831026,94.4126430243,94.403312308,
+	94.3939909353,94.3846788878,94.375376147,94.3660826947,94.3567985126,
+	94.3475235826,94.3382578864,94.329001406,94.3197541234,94.3105160205,
+	94.3012870794,94.2920672823,94.2828566112,94.2736550485,94.2644625763,
+	94.255279177,94.2461048331,94.2369395268,94.2277832407,94.2186359572,
+	94.2094976591,94.2003683288,94.1912479492,94.1821365028,94.1730339724,
+	94.163940341,94.1548555913,94.1457797063,94.136712669,94.1276544623,
+	94.1186050694,94.1095644733,94.1005326572,94.0915096044,94.082495298,
+	94.0734897214,94.064492858,94.0555046911,94.0465252043,94.0375543809,
+	94.0285922045,94.0196386587,94.0106937272,94.0017573936,93.9928296417,
+	93.9839104552,93.974999818,93.9660977138,93.9572041267,93.9483190405,
+	93.9394424393,93.9305743071,93.921714628,93.9128633861,93.9040205657,
+	93.8951861508,93.8863601258,93.8775424751,93.8687331828,93.8599322335,
+	93.8511396116,93.8423553016,93.8335792879,93.8248115552,93.816052088,
+	93.8073008711,93.798557889,93.7898231266,93.7810965686,93.7723781999,
+	93.7636680053
+	};
+
+tubetable_12AX7_rtable_0(r) = (tubetable_12AX7_0,r):rdtable;
+tubetable_12AX7_rtable_1(r) = (tubetable_12AX7_1,r):rdtable;
+
+
diff --git a/architecture/unsupported-arch/jack-wx.cpp b/architecture/unsupported-arch/jack-wx.cpp
index e55f44b..53a935a 100644
--- a/architecture/unsupported-arch/jack-wx.cpp
+++ b/architecture/unsupported-arch/jack-wx.cpp
@@ -31,68 +31,6 @@
 // macosx: g++ karplus-strong.cpp  -D__WXMAC__ -DWXMAKINGDLL -lwx_mac-2.4 -ljack -o karplus
 
 using namespace std ;
- 
-	
-#ifdef __GNUC__
-
-//-------------------------------------------------------------------
-// Generic min and max using gcc extensions
-//-------------------------------------------------------------------
-
-#define max(x,y) ((x)>?(y))
-#define min(x,y) ((x)<?(y))
-
-//abs(x) should be already predefined
-
-#else
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-		
-#endif
 
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
diff --git a/architecture/unsupported-arch/oss-wx.cpp b/architecture/unsupported-arch/oss-wx.cpp
index c56aef5..50c42c7 100644
--- a/architecture/unsupported-arch/oss-wx.cpp
+++ b/architecture/unsupported-arch/oss-wx.cpp
@@ -27,67 +27,6 @@
 
 using namespace std ;
  
-	
-#ifdef __GNUC__
-
-//-------------------------------------------------------------------
-// Generic min and max using gcc extensions
-//-------------------------------------------------------------------
-
-#define max(x,y) ((x)>?(y))
-#define min(x,y) ((x)<?(y))
-
-//abs(x) should be already predefined
-
-#else
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-		
-#endif
 
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
diff --git a/architecture/unsupported-arch/pa-wx.cpp b/architecture/unsupported-arch/pa-wx.cpp
index dca7a0c..e074c86 100644
--- a/architecture/unsupported-arch/pa-wx.cpp
+++ b/architecture/unsupported-arch/pa-wx.cpp
@@ -29,67 +29,6 @@
 
 using namespace std ;
  
-	
-#ifdef __GNUC__
-
-//-------------------------------------------------------------------
-// Generic min and max using gcc extensions
-//-------------------------------------------------------------------
-
-#define max(x,y) ((x)>?(y))
-#define min(x,y) ((x)<?(y))
-
-//abs(x) should be already predefined
-
-#else
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
-		
-#endif
 
 // abs is now predefined
 //template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
diff --git a/architecture/vst.cpp b/architecture/vst.cpp
index f1b73e9..cc3c4e4 100644
--- a/architecture/vst.cpp
+++ b/architecture/vst.cpp
@@ -9,8 +9,9 @@
 /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
 
 /************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2004-2011 Remy Muller
+ ************************************************************************
+  FAUST VSTi Architecture File
+	Copyright (C) 2013 by Yan Michalevsy
 	All rights reserved.
     ----------------------------BSD License------------------------------
 	Redistribution and use in source and binary forms, with or without 
@@ -23,7 +24,7 @@
 		  copyright notice, this list of conditions and the following 
 		  disclaimer in the documentation and/or other materials provided 
 		  with the distribution.
-    	* Neither the name of Remy Muller nor the names of its 
+    	* Neither the name of Julius Smith nor the names of its 
 		  contributors may be used to endorse or promote products derived 
 		  from this software without specific prior written permission.
 
@@ -48,18 +49,61 @@
  ************************************************************************
  ************************************************************************/
 
-
 /********************************************************************
- * VST wrapper for the FAUST language. 
- * Author: remy muller remy.muller at ircam.fr           
- * http://www.smartelectronix.com/~mdsp/            
+ * vsti-poly.cpp - Polyphonic VSTi-2.4 wrapper for the FAUST language. 
+ *
+ * Usage: faust -a vst.cpp myfaustprog.dsp
+ *
+ * By Yan Michalevsky (http://www.stanford.edu/~yanm2/)
+ * based on vsti-mono.cpp by
+ * Julius Smith (http://ccrma.stanford.edu/~jos/), based on vst.cpp
+ * by Remy Muller <remy.muller at ircam.fr>
+ * (http://www.smartelectronix.com/~mdsp/).  Essentially, vst.cpp was
+ * first edited to look more like the "again" programming sample that
+ * comes with the VST-2.4 SDK from Steinberg. Next, features from the
+ * "vstxsynth" program sample were added to give simple MIDI synth
+ * support analogous to that of faust2pd, except that only one voice
+ * is supported.  (If the Faust patch has any input signals, this
+ * architecture file should reduce to vst2p4.cpp --- i.e., basic VST
+ * plugin support.)  As with faust2pd, to obtain MIDI control via
+ * NoteOn/Off, Velocity, and KeyNumber, there must be a button named
+ * "gate" and sliders (or numeric entries) named "gain" and "freq" in
+ * the Faust patch specified in myfaustprog.dsp.
+ *
+ * NOTES:
+ *  Relies on automatically generated slider GUI for VST plugins.
+ *   - Horizontal and vertical sliders mapped to "vstSlider"
+ *   - Numeric Entries similarly converted to "vstSlider"
+ *   - No support for bar graphs or additional numeric and text displays
+ *   - Tested on the Muse Receptor Pro 1.0, System Version 1.6.20070717,
+ *     using Visual C++ 2008 Express Edition 
+ *     (part of the Microsoft Visual Studio 2008, Beta 2)
+ *   - Reference: 
+ * http://ccrma.stanford.edu/realsimple/faust/Generating_VST_Plugin_Faust.html
+ *
+ * Initial work on the polyphonic VSTi architecture was done as part
+ * of Music 420B class in Stanford University and in summarized in
+ * http://stanford.edu/~yanm2/files/mus420b.pdf
  *
  * FAUST 
- * Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
- * http://www.grame.fr/                      
- * 
+ * Copyright (C) 2003-2007 GRAME, Centre National de Creation Musicale
+ * http://www.grame.fr/			     
+ *
  ********************************************************************/
 
+// Suggestion: Faust could replace all leading comments in this file
+// by the following shorter comment:
+
+/********************************************************************
+ * C++ source generated by the following command line:
+ *
+ *   faust -a vsti-poly.cpp name.dsp -o name-vsti.cpp
+ *
+ ********************************************************************/
+
+// (where the filenames could be really right, and the path to vsti-poly.cpp
+// could be included as well.)
+
 #include <stdlib.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -71,19 +115,26 @@
 //#include <unistd.h>
 #include <fcntl.h>
 #include <assert.h>
+#include <cstdio>
 #include <string>
+#include <cstring>
+#include <algorithm>
 #include <vector>
 #include <math.h>
 
-using namespace std ;
+#include <map>
+#include <list>
+
+// #define DEBUG
 
-// There is a bug with powf() when cross compiling with mingw
-// the following macro avoid the problem
-#ifdef WIN32
-#define powf(x,y) pow(x,y)
-#define expf(x) exp(x)
+#ifdef DEBUG
+#define TRACE(x) x
+#else
+#define TRACE(x)
 #endif
 
+using namespace std ;
+
 // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
 // flags to avoid costly denormals
 #ifdef __SSE__
@@ -97,81 +148,26 @@ using namespace std ;
     #define AVOIDDENORMALS 
 #endif
 
-struct Meta
+struct Meta : std::map<const char*, const char*>
 {
-    void declare (const char* key, const char* value) {  }
-};
-	
-	
-#ifdef __GNUC__
-
-//-------------------------------------------------------------------
-// Generic min and max using gcc extensions
-//-------------------------------------------------------------------
-
-#define max(x,y) ((x)>?(y))
-#define min(x,y) ((x)<?(y))
-
-//abs(x) should be already predefined
-
-#else
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int 		max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int 		max (int a, int b) 			{ return (a>b) ? a : b; }
-
-inline long 	max (long a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (int a, long b) 		{ return (a>b) ? a : b; }
-inline long 	max (long a, int b) 		{ return (a>b) ? a : b; }
-
-inline float 	max (float a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (int a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, int b) 		{ return (a>b) ? a : b; }
-inline float 	max (long a, float b) 		{ return (a>b) ? a : b; }
-inline float 	max (float a, long b) 		{ return (a>b) ? a : b; }
-
-inline double 	max (double a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (int a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, int b) 		{ return (a>b) ? a : b; }
-inline double 	max (long a, double b) 		{ return (a>b) ? a : b; }
-inline double 	max (double a, long b) 		{ return (a>b) ? a : b; }
-inline double 	max (float a, double b) 	{ return (a>b) ? a : b; }
-inline double 	max (double a, float b) 	{ return (a>b) ? a : b; }
-
-
-inline int 		min (int a, int b) 			{ return (a<b) ? a : b; }
-
-inline long 	min (long a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (int a, long b) 		{ return (a<b) ? a : b; }
-inline long 	min (long a, int b) 		{ return (a<b) ? a : b; }
-
-inline float 	min (float a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (int a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, int b) 		{ return (a<b) ? a : b; }
-inline float 	min (long a, float b) 		{ return (a<b) ? a : b; }
-inline float 	min (float a, long b) 		{ return (a<b) ? a : b; }
-
-inline double 	min (double a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (int a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, int b) 		{ return (a<b) ? a : b; }
-inline double 	min (long a, double b) 		{ return (a<b) ? a : b; }
-inline double 	min (double a, long b) 		{ return (a<b) ? a : b; }
-inline double 	min (float a, double b) 	{ return (a<b) ? a : b; }
-inline double 	min (double a, float b) 	{ return (a<b) ? a : b; }
+    void declare (const char* key, const char* value) { (*this)[key] = value; }
 		
-#endif
+		const char* get(const char* key, const char* defaultString) {
+			if (this->find(key) != this->end()) {
+				return (*this)[key];
+			}
+			else {
+				return defaultString;
+			}
+		} // end of get
+}; // end of Meta
 
 // abs is now predefined
-//template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
-
+//template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
 
-inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
-
-inline int int2pow2 (int x)	{ int r=0; while ((1<<r)<x) r++; return r; }
+inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
 
+inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; }
 
 /******************************************************************************
 *******************************************************************************
@@ -194,41 +190,6 @@ inline int int2pow2 (int x)	{ int r=0; while ((1<<r)<x) r++; return r; }
 *******************************************************************************
 *******************************************************************************/
 
-class UI
-{
-    bool	fStopped;
-		
-public:
-			
-    UI() : fStopped(false) {}
-    virtual ~UI() {}
-		
-    virtual void addButton(char* label, float* zone) = 0;
-    virtual void addToggleButton(char* label, float* zone) = 0;
-    virtual void addCheckButton(char* label, float* zone) = 0;
-    virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
-    virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
-    virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
-	
-	virtual void addNumDisplay(char* label, float* zone, int precision) = 0;
-	virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max) = 0;
-	virtual void addHorizontalBargraph(char* label, float* zone, float min, float max) = 0;
-	virtual void addVerticalBargraph(char* label, float* zone, float min, float max) = 0;
-		
-    virtual void openFrameBox(char* label) = 0;
-    virtual void openTabBox(char* label) = 0;
-    virtual void openHorizontalBox(char* label) = 0;
-    virtual void openVerticalBox(char* label) = 0;
-    virtual void closeBox() = 0;
-		
-    virtual void run() {};
-		
-    void stop()		{ fStopped = true; }
-    bool stopped() 	{ return fStopped; }
-
-    virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
 
 /******************************************************************************
 *******************************************************************************
@@ -236,432 +197,776 @@ public:
 *								FAUST DSP
 *
 *******************************************************************************
-*******************************************************************************/
-
-
+*****************************************************************************/
 
-//----------------------------------------------------------------
-//  definition du processeur de signal
-//----------------------------------------------------------------
-			
-class dsp {
+#include "faust/vst/vstui.h"
+#include "faust/audio/dsp.h"
 
-protected:
-	 
-    int fSamplingFreq;
-		
-public:
-	 
-    dsp() {}
-	virtual ~dsp() {}
-    virtual int getNumInputs() 										= 0;
-    virtual int getNumOutputs() 									= 0;
-    virtual void buildUserInterface(UI* interface) 					= 0;
-    virtual void init(int samplingRate) 							= 0;
-    virtual void compute(int len, float** inputs, float** outputs) 	= 0;
-};
-		
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
 /**************************BEGIN USER SECTION **************************/
 		
 <<includeclass>>
 
+#include "faust/vst/voice.h"
+
 /***************************END USER SECTION ***************************/
 
 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
 					
-/******************************************************************************
+/*****************************************************************************
  *
  * VST wrapper
  * 
- ******************************************************************************/
+ ****************************************************************************/
 
 #include "audioeffectx.h" 
 
-class vstUI;
+///////////////////////////////////////////////////////////////////
+// Constants
+///////////////////////////////////////////////////////////////////
 
-class Faust : public AudioEffectX
-{
-public:
-	Faust(audioMasterCallback audioMaster);
-	virtual ~Faust();
+#define MAX_NOUTS (2)
 
-	virtual void	process(float **inputs, float **outputs, long sampleFrames);
-	virtual void	processReplacing(float **inputs, float **outputs, long sampleFrames);
+//----------------------------------------------------------------------------
+// Faust class prototype
+//----------------------------------------------------------------------------
+#include "faust/vst/faust.h"
+/*--------------------------------------------------------------------------*/
 
-	virtual void	setProgramName(char *name);
-	virtual void	setProgram(long index);
-	virtual void	getProgramName(char *name);
+//----------------------------------------------------------------------------
+// Class Implementations 
+//----------------------------------------------------------------------------
 
-	virtual void	setParameter(long index, float value);
-	virtual float	getParameter(long index);
-	virtual void	getParameterLabel(long index, char *label);
-	virtual void	getParameterDisplay(long index, char *text);
-	virtual void	getParameterName(long index, char *text);
+#define kNumPrograms (1)
 
-	virtual void	setSampleRate(float sampleRate);
+AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
+{
+	TRACE( fprintf(stderr, "Faust VSTi: Creating VST instance\n") );
+	
+  // The dsp and its UI need to be allocated now because
+  // AudioEffectX wants the no. parameters available as an instance argument:
+	mydsp* dspi = new mydsp();
+	vstUI* dspUIi = new vstUI();
+  dspi->buildUserInterface(dspUIi);
 
-	virtual bool	getEffectName (char* name);
-	virtual bool	getVendorString (char* text);
-	virtual bool	getProductString (char* text);
+  TRACE( fprintf(stderr,"=== Faust vsti: created\n") ); // look for this in the system log
 
-	virtual bool	getInputProperties (long index, VstPinProperties* properties);
-	virtual bool	getOutputProperties (long index, VstPinProperties* properties);
+  return new Faust(audioMaster, dspi, dspUIi);
+}
 
-private:
-	mydsp*	dsp;
-	vstUI*	dspUI;
-};
+//-----------------------------------------------------------------------------
+// Faust
+//-----------------------------------------------------------------------------
+Faust::Faust(audioMasterCallback audioMaster, dsp* dspi, vstUI* dspUIi)
+  : AudioEffectX(audioMaster, kNumPrograms, dspUIi->GetNumParams()),
+		m_dsp(dspi), m_dspUI(dspUIi), 
+		m_voices(MAX_POLYPHONY, (Voice*)NULL),
+		m_playingVoices(),
+		m_freeVoices(),
+		m_prevVoice(-1),
+		m_tempOutputs(NULL),
+		m_tempOutputSize(INITIAL_TEMP_OUTPUT_SIZE),
+		m_currentNotes(),
+		m_currentVelocities(),
+		m_currentDeltas()
+{
+#ifdef DEBUG
+  fprintf(stderr,"=== Faust vsti: classInit:\n");
+#endif
 
-/*--------------------------------------------------------------------------*/
-class vstUIObject {
-protected:
-    string fLabel;
-    float* fZone;
-		
-    float range(float min, float max, float val) 
-		{	// VST parameters are normalized in the range [0;1]
-			val = min + val * (max - min);
-			return (val < min) ? min : (val > max) ? max : val;
-		}
-	 
-public:			
-    vstUIObject(char* label, float* zone):fLabel(label),fZone(zone) {}
-    virtual ~vstUIObject() {}
-
-    virtual void  GetName(char *text){std::strcpy(text,fLabel.c_str());}
-    virtual void  SetValue(double f) {*fZone = range(0.0f,1.0f,(float)f);}
-    virtual float GetValue() {return *fZone;}
-    virtual void  GetDisplay(char *text){std::sprintf(text,"%f",*fZone);}
-    virtual long  GetID() 
-		{	/* returns the sum of all the ASCII characters  contained in the parameter's label */
-			int i;
-			long acc;
-			for(i=0,acc = 0;i<fLabel.length();i++) acc += (fLabel.c_str())[i];
-			return acc;
-		}
-};
+  mydsp::classInit((int)getSampleRate()); // Ask AudioEffect for sample-rate
+
+  setProgram(0);
+  setProgramName("Default");
+
+  if (audioMaster) {
+    setNumInputs(m_dsp->getNumInputs());
+    setNumOutputs(m_dsp->getNumOutputs());		
+    canProcessReplacing();
+    if (m_dsp->getNumInputs() == 0) {
+      isSynth(); // at least let's hope so!
+      if (m_dsp->getNumOutputs() < 1) {
+				fprintf(stderr,"*** faust: vsti: No signal inputs or outputs, "
+						"and Faust has no MIDI outputs!\n");
+			}
+    }
+    setUniqueID(m_dspUI->makeID());					
+  }
+
+	// Initialize all members related to polyphonic performance
+	TRACE( fprintf(stderr, "Faust VSTi: Initializing voices and temporary output buffers\n") );
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		m_voices[i] = new Voice((int)getSampleRate());
+		m_freeVoices.push_back(i);
+	}
 
-/*--------------------------------------------------------------------------*/
-class vstToggleButton : public vstUIObject {
-	
-public:	
-	
-    vstToggleButton(char* label, float* zone):vstUIObject(label,zone) {}
-    virtual ~vstToggleButton() {}
-    virtual float GetValue() {return *fZone;}
-    virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}				
-    virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
-};
+	TRACE( fprintf(stderr, "Faust VSTi: Allocating %d temporary output "
+								 "buffers\n", m_dsp->getNumOutputs()) );
+	m_tempOutputs = (FAUSTFLOAT**) malloc(sizeof(FAUSTFLOAT*) * m_dsp->getNumOutputs());
+	for (int i = 0; i < m_dsp->getNumOutputs(); ++i) {
+		m_tempOutputs[i] = (FAUSTFLOAT*) malloc(sizeof(FAUSTFLOAT) * m_tempOutputSize);
+	}
 
-/*--------------------------------------------------------------------------*/
-class vstCheckButton : public vstUIObject {
-	
-public:
-	
-    vstCheckButton(char* label, float* zone):vstUIObject(label,zone) {}	
-    virtual ~vstCheckButton() {}
-    virtual float GetValue() {return *fZone;}
-    virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}
-    virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}		
-};
+  initProcess();
+  if (m_dsp->getNumInputs() == 0) {
+    suspend(); //  Synths start out quiet
+  }
+} // end of Faust constructor
 
-/*--------------------------------------------------------------------------*/
-class vstButton : public vstUIObject {
-	
-public:
+//----------------------------------------------------------------------------
+Faust::~Faust()
+{
+	TRACE( fprintf(stderr, "Calling Faust VST destructor\n") );
 	
-    vstButton(char* label, float* zone):vstUIObject(label,zone) {}
-    virtual ~vstButton() {}		
-    virtual float GetValue() {return *fZone;}
-    virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}		
-    virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
-};
+	for (int i = 0; i < m_dsp->getNumOutputs(); ++i) {
+		free(m_tempOutputs[i]);
+		m_tempOutputs[i] = NULL;
+	}
 
-/*--------------------------------------------------------------------------*/
-class vstSlider : public vstUIObject{
+	free(m_tempOutputs);
 
-private:
-	
-    float fInit;
-    float fMin;
-    float fMax;
-    float fStep;
-	
-public:	
-	
-    vstSlider(char* label, float* zone, float init, float min, float max, float step)
-        :vstUIObject(label,zone), fInit(init), fMin(min), fMax(max),fStep(step) {}
-    virtual ~vstSlider() {}	
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		if (NULL != m_voices[i]) {
+			delete m_voices[i];
+			m_voices[i] = NULL;
+		}
+	}
 
-    virtual float GetValue() {return (*fZone-fMin)/(fMax-fMin);}	// normalize
-    virtual void SetValue(double f) {*fZone = range(fMin,fMax,(float)f);} // expand
-};
+  if (m_dspUI) {
+		delete m_dspUI;
+	}
 
-/*--------------------------------------------------------------------------*/
-class vstUI : public UI
-{
-private:
-	
-    vector<vstUIObject*> fUITable;
-		
-public:
-			
-    vstUI(){}
-    virtual ~vstUI() 
-		{
-			for (vector<vstUIObject*>::iterator iter = fUITable.begin(); iter != fUITable.end(); iter++) delete *iter;
-   		}
-		
-    void addButton(char* label, float* zone) {fUITable.push_back(new vstButton(label, zone));}
-		
-    void addToggleButton(char* label, float* zone) {fUITable.push_back(new vstToggleButton(label, zone));}
-		
-    void addCheckButton(char* label, float* zone) {fUITable.push_back(new vstCheckButton(label, zone));}
-		
-    void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) 
-		{ 	
-			fUITable.push_back(new vstSlider(label, zone, init, min, max, step));
-		}
-		
-    void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) 
-		{
-			fUITable.push_back(new vstSlider(label, zone, init, min, max, step));
-		}
-		
-    void addNumEntry(char* label, float* zone, float init, float min, float max, float step) {}
-		
-    void openFrameBox(char* label) {}
-    void openTabBox(char* label) {}
-    void openHorizontalBox(char* label) {}
-    void openVerticalBox(char* label) {}
-    void closeBox() {}
-		
-    void  SetValue(int index, double f) {assert(index<fUITable.size()); fUITable[index]->SetValue(f);}
-    float GetValue(long index)	{assert(index<fUITable.size()); return fUITable[index]->GetValue();}
-    void  GetDisplay(long index, char *text) {assert(index<fUITable.size()); fUITable[index]->GetDisplay(text);}
-    void  GetName(long index, char *text) {assert(index<fUITable.size()); fUITable[index]->GetName(text);}
-    long  GetNumParams() {return fUITable.size();}
-
-    long  makeID()
-        /* Creates a (unique?)id by summing all the parameter's labels, 
-         * then wrapping it in the range [0;maxNumberOfId] and adding 
-         * this number to the offset made by the Four Character ID: 'FAUS'
-         */
-		{   
-			const long maxNumberOfId = 128;
-			long baseid = 'FAUS';
-            long id=0;
-			for(int i=0;i<fUITable.size();i++) id += fUITable[i]->GetID();
-			return baseid + id % maxNumberOfId;
-		}
-		
-	// To be implemented
-	void addNumDisplay(char* label, float* zone, int precision){}
-	void addTextDisplay(char* label, float* zone, char* names[], float min, float max){}
-	void addHorizontalBargraph(char* label, float* zone, float min, float max){}
-	void addVerticalBargraph(char* label, float* zone, float min, float max){}
-};
+  if (m_dsp) {
+		delete m_dsp;
+	}
+
+} // end of Faust destructor
 
 //-----------------------------------------------------------------------------
-#define NUM_PROGRAMS 0
-#define FAKE_NUM_PARAMS 16
+void Faust::setProgram (VstInt32 program)
+// Override this method of AudioEffect in order to set 
+// local instance variables corresponding to the current MIDI program.
+// Here there is only one program.
+{
+  if (program < 0 || program >= kNumPrograms) {
+		fprintf(stderr,
+						"*** Faust vsti: setting program to %d is OUT OF RANGE\n",
+						program);
+    return;
+  }  
+
+#ifdef DEBUG
+  fprintf(stderr,"=== Faust vsti: setting program to %d\n",program);
+#endif
+
+  curProgram = program; // curProgram defined in audioeffect.h
+} // end of setProgram
 
-Faust::Faust(audioMasterCallback audioMaster)
-    :AudioEffectX(audioMaster, NUM_PROGRAMS,FAKE_NUM_PARAMS)
+//----------------------------------------------------------------------------
+void Faust::setProgramName (const char* name)
 {
-	dsp = new mydsp();
-	dspUI= new vstUI();
-	dsp->buildUserInterface(dspUI);
-	dsp->init(long(getSampleRate()));
-	
-	/* we override here the fake number of parameters with the real one*/
-	this->cEffect.numParams = this->numParams = dspUI->GetNumParams();
-	  
-	setNumInputs(dsp->getNumInputs());		
-	setNumOutputs(dsp->getNumOutputs());		
-	setUniqueID(dspUI->makeID());					
-	canProcessReplacing();//?
+  vst_strncpy (programName, name, kVstMaxProgNameLen);
 }
 
 //----------------------------------------------------------------------------
-Faust::~Faust()
+void Faust::getProgramName(char *name)
 {
-	if (dsp) delete dsp;
-	if (dspUI) delete dspUI;
+  vst_strncpy (name, programName, kVstMaxProgNameLen);
 }
 
-//-----------------------------------------------------------------------------
-void Faust::setParameter(long index, float value)
+//----------------------------------------------------------------------------
+void Faust::getParameterLabel(VstInt32 index, char *label)
+{	
+	const char* unit = "";
+	if (index < numParams) {
+		 unit = m_dspUI->getControlMetadata(index, "unit", "");
+	}
+
+	vst_strncpy (label, unit, kVstMaxParamStrLen); // parameter units in Name
+
+	TRACE( fprintf(stderr, "Called getParameterLabel for parameter %d, returning %s\n",
+								 index, label) );
+} // end of getParameterLabel
+
+//----------------------------------------------------------------------------
+void Faust::getParameterDisplay(VstInt32 index, char *text)
 {
-    if(index<numParams)
-        dspUI->SetValue(index,value);
+  if(index < numParams) {
+    m_dspUI->GetDisplay(index,text); // get displayed float value as text
+	}
+  else {
+    vst_strncpy (text, "IndexOutOfRange", kVstMaxParamStrLen);
+	}
 }
-//-----------------------------------------------------------------------------
-float Faust::getParameter(long index)
+
+//----------------------------------------------------------------------------
+void Faust::getParameterName(VstInt32 index, char *label)
+{
+  if(index < numParams) {
+    m_dspUI->GetName(index,label); // parameter name, including units
+	} else {
+    vst_strncpy (label, "IndexOutOfRange", kVstMaxParamStrLen);
+	}
+} // end of getParamterName
+
+//--------------------
+
+bool Faust::getParameterProperties(VstInt32 index, VstParameterProperties* properties)
+{
+	if (index < 0 || index >= m_dspUI->GetNumParams()) {
+		TRACE( fprintf(stderr, "Faust VSTi: Invalid parameter index %d\n",
+									 index) );
+		return false;
+	}
+
+	TRACE( fprintf(stderr, "Faust VSTi: getParameterProperties called with index %d\n",
+								 index) );
+
+	if ( index == m_dspUI->gateIndex ) {
+		properties->flags |= kVstParameterIsSwitch;
+	}
+
+	getParameterName(index, properties->label);
+	
+	// TODO: set parameter range
+	const vstSlider* slider = dynamic_cast<const vstSlider*>(m_dspUI);
+	if (NULL != slider) {
+		// has min-max range
+		properties->minInteger = slider->getMinValue();
+		properties->maxInteger = slider->getMaxValue();
+		properties->stepInteger = slider->getStep();
+	}
+
+	return true;
+} // end of getParameterProperties
+
+//----------------------------------------------------------------------------
+void Faust::setParameter(VstInt32 index, float value)
 {
-    if(index<numParams)
-        return dspUI->GetValue(index);
-    else
-        return 0.0f;
+	if (index >= numParams || index < 0) {
+		TRACE( fprintf(stderr, "Faust VSTi: Invalid parameter index %d\n",
+									 index) );
+		return;
+	}
+
+  m_dspUI->SetValue(index, value);
+
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		TRACE( fprintf(stderr, "Setting parameter %d for voice %d to value %f\n",
+									 index, i, value) );
+		m_voices[i]->SetValue(index, value);
+	}
+} // end of setParameter
+
+//----------------------------------------------------------------------------
+float Faust::getParameter(VstInt32 index)
+{
+	return (index >= 0 && index < numParams) ? m_dspUI->GetValue(index) : 0.0f;
 }
+
 //-----------------------------------------------------------------------------
-void Faust::getParameterName(long index, char *label)
+bool Faust::getInputProperties (VstInt32 index, VstPinProperties* properties)
 {
-    if(index<numParams)
-        dspUI->GetName(index,label);
-    else
-        strcpy(label,"");
+  if(index < 0 || index >= m_dsp->getNumInputs()) {
+		return false;
+	}
+
+	sprintf (properties->label, "Grame Faust DSP input: %d",index);
+	sprintf (properties->shortLabel, "In %d",index);
+	properties->flags = kVstPinIsActive;
+	if (m_dsp->getNumInputs() == 2) {
+		properties->flags |= kVstPinIsStereo;
+	}
+	
+	return true;
 }
+
 //-----------------------------------------------------------------------------
-void Faust::getParameterDisplay(long index, char *text)
+bool Faust::getOutputProperties (VstInt32 index, VstPinProperties* properties)
 {
-    if(index<numParams)
-        dspUI->GetDisplay(index,text);
-    else
-        strcpy(text,"");
+  if(index < 0 || m_dsp->getNumOutputs() < 1) {
+		return false;
+	}
+
+	sprintf (properties->label, "Grame Faust DSP output: %d",index);
+	sprintf (properties->shortLabel, "Out %d",index);
+	properties->flags = kVstPinIsActive;
+	if (m_dsp->getNumOutputs() == 2) {
+		properties->flags |= kVstPinIsStereo;
+	}
+	return true;
 }
-//-----------------------------------------------------------------------------
-void Faust::getParameterLabel(long index, char *label)
+
+//----------------------------------------------------------------------------
+bool Faust::getProgramNameIndexed (VstInt32 category, VstInt32 index, 
+																	 char* text)
 {
-	strcpy(label,"");
+  if (index < kNumPrograms) {
+      vst_strncpy (text, programName, kVstMaxProgNameLen);
+      return true;
+  }
+  return false;
 }
 
+const char* Faust::getMetadata(const char* key, const char* defaultString)
+{
+	Meta meta;
+	mydsp::metadata(&meta);
+	return meta.get(key, defaultString);
+} // end of getMetadata
+
 //-----------------------------------------------------------------------------
-void Faust::setProgramName(char *name)
+bool Faust::getEffectName (char* name)
 {
-	// this template does not use programs yet
+  const char* effectName = getMetadata("name", "Effect Name goes here");
+  vst_strncpy (name, effectName, kVstMaxEffectNameLen);
+  return true;
 }
+
 //-----------------------------------------------------------------------------
-void Faust::setProgram(long index)
+bool Faust::getVendorString (char* text)
 {
-	// this template does not use programs yet
-};
+  const char* vendorString = getMetadata("author", "Vendor String goes here");
+  vst_strncpy (text, vendorString, kVstMaxVendorStrLen);
+  return true;
+}
+
 //-----------------------------------------------------------------------------
-void Faust::getProgramName(char *name)
+bool Faust::getProductString (char* text)
 {
-	// this template does not use programs yet
-	strcpy(name, "");
+  const char* productString = getMetadata("name", "Product String goes here");
+  vst_strncpy (text, productString, kVstMaxProductStrLen);
+  return true;
 }
+
 //-----------------------------------------------------------------------------
-void Faust::process(float **inputs, float **outputs, long sampleFrames)
-{
-	AVOIDDENORMALS;
-    dsp->compute(sampleFrames, inputs, outputs);
+VstInt32 Faust::getVendorVersion ()
+{ 
+	const char* versionString = getMetadata("version", "0.0");
+  return (VstInt32)atof(versionString);
 }
+
 //-----------------------------------------------------------------------------
-void Faust::processReplacing(float **inputs, float **outputs, long sampleFrames)
+VstInt32 Faust::canDo (const char* text)
 {
-	AVOIDDENORMALS;
-    dsp->compute(sampleFrames, inputs, outputs);
+  if (!strcmp (text, "receiveVstEvents")) {
+    return 1;
+	}
+  
+	if (!strcmp (text, "receiveVstMidiEvent")) {
+    return 1;
+	}
+
+  if (!strcmp (text, "midiProgramNames")) {
+    return 1;
+	}
+
+  return -1;	// explicitly can't do; 0 => don't know
+} // end of canDo
+
+//----------------------------------------------------------------------------
+VstInt32 Faust::getNumMidiInputChannels ()
+{
+  return 1; // one MIDI-in channel
 }
-//-----------------------------------------------------------------------------
-void Faust::setSampleRate(float sampleRate)
+
+//----------------------------------------------------------------------------
+VstInt32 Faust::getNumMidiOutputChannels ()
 {
-	// allways call this
-	AudioEffect::setSampleRate(sampleRate);
-	dsp->init(long(getSampleRate()));
+  return 0; // no MIDI-outs
 }
-//-----------------------------------------------------------------------------------------
-bool Faust::getEffectName (char* name)
+
+//----------------------------------------------------------------------------
+VstInt32 Faust::getMidiProgramName (VstInt32 channel, MidiProgramName* mpn)
 {
-	return false;
+  VstInt32 prg = mpn->thisProgramIndex;
+  if (prg < 0 || prg > 0) return 0;
+  fillProgram (channel, prg, mpn);
+  return 1; // we have only 1 "MIDI program"
 }
-//-----------------------------------------------------------------------------------------
-bool Faust::getVendorString (char* text)
+
+//------------------------------------------------------------------------
+VstInt32 Faust::getCurrentMidiProgram (VstInt32 channel, MidiProgramName* mpn)
 {
-	strcpy (text, "Grame");
-	return true;
+  // There is only one MIDI program here, so return it regardless of MIDI channel:
+  if (channel < 0 || channel >= 16 || !mpn) return -1;
+  VstInt32 prg = 0;
+  mpn->thisProgramIndex = prg;
+  fillProgram (channel, prg, mpn);
+  return prg;
 }
-//-----------------------------------------------------------------------------------------
-bool Faust::getProductString (char* text)
+
+//------------------------------------------------------------------------
+void Faust::fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn)
+// Fill mpn struct for given channel.  Here there should be only one.
 {
-	strcpy (text, "Faust DSP");
-	return true;
+  mpn->midiBankMsb = mpn->midiBankLsb = -1;
+  mpn->reserved = 0;
+  mpn->flags = 0;
+  vst_strncpy (mpn->name, programName, kVstMaxProgNameLen);
+  mpn->midiProgram = (char)prg; // prg should only be 0
+  mpn->parentCategoryIndex = -1;
 }
-//-----------------------------------------------------------------------------------------
-bool Faust::getInputProperties (long index, VstPinProperties* properties)
-{
-    if(index>=0 && index<dsp->getNumOutputs())
-    {
-        sprintf (properties->label	  , "Grame Faust DSP: %d",index);
-        sprintf (properties->shortLabel, "Faust: %d",index);
-        properties->flags = kVstPinIsActive;			
-        return true;
-    }
-    else
-        return false;
+
+//------------------------------------------------------------------------
+VstInt32 Faust::getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* cat)
+// VST host wants to fill cat struct for given channel.  We have only one category.
+{
+  cat->parentCategoryIndex = -1;	// -1:no parent category
+  cat->flags = 0;			// reserved, none defined yet, zero.
+  VstInt32 category = cat->thisCategoryIndex;
+  vst_strncpy (cat->name, "Faust Patch", kVstMaxProgNameLen);
+  return 1; // one category
 }
-//-----------------------------------------------------------------------------------------
-bool Faust::getOutputProperties (long index, VstPinProperties* properties)
-{
-    if(index>=0 && index<dsp->getNumInputs())
-    {
-        sprintf (properties->label	  , "Grame Faust DSP: %d",index);
-        sprintf (properties->shortLabel, "Faust: %d",index);
-        properties->flags = kVstPinIsActive;			
-        return true;
-    }
-    else
-        return false;
+
+//***********************************************************************
+
+//----------------------------------------------------------------------------
+void Faust::setSampleRate(float sampleRate)
+{
+  AudioEffect::setSampleRate(sampleRate);
+  m_dsp->init((int)getSampleRate()); // in case AudioEffect altered it
+
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		m_voices[i]->m_dsp.init((int)getSampleRate());
+	}
 }
 
-/*****************************************************************************
- *
- * DLL Entry Point
- *
- ******************************************************************************/
-bool oome = false;
+//----------------------------------------------------------------------------
+void Faust::initProcess ()
+{
+  currentVelocity = currentNote = currentDelta = 0;
+  m_dsp->init((int)getSampleRate());
 
-#if MAC
-#pragma export on
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		m_voices[i]->m_dsp.init((int)getSampleRate());
+	}
+}
+
+//----------------------------------------------------------------------------
+void Faust::processReplacing(FAUSTFLOAT** inputs, FAUSTFLOAT** outputs, VstInt32 sampleFrames)
+{
+    AVOIDDENORMALS;
+#ifdef DEBUG
+    // fprintf(stderr,"=== Faust vsti: processReplacing . . .\n");
 #endif
 
-// prototype of the export function main
-#if BEOS
-#define main main_plugin
-extern "C" __declspec(dllexport) AEffect *main_plugin (audioMasterCallback audioMaster);
+  if (m_dsp->getNumInputs() > 0) {
+		// We're an effect . . . keep going:
+    m_dsp->compute(sampleFrames, inputs, outputs);
+  }
+	else { 
+		// We're a synth . . . 
+		synthProcessReplacing(inputs, outputs, sampleFrames);
+	}
+} // end of processReplacing
 
-#elif MACX
-#define main main_macho
-extern "C" AEffect *main_macho (audioMasterCallback audioMaster);
+inline float midiToFreq(int note) {
+	return 440.0f*powf(2.0f,(((float)note)-69.0f)/12.0f);
+}
 
-#else
-AEffect *main (audioMasterCallback audioMaster);
-#endif
+void Faust::synthProcessReplacing(FAUSTFLOAT** inputs, FAUSTFLOAT** outputs, 
+																	VstInt32 sampleFrames)
+{
+	float* outptr[MAX_NOUTS] = {NULL,};
+	int i;
+	int nouts = m_dsp->getNumOutputs();
+
+	if (nouts > MAX_NOUTS) {
+		TRACE( fprintf(stderr, "VSTi: nouts > MAX_NOUTS. Number of outputs (%d) exceeds limit. "
+									 "Truncated to maximum.\n", nouts) );
+		nouts = MAX_NOUTS;
+	}
+
+	// we're synthesizing . . .
+	if (m_currentNotes.size() > 0) {
+		int previousDelta = 0;
+		while (m_currentNotes.size() > 0) { // a new note
+			currentDelta = m_currentDeltas.front();
+			// but waiting out a timestamp delay . . .
+			if (currentDelta >= sampleFrames) { 
+				// start time is after this chunk
+				for(std::list<VstInt32>::iterator it = m_currentDeltas.begin(); it != m_currentDeltas.end(); ++it) {
+					*it -= sampleFrames;
+				}
+				compute(inputs, outputs, sampleFrames);
+				return;
+			}
+			else {
+				m_currentDeltas.pop_front();
+				currentNote = m_currentNotes.front();
+				m_currentNotes.pop_front();
+				currentVelocity = m_currentVelocities.front();
+				m_currentVelocities.pop_front();
+				if (currentVelocity > 0) { // Note on
+					// Reserve a free voice for the played 
+					int currentVoice;
+					if (m_freeVoices.size() > 0) {
+						currentVoice = m_freeVoices.front();
+						m_freeVoices.pop_front();
+						struct voice_node *n = new voice_node;
+						n->note = currentNote;
+						n->voice = currentVoice;
+						m_playingVoices.push_back(n);
+					}
+					else {
+						voice_node *front = m_playingVoices.front();
+						currentVoice = front->voice;
+						float freq = midiToFreq(front->note);
+						m_voices[currentVoice]->setPrevFreq(freq);
+						front->note = currentNote;
+						m_playingVoices.pop_front();
+						m_playingVoices.push_back(front);
+					}
+					memset(outptr, 0, sizeof(outptr));
+					// Before the note starts
+					assert(nouts <= MAX_NOUTS);
+					for (i = 0; i < nouts; i++) {
+						outptr[i] = outputs[i] + previousDelta; // leaving caller's pointers alone
+					}
+					compute(inputs, outptr, currentDelta - previousDelta);
+					// Note start
+					float freq = midiToFreq(currentNote);
+					m_voices[currentVoice]->setFreq(freq); // Hz - requires Faust control-signal "freq"
+					float gain = currentVelocity/127.0f;
+					m_voices[currentVoice]->setGain(gain); // 0-1 - requires Faust control-signal "gain"
+					m_voices[currentVoice]->setGate(1.0f); // 0 or 1 - requires Faust control-signal "gate"
+				}
+				else { // Note off
+					// Find the voice to be turned off
+					int currentVoice;
+					bool voiceFound = false;
+					std::list<voice_node*>::iterator voice_iter = m_playingVoices.begin();
+					for (; voice_iter != m_playingVoices.end(); voice_iter++) {
+						if (currentNote == (*voice_iter)->note) {
+							currentVoice = (*voice_iter)->voice;
+							TRACE( fprintf(stderr, "=== Faust VSTi: Found matching voice for note %d: %d\n", currentNote, currentVoice) );
+							if (std::find(m_releasedVoices.begin(), m_releasedVoices.end(), currentVoice) == m_releasedVoices.end()) {
+								m_releasedVoices.push_back(currentVoice);
+								voiceFound = true;
+							}
+						}
+					}
+					memset(outptr, 0, sizeof(outptr));
+					// Before the note ends
+					for (i = 0; i < nouts; i++) {
+						outptr[i] = outputs[i] + previousDelta; // leaving caller's pointers alone
+					}
+					compute(inputs, outptr, currentDelta - previousDelta);
+					// Note end
+					if (voiceFound) {
+						m_voices[currentVoice]->setGate(0);
+					}
+				}
+				previousDelta = currentDelta;
+			}
+		}
+		memset(outptr, 0, sizeof(outptr));
+		// Compute the left over time
+		int count = sampleFrames - currentDelta;
+		// Left over time in chunk
+		for (i = 0; i < nouts; i++) {
+			outptr[i] = outputs[i] + currentDelta; // leaving caller's pointers alone
+		}
+		compute(inputs, outptr, count);
+	}
+	else {
+		compute(inputs, outputs, sampleFrames);
+	}
+
+} // end of synthProcessReplacing
 
-AEffect *main (audioMasterCallback audioMaster)
+void Faust :: compute(FAUSTFLOAT** inputs, FAUSTFLOAT** outputs, 
+											VstInt32 sampleFrames)
 {
-	// get vst version
-	if (!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
-		return 0;  // old version
+	const unsigned int output_buffer_size = sizeof(FAUSTFLOAT) * sampleFrames;
 
-	AudioEffect* effect = new Faust(audioMaster);
-	if (!effect)
-		return 0;
-	if (oome)
-	{
-		delete effect;
-		return 0;
+	// Clear the buffers
+	for (int i = 0; i < m_dsp->getNumOutputs(); ++i) {
+		for (int frame = 0; frame < sampleFrames; ++frame) {
+			outputs[i][frame] = 0;
+		}
 	}
-	return effect->getAeffect ();
-}
 
-#if MAC
-#pragma export off
-#endif
+	if (sampleFrames > (VstInt32)m_tempOutputSize) {
+		// if requested number of samples to synthesize exceeds current temporary buffer
+		TRACE( fprintf(stderr, "Faust VSTi: Increasing temporary buffer to %d frames\n",
+									 sampleFrames) );
+		for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+			m_tempOutputs[i] = (FAUSTFLOAT*) realloc(m_tempOutputs[i], output_buffer_size * m_dsp->getNumOutputs());
+			m_tempOutputSize = sampleFrames;
+		}
+	}
+	
+	std::list<voice_node*> removed;
+	std::list<voice_node*>::iterator voice_iter = m_playingVoices.begin();
+	for(;voice_iter != m_playingVoices.end(); voice_iter++) {
+		int voice = (*voice_iter)->voice;
+		m_voices[voice]->m_dsp.compute(sampleFrames, inputs, m_tempOutputs);
+
+		bool silent = true;
+		// mix current voice into output
+		for (int i = 0; i < m_dsp->getNumOutputs(); ++i) {
+			for (int frame = 0; frame < sampleFrames; ++frame) {
+				outputs[i][frame] += m_tempOutputs[i][frame];
+				if (fabs(m_tempOutputs[i][frame]) > 1e-6) {
+					silent = false;
+				}
+			}
+		}
+		if (silent) {
+			std::vector<VstInt32>::iterator it;
+			it = std::find(m_releasedVoices.begin(), m_releasedVoices.end(), voice);
+			if (it != m_releasedVoices.end()) {
+				m_freeVoices.push_back(voice);
+				m_releasedVoices.erase(it);
+				removed.push_back(*voice_iter);
+			}
+		}
+	} // end of signal computation and mixdown
+	while (removed.size() > 0) {
+		std::list<voice_node*>::iterator it;
+		it = std::find(m_playingVoices.begin(), m_playingVoices.end(), removed.front());
+		float freq = midiToFreq((*it)->note);
+		m_voices[(*it)->voice]->setPrevFreq(freq);
+		free(*it);
+		m_playingVoices.erase(it);
+		removed.pop_front();
+	}
 
-#if WIN32
-#include <windows.h>
-void* hInstance;
-BOOL WINAPI DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved)
+	// normalize sample by the max polyphony
+	for (int i = 0; i < m_dsp->getNumOutputs(); ++i) {
+		for (int frame = 0; frame < sampleFrames; ++frame) {
+			outputs[i][frame] /= (FAUSTFLOAT)sqrt(MAX_POLYPHONY);
+		}
+	}
+} // end of compute
+
+//-----------------------------------------------------------------------------
+VstInt32 Faust::processEvents (VstEvents* ev)
 {
-	hInstance = hInst;
+  if (ev->numEvents > 0) {
+	  TRACE( fprintf(stderr,"=== Faust vsti: processEvents processing %d "
+									 "events\n", ev->numEvents) );
+  }
+
+  for (VstInt32 i = 0; i < ev->numEvents; i++) {
+		TRACE( fprintf(stderr,"=== Faust vsti: event type = %d\n", 
+					(ev->events[i])->type) );
+		if ((ev->events[i])->type != kVstMidiType) {
+			TRACE( fprintf(stderr,"=== Faust vsti: EVENT IGNORED!\n") );
+			continue;
+		}
+
+		VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
+		char* midiData = event->midiData;
+		VstInt32 chan = midiData[0] & 0xf;
+		VstInt32 status = midiData[0] & 0xf0;
+
+#ifdef DEBUG
+		fprintf(stderr,"\n=== Faust vsti: event->midiData[0] = 0x%x\n", 
+				event->midiData[0]);
+		fprintf(stderr,"=== Faust vsti: midi channel = 0x%x\n", chan);
+		fprintf(stderr,"=== Faust vsti: midi status = 0x%x\n", status);
+		fprintf(stderr,"=== Faust vsti: event->midiData[1] = 0x%x\n", 
+				event->midiData[1]);
+		fprintf(stderr,"=== Faust vsti: event->midiData[2] = 0x%x\n", 
+				event->midiData[2]);
+#endif
+
+		VstInt32 note = midiData[1] & 0x7f;
+
+		if (status == 0x90) { // note on
+			VstInt32 velocity = midiData[2] & 0x7f;
+			TRACE( fprintf(stderr,
+						"=== Faust vsti: note = %d, velocity = %d, delay = %d\n",
+						note,velocity,event->deltaFrames) );
+			if (velocity > 0) {
+				noteOn(note, velocity, event->deltaFrames);
+			} 
+			else {
+				noteOff(note, event->deltaFrames);
+			}
+		} 
+		else if (status == 0x80) { // note off
+			noteOff(note, event->deltaFrames);
+			//      } else if (status == 0xA0) { // poly aftertouch
+		} else if (status == 0xB0) { // control change
+			/* DO SOMETHING WITH THE CONTROLLER DATA */
+			fprintf(stderr,"=== Faust vsti: CONTROL CHANGE (status 0xB0)!\n");
+			if (midiData[1] == 0x7e || midiData[1] == 0x7b) { // all notes off
+				fprintf(stderr,"=== Faust vsti: ALL NOTES OFF!\n");
+
+				//TODO: figure out how to signal all notes off
+				// why is all-notes-off inside a "control change" event?
+				allNotesOff(); 
+			}
+		}
+		else if (status == 0xE0) { // pitch change
+			int val = midiData[1] | (midiData[2] << 7);
+			float bend = (val - 0x2000) / 8192.0f;
+			bendPitch(bend);
+		}
+		//      } else if (status == 0xF0) { // SYSX ...
+		//      } else if (status == 0xC0) { // program change
+		//      } else if (status == 0xD0) { // mono aftertouch
+		// For a list, see 
+		// http://www.alfred-j-faust.de/rft/midi%20status%20types.html
+
+		TRACE( fprintf(stderr,"=== Faust vsti: Going to next event\n") );
+
+		event++;
+	}
+
 	return 1;
 }
+
+//----------------------------------------------------------------------------
+
+void Faust::bendPitch(float bend)
+{
+	TRACE( fprintf(stderr, "Bending pitch by %f\n", bend) );
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		m_voices[i]->setPitchBend(bend);
+	}
+} // end of Faust::bendPitch
+
+void Faust::noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta)
+{
+#ifdef DEBUG
+    fprintf(stderr,"=== Faust vsti: noteOn: note = %d, vel = %d, del = %d\n",note,velocity,delta);
 #endif
+	m_currentNotes.push_back(note);
+	m_currentVelocities.push_back(velocity);
+	m_currentDeltas.push_back(delta);
+} // end of noteOn
 
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
+//-----------------------------------------------------------------------------
+void Faust::noteOff (VstInt32 note, VstInt32 delta)
+{
+	TRACE( fprintf(stderr,"=== Faust vsti: noteOff\n") );
+	m_currentNotes.push_back(note);
+	m_currentVelocities.push_back(0);
+	m_currentDeltas.push_back(delta);
+} // end of nToteOff
 
+void Faust::allNotesOff( void )
+{
+	TRACE( fprintf(stderr, "All notes off\n") );
+	
+	for (unsigned int i = 0; i < MAX_POLYPHONY; ++i) {
+		m_voices[i]->setGate(0);
+	}
+
+	std::list<voice_node*>::iterator voice_iter = m_playingVoices.begin();
+	for (; voice_iter != m_playingVoices.end(); voice_iter++) {
+		int voice = (*voice_iter)->voice;
+		if (std::find(m_releasedVoices.begin(), m_releasedVoices.end(), voice) == m_releasedVoices.end()) {
+			m_releasedVoices.push_back(voice);
+		}
+	}
+} // end of Faust::allNotesOff
+
+/********************END ARCHITECTURE SECTION (part 2/2)****************/
 
diff --git a/architecture/vst2p4.cpp b/architecture/vst2p4.cpp
deleted file mode 100644
index 41f173c..0000000
--- a/architecture/vst2p4.cpp
+++ /dev/null
@@ -1,648 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections : 
-	the ARCHITECTURE section (in two parts) and the USER section. Each section 
-	is governed by its own copyright and license. Please check individually 
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
- ************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2007-2011 Remy Muller & Julius Smith
-	All rights reserved.
-    ----------------------------BSD License------------------------------
-	Redistribution and use in source and binary forms, with or without 
-	modification, are permitted provided that the following conditions 
-	are met:
-
-    	* Redistributions of source code must retain the above copyright 
-		  notice, this list of conditions and the following disclaimer.
-    	* Redistributions in binary form must reproduce the above 
-		  copyright notice, this list of conditions and the following 
-		  disclaimer in the documentation and/or other materials provided 
-		  with the distribution.
-    	* Neither the name of Remy Muller or Julius Smith or of its 
-		  contributors may be used to endorse or promote products derived 
-		  from this software without specific prior written permission.
-
-	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-	FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-	COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
-	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
-	BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
-	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
-	OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    ----------------------------VST SDK----------------------------------
-	In order to compile a VST (TM) plugin with this architecture file 
-	you will need the proprietary VST SDK from Steinberg. Please check 
-	the corresponding license.
-
- ************************************************************************
- ************************************************************************/
-
-
-
-/********************************************************************
- * VST-2.4 wrapper for the FAUST language. 
- *
- * Usage: faust -a vst2p4.cpp myfaustprog.dsp
- *
- * By Julius Smith (http://ccrma.stanford.edu/~jos/), based on 
- * vst.cpp by remy muller remy.muller at ircam.fr 
- * http://www.smartelectronix.com/~mdsp/.
- * Essentially, vst.cpp was edited to look more like the "again" 
- * programming sample that comes with the VST-2.4 SDK from Steinberg.
- *
- * NOTES:
- *  Relies on automatically generated slider GUI for VST plugins.
- *   - Horizontal and vertical sliders mapped to "vstSlider"
- *   - Numeric Entries similarly converted to "vstSlider"
- *   - No support for bar graphs or additional numeric and text displays
- *   - Tested on the Muse Receptor Pro 1.0, System Version 1.6.20070717,
- *     using Visual C++ 2008 Express Edition 
- *     (part of the Microsoft Visual Studio 2008, Beta 2)
- *   - Reference: 
- * http://ccrma.stanford.edu/realsimple/faust/Generating_VST_Plugin_Faust.html
- *
- * FAUST 
- * Copyright (C) 2003-2007 GRAME, Centre National de Creation Musicale
- * http://www.grame.fr/			     
- *
- ********************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <math.h>
-#include <errno.h>
-#include <time.h>
-//#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <string>
-#include <vector>
-#include <map>
-#include <cstring>
-#include <cmath>
-
-using namespace std ;
-
-// There is a bug with powf() when cross compiling with mingw
-// the following macro avoid the problem
-#ifdef WIN32
-#define powf(x,y) pow(x,y)
-#define expf(x) exp(x)
-#endif
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #define AVOIDDENORMALS 
-#endif
-
-struct Meta : std::map<std::string, std::string>
-{
-    void declare(const char* key, const char* value)
-    {
-        (*this)[key] = value;
-    }
-};
-	
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int	max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int	max (int a, int b)		{ return (a>b) ? a : b; }
-
-inline long	max (long a, long b)		{ return (a>b) ? a : b; }
-inline long	max (int a, long b)		{ return (a>b) ? a : b; }
-inline long	max (long a, int b)		{ return (a>b) ? a : b; }
-
-inline float	max (float a, float b)		{ return (a>b) ? a : b; }
-inline float	max (int a, float b)		{ return (a>b) ? a : b; }
-inline float	max (float a, int b)		{ return (a>b) ? a : b; }
-inline float	max (long a, float b)		{ return (a>b) ? a : b; }
-inline float	max (float a, long b)		{ return (a>b) ? a : b; }
-
-inline double	max (double a, double b)	{ return (a>b) ? a : b; }
-inline double	max (int a, double b)		{ return (a>b) ? a : b; }
-inline double	max (double a, int b)		{ return (a>b) ? a : b; }
-inline double	max (long a, double b)		{ return (a>b) ? a : b; }
-inline double	max (double a, long b)		{ return (a>b) ? a : b; }
-inline double	max (float a, double b)		{ return (a>b) ? a : b; }
-inline double	max (double a, float b)		{ return (a>b) ? a : b; }
-
-inline int	min (int a, int b)		{ return (a<b) ? a : b; }
-
-inline long	min (long a, long b)		{ return (a<b) ? a : b; }
-inline long	min (int a, long b)		{ return (a<b) ? a : b; }
-inline long	min (long a, int b)		{ return (a<b) ? a : b; }
-
-inline float	min (float a, float b)		{ return (a<b) ? a : b; }
-inline float	min (int a, float b)		{ return (a<b) ? a : b; }
-inline float	min (float a, int b)		{ return (a<b) ? a : b; }
-inline float	min (long a, float b)		{ return (a<b) ? a : b; }
-inline float	min (float a, long b)		{ return (a<b) ? a : b; }
-
-inline double	min (double a, double b)	{ return (a<b) ? a : b; }
-inline double	min (int a, double b)		{ return (a<b) ? a : b; }
-inline double	min (double a, int b)		{ return (a<b) ? a : b; }
-inline double	min (long a, double b)		{ return (a<b) ? a : b; }
-inline double	min (double a, long b)		{ return (a<b) ? a : b; }
-inline double	min (float a, double b)		{ return (a<b) ? a : b; }
-inline double	min (double a, float b)		{ return (a<b) ? a : b; }
-		
-// abs is now predefined
-//template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
-
-inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
-
-inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; }
-
-/******************************************************************************
-*******************************************************************************
-*
-*							       VECTOR INTRINSICS
-*
-*******************************************************************************
-*******************************************************************************/
-
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
-<<includeIntrinsic>>
-
-/******************************************************************************
-*******************************************************************************
-*
-*								USER INTERFACE
-*
-*******************************************************************************
-*******************************************************************************/
-
-class UI
-{
-  bool	fStopped;
-		
-public:
-			
-  UI() : fStopped(false) {}
-  virtual ~UI() {}
-		
-  virtual void addButton(const char* label, float* zone) = 0;
-  virtual void addToggleButton(const char* label, float* zone) = 0;
-  virtual void addCheckButton(const char* label, float* zone) = 0;
-  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	
-  virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-  virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
-  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-		
-  virtual void openFrameBox(const char* label) = 0;
-  virtual void openTabBox(const char* label) = 0;
-  virtual void openHorizontalBox(const char* label) = 0;
-  virtual void openVerticalBox(const char* label) = 0;
-  virtual void closeBox() = 0;
-		
-  virtual void run() {};
-		
-  void stop()		{ fStopped = true; }
-  bool stopped()	{ return fStopped; }
-
-  virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
-
-/******************************************************************************
-*******************************************************************************
-*
-*								FAUST DSP
-*
-*******************************************************************************
-*******************************************************************************/
-
-
-
-//----------------------------------------------------------------
-//  Base dsp class for this architecture
-//----------------------------------------------------------------
-			
-class dsp {
-
-protected:
-	 
-  int fSamplingFreq;
-		
-public:
-	 
-  dsp() {}
-  virtual ~dsp() {}
-  virtual int getNumInputs() = 0;
-  virtual int getNumOutputs() = 0;
-  virtual void buildUserInterface(UI* interface) = 0;
-  virtual void init(int samplingRate) = 0;
-  virtual void compute(int len, float** inputs, float** outputs) = 0;
-};
-		
-/********************END ARCHITECTURE SECTION (part 1/2)****************/
-
-/**************************BEGIN USER SECTION **************************/
-		
-<<includeclass>>
-
-/***************************END USER SECTION ***************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
-					
-
-/******************************************************************************
- *
- * VST wrapper
- * 
- ******************************************************************************/
-
-#include "audioeffectx.h" 
-
-class vstUI;
-
-class Faust : public AudioEffectX
-{
-
-private:
-  mydsp*    dsp;
-  vstUI*    dspUI;
-  char      programName[kVstMaxProgNameLen + 1];
-  Meta      meta;
-
-public:
-  Faust(audioMasterCallback audioMaster, mydsp* dspi, vstUI* dspUIi);
-  virtual ~Faust();
-
-  virtual void	processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames);
-
-  virtual void	setProgramName(char *name);
-  virtual void	getProgramName(char *name);
-
-  virtual void	setParameter(VstInt32 index, float value);
-  virtual float	getParameter(VstInt32 index);
-  virtual void	getParameterLabel(VstInt32 index, char *label);
-  virtual void	getParameterDisplay(VstInt32 index, char *text);
-  virtual void	getParameterName(VstInt32 index, char *text);
-
-  virtual void	setSampleRate(float sampleRate);
-
-  virtual bool	getEffectName (char* name);
-  virtual bool	getVendorString (char* text);
-  virtual bool	getProductString (char* text);
-  virtual VstInt32 getVendorVersion ();
-
-  virtual bool	getInputProperties (VstInt32 index, VstPinProperties* properties);
-  virtual bool	getOutputProperties (VstInt32 index, VstPinProperties* properties);
-};
-
-/*--------------------------------------------------------------------------*/
-class vstUIObject {
-protected:
-  string fLabel;
-  float* fZone;
-		
-  float range(float min, float max, float val) 
-  {	// VST parameters are normalized in the range [0;1]
-    val = min + val * (max - min);
-    return (val < min) ? min : (val > max) ? max : val;
-  }
-	 
-public:			
-  vstUIObject(const char* label, float* zone):fLabel(label),fZone(zone) {}
-  virtual ~vstUIObject() {}
-
-  virtual void  GetName(char *text){std::strcpy(text,fLabel.c_str());}
-  virtual void  SetValue(double f) {*fZone = range(0.0f,1.0f,(float)f);}
-  virtual float GetValue() {return *fZone;}
-  virtual void  GetDisplay(char *text){std::sprintf(text,"%f",*fZone);}
-  virtual long  GetID() 
-  {	/* returns the sum of all the ASCII characters  contained in the parameter's label */
-    unsigned int i;
-    long acc;
-    for(i=0,acc = 0;i<fLabel.length();i++) acc += (fLabel.c_str())[i];
-    return acc;
-  }
-};
-
-/*--------------------------------------------------------------------------*/
-class vstToggleButton : public vstUIObject {
-	
-public:	
-	
-  vstToggleButton(const char* label, float* zone):vstUIObject(label,zone) {}
-  virtual ~vstToggleButton() {}
-  virtual float GetValue() {return *fZone;}
-  virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}				
-  virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
-};
-
-/*--------------------------------------------------------------------------*/
-class vstCheckButton : public vstUIObject {
-	
-public:
-	
-  vstCheckButton(const char* label, float* zone):vstUIObject(label,zone) {}
-  virtual ~vstCheckButton() {}
-  virtual float GetValue() {return *fZone;}
-  virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}
-  virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}		
-};
-
-/*--------------------------------------------------------------------------*/
-class vstButton : public vstUIObject {
-	
-public:
-	
-  vstButton(const char* label, float* zone):vstUIObject(label,zone) {}
-  virtual ~vstButton() {}		
-  virtual float GetValue() {return *fZone;}
-  virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}		
-  virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
-};
-
-/*--------------------------------------------------------------------------*/
-class vstSlider : public vstUIObject{
-
-private:
-	
-  float fInit;
-  float fMin;
-  float fMax;
-  float fStep;
-	
-public:	
-	
-  vstSlider(const char* label, float* zone, float init, float min, float max, float step)
-    :vstUIObject(label,zone), fInit(init), fMin(min), fMax(max),fStep(step) {}
-  virtual ~vstSlider() {}	
-
-  virtual float GetValue() {return (*fZone-fMin)/(fMax-fMin);}	// normalize
-  virtual void SetValue(double f) {*fZone = range(fMin,fMax,(float)f);} // expand
-};
-
-/*--------------------------------------------------------------------------*/
-class vstUI : public UI
-{
-private:
-	
-  vector<vstUIObject*> fUITable;
-		
-public:
-			
-  vstUI(){}
-  virtual ~vstUI() 
-  {
-    for (vector<vstUIObject*>::iterator iter = fUITable.begin(); iter != fUITable.end(); iter++) delete *iter;
-  }
-		
-  void addButton(const char* label, float* zone) {fUITable.push_back(new vstButton(label, zone));}
-		
-  void addToggleButton(const char* label, float* zone) {fUITable.push_back(new vstToggleButton(label, zone));}
-		
-  void addCheckButton(const char* label, float* zone) {fUITable.push_back(new vstCheckButton(label, zone));}
-		
-  void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-  { 	
-    fUITable.push_back(new vstSlider(label, zone, init, min, max, step));
-  }
-		
-  void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-  {
-    fUITable.push_back(new vstSlider(label, zone, init, min, max, step));
-  }
-		
-  void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-  { /* Number entries converted to horizontal sliders */
-    fUITable.push_back(new vstSlider(label, zone, init, min, max, step));
-  }
-		
-  void openFrameBox(const char* label) {}
-  void openTabBox(const char* label) {}
-  void openHorizontalBox(const char* label) {}
-  void openVerticalBox(const char* label) {}
-  void closeBox() {}
-		
-  void  SetValue(VstInt32 index, double f) {assert(index<fUITable.size()); fUITable[index]->SetValue(f);}
-  float GetValue(VstInt32 index) {assert(index<fUITable.size()); return fUITable[index]->GetValue();}
-  void  GetDisplay(VstInt32 index, char *text) {assert(index<fUITable.size()); fUITable[index]->GetDisplay(text);}
-  void  GetName(VstInt32 index, char *text) {assert(index<fUITable.size()); fUITable[index]->GetName(text);}
-  long  GetNumParams() {return fUITable.size();}
-
-  long  makeID()
-    /* Creates a (unique?)id by summing all the parameter's labels, 
-     * then wrapping it in the range [0;maxNumberOfId] and adding 
-     * this number to the offset made by the Four Character ID: 'FAUS'
-     */
-  {   
-    const long maxNumberOfId = 128;
-    long baseid = 'FAUS';
-    long id=0;
-    for(int i=0;i<fUITable.size();i++) id += fUITable[i]->GetID();
-    return baseid + id % maxNumberOfId;
-  }
-		
-  // To be implemented
-  void addNumDisplay(const char* label, float* zone, int precision){}
-  void addTextDisplay(const char* label, float* zone, char* names[], float min, float max){}
-  void addHorizontalBargraph(const char* label, float* zone, float min, float max){}
-  void addVerticalBargraph(const char* label, float* zone, float min, float max){}
-};
-
-//-----------------------------------------------------------------------------
-#define NUM_PROGRAMS 0
-
-AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
-{
-// The dsp and its UI need to be allocated now because
-// AudioEffectX wants the no. parameters available as an instance argument:
-  mydsp* dspi = new mydsp();
-  vstUI* dspUIi = new vstUI(); 
-  dspi->buildUserInterface(dspUIi);
-  return new Faust(audioMaster,dspi,dspUIi);
-}
-
-Faust::Faust(audioMasterCallback audioMaster, mydsp* dspi, vstUI* dspUIi)
-  : AudioEffectX(audioMaster, NUM_PROGRAMS, dspUIi->GetNumParams())
-{
-  // Copy the pointers to dsp and dspUI instances and take them over 
-  // (we'll also deallocate):
-  dsp = dspi;
-  dspUI = dspUIi;
-  dsp->init(long(getSampleRate()));
-  meta["name"] = "FaustFx";
-  mydsp::metadata(&meta);
-  setNumInputs(dsp->getNumInputs());		
-  setNumOutputs(dsp->getNumOutputs());		
-  setUniqueID(dspUI->makeID());					
-  canProcessReplacing();
-
-  vst_strncpy(programName, "Default", kVstMaxProgNameLen); // default program name
-}
-
-//----------------------------------------------------------------------------
-Faust::~Faust()
-{
-  if (dsp) delete dsp;
-  if (dspUI) delete dspUI;
-}
-
-//-------------------------------------------------------------------------------------------------------
-void Faust::setProgramName (char* name)
-{
-  // this template does not use programs yet - just say "Default":
-  vst_strncpy (programName, name, kVstMaxProgNameLen);
-}
-
-//-----------------------------------------------------------------------------
-void Faust::getProgramName(char *name)
-{
-  vst_strncpy (name, programName, kVstMaxProgNameLen);
-}
-
-//-----------------------------------------------------------------------------
-void Faust::setParameter(VstInt32 index, float value)
-{
-  if(index<numParams)
-    dspUI->SetValue(index,value);
-}
-
-//-----------------------------------------------------------------------------
-float Faust::getParameter(VstInt32 index)
-{
-  if(index<numParams)
-    return dspUI->GetValue(index);
-  else
-    return 0.0f;
-}
-//-----------------------------------------------------------------------------
-void Faust::getParameterName(VstInt32 index, char *label)
-{
-  if(index<numParams)
-    dspUI->GetName(index,label); // parameter name, including units
-  else
-    vst_strncpy (label, "IndexOutOfRange", kVstMaxParamStrLen);
-}
-//-----------------------------------------------------------------------------
-void Faust::getParameterDisplay(VstInt32 index, char *text)
-{
-  if(index<numParams)
-    dspUI->GetDisplay(index,text); // displayed float value as text
-  else
-    vst_strncpy (text, "IndexOutOfRange", kVstMaxParamStrLen);
-}
-//-----------------------------------------------------------------------------
-void Faust::getParameterLabel(VstInt32 index, char *label)
-{
-  vst_strncpy (label, "", kVstMaxParamStrLen); // parameter units in Name
-}
-
-//-----------------------------------------------------------------------------
-void Faust::setSampleRate(float sampleRate)
-{
-  // allways call this
-  AudioEffect::setSampleRate(sampleRate);
-  dsp->init(long(getSampleRate()));
-}
-
-//-----------------------------------------------------------------------------------------
-bool Faust::getEffectName (char* text)
-{
-  vst_strncpy (text, meta["name"].c_str(), kVstMaxProductStrLen);
-  return true;
-}
-
-//-----------------------------------------------------------------------------------------
-bool Faust::getVendorString (char* text)
-{
-  if (meta.count("author") > 0) {
-    vst_strncpy (text, meta["author"].c_str(), kVstMaxVendorStrLen);
-    return true;
-  } else {
-    return false;
-  }
-}
-
-//-----------------------------------------------------------------------------------------
-bool Faust::getProductString (char* text)
-{
-  vst_strncpy (text, meta["name"].c_str(), kVstMaxProductStrLen);
-  return true;
-}
-
-//-----------------------------------------------------------------------------------------
-VstInt32 Faust::getVendorVersion ()
-{ 
-	return 1000; 
-}
-
-//-----------------------------------------------------------------------------
-void Faust::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
-{
-    AVOIDDENORMALS;
-    dsp->compute(sampleFrames, inputs, outputs);
-}
-
-//-----------------------------------------------------------------------------------------
-bool Faust::getInputProperties (VstInt32 index, VstPinProperties* properties)
-{
-  if(index>=0 && index<dsp->getNumInputs())
-  {
-    sprintf (properties->label, "Grame Faust DSP input: %d",index);
-    sprintf (properties->shortLabel, "In %d",index);
-    properties->flags = kVstPinIsActive;
-    if (dsp->getNumInputs() == 2) {
-      properties->flags |= kVstPinIsStereo;
-    }
-    return true;
-  }
-  else
-    return false;
-}
-
-//-----------------------------------------------------------------------------------------
-bool Faust::getOutputProperties (VstInt32 index, VstPinProperties* properties)
-{
-  if(index>=0 && index<dsp->getNumOutputs())
-  {
-    sprintf (properties->label, "Grame Faust DSP output: %d",index);
-    sprintf (properties->shortLabel, "Out %d",index);
-    properties->flags = kVstPinIsActive;
-    if (dsp->getNumOutputs() == 2) {
-      properties->flags |= kVstPinIsStereo;
-    }
-    return true;
-  }
-  else
-    return false;
-}
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
-
diff --git a/architecture/vsti-mono.cpp b/architecture/vsti-mono.cpp
deleted file mode 100644
index 51fc0f9..0000000
--- a/architecture/vsti-mono.cpp
+++ /dev/null
@@ -1,1072 +0,0 @@
-/************************************************************************
-
-	IMPORTANT NOTE : this file contains two clearly delimited sections : 
-	the ARCHITECTURE section (in two parts) and the USER section. Each section 
-	is governed by its own copyright and license. Please check individually 
-	each section for license and copyright information.
-*************************************************************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
-
-/************************************************************************
- ************************************************************************
-    FAUST Architecture File
-	Copyright (C) 2007-2011 Julius Smith
-	All rights reserved.
-    ----------------------------BSD License------------------------------
-	Redistribution and use in source and binary forms, with or without 
-	modification, are permitted provided that the following conditions 
-	are met:
-
-    	* Redistributions of source code must retain the above copyright 
-		  notice, this list of conditions and the following disclaimer.
-    	* Redistributions in binary form must reproduce the above 
-		  copyright notice, this list of conditions and the following 
-		  disclaimer in the documentation and/or other materials provided 
-		  with the distribution.
-    	* Neither the name of Julius Smith nor the names of its 
-		  contributors may be used to endorse or promote products derived 
-		  from this software without specific prior written permission.
-
-	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-	FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-	COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
-	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
-	BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
-	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
-	OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    ----------------------------VST SDK----------------------------------
-	In order to compile a VST (TM) plugin with this architecture file 
-	you will need the proprietary VST SDK from Steinberg. Please check 
-	the corresponding license.
-
- ************************************************************************
- ************************************************************************/
-
-/********************************************************************
- * vsti-mono.cpp - Monaural VSTi-2.4 wrapper for the FAUST language. 
- *
- * Usage: faust -a vsti-mono.cpp myfaustprog.dsp
- *
- * By Julius Smith (http://ccrma.stanford.edu/~jos/), based on vst.cpp
- * by remy muller <remy.muller at ircam.fr>
- * (http://www.smartelectronix.com/~mdsp/).  Essentially, vst.cpp was
- * first edited to look more like the "again" programming sample that
- * comes with the VST-2.4 SDK from Steinberg. Next, features from the
- * "vstxsynth" program sample were added to give simple MIDI synth
- * support analogous to that of faust2pd, except that only one voice
- * is supported.  (If the Faust patch has any input signals, this
- * architecture file should reduce to vst2p4.cpp --- i.e., basic VST
- * plugin support.)  As with faust2pd, to obtain MIDI control via
- * NoteOn/Off, Velocity, and KeyNumber, there must be a button named
- * "gate" and sliders (or numeric entries) named "gain" and "freq" in
- * the Faust patch specified in myfaustprog.dsp.
- *
- * NOTES:
- *  Relies on automatically generated slider GUI for VST plugins.
- *   - Horizontal and vertical sliders mapped to "vstSlider"
- *   - Numeric Entries similarly converted to "vstSlider"
- *   - No support for bar graphs or additional numeric and text displays
- *   - Tested on the Muse Receptor Pro 1.0, System Version 1.6.20070717,
- *     using Visual C++ 2008 Express Edition 
- *     (part of the Microsoft Visual Studio 2008, Beta 2)
- *   - Reference: 
- * http://ccrma.stanford.edu/realsimple/faust/Generating_VST_Plugin_Faust.html
- *
- * FAUST 
- * Copyright (C) 2003-2007 GRAME, Centre National de Creation Musicale
- * http://www.grame.fr/			     
- *
- ********************************************************************/
-
-// Suggestion: Faust could replace all leading comments in this file
-// by the following shorter comment:
-
-/********************************************************************
- * C++ source generated by the following command line:
- *
- *   faust -a vsti.cpp name.dsp -o name-vsti.cpp
- *
- ********************************************************************/
-
-// (where the filenames could be really right, and the path to vsti.cpp
-// could be included as well.)
-
-#include <stdlib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <math.h>
-#include <errno.h>
-#include <time.h>
-//#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <string>
-#include <vector>
-#include <math.h>
-
-using namespace std ;
-
-// There is a bug with powf() when cross compiling with mingw
-// the following macro avoid the problem
-#ifdef WIN32
-#define powf(x,y) pow(x,y)
-#define expf(x) exp(x)
-#endif
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #define AVOIDDENORMALS 
-#endif
-
-struct Meta
-{
-    void declare (const char* key, const char* value) {  }
-};
-	
-	
-#ifdef __GNUC__
-
-//-------------------------------------------------------------------
-// Generic min and max using gcc extensions
-//-------------------------------------------------------------------
-
-#define max(x,y) ((x)>?(y))
-#define min(x,y) ((x)<?(y))
-
-//abs(x) should be already predefined
-
-#else
-
-//-------------------------------------------------------------------
-// Generic min and max using c++ inline
-//-------------------------------------------------------------------
-
-inline int	max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
-inline int	max (int a, int b)		{ return (a>b) ? a : b; }
-
-inline long	max (long a, long b)		{ return (a>b) ? a : b; }
-inline long	max (int a, long b)		{ return (a>b) ? a : b; }
-inline long	max (long a, int b)		{ return (a>b) ? a : b; }
-
-inline float	max (float a, float b)		{ return (a>b) ? a : b; }
-inline float	max (int a, float b)		{ return (a>b) ? a : b; }
-inline float	max (float a, int b)		{ return (a>b) ? a : b; }
-inline float	max (long a, float b)		{ return (a>b) ? a : b; }
-inline float	max (float a, long b)		{ return (a>b) ? a : b; }
-
-inline double	max (double a, double b)	{ return (a>b) ? a : b; }
-inline double	max (int a, double b)		{ return (a>b) ? a : b; }
-inline double	max (double a, int b)		{ return (a>b) ? a : b; }
-inline double	max (long a, double b)		{ return (a>b) ? a : b; }
-inline double	max (double a, long b)		{ return (a>b) ? a : b; }
-inline double	max (float a, double b)		{ return (a>b) ? a : b; }
-inline double	max (double a, float b)		{ return (a>b) ? a : b; }
-
-inline int	min (int a, int b)		{ return (a<b) ? a : b; }
-
-inline long	min (long a, long b)		{ return (a<b) ? a : b; }
-inline long	min (int a, long b)		{ return (a<b) ? a : b; }
-inline long	min (long a, int b)		{ return (a<b) ? a : b; }
-
-inline float	min (float a, float b)		{ return (a<b) ? a : b; }
-inline float	min (int a, float b)		{ return (a<b) ? a : b; }
-inline float	min (float a, int b)		{ return (a<b) ? a : b; }
-inline float	min (long a, float b)		{ return (a<b) ? a : b; }
-inline float	min (float a, long b)		{ return (a<b) ? a : b; }
-
-inline double	min (double a, double b)	{ return (a<b) ? a : b; }
-inline double	min (int a, double b)		{ return (a<b) ? a : b; }
-inline double	min (double a, int b)		{ return (a<b) ? a : b; }
-inline double	min (long a, double b)		{ return (a<b) ? a : b; }
-inline double	min (double a, long b)		{ return (a<b) ? a : b; }
-inline double	min (float a, double b)		{ return (a<b) ? a : b; }
-inline double	min (double a, float b)		{ return (a<b) ? a : b; }
-		
-#endif
-
-// abs is now predefined
-//template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
-
-inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
-
-inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; }
-
-/******************************************************************************
-*******************************************************************************
-*
-*							       VECTOR INTRINSICS
-*
-*******************************************************************************
-*******************************************************************************/
-
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
-<<includeIntrinsic>>
-
-/******************************************************************************
-*******************************************************************************
-*
-*								USER INTERFACE
-*
-*******************************************************************************
-*******************************************************************************/
-
-class UI
-{
-  bool	fStopped;
-
-public:
-			
-  UI() : fStopped(false) {}
-  virtual ~UI() {}
-		
-  virtual void addButton(char* label, float* zone) = 0;
-  virtual void addToggleButton(char* label, float* zone) = 0;
-  virtual void addCheckButton(char* label, float* zone) = 0;
-  virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
-  virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
-  virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
-	
-  virtual void addNumDisplay(char* label, float* zone, int precision) = 0;
-  virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max) = 0;
-  virtual void addHorizontalBargraph(char* label, float* zone, float min, float max) = 0;
-  virtual void addVerticalBargraph(char* label, float* zone, float min, float max) = 0;
-		
-  virtual void openFrameBox(char* label) = 0;
-  virtual void openTabBox(char* label) = 0;
-  virtual void openHorizontalBox(char* label) = 0;
-  virtual void openVerticalBox(char* label) = 0;
-  virtual void closeBox() = 0;
-		
-  virtual void run() {};
-		
-  void stop()		{ fStopped = true; }
-  bool stopped()	{ return fStopped; }
-
-  virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
-
-/******************************************************************************
-*******************************************************************************
-*
-*								FAUST DSP
-*
-*******************************************************************************
-*******************************************************************************/
-
-
-
-//----------------------------------------------------------------
-//  Base dsp class for this architecture
-//----------------------------------------------------------------
-			
-class dsp {
-
-protected:
-	 
-  int fSamplingFreq;
-		
-public:
-	 
-  dsp() {}
-  virtual ~dsp() {}
-  virtual int getNumInputs() = 0;
-  virtual int getNumOutputs() = 0;
-  virtual void buildUserInterface(UI* interface) = 0;
-  virtual void init(int samplingRate) = 0;
-  virtual void compute(int len, float** inputs, float** outputs) = 0;
-};
-		
-/********************END ARCHITECTURE SECTION (part 1/2)****************/
-
-/**************************BEGIN USER SECTION **************************/
-		
-<<includeclass>>
-
-/***************************END USER SECTION ***************************/
-
-/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
-					
-/******************************************************************************
- *
- * VST wrapper
- * 
- ******************************************************************************/
-
-#include "audioeffectx.h" 
-
-class vstUI;
-
-//------------------------------------------------------------------------------
-// Faust class prototype
-//------------------------------------------------------------------------------
-class Faust : public AudioEffectX
-{
-public:
-  Faust(audioMasterCallback audioMaster, mydsp* dspi, vstUI* dspUIi);
-  virtual ~Faust();
-
-  virtual void processReplacing (float **inputs, float **outputs, VstInt32 sampleFrames);
-  virtual VstInt32 processEvents (VstEvents* events);
-
-  virtual void setProgram (VstInt32 program);
-  virtual void setProgramName (char *name);
-  virtual void getProgramName (char *name);
-  virtual bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char *text);
-
-  virtual void setParameter (VstInt32 index, float value);
-  virtual float getParameter (VstInt32 index);
-  virtual void getParameterLabel (VstInt32 index, char *label);
-  virtual void getParameterDisplay (VstInt32 index, char *text);
-  virtual void getParameterName (VstInt32 index, char *text);
-
-  virtual void setSampleRate (float sampleRate);
-
-  virtual bool getInputProperties (VstInt32 index, VstPinProperties *properties);
-  virtual bool getOutputProperties (VstInt32 index, VstPinProperties *properties);
-
-  virtual bool getEffectName (char *name);
-  virtual bool getVendorString (char *text);
-  virtual bool getProductString (char *text);
-  virtual VstInt32 getVendorVersion ();
-  virtual VstInt32 canDo (char *text);
-
-  virtual VstInt32 getNumMidiInputChannels ();
-  virtual VstInt32 getNumMidiOutputChannels ();
-
-  virtual VstInt32 getMidiProgramName (VstInt32 channel, MidiProgramName *midiProgramName);
-  virtual VstInt32 getCurrentMidiProgram (VstInt32 channel, MidiProgramName *currentProgram);
-  virtual VstInt32 getMidiProgramCategory (VstInt32 channel, MidiProgramCategory *category);
-
-private:
-  mydsp*	dsp;
-  vstUI*	dspUI;
-
-  // For synths:
-  bool noteIsOn;
-  VstInt32 currentNote;
-  VstInt32 currentVelocity;
-  VstInt32 currentDelta;
-
-  void initProcess ();
-  void noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta);
-  void noteOff ();
-  void fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn);
-
-  char programName[kVstMaxProgNameLen + 1];
-};
-
-/*--------------------------------------------------------------------------*/
-class vstUIObject { /* superclass of all VST UI widgets */
-protected:
-  string fLabel;
-  float* fZone;
-		
-  inline float clip(float min, float max, float val) 
-  {
-    return (val < min) ? min : (val > max) ? max : val;
-  }
-	 
-  inline float normalize(float min, float max, float val) 
-  { // VST parameters are normalized to the range [0;1] on the host
-    val = min + val * (max - min);
-    return (val < min) ? min : (val > max) ? max : val;
-  }
-	 
-public:			
-  vstUIObject(char* label, float* zone):fLabel(label),fZone(zone) {}
-  virtual ~vstUIObject() {}
-
-  virtual void  GetName(char *text){std::strcpy(text,fLabel.c_str());}
-  virtual void  SetValue(double f) {*fZone = normalize(0.0f,1.0f,(float)f);}
-  virtual void  SetValueNoNormalization(double f) {*fZone = clip(0.0f,1.0f,(float)f);}
-  virtual float GetValue() {return *fZone;}
-  virtual void  GetDisplay(char *text){std::sprintf(text,"%f",*fZone);}
-  virtual long  GetID() 
-  {	/* returns the sum of all the ASCII characters  contained in the parameter's label */
-    unsigned int i;
-    long acc;
-    for(i=0,acc = 0;i<fLabel.length();i++) acc += (fLabel.c_str())[i];
-    return acc;
-  }
-};
-
-/*--------------------------------------------------------------------------*/
-class vstToggleButton : public vstUIObject {
-	
-public:	
-	
-  vstToggleButton(char* label, float* zone):vstUIObject(label,zone) {}
-  virtual ~vstToggleButton() {}
-  virtual float GetValue() {return *fZone;}
-  virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}
-  virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
-};
-
-/*--------------------------------------------------------------------------*/
-class vstCheckButton : public vstUIObject {
-	
-public:
-	
-  vstCheckButton(char* label, float* zone):vstUIObject(label,zone) {}	
-  virtual ~vstCheckButton() {}
-  virtual float GetValue() {return *fZone;}
-  virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}
-  virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}		
-};
-
-/*--------------------------------------------------------------------------*/
-class vstButton : public vstUIObject {
-	
-public:
-	
-  vstButton(char* label, float* zone):vstUIObject(label,zone) {}
-  virtual ~vstButton() {}		
-  virtual float GetValue() {return *fZone;}
-  virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;}		
-  virtual void  GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");}
-};
-
-/*--------------------------------------------------------------------------*/
-class vstSlider : public vstUIObject{
-
-private:
-	
-  float fInit;
-  float fMin;
-  float fMax;
-  float fStep;
-	
-public:	
-	
-  vstSlider(char* label, float* zone, float init, float min, float max, float step)
-    :vstUIObject(label,zone), fInit(init), fMin(min), fMax(max),fStep(step) {}
-  virtual ~vstSlider() {}	
-
-  // The VST host calls GetValue() and expects a result in [0,1].
-  // The VST host calls SetValue(f) with f in [0,1]. We convert to real units.
-  // When we process MIDI controls, we call SetValueNoNormalization(f) with f in real units.
-  virtual float GetValue() {return (*fZone-fMin)/(fMax-fMin);}	// normalize
-  virtual void SetValue(double f) {*fZone = normalize(fMin,fMax,(float)f);} // denormalize
-  virtual void SetValueNoNormalization(double f) {*fZone = clip(fMin,fMax,(float)f);} // raw
-};
-
-/*--------------------------------------------------------------------------*/
-class vstUI : public UI
-{
-private:
-	
-  vector<vstUIObject*> fUITable;
-
-public:
-			
-  int freqIndex;
-  int gainIndex;
-  int gateIndex;
-
-  vstUI(){   
-    freqIndex = gainIndex = gateIndex = -1;
-  }
-  virtual ~vstUI() 
-  {
-    for (vector<vstUIObject*>::iterator iter = fUITable.begin(); iter != fUITable.end(); iter++) delete *iter;
-  }
-
-  void setAny(int anyIndex, float val, char *str) {
-    if (anyIndex<0) {
-#ifdef DEBUG
-      // On the Receptor, and perhaps other hosts, output to stderr is logged in a file.
-      fprintf(stderr,"*** Faust vsti: %sIndex = %d never set!\n",str,anyIndex);
-#endif
-      return;
-    }
-    if (anyIndex >= fUITable.size()) {
-#ifdef DEBUG
-        fprintf(stderr,"*** Faust vsti: %sIndex = %d too large!\n",str,anyIndex);
-#endif
-	return;
-    }
-#ifdef DEBUG
-    fprintf(stderr,"*** Faust vsti: Setting %sIndex = %d to %f\n",str,anyIndex,val);
-#endif
-    fUITable[anyIndex]->SetValueNoNormalization(val);
-  }
-		
-  void setFreq(float val) {
-    setAny(freqIndex, val, "freq");
-  }
-		
-  void setGate(float val) {
-    setAny(gateIndex, val, "gate");
-  }
-		
-  void setGain(float val) {
-    setAny(gainIndex, val, "gain");
-  }
-
-  bool ckAnyMatch(char* label, char* indexName, int *index) {
-    if (_stricmp(label,indexName)==0) { 
-#ifdef DEBUG
-      fprintf(stderr,"=== Faust vsti: label '%s' matches '%s'\n",label,indexName);
-#endif
-      *index = fUITable.size() - 1; 
-      return true;
-    }
-    return false;
-  }
-
-  void ckAllMatches(char* label) {
-    ckAnyMatch(label,"gain",&gainIndex);
-    ckAnyMatch(label,"gate",&gateIndex);
-    ckAnyMatch(label,"freq",&freqIndex);
-  }
-
-  void addButton(char* label, float* zone) {
-    vstButton* theButton = new vstButton(label, zone);
-    fUITable.push_back(theButton);
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: Adding Button with label '%s'\n",label);
-#endif
-    ckAnyMatch(label,"gate",&gateIndex);
-  }
-		
-  void addToggleButton(char* label, float* zone) {fUITable.push_back(new vstToggleButton(label, zone));}
-		
-  void addCheckButton(char* label, float* zone) {fUITable.push_back(new vstCheckButton(label, zone));}
-		
-  void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) 
-  { 	
-    vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step);
-    fUITable.push_back(theSlider);
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: Adding VSlider (HSlider) with label '%s'\n",label);
-#endif
-    ckAllMatches(label);
-  }
-		
-  void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) 
-  {
-    vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step);
-    fUITable.push_back(theSlider);
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: Adding HSlider with label '%s'\n",label);
-#endif
-    ckAllMatches(label);
-  }
-		
-  void addNumEntry(char* label, float* zone, float init, float min, float max, float step)
-  { /* Number entries converted to horizontal sliders */
-    vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step);
-    fUITable.push_back(theSlider);
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: Adding NumEntry (HSlider) with label '%s'\n",label);
-#endif
-    ckAllMatches(label);
-  }
-		
-  void openFrameBox(char* label) {}
-  void openTabBox(char* label) {}
-  void openHorizontalBox(char* label) {}
-  void openVerticalBox(char* label) {}
-  void closeBox() {}
-		
-  void  SetValue(VstInt32 index, double f) {assert(index<fUITable.size()); fUITable[index]->SetValue(f);}
-  float GetValue(VstInt32 index) {assert(index<fUITable.size()); return fUITable[index]->GetValue();}
-  void  GetDisplay(VstInt32 index, char *text) {assert(index<fUITable.size()); fUITable[index]->GetDisplay(text);}
-  void  GetName(VstInt32 index, char *text) {assert(index<fUITable.size()); fUITable[index]->GetName(text);}
-  long  GetNumParams() {return fUITable.size();}
-
-  long  makeID()
-    /* Creates a (unique?)id by summing all the parameter's labels, 
-     * then wrapping it in the range [0;maxNumberOfId] and adding 
-     * this number to the offset made by the Four Character ID: 'FAUS'
-     */
-  {   
-    const long maxNumberOfId = 128;
-    long baseid = 'FAUS';
-    long id=0;
-    for(int i=0;i<fUITable.size();i++) id += fUITable[i]->GetID();
-    return baseid + id % maxNumberOfId;
-  }
-		
-  // To be implemented
-  void addNumDisplay(char* label, float* zone, int precision){}
-  void addTextDisplay(char* label, float* zone, char* names[], float min, float max){}
-  void addHorizontalBargraph(char* label, float* zone, float min, float max){}
-  void addVerticalBargraph(char* label, float* zone, float min, float max){}
-};
-
-//-----------------------------------------------------------------------------
-// Class Implementations 
-//-----------------------------------------------------------------------------
-
-#define kNumPrograms 1
-
-AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
-{
-  // The dsp and its UI need to be allocated now because
-  // AudioEffectX wants the no. parameters available as an instance argument:
-  mydsp* dspi = new mydsp();
-  vstUI* dspUIi = new vstUI(); 
-  dspi->buildUserInterface(dspUIi);
-#ifdef DEBUG
-  fprintf(stderr,"=== Faust vsti: created\n"); // look for this in the system log
-#endif
-  return new Faust(audioMaster,dspi,dspUIi);
-}
-
-//-----------------------------------------------------------------------------
-// Faust
-//-----------------------------------------------------------------------------
-Faust::Faust(audioMasterCallback audioMaster, mydsp* dspi, vstUI* dspUIi)
-  :AudioEffectX(audioMaster, kNumPrograms,dspUIi->GetNumParams())
-{
-  // Copy the pointers to dsp and dspUI instances and take them over 
-  // (we'll also deallocate):
-  dsp = dspi;
-  dspUI = dspUIi;
-
-#ifdef DEBUG
-  fprintf(stderr,"=== Faust vsti: classInit:\n");
-#endif
-
-  dsp->classInit((int)getSampleRate()); // Ask AudioEffect for sample-rate
-
-  setProgram(0);
-  setProgramName("Default");
-
-  if (audioMaster) {
-    setNumInputs(dsp->getNumInputs());
-    setNumOutputs(dsp->getNumOutputs());		
-    canProcessReplacing();
-    if (dsp->getNumInputs() == 0) {
-      isSynth(); // at least let's hope so!
-      if (dsp->getNumOutputs() < 1) {
-	fprintf(stderr,"*** faust: vsti: No signal inputs or outputs, and Faust has no MIDI outputs!\n");
-      }
-    }
-    setUniqueID(dspUI->makeID());					
-  }
-  initProcess();
-  if (dsp->getNumInputs() == 0) {
-    suspend(); //  Synths start out quiet
-  }
-}
-
-//----------------------------------------------------------------------------
-Faust::~Faust()
-{
-  if (dsp) delete dsp;
-  if (dspUI) delete dspUI;
-}
-
-//-----------------------------------------------------------------------------
-void Faust::setProgram (VstInt32 program)
-// Override this method of AudioEffect in order to set 
-// local instance variables corresponding to the current MIDI program.
-// Here there is only one program.
-{
-  if (program < 0 || program >= kNumPrograms) {
-    fprintf(stderr,"*** Faust vsti: setting program to %d is OUT OF RANGE\n",program);
-    return;
-  }  
-#ifdef DEBUG
-  fprintf(stderr,"=== Faust vsti: setting program to %d\n",program);
-#endif
-  curProgram = program; // curProgram defined in audioeffect.h
-}
-
-//------------------------------------------------------------------------------
-void Faust::setProgramName (char* name)
-{
-  vst_strncpy (programName, name, kVstMaxProgNameLen);
-}
-
-//-----------------------------------------------------------------------------
-void Faust::getProgramName(char *name)
-{
-  vst_strncpy (name, programName, kVstMaxProgNameLen);
-}
-
-//-----------------------------------------------------------------------------
-void Faust::getParameterLabel(VstInt32 index, char *label)
-{
-  // We are not using parameter "units" display:
-  vst_strncpy (label, "", kVstMaxParamStrLen); // parameter units in Name
-}
-
-//-----------------------------------------------------------------------------
-void Faust::getParameterDisplay(VstInt32 index, char *text)
-{
-  if(index<numParams)
-    dspUI->GetDisplay(index,text); // get displayed float value as text
-  else
-    vst_strncpy (text, "IndexOutOfRange", kVstMaxParamStrLen);
-}
-
-//-----------------------------------------------------------------------------
-void Faust::getParameterName(VstInt32 index, char *label)
-{
-  if(index<numParams)
-    dspUI->GetName(index,label); // parameter name, including units
-  else
-    vst_strncpy (label, "IndexOutOfRange", kVstMaxParamStrLen);
-}
-
-//-----------------------------------------------------------------------------
-void Faust::setParameter(VstInt32 index, float value)
-{
-  if(index<numParams)
-    dspUI->SetValue(index,value);
-}
-
-//-----------------------------------------------------------------------------
-float Faust::getParameter(VstInt32 index)
-{
-  if(index<numParams)
-    return dspUI->GetValue(index);
-  else
-    return 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-bool Faust::getInputProperties (VstInt32 index, VstPinProperties* properties)
-{
-  if(index>=0 && index<dsp->getNumInputs())
-  {
-    sprintf (properties->label, "Grame Faust DSP input: %d",index);
-    sprintf (properties->shortLabel, "In %d",index);
-    properties->flags = kVstPinIsActive;
-    if (dsp->getNumInputs() == 2) {
-      properties->flags |= kVstPinIsStereo;
-    }
-    return true;
-  }
-  else
-    return false;
-}
-
-//-----------------------------------------------------------------------------
-bool Faust::getOutputProperties (VstInt32 index, VstPinProperties* properties)
-{
-  if(index>=0 && index<dsp->getNumOutputs())
-  {
-    sprintf (properties->label, "Grame Faust DSP output: %d",index);
-    sprintf (properties->shortLabel, "Out %d",index);
-    properties->flags = kVstPinIsActive;
-    if (dsp->getNumOutputs() == 2) {
-      properties->flags |= kVstPinIsStereo;
-    }
-    return true;
-  }
-  else
-    return false;
-}
-
-//-----------------------------------------------------------------------------
-bool Faust::getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text)
-{
-  if (index < kNumPrograms) {
-      vst_strncpy (text, programName, kVstMaxProgNameLen);
-      return true;
-  }
-  return false;
-}
-
-//-----------------------------------------------------------------------------
-bool Faust::getEffectName (char* name)
-{
-  // Get from Faust-supplied metadata?
-  vst_strncpy (name, "Effect Name goes here", kVstMaxEffectNameLen);
-  return true;
-}
-
-//-----------------------------------------------------------------------------
-bool Faust::getVendorString (char* text)
-{
-  vst_strncpy (text, "Vendor String goes here", kVstMaxVendorStrLen);
-  return true;
-}
-
-//-----------------------------------------------------------------------------
-bool Faust::getProductString (char* text)
-{
-  vst_strncpy (text, "Product String goes here", kVstMaxProductStrLen);
-  return true;
-}
-
-//-----------------------------------------------------------------------------
-VstInt32 Faust::getVendorVersion ()
-{ 
-  return 1000; 
-}
-
-//-----------------------------------------------------------------------------
-VstInt32 Faust::canDo (char* text)
-{
-  if (!strcmp (text, "receiveVstEvents"))
-    return 1;
-  if (!strcmp (text, "receiveVstMidiEvent"))
-    return 1;
-  if (!strcmp (text, "midiProgramNames"))
-    return 1;
-  return -1;	// explicitly can't do; 0 => don't know
-}
-
-//-----------------------------------------------------------------------------
-VstInt32 Faust::getNumMidiInputChannels ()
-{
-  return 1; // one MIDI-in channel
-}
-
-//-----------------------------------------------------------------------------
-VstInt32 Faust::getNumMidiOutputChannels ()
-{
-  return 0; // no MIDI-outs
-}
-
-//-----------------------------------------------------------------------------
-VstInt32 Faust::getMidiProgramName (VstInt32 channel, MidiProgramName* mpn)
-{
-  VstInt32 prg = mpn->thisProgramIndex;
-  if (prg < 0 || prg > 0) return 0;
-  fillProgram (channel, prg, mpn);
-  return 1; // we have only 1 "MIDI program"
-}
-
-//------------------------------------------------------------------------
-VstInt32 Faust::getCurrentMidiProgram (VstInt32 channel, MidiProgramName* mpn)
-{
-  // There is only one MIDI program here, so return it regardless of MIDI channel:
-  if (channel < 0 || channel >= 16 || !mpn) return -1;
-  VstInt32 prg = 0;
-  mpn->thisProgramIndex = prg;
-  fillProgram (channel, prg, mpn);
-  return prg;
-}
-
-//------------------------------------------------------------------------
-void Faust::fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn)
-// Fill mpn struct for given channel.  Here there should be only one.
-{
-  mpn->midiBankMsb = mpn->midiBankLsb = -1;
-  mpn->reserved = 0;
-  mpn->flags = 0;
-  vst_strncpy (mpn->name, programName, kVstMaxProgNameLen);
-  mpn->midiProgram = (char)prg; // prg should only be 0
-  mpn->parentCategoryIndex = -1;
-}
-
-//------------------------------------------------------------------------
-VstInt32 Faust::getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* cat)
-// VST host wants to fill cat struct for given channel.  We have only one category.
-{
-  cat->parentCategoryIndex = -1;	// -1:no parent category
-  cat->flags = 0;			// reserved, none defined yet, zero.
-  VstInt32 category = cat->thisCategoryIndex;
-  vst_strncpy (cat->name, "Faust Patch", kVstMaxProgNameLen);
-  return 1; // one category
-}
-
-//***********************************************************************
-
-//-----------------------------------------------------------------------------
-void Faust::setSampleRate(float sampleRate)
-{
-  AudioEffect::setSampleRate(sampleRate);
-  dsp->instanceInit((int)getSampleRate()); // in case AudioEffect altered it
-}
-
-//-----------------------------------------------------------------------------
-void Faust::initProcess ()
-{
-  noteIsOn = false;
-  currentDelta = currentNote = currentDelta = 0;
-  dsp->instanceInit((int)getSampleRate());
-}
-
-//-----------------------------------------------------------------------------
-void Faust::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
-{
-    AVOIDDENORMALS;
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: processReplacing . . .\n");
-#endif
-
-  if (dsp->getNumInputs() > 0) { // We're an effect . . . keep going:
-
-    dsp->compute(sampleFrames, inputs, outputs);
-
-  } else { // We're a synth . . . 
-    int i, nouts = dsp->getNumOutputs();
-
-    if (noteIsOn) { // we're synthesizing . . .
-
-      if (currentDelta > 0) {  // but waiting out a timestamp delay . . .
-	if (currentDelta >= sampleFrames) { // start time is after this chunk
-	  currentDelta -= sampleFrames;
-	  // According to the VST programming sample, we DON'T clear the output buffers yet.
-	  // Could this be a bug in the sample program?  I would like to add the following:
-	  // for (i=0; i<nouts; i++) { memset (outptr[i], 0, sampleFrames * sizeof (float)); }
-	  return;
-	} else {
-	  // float* outptr[nouts];
-	  float** outptr = (float **)malloc(nouts * sizeof(float*));
-
-#ifdef DEBUG
-	  fprintf(stderr,"*** Faust vsti: currentDelta = %d\n",currentDelta);
-#endif
-
-	  for (i=0; i<nouts; i++) {
-	    outptr[i] = outputs[i]; // leaving caller's pointers alone
-	    // According to the VST programming sample, we DO clear the output buffers now
-	    // (since the start-time for the note is somewhere within the current chunk buf).
-	    memset (outptr[i], 0, currentDelta * sizeof (float));
-	    outptr[i] += currentDelta;
-	  }
-	  sampleFrames -= currentDelta;
-	  currentDelta = 0;
-	  dsp->compute(sampleFrames, inputs, outptr);
-	  free(outptr);
-	}
-      } else {
-	dsp->compute(sampleFrames, inputs, outputs);
-      }
-
-    } else { // silence until NoteOn . . .
-      for (i=0; i<nouts; i++) {	memset (outputs[i], 0, sampleFrames * sizeof (float)); }
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-VstInt32 Faust::processEvents (VstEvents* ev)
-{
-  if (ev->numEvents > 0) {
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: processEvents processing %d events\n",
-	    ev->numEvents);
-#endif
-  }
-
-  for (VstInt32 i = 0; i < ev->numEvents; i++)
-    {
-#ifdef DEBUG
-      fprintf(stderr,"=== Faust vsti: event type = %d\n", 
-	      (ev->events[i])->type);
-#endif
-      if ((ev->events[i])->type != kVstMidiType) {
-#ifdef DEBUG
-	fprintf(stderr,"=== Faust vsti: EVENT IGNORED!\n");
-#endif
-	continue;
-      }
-      VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
-      char* midiData = event->midiData;
-      VstInt32 chan = midiData[0] & 0xf;
-      VstInt32 status = midiData[0] & 0xf0;
-#ifdef DEBUG
-      fprintf(stderr,"\n=== Faust vsti: event->midiData[0] = 0x%x\n", 
-	      event->midiData[0]);
-      fprintf(stderr,"=== Faust vsti: midi channel = 0x%x\n", chan);
-      fprintf(stderr,"=== Faust vsti: midi status = 0x%x\n", status);
-      fprintf(stderr,"=== Faust vsti: event->midiData[1] = 0x%x\n", 
-	      event->midiData[1]);
-      fprintf(stderr,"=== Faust vsti: event->midiData[2] = 0x%x\n", 
-	      event->midiData[2]);
-#endif
-
-      if (status == 0x90) { // note on
-	VstInt32 note = midiData[1] & 0x7f;
-	VstInt32 velocity = midiData[2] & 0x7f;
-#ifdef DEBUG
-	fprintf(stderr,
-		"=== Faust vsti: note = %d, velocity = %d, delay = %d\n",
-		note,velocity,event->deltaFrames);
-#endif
-	if (velocity>0) {
-	  noteOn(note, velocity, event->deltaFrames);
-	} else {
-	  noteOff();
-	}
-      } else if (status == 0x80) { // note off
-	noteOff();
-	//      } else if (status == 0xA0) { // poly aftertouch
-      } else if (status == 0xB0) { // control change
-	/* DO SOMETHING WITH THE CONTROLLER DATA */
-	fprintf(stderr,"=== Faust vsti: CONTROL CHANGE (status 0xB0)!\n");
-	if (midiData[1] == 0x7e || midiData[1] == 0x7b) { // all notes off
-	  fprintf(stderr,"=== Faust vsti: ALL NOTES OFF!\n");
-	  noteOff (); // why is all-notes-off inside a "control change" event?
-	}
-	//      } else if (status == 0xC0) { // program change
-	//      } else if (status == 0xD0) { // mono aftertouch
-	//      } else if (status == 0xE0) { // pitch change
-	//      } else if (status == 0xF0) { // SYSX ...
-      }
-      // For a list, see 
-      // http://www.alfred-j-faust.de/rft/midi%20status%20types.html
-
-#ifdef DEBUG
-      fprintf(stderr,"=== Faust vsti: Going to next event\n", event->midiData[2]);
-#endif
-
-      event++;
-    }
-  return 1;
-}
-
-//-----------------------------------------------------------------------------
-void Faust::noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta)
-{
-#ifdef DEBUG
-  fprintf(stderr,"=== Faust vsti: noteOn: note = %d, vel = %d, del = %d\n",note,velocity,delta);
-#endif
-  currentNote = note;
-  currentVelocity = velocity;
-  currentDelta = delta;
-  noteIsOn = true;
-  float freq = 440.0f * powf(2.0f,(((float)note)-69.0f)/12.0f);
-  float gain = velocity/127.0f;
-  dspUI->setFreq(freq); // Hz - requires Faust control-signal "freq"
-  dspUI->setGain(gain); // 0-1 - requires Faust control-signal "gain"
-  dspUI->setGate(1.0f); // 0 or 1 - requires Faust button-signal "gate"
-}
-
-//-----------------------------------------------------------------------------
-void Faust::noteOff ()
-{
-  if (noteIsOn) {
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: noteOff\n");
-#endif
-    dspUI->setGate(0);
-  } else {
-#ifdef DEBUG
-    fprintf(stderr,"=== Faust vsti: noteOff IGNORED (note was not on)\n");
-#endif
-  }
-}
-
-
-/********************END ARCHITECTURE SECTION (part 2/2)****************/
-
diff --git a/architecture/webaudio/ExportLib.js b/architecture/webaudio/ExportLib.js
new file mode 100644
index 0000000..b1c1aba
--- /dev/null
+++ b/architecture/webaudio/ExportLib.js
@@ -0,0 +1,142 @@
+/************************************************************
+***************** Interface to FaustWeb *********************
+************************************************************/
+
+//--- Send asynchronous GET request to faustweb to get the list of available targets
+// @exportUrl : url of FaustWeb service to target
+// @callback : function called once request succeeded 
+// 				- @param : the available targets as a JSON application
+// json = {"platform1":["arch1", "arch2", ..., "archn"], ... , "platformn":["arch1", "arch2", ..., "archn"]}
+
+function getTargets(exportUrl, callback, errCallback){
+
+	var getrequest = new XMLHttpRequest();
+				
+	getrequest.onreadystatechange = function() {
+		if(getrequest.readyState == 4 && getrequest.status == 200)				    		
+			callback(getrequest.responseText);
+		else if(getrequest.readyState == 4 && getrequest.status == 400)				    		
+			errCallback(getrequest.responseText);
+	}
+				
+	var targetsUrl = exportUrl + "/targets";
+				
+	getrequest.open("GET", targetsUrl, true);
+	getrequest.send(null);
+}	
+
+//--- Send asynchronous POST request to faustweb to compile a faust DSP
+// @exportUrl : url of FaustWeb service to target
+// @name : name of DSP to compile
+// @source_code : faust code to compile
+// @callback : function called once request succeeded 
+// 				- @param : the sha key corresponding to source_code
+function getSHAKey(exportUrl, name, source_code, callback, errCallback){
+
+	var filename = name+".dsp";
+
+	var file = new File([source_code], filename);
+
+	var newRequest = new XMLHttpRequest();
+
+	var params = new FormData();
+	params.append('file', file);
+
+	var urlToTarget = exportUrl + "/filepost";	
+	
+	newRequest.open("POST", urlToTarget, true);
+
+	newRequest.onreadystatechange = function() {
+		if(newRequest.readyState == 4 && newRequest.status == 200)
+			callback(newRequest.responseText);
+		else if(newRequest.readyState == 4 && newRequest.status == 400)
+			errCallback(newRequest.responseText);
+	}
+				
+	newRequest.send(params);
+}	
+	
+//--- Send asynchronous GET request to precompile target 
+// @exportUrl : url of FaustWeb service to target
+// @sha : sha key of DSP to precompile
+// @platform/architecture : platform/architecture to precompile
+// @callback : function called once request succeeded 
+// 				- @param : the sha key 
+function sendPrecompileRequest(exportUrl, sha, platform, architecture, callback){
+			
+	var getrequest = new XMLHttpRequest();
+				
+	getrequest.onreadystatechange = function() {
+		if(getrequest.readyState == 4)
+			callback(sha);
+	}
+			
+	var compileUrl = exportUrl + "/" + sha + "/" + platform + "/" + architecture + "/precompile" ;
+				
+	getrequest.open("GET", compileUrl, true);
+	getrequest.send(null);
+
+}
+
+//--- Transform target 
+// WARNING = THIS FUNCTION REQUIRES QRCODE.JS TO BE INCLUDED IN YOUR HTML FILE
+// @exportUrl : url of FaustWeb service to target
+// @sha : sha key of DSP
+// @platform/architecture/target : platform/architecture/target compiled
+// @cote : width and height of the returned QrCode
+function getQrCode(url, sha, plateform, architecture, target, size){
+
+	var downloadString = url + "/" + sha + "/" + plateform + "/" + architecture + "/" + target;
+	
+	var whiteContainer = document.createElement('div');
+	whiteContainer.style.cssText = "width:" + size.toString() + "px; height:" + size.toString() + "px; background-color:white; position:relative; margin-left:auto; margin-right:auto; padding:3px;";
+	
+	var qqDiv = document.createElement('qrcode');
+	
+	var qq = new QRCode(qqDiv, {
+    	text: downloadString,
+	    width: size,
+    	height: size,
+	    colorDark : "#000000",
+    	colorLight : "#ffffff",
+	    correctLevel : QRCode.CorrectLevel.H
+	});
+
+	whiteContainer.appendChild(qqDiv);
+
+	return whiteContainer;
+}
+
+// Return the array of available platforms from the json description
+function getPlatforms(json){
+	
+	var platforms = [];
+	
+	var data = JSON.parse(json);
+	var index = 0;
+
+	for (var p in data) {
+		platforms[index] = p;
+		index++;
+    }
+
+	return platforms;
+}
+
+// Return the list of available architectures for a specific platform
+// from the json description
+function getArchitectures(json, platform){
+	
+	var architectures = [];
+		
+	var data = JSON.parse(json);
+		
+	return data[platform]						
+//     var archs = data[platform];
+			
+// 	for (var i =0; i<archs.length; i++)
+// 		architectures[i] = archs[i];
+// 	
+// 	return architectures;
+}
+
diff --git a/architecture/webaudio/export-wrapper.html b/architecture/webaudio/export-wrapper.html
new file mode 100644
index 0000000..3b3c1f0
--- /dev/null
+++ b/architecture/webaudio/export-wrapper.html
@@ -0,0 +1,301 @@
+<!-- Add FaustWeb Compilation service to Page -->
+<div id="export" style="color:white; position: absolute; width:400px; padding:2px 2px 2px 2px; background-color:7F7F7F; visibility:hidden; ">
+
+<div id="centerDiv" style="position:relative; margin-right:auto; margin-left:auto; text-align:center;">
+<input id="exportUrl" style="color:white; border:0px; text-align:center; font-size:16px; background-color:transparent; outline: 0px solid transparent; position:relative; margin-left:auto; maring-right: auto; text-align:center;" contenteditable="true" value="http://faustservice.grame.fr" onkeyup="onEnterKey()"/>
+</br>
+</br>
+</br>
+  <div id="refreshButton" style="position:absolute; left:10px; top:46px;">
+	<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+	 width="50.000000pt" height="50.000000pt" viewBox="0 0 50.000000 50.000000"
+	 preserveAspectRatio="xMidYMid meet">
+	<g transform="translate(0.000000,50.000000) scale(0.100000,-0.100000)"
+	fill="#000000" stroke="none">
+	<path d="M186 309 c-37 -29 -37 -89 0 -118 28 -22 69 -27 93 -12 23 15 3 30
+	-33 24 -29 -4 -37 -1 -51 21 -16 24 -16 28 -1 51 18 27 63 34 84 13 17 -17 15
+	-31 -3 -24 -20 7 -19 1 6 -28 l22 -25 18 24 c20 25 25 40 9 30 -5 -3 -16 7
+	-24 23 -25 47 -75 56 -120 21z"/>
+	</g>
+	</svg>
+</div>
+  <select id="Platform" style="width:250px;" onChange="changeArchs()">
+  </select>
+  </br>
+    <select id="Architecture" style="width:250px;">
+  </select>
+  </br>
+  </br>
+  <input id="exportButton" type="button" value="Export" onclick="getFaustSource()" style="border: 2px solid white; border-radius:8px; color:white; font-size:16px;  background-color:transparent;"/>
+	</br>
+  </br>
+  <div id="qrDiv">
+  
+  <div id="loader" style="visibility:hidden;">
+  <svg width='50px' height='50px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-ring">
+  <rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect>
+  <defs>
+    <filter id="uil-ring-shadow" x="-100%" y="-100%" width="300%" height="300%">
+      <feOffset result="offOut" in="SourceGraphic" dx="0" dy="0"></feOffset>
+      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="0"></feGaussianBlur>
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend>
+    </filter>
+  </defs>
+  <path d="M10,50c0,0,0,0.5,0.1,1.4c0,0.5,0.1,1,0.2,1.7c0,0.3,0.1,0.7,0.1,1.1c0.1,0.4,0.1,0.8,0.2,1.2c0.2,0.8,0.3,1.8,0.5,2.8 c0.3,1,0.6,2.1,0.9,3.2c0.3,1.1,0.9,2.3,1.4,3.5c0.5,1.2,1.2,2.4,1.8,3.7c0.3,0.6,0.8,1.2,1.2,1.9c0.4,0.6,0.8,1.3,1.3,1.9 c1,1.2,1.9,2.6,3.1,3.7c2.2,2.5,5,4.7,7.9,6.7c3,2,6.5,3.4,10.1,4.6c3.6,1.1,7.5,1.5,11.2,1.6c4-0.1,7.7-0.6,11.3-1.6 c3.6-1.2,7-2.6,10-4.6c3-2,5.8-4.2,7.9-6.7c1.2-1.2,2.1-2.5,3.1-3.7c0.5-0.6,0.9-1.3,1.3-1.9c0.4-0.6,0.8-1.3,1.2-1.9 c0.6-1.3,1.3-2.5,1.8-3.7c0.5-1.2,1-2.4,1.4-3.5c0.3-1.1,0.6-2.2,0.9-3.2c0.2-1,0.4-1.9,0.5-2.8c0.1-0.4,0.1-0.8,0.2-1.2 c0-0.4,0.1-0.7,0.1-1.1c0.1-0.7,0.1-1.2,0.2-1.7C90,50.5,90,50,90,50s0,0.5,0,1.4c0,0.5,0,1,0,1.7c0,0.3,0,0.7,0,1.1 c0,0.4-0.1,0.8-0.1,1.2c-0.1,0.9-0.2,1.8-0.4,2.8c-0.2,1-0.5,2.1-0.7,3.3c-0.3,1.2-0.8,2.4-1.2,3.7c-0.2,0.7-0.5,1.3-0.8,1.9 c-0.3,0.7-0.6,1.3-0.9,2c-0.3,0.7-0.7,1.3-1.1,2c-0.4,0.7-0.7,1.4-1.2,2c-1,1.3-1.9,2.7-3.1,4c-2.2,2.7-5,5-8.1,7.1 c-0.8,0.5-1.6,1-2.4,1.5c-0.8,0.5-1.7,0.9-2.6,1.3L66,87.7l-1.4,0.5c-0.9,0.3-1.8,0.7-2.8,1c-3.8,1.1-7.9,1.7-11.8,1.8L47,90.8 c-1,0-2-0.2-3-0.3l-1.5-0.2l-0.7-0.1L41.1,90c-1-0.3-1.9-0.5-2.9-0.7c-0.9-0.3-1.9-0.7-2.8-1L34,87.7l-1.3-0.6 c-0.9-0.4-1.8-0.8-2.6-1.3c-0.8-0.5-1.6-1-2.4-1.5c-3.1-2.1-5.9-4.5-8.1-7.1c-1.2-1.2-2.1-2.7-3.1-4c-0.5-0.6-0.8-1.4-1.2-2 c-0.4-0.7-0.8-1.3-1.1-2c-0.3-0.7-0.6-1.3-0.9-2c-0.3-0.7-0.6-1.3-0.8-1.9c-0.4-1.3-0.9-2.5-1.2-3.7c-0.3-1.2-0.5-2.3-0.7-3.3 c-0.2-1-0.3-2-0.4-2.8c-0.1-0.4-0.1-0.8-0.1-1.2c0-0.4,0-0.7,0-1.1c0-0.7,0-1.2,0-1.7C10,50.5,10,50,10,50z" fill="white" filter="url(#uil-ring-shadow)">
+    <animateTransform attributeName="transform" type="rotate" from="0 50 50" to="360 50 50" repeatCount="indefinite" dur="1.5s"></animateTransform>
+  </path>
+</svg>
+</div>
+  </div>
+</div>
+  </br>
+</div>
+
+
+<div id="plusImg" style="position: absolute; z-index=4; visibility:visible;">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="50.000000pt" height="51.000000pt" viewBox="0 0 50.000000 51.000000"
+ preserveAspectRatio="xMidYMid meet">
+<g transform="translate(0.000000,51.000000) scale(0.100000,-0.100000)"
+fill="#f9be0d" stroke="none">
+<path d="M205 481 c-89 -22 -153 -85 -175 -174 -25 -96 28 -204 122 -251 84
+-42 166 -31 239 33 126 107 95 315 -56 376 -43 18 -95 24 -130 16z m153 -54
+c58 -38 97 -120 89 -188 -7 -60 -36 -109 -84 -146 -51 -39 -154 -45 -212 -12
+-116 65 -137 235 -39 326 64 60 173 69 246 20z"/>
+<path d="M190 373 l0 -53 -55 0 -55 0 0 -60 0 -60 55 0 55 0 0 -55 0 -55 60 0
+60 0 0 55 0 55 53 0 53 0 0 60 -1 60 -52 0 -52 0 -3 52 -3 51 -58 1 -57 1 0
+-52z m100 -18 l0 -55 50 0 50 0 0 -40 0 -40 -50 0 -50 0 0 -55 0 -55 -40 0
+-40 0 0 55 0 55 -55 0 -55 0 0 40 0 40 55 0 55 0 0 55 0 55 40 0 40 0 0 -55z"/>
+</g>
+</svg>
+</div>
+<div id="moinsImg" style="position: absolute; z-index=4; visibility:hidden;">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="50.000000pt" height="51.000000pt" viewBox="0 0 50.000000 51.000000"
+ preserveAspectRatio="xMidYMid meet" >
+<g transform="translate(0.000000,51.000000) scale(0.100000,-0.100000)"
+fill="#f9be0d" stroke="none">
+<path d="M187 466 c-92 -34 -157 -123 -157 -217 0 -100 79 -196 180 -218 143
+-31 270 72 270 219 0 66 -16 107 -59 153 -57 62 -161 90 -234 63z m162 -36
+c78 -39 118 -115 107 -204 -19 -167 -227 -236 -342 -114 -46 48 -57 76 -58
+139 -1 74 39 142 103 176 56 29 136 31 190 3z"/>
+<path d="M90 250 l0 -60 170 0 170 0 0 60 0 60 -170 0 -170 0 0 -60z m320 0
+l0 -40 -150 0 -150 0 0 40 0 40 150 0 150 0 0 -40z"/>
+</g>
+</svg>
+</div>
+
+<script src="http://faust.grame.fr/webaudio/ExportLib.js"></script>
+<script src="http://faust.grame.fr/webaudio/qrcode.js"></script>
+
+<script >
+
+function onEnterKey(e)
+{
+	if (!e) { var e = window.event; } 
+	
+	if (e.keyCode == 13) { 
+		e.preventDefault(); 
+		updateFWTargets();
+	}
+}
+
+function openExport()
+{
+	document.getElementById("plusImg").style.visibility = "hidden";
+	document.getElementById("moinsImg").style.visibility = "visible";
+	document.getElementById("export").style.visibility = "visible";
+}
+
+function closeExport(event)
+{
+	if (!event) { event = window.event; } 
+
+	var target = event.target
+	while(target && target != document.getElementById("export") && target != document.getElementById("plusImg") )
+		target= target.parentNode;
+
+	if (!target) {
+		document.getElementById("plusImg").style.visibility = "visible";
+		document.getElementById("moinsImg").style.visibility = "hidden";
+		document.getElementById("export").style.visibility = "hidden";	
+	}
+}
+
+function updateQrCode(sha)
+{
+    // Empty Div before adding new qrcode
+	var toEmpty = document.getElementById("qrDiv");
+
+	document.getElementById("loader").style.visibility = "hidden";
+	
+	for (var i = toEmpty.children.length-1; i >= 0;  i--) {
+		if (toEmpty.children[i].id != "loader") {
+	    	toEmpty.removeChild(toEmpty.children[i]);
+        }
+	}
+	
+	var plateform = document.getElementById("Platform").options[document.getElementById("Platform").selectedIndex].value;
+	var architecture = document.getElementById("Architecture").options[document.getElementById("Architecture").selectedIndex].value;
+	var output = "binary.zip";
+	
+	if (plateform == "android") {
+		output = "binary.apk";
+    }
+	
+	var link = document.createElement('a');
+	link.href = document.getElementById("exportUrl").value + "/" + sha + "/" + plateform + "/" + architecture + "/" + output;
+
+	// 	Delete existing content if existing
+	var qrcodeSpan = document.getElementById('qrcodeDiv');
+	if (qrcodeSpan) {
+		qrcodeSpan.parentNode.removeChild(qrcodeSpan);
+    }
+	
+	var myWhiteDiv = getQrCode(document.getElementById("exportUrl").value, sha, plateform, architecture, output, 130);
+
+	document.getElementById("qrDiv").appendChild(link);
+	link.appendChild(myWhiteDiv);
+}
+
+function cancelLoader()
+{
+	document.getElementById("loader").style.visibility = "hidden";
+}
+
+function getFaustSource()
+{
+    document.getElementById("loader").style.visibility = "visible";
+    
+    if (dsp_code == null) {
+
+        var url = window.location.href.split('.html').shift() + ".dsp";
+        var filename = url.toString().split( '/' ).pop();
+        filename = filename.toString().split('.').shift();
+        var xmlhttp = new XMLHttpRequest();
+
+        xmlhttp.onreadystatechange=function(){
+            if (xmlhttp.readyState==4 && xmlhttp.status == 200) {
+                var dsp_code = xmlhttp.responseText;
+                getSHAKey(document.getElementById("exportUrl").value, filename, dsp_code, updateQrCode, cancelLoader);
+            }
+        }
+        xmlhttp.open("GET", url, false );
+        xmlhttp.send(); 
+    } else {
+        // Global 'dsp_code', so use it
+        getSHAKey(document.getElementById("exportUrl").value, "FaustDSP", dsp_code, updateQrCode, cancelLoader);
+    }
+}
+
+function cleanComboBox(id)
+{
+	while(document.getElementById(id).childNodes.length > 0) {
+		document.getElementById(id).removeChild(document.getElementById(id).childNodes[0]);
+	}
+}
+
+function changeArchs()
+{
+    // CLEAN COMBOBOX BEFORE ADDING NEW OPTIONS
+	cleanComboBox("Architecture");
+
+	var plat = document.getElementById("Platform").options[document.getElementById("Platform").selectedIndex].value;
+	var archs = getArchitectures(window.json, plat);
+		
+	for (var j = 0; j < archs.length; j++) {
+        var a = document.createElement('option');
+		a.text = archs[j];
+		document.getElementById("Architecture").options.add(a);
+	}
+}
+
+function updateFWTargets()
+{
+    // CLEAN COMBOBOX BEFORE ADDING NEW OPTIONS
+	cleanComboBox("Platform");
+	cleanComboBox("Architecture");
+
+	getTargets(document.getElementById("exportUrl").value, function(json) {
+	
+		window.json = json;
+		var plats = getPlatforms(json);	
+	
+		for (var i = 0; i < plats.length; i++) {
+			var o=document.createElement('option');
+			o.text=plats[i];
+			document.getElementById("Platform").options.add(o);
+		}
+		
+        changeArchs();
+	}, function(){});
+}
+
+function changeOrientation(orientation)
+{
+	if (orientation == "topright") {
+		document.getElementById("plusImg").style.top = "0px";
+		document.getElementById("plusImg").style.right = "0px";		
+		document.getElementById("moinsImg").style.top = "0px";
+		document.getElementById("moinsImg").style.right = "0px";		
+		
+		document.getElementById("export").style.top = "0%";
+		document.getElementById("export").style.right = "0%";
+		document.getElementById("export").style.boxShadow ="0px 2px 2px 0px white";
+		document.getElementById("export").style.borderRadius ="0px 0px 0px 25px";
+		document.getElementById("export").style.borderBottom = "3px solid white";
+		document.getElementById("export").style.borderLeft ="3px solid white";
+	} else if(orientation == "bottomright") {
+	
+		document.getElementById("plusImg").style.bottom = "0px";
+		document.getElementById("plusImg").style.right = "0px";			
+		document.getElementById("moinsImg").style.bottom = "0px";
+		document.getElementById("moinsImg").style.right = "0px";			
+		
+		document.getElementById("export").style.bottom = "0%";
+		document.getElementById("export").style.right = "0%";
+		document.getElementById("export").style.boxShadow ="2px 2px 0px px white";
+		document.getElementById("export").style.borderRadius ="25px 0px 0px 0px";
+		document.getElementById("export").style.borderTop = "3px solid white";
+		document.getElementById("export").style.borderLeft ="3px solid white";
+	} else if(orientation == "bottomleft") {
+		document.getElementById("plusImg").style.bottom = "0px";
+		document.getElementById("plusImg").style.left = "0px";		
+		document.getElementById("moinsImg").style.bottom = "0px";
+		document.getElementById("moinsImg").style.left = "0px";
+		
+		document.getElementById("export").style.bottom = "0%";
+		document.getElementById("export").style.left = "0%";
+		document.getElementById("export").style.boxShadow ="2px 0px 2px 0px white";
+		document.getElementById("export").style.borderRadius ="0px 25px 0px 0px";
+		document.getElementById("export").style.borderTop = "3px solid white";
+		document.getElementById("export").style.borderRight ="3px solid white";		
+	} else if(orientation == "topleft") {
+		document.getElementById("plusImg").style.top = "0px";
+		document.getElementById("plusImg").style.left = "0px";		
+		document.getElementById("moinsImg").style.top = "0px";
+		document.getElementById("moinsImg").style.left = "0px";
+
+		document.getElementById("export").style.top = "0%";
+		document.getElementById("export").style.left = "0%";
+		document.getElementById("export").style.boxShadow ="0px 0px 2px 2px white";
+		document.getElementById("export").style.borderRadius ="0px 0px 25px 0px";
+		document.getElementById("export").style.borderBottom = "3px solid white";
+		document.getElementById("export").style.borderRight ="3px solid white";		
+	}
+}
+
+changeOrientation("topright");
+// changeOrientation("bottomright");
+// changeOrientation("bottomleft");
+// changeOrientation("topleft");
+
+updateFWTargets();
+
+document.getElementById("refreshButton").onclick=updateFWTargets;
+document.getElementById("plusImg").onclick=openExport;
+document.getElementById("moinsImg").onclick=closeExport;
+document.body.addEventListener("click", closeExport, false);
+</script>
+
+<!-- End FaustWeb Compilation Service -->
diff --git a/architecture/webaudio/qrcode.js b/architecture/webaudio/qrcode.js
new file mode 100644
index 0000000..1980d68
--- /dev/null
+++ b/architecture/webaudio/qrcode.js
@@ -0,0 +1,614 @@
+/**
+ * @fileoverview
+ * - Using the 'QRCode for Javascript library'
+ * - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
+ * - this library has no dependencies.
+ * 
+ * @author davidshimjs
+ * @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
+ * @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
+ */
+var QRCode;
+
+(function () {
+	//---------------------------------------------------------------------
+	// QRCode for JavaScript
+	//
+	// Copyright (c) 2009 Kazuhiko Arase
+	//
+	// URL: http://www.d-project.com/
+	//
+	// Licensed under the MIT license:
+	//   http://www.opensource.org/licenses/mit-license.php
+	//
+	// The word "QR Code" is registered trademark of 
+	// DENSO WAVE INCORPORATED
+	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
+	//
+	//---------------------------------------------------------------------
+	function QR8bitByte(data) {
+		this.mode = QRMode.MODE_8BIT_BYTE;
+		this.data = data;
+		this.parsedData = [];
+
+		// Added to support UTF-8 Characters
+		for (var i = 0, l = this.data.length; i < l; i++) {
+			var byteArray = [];
+			var code = this.data.charCodeAt(i);
+
+			if (code > 0x10000) {
+				byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
+				byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
+				byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
+				byteArray[3] = 0x80 | (code & 0x3F);
+			} else if (code > 0x800) {
+				byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
+				byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
+				byteArray[2] = 0x80 | (code & 0x3F);
+			} else if (code > 0x80) {
+				byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
+				byteArray[1] = 0x80 | (code & 0x3F);
+			} else {
+				byteArray[0] = code;
+			}
+
+			this.parsedData.push(byteArray);
+		}
+
+		this.parsedData = Array.prototype.concat.apply([], this.parsedData);
+
+		if (this.parsedData.length != this.data.length) {
+			this.parsedData.unshift(191);
+			this.parsedData.unshift(187);
+			this.parsedData.unshift(239);
+		}
+	}
+
+	QR8bitByte.prototype = {
+		getLength: function (buffer) {
+			return this.parsedData.length;
+		},
+		write: function (buffer) {
+			for (var i = 0, l = this.parsedData.length; i < l; i++) {
+				buffer.put(this.parsedData[i], 8);
+			}
+		}
+	};
+
+	function QRCodeModel(typeNumber, errorCorrectLevel) {
+		this.typeNumber = typeNumber;
+		this.errorCorrectLevel = errorCorrectLevel;
+		this.modules = null;
+		this.moduleCount = 0;
+		this.dataCache = null;
+		this.dataList = [];
+	}
+
+	QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
+	return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
+	this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
+	if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
+	this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
+	return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
+	return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
+	this.modules[r][6]=(r%2==0);}
+	for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
+	this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
+	for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
+	for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
+	for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
+	this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
+	var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
+	this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
+	row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
+	var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
+	if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
+	+buffer.getLengthInBits()
+	+">"
+	+totalDataCount*8
+	+")");}
+	if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
+	while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
+	while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
+	buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
+	buffer.put(QRCodeModel.PAD1,8);}
+	return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
+	offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
+	var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
+	var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
+	for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
+	return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
+	return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
+	return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
+	return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
+	return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
+	for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
+	if(r==0&&c==0){continue;}
+	if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
+	if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
+	for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
+	for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
+	for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
+	var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
+	var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
+	return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
+	while(n>=256){n-=255;}
+	return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
+	for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
+	for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
+	function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
+	var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
+	this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
+	QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
+	return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
+	var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
+	for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
+	return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
+	QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
+	var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
+	return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
+	QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
+	if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
+	this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
+	
+	function _isSupportCanvas() {
+		return typeof CanvasRenderingContext2D != "undefined";
+	}
+	
+	// android 2.x doesn't support Data-URI spec
+	function _getAndroid() {
+		var android = false;
+		var sAgent = navigator.userAgent;
+		
+		if (/android/i.test(sAgent)) { // android
+			android = true;
+			var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
+			
+			if (aMat && aMat[1]) {
+				android = parseFloat(aMat[1]);
+			}
+		}
+		
+		return android;
+	}
+	
+	var svgDrawer = (function() {
+
+		var Drawing = function (el, htOption) {
+			this._el = el;
+			this._htOption = htOption;
+		};
+
+		Drawing.prototype.draw = function (oQRCode) {
+			var _htOption = this._htOption;
+			var _el = this._el;
+			var nCount = oQRCode.getModuleCount();
+			var nWidth = Math.floor(_htOption.width / nCount);
+			var nHeight = Math.floor(_htOption.height / nCount);
+
+			this.clear();
+
+			function makeSVG(tag, attrs) {
+				var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
+				for (var k in attrs)
+					if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
+				return el;
+			}
+
+			var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
+			svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
+			_el.appendChild(svg);
+
+			svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
+			svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
+
+			for (var row = 0; row < nCount; row++) {
+				for (var col = 0; col < nCount; col++) {
+					if (oQRCode.isDark(row, col)) {
+						var child = makeSVG("use", {"x": String(row), "y": String(col)});
+						child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
+						svg.appendChild(child);
+					}
+				}
+			}
+		};
+		Drawing.prototype.clear = function () {
+			while (this._el.hasChildNodes())
+				this._el.removeChild(this._el.lastChild);
+		};
+		return Drawing;
+	})();
+
+	var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
+
+	// Drawing in DOM by using Table tag
+	var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
+		var Drawing = function (el, htOption) {
+			this._el = el;
+			this._htOption = htOption;
+		};
+			
+		/**
+		 * Draw the QRCode
+		 * 
+		 * @param {QRCode} oQRCode
+		 */
+		Drawing.prototype.draw = function (oQRCode) {
+            var _htOption = this._htOption;
+            var _el = this._el;
+			var nCount = oQRCode.getModuleCount();
+			var nWidth = Math.floor(_htOption.width / nCount);
+			var nHeight = Math.floor(_htOption.height / nCount);
+			var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
+			
+			for (var row = 0; row < nCount; row++) {
+				aHTML.push('<tr>');
+				
+				for (var col = 0; col < nCount; col++) {
+					aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
+				}
+				
+				aHTML.push('</tr>');
+			}
+			
+			aHTML.push('</table>');
+			_el.innerHTML = aHTML.join('');
+			
+			// Fix the margin values as real size.
+			var elTable = _el.childNodes[0];
+			var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
+			var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
+			
+			if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
+				elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";	
+			}
+		};
+		
+		/**
+		 * Clear the QRCode
+		 */
+		Drawing.prototype.clear = function () {
+			this._el.innerHTML = '';
+		};
+		
+		return Drawing;
+	})() : (function () { // Drawing in Canvas
+		function _onMakeImage() {
+			this._elImage.src = this._elCanvas.toDataURL("image/png");
+			this._elImage.style.display = "block";
+			this._elCanvas.style.display = "none";			
+		}
+		
+		// Android 2.1 bug workaround
+		// http://code.google.com/p/android/issues/detail?id=5141
+		if (this._android && this._android <= 2.1) {
+	    	var factor = 1 / window.devicePixelRatio;
+	        var drawImage = CanvasRenderingContext2D.prototype.drawImage; 
+	    	CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
+	    		if (("nodeName" in image) && /img/i.test(image.nodeName)) {
+		        	for (var i = arguments.length - 1; i >= 1; i--) {
+		            	arguments[i] = arguments[i] * factor;
+		        	}
+	    		} else if (typeof dw == "undefined") {
+	    			arguments[1] *= factor;
+	    			arguments[2] *= factor;
+	    			arguments[3] *= factor;
+	    			arguments[4] *= factor;
+	    		}
+	    		
+	        	drawImage.apply(this, arguments); 
+	    	};
+		}
+		
+		/**
+		 * Check whether the user's browser supports Data URI or not
+		 * 
+		 * @private
+		 * @param {Function} fSuccess Occurs if it supports Data URI
+		 * @param {Function} fFail Occurs if it doesn't support Data URI
+		 */
+		function _safeSetDataURI(fSuccess, fFail) {
+            var self = this;
+            self._fFail = fFail;
+            self._fSuccess = fSuccess;
+
+            // Check it just once
+            if (self._bSupportDataURI === null) {
+                var el = document.createElement("img");
+                var fOnError = function() {
+                    self._bSupportDataURI = false;
+
+                    if (self._fFail) {
+                        self._fFail.call(self);
+                    }
+                };
+                var fOnSuccess = function() {
+                    self._bSupportDataURI = true;
+
+                    if (self._fSuccess) {
+                        self._fSuccess.call(self);
+                    }
+                };
+
+                el.onabort = fOnError;
+                el.onerror = fOnError;
+                el.onload = fOnSuccess;
+                el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
+                return;
+            } else if (self._bSupportDataURI === true && self._fSuccess) {
+                self._fSuccess.call(self);
+            } else if (self._bSupportDataURI === false && self._fFail) {
+                self._fFail.call(self);
+            }
+		};
+		
+		/**
+		 * Drawing QRCode by using canvas
+		 * 
+		 * @constructor
+		 * @param {HTMLElement} el
+		 * @param {Object} htOption QRCode Options 
+		 */
+		var Drawing = function (el, htOption) {
+    		this._bIsPainted = false;
+    		this._android = _getAndroid();
+		
+			this._htOption = htOption;
+			this._elCanvas = document.createElement("canvas");
+			this._elCanvas.width = htOption.width;
+			this._elCanvas.height = htOption.height;
+			el.appendChild(this._elCanvas);
+			this._el = el;
+			this._oContext = this._elCanvas.getContext("2d");
+			this._bIsPainted = false;
+			this._elImage = document.createElement("img");
+			this._elImage.alt = "Scan me!";
+			this._elImage.style.display = "none";
+			this._el.appendChild(this._elImage);
+			this._bSupportDataURI = null;
+		};
+			
+		/**
+		 * Draw the QRCode
+		 * 
+		 * @param {QRCode} oQRCode 
+		 */
+		Drawing.prototype.draw = function (oQRCode) {
+            var _elImage = this._elImage;
+            var _oContext = this._oContext;
+            var _htOption = this._htOption;
+            
+			var nCount = oQRCode.getModuleCount();
+			var nWidth = _htOption.width / nCount;
+			var nHeight = _htOption.height / nCount;
+			var nRoundedWidth = Math.round(nWidth);
+			var nRoundedHeight = Math.round(nHeight);
+
+			_elImage.style.display = "none";
+			this.clear();
+			
+			for (var row = 0; row < nCount; row++) {
+				for (var col = 0; col < nCount; col++) {
+					var bIsDark = oQRCode.isDark(row, col);
+					var nLeft = col * nWidth;
+					var nTop = row * nHeight;
+					_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
+					_oContext.lineWidth = 1;
+					_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;					
+					_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
+					
+					// 안티 앨리어싱 방지 처리
+					_oContext.strokeRect(
+						Math.floor(nLeft) + 0.5,
+						Math.floor(nTop) + 0.5,
+						nRoundedWidth,
+						nRoundedHeight
+					);
+					
+					_oContext.strokeRect(
+						Math.ceil(nLeft) - 0.5,
+						Math.ceil(nTop) - 0.5,
+						nRoundedWidth,
+						nRoundedHeight
+					);
+				}
+			}
+			
+			this._bIsPainted = true;
+		};
+			
+		/**
+		 * Make the image from Canvas if the browser supports Data URI.
+		 */
+		Drawing.prototype.makeImage = function () {
+			if (this._bIsPainted) {
+				_safeSetDataURI.call(this, _onMakeImage);
+			}
+		};
+			
+		/**
+		 * Return whether the QRCode is painted or not
+		 * 
+		 * @return {Boolean}
+		 */
+		Drawing.prototype.isPainted = function () {
+			return this._bIsPainted;
+		};
+		
+		/**
+		 * Clear the QRCode
+		 */
+		Drawing.prototype.clear = function () {
+			this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
+			this._bIsPainted = false;
+		};
+		
+		/**
+		 * @private
+		 * @param {Number} nNumber
+		 */
+		Drawing.prototype.round = function (nNumber) {
+			if (!nNumber) {
+				return nNumber;
+			}
+			
+			return Math.floor(nNumber * 1000) / 1000;
+		};
+		
+		return Drawing;
+	})();
+	
+	/**
+	 * Get the type by string length
+	 * 
+	 * @private
+	 * @param {String} sText
+	 * @param {Number} nCorrectLevel
+	 * @return {Number} type
+	 */
+	function _getTypeNumber(sText, nCorrectLevel) {			
+		var nType = 1;
+		var length = _getUTF8Length(sText);
+		
+		for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
+			var nLimit = 0;
+			
+			switch (nCorrectLevel) {
+				case QRErrorCorrectLevel.L :
+					nLimit = QRCodeLimitLength[i][0];
+					break;
+				case QRErrorCorrectLevel.M :
+					nLimit = QRCodeLimitLength[i][1];
+					break;
+				case QRErrorCorrectLevel.Q :
+					nLimit = QRCodeLimitLength[i][2];
+					break;
+				case QRErrorCorrectLevel.H :
+					nLimit = QRCodeLimitLength[i][3];
+					break;
+			}
+			
+			if (length <= nLimit) {
+				break;
+			} else {
+				nType++;
+			}
+		}
+		
+		if (nType > QRCodeLimitLength.length) {
+			throw new Error("Too long data");
+		}
+		
+		return nType;
+	}
+
+	function _getUTF8Length(sText) {
+		var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
+		return replacedText.length + (replacedText.length != sText ? 3 : 0);
+	}
+	
+	/**
+	 * @class QRCode
+	 * @constructor
+	 * @example 
+	 * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
+	 *
+	 * @example
+	 * var oQRCode = new QRCode("test", {
+	 *    text : "http://naver.com",
+	 *    width : 128,
+	 *    height : 128
+	 * });
+	 * 
+	 * oQRCode.clear(); // Clear the QRCode.
+	 * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
+	 *
+	 * @param {HTMLElement|String} el target element or 'id' attribute of element.
+	 * @param {Object|String} vOption
+	 * @param {String} vOption.text QRCode link data
+	 * @param {Number} [vOption.width=256]
+	 * @param {Number} [vOption.height=256]
+	 * @param {String} [vOption.colorDark="#000000"]
+	 * @param {String} [vOption.colorLight="#ffffff"]
+	 * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 
+	 */
+	QRCode = function (el, vOption) {
+		this._htOption = {
+			width : 256, 
+			height : 256,
+			typeNumber : 4,
+			colorDark : "#000000",
+			colorLight : "#ffffff",
+			correctLevel : QRErrorCorrectLevel.H
+		};
+		
+		if (typeof vOption === 'string') {
+			vOption	= {
+				text : vOption
+			};
+		}
+		
+		// Overwrites options
+		if (vOption) {
+			for (var i in vOption) {
+				this._htOption[i] = vOption[i];
+			}
+		}
+		
+		if (typeof el == "string") {
+			el = document.getElementById(el);
+		}
+
+		if (this._htOption.useSVG) {
+			Drawing = svgDrawer;
+		}
+		
+		this._android = _getAndroid();
+		this._el = el;
+		this._oQRCode = null;
+		this._oDrawing = new Drawing(this._el, this._htOption);
+		
+		if (this._htOption.text) {
+			this.makeCode(this._htOption.text);	
+		}
+	};
+	
+	/**
+	 * Make the QRCode
+	 * 
+	 * @param {String} sText link data
+	 */
+	QRCode.prototype.makeCode = function (sText) {
+		this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
+		this._oQRCode.addData(sText);
+		this._oQRCode.make();
+		this._el.title = sText;
+		this._oDrawing.draw(this._oQRCode);			
+		this.makeImage();
+	};
+	
+	/**
+	 * Make the Image from Canvas element
+	 * - It occurs automatically
+	 * - Android below 3 doesn't support Data-URI spec.
+	 * 
+	 * @private
+	 */
+	QRCode.prototype.makeImage = function () {
+		if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
+			this._oDrawing.makeImage();
+		}
+	};
+	
+	/**
+	 * Clear the QRCode
+	 */
+	QRCode.prototype.clear = function () {
+		this._oDrawing.clear();
+	};
+	
+	/**
+	 * @name QRCode.CorrectLevel
+	 */
+	QRCode.CorrectLevel = QRErrorCorrectLevel;
+})();
diff --git a/architecture/webaudio/webaudio-asm-emcc.js b/architecture/webaudio/webaudio-asm-emcc.js
new file mode 100644
index 0000000..22f426c
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm-emcc.js
@@ -0,0 +1,271 @@
+/*
+ faust2webaudio
+ 
+ Primarily written by Myles Borins
+ During the Spring 2013 offering of Music 420b with Julius Smith
+ A bit during the Summer of 2013 with the help of Joshua Kit Clayton
+ And finally a sprint during the late fall of 2013 to get everything working
+ A Special thanks to Yann Orlarey and Stéphane Letz
+ 
+ faust2webaudio is distributed under the terms the MIT or GPL2 Licenses.
+ Choose the license that best suits your project. The text of the MIT and GPL
+ licenses are at the root directory.
+ 
+ Additional code : GRAME 2014
+*/
+
+'use strict';
+
+var faust = faust || {};
+
+var DSP_constructor = Module.cwrap('DSP_constructor', 'number', ['number']);
+var DSP_destructor = Module.cwrap('DSP_destructor', null, ['number']);
+var DSP_compute = Module.cwrap('DSP_compute', null, ['number', 'number', 'number', 'number']);
+var DSP_getNumInputs = Module.cwrap('DSP_getNumInputs', 'number', ['number']);
+var DSP_getNumOutputs = Module.cwrap('DSP_getNumOutputs', 'number', ['number']);
+var DSP_getJSON = Module.cwrap('DSP_getJSON', 'number', ['number']);
+var DSP_setValue = Module.cwrap('DSP_setValue', null, ['number', 'number', 'number']);
+var DSP_getValue = Module.cwrap('DSP_getValue', 'number', ['number', 'number']);
+
+// Standard Faust DSP
+
+faust.DSP = function (context, buffer_size) {
+    
+    var handler = null;
+    var ins, outs;
+    var numIn, numOut;
+    
+    var scriptProcessor;
+    
+    var dspInChannnels = [];
+    var dspOutChannnels = [];
+   
+    // Path string
+    var path_ptr = Module._malloc(512);
+    
+    // bargraph
+    var ouputs_timer = 5;
+    var ouputs_items = [];
+    
+    // input items
+    var inputs_items = [];
+    
+    var ptr = DSP_constructor(context.sampleRate);
+    
+    function update_outputs () 
+    {
+        if (ouputs_items.length > 0 && handler && ouputs_timer-- === 0) {
+            ouputs_timer = 5;
+            for (var i = 0; i < ouputs_items.length; i++) {
+                Module.writeStringToMemory(ouputs_items[i], path_ptr);
+                handler(ouputs_items[i], DSP_getValue(ptr, path_ptr));
+            }
+        }
+    }
+        
+    // JSON parsing
+    function parse_ui (ui) 
+    {
+         for (var i = 0; i < ui.length; i++) {
+            parse_group(ui[i]);
+        }
+    }
+    
+    function parse_group (group) 
+    {
+        if (group.items) {
+            parse_items(group.items);
+        }
+    }
+    
+    function parse_items (items) 
+    {
+        for (var i = 0; i < items.length; i++) {
+            parse_item(items[i]);
+        }
+    }
+    
+    function parse_item (item) 
+    {
+        if (item.type === "vgroup" || item.type === "hgroup" || item.type === "tgroup") {
+            parse_items(item.items);
+        } else if (item.type === "hbargraph" || item.type === "vbargraph") {
+            // Keep bargraph adresses
+            ouputs_items.push(item.address);
+        } else if (item.type === "vslider" || item.type === "hslider" || item.type === "button" || item.type === "checkbox" || item.type === "nentry") {
+            // Keep inputs adresses
+            inputs_items.push(item.address);
+        }
+    }
+    
+    function compute (e) 
+    {
+        // Read inputs
+        for (var i = 0; i < numIn; i++) {
+            var input = e.inputBuffer.getChannelData(i);
+            var dspInput = dspInChannnels[i];
+            for (var j = 0; j < input.length; j++) {
+                dspInput[j] = input[j];
+            }
+        }
+        
+        // Compute
+        DSP_compute(ptr, buffer_size, ins, outs);
+       
+        // Update bargraph
+        update_outputs();
+        
+        // Write outputs
+        for (var i = 0; i < numOut; i++) {
+            var output = e.outputBuffer.getChannelData(i);
+            var dspOutput = dspOutChannnels[i];
+            for (var j = 0; j < output.length; j++) {
+                output[j] = dspOutput[j];
+            }
+        }
+    }
+    
+    function init ()
+    {
+        var i;
+        var ptr_size = 4; //assuming pointer in emscripten are 32bits
+        var sample_size = 4;
+        
+        // Get input / output counts
+        numIn = DSP_getNumInputs(ptr);
+        numOut = DSP_getNumOutputs(ptr);
+        
+        // Setup web audio context
+        scriptProcessor = context.createScriptProcessor(buffer_size, numIn, numOut);
+        scriptProcessor.onaudioprocess = compute;
+        
+        if (numIn > 0) {
+            ins = Module._malloc(ptr_size * numIn);
+            for (i = 0; i < numIn; i++) { 
+                HEAP32[(ins >> 2) + i] = Module._malloc(buffer_size * sample_size); 
+            }
+            
+            // Prepare Ins buffer tables
+            var dspInChans = HEAP32.subarray(ins >> 2, (ins + numIn * ptr_size) >> 2);
+            for (i = 0; i < numIn; i++) {
+                dspInChannnels[i] = HEAPF32.subarray(dspInChans[i] >> 2, (dspInChans[i] + buffer_size * sample_size) >> 2);
+            }
+        }
+        
+        if (numOut > 0) {
+        
+            outs = Module._malloc(ptr_size * numOut); 
+            for (i = 0; i < numOut; i++) { 
+                HEAP32[(outs >> 2) + i] = Module._malloc(buffer_size * sample_size);
+            }
+           
+            // Prepare Outs buffer tables
+            var dspOutChans = HEAP32.subarray(outs >> 2, (outs + numOut * ptr_size) >> 2);
+            for (i = 0; i < numOut; i++) {
+                dspOutChannnels[i] = HEAPF32.subarray(dspOutChans[i] >> 2, (dspOutChans[i] + buffer_size * sample_size) >> 2);
+            }
+        }
+                                
+        // bargraph
+        parse_ui(JSON.parse(Pointer_stringify(DSP_getJSON(ptr))).ui);
+    }
+    
+    init();
+    
+    // External API
+    return {
+    
+        getNumInputs : function () 
+        {
+            return DSP_getNumInputs(ptr);
+        },
+        
+        getNumOutputs : function() 
+        {
+            return DSP_getNumOutputs(ptr);
+        },
+                
+        destroy : function ()
+        {
+            DSP_destructor(ptr);
+            
+            if (numIn > 0) {
+                for (var i = 0; i < numIn; i++) { 
+                    Module._free(HEAP32[(ins >> 2) + i]); 
+                }
+                Module._free(ins);
+            }
+             
+            if (numOut > 0) {
+                for (var i = 0; i < numOut; i++) { 
+                    Module._free(HEAP32[(outs >> 2) + i]);
+                }
+                Module._free(outs);
+            }
+            
+            Module._free(path_ptr);
+        },
+        
+        // Connect/disconnect to another node
+        connect : function (node) 
+        {
+            if (node.getProcessor !== undefined) {
+                scriptProcessor.connect(node.getProcessor());
+            } else {
+                scriptProcessor.connect(node);
+            }
+        },
+
+        disconnect : function (node) 
+        {
+            if (node.getProcessor !== undefined) {
+                scriptProcessor.disconnect(node.getProcessor());
+            } else {
+                scriptProcessor.disconnect(node);
+            }
+        },
+    
+        setHandler: function (hd)
+        {
+            handler = hd;
+        },
+       
+        start : function () 
+        {
+            scriptProcessor.connect(context.destination);
+        },
+        
+        stop : function () 
+        {
+            scriptProcessor.disconnect(context.destination);
+        },
+        
+        setValue : function (path, val) 
+        {
+            Module.writeStringToMemory(path, path_ptr);
+            DSP_setValue(ptr, path_ptr, val);
+        },
+        
+        getValue : function (path) 
+        {
+            Module.writeStringToMemory(path, path_ptr);
+            return DSP_getValue(ptr, path_ptr);
+        },
+         
+        json : function ()
+        {
+            return Pointer_stringify(DSP_getJSON(ptr));
+        },
+        
+        controls : function ()
+        {
+            return inputs_items;
+        },
+        
+        getProcessor : function ()
+        {
+            return scriptProcessor;
+        }
+    };
+};
+
diff --git a/architecture/webaudio/webaudio-asm-footer.html b/architecture/webaudio/webaudio-asm-footer.html
new file mode 100644
index 0000000..69d747d
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm-footer.html
@@ -0,0 +1,120 @@
+
+
+<script>
+
+var isWebKitAudio = (typeof (webkitAudioContext) !== "undefined");
+var audio_context = (isWebKitAudio) ? new webkitAudioContext() : new AudioContext();
+var audio_input = null;
+var DSP = null;
+var faustsvg = null;
+var dsp_code = null;
+
+function changeBufferSize(buffer_size)
+{
+    var new_buffer_size = buffer_size.options[buffer_size.selectedIndex].value;
+    console.log(new_buffer_size);
+    startNewDSP(new_buffer_size);
+}
+ 
+// Audio input handling
+
+function activateAudioInput()
+{
+    if (!navigator.getUserMedia) {
+        navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
+    }
+   
+    if (navigator.getUserMedia) {
+        navigator.getUserMedia({audio:true}, getDevice, function(e) {
+                alert('Error getting audio input');
+                console.log(e);
+        });
+    } else {
+        alert('Audio input API not available');
+    }
+}
+
+function getDevice(device) 
+{
+    // Create an AudioNode from the stream.
+    audio_input = audio_context.createMediaStreamSource(device);
+    
+    // Connect it to the destination.
+    audio_input.connect(DSP.getProcessor());
+}
+
+function startDSPAux(buffer_size) 
+{
+    console.log("startDSP %d", buffer_size);
+    if (DSP) {
+        if (audio_input) {
+            audio_input.disconnect(DSP.getProcessor());
+        }
+        _f4u$t.hard_delete(faustsvg);
+        DSP.stop();
+        DSP.destroy();
+    }
+    DSP = faust.DSP(audio_context, buffer_size);
+    if (DSP.getNumInputs() > 0) {
+        activateAudioInput();
+    }
+    DSP.start();
+    console.log(DSP.json());
+    console.log(DSP.controls());
+    
+    // kludge...ideally, this needs to not be part of the imported JS
+    _f4u$t.main_loop = function() {}
+    
+    faustsvg = $('<div />');
+    $('body').append(faustsvg);
+    var handler = _f4u$t.main(DSP.json(), faustsvg, DSP.setValue);
+    DSP.setHandler(handler);
+}
+
+function startDSP() 
+{
+    startDSPAux(1024);
+}
+
+function startNewDSP(buffer_size) 
+{
+    startDSPAux(buffer_size);
+}
+
+// To activate audio on iOS
+window.addEventListener('touchstart', function() {
+
+	// create empty buffer
+	var buffer = audio_context.createBuffer(1, 1, 22050);
+	var source = audio_context.createBufferSource();
+	source.buffer = buffer;
+
+	// connect to output (your speakers)
+	source.connect(audio_context.destination);
+
+	// play the file
+	source.noteOn(0);
+
+}, false);
+
+// General
+
+$(startDSP);
+
+</script>
+
+<P>
+<center>
+<form method="POST" name="menu" >
+  <select name="selectedBuffer" 
+    onChange="changeBufferSize(this.form.selectedBuffer)">
+    <option value = 256> 256 </option>
+    <option value = 512> 512 </option>
+    <option selected value = 1024> 1024 </option>
+    <option value = 2048> 2048 </option>
+    <option value = 4096> 4096 </option>
+    <option value = 8192> 8192 </option>
+  </select>
+</form>
+</center>
+
diff --git a/architecture/webaudio/webaudio-asm-poly-emcc.js b/architecture/webaudio/webaudio-asm-poly-emcc.js
new file mode 100644
index 0000000..4f01f3c
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm-poly-emcc.js
@@ -0,0 +1,326 @@
+/*
+ faust2webaudio
+ 
+ Primarily written by Myles Borins
+ During the Spring 2013 offering of Music 420b with Julius Smith
+ A bit during the Summer of 2013 with the help of Joshua Kit Clayton
+ And finally a sprint during the late fall of 2013 to get everything working
+ A Special thanks to Yann Orlarey and Stéphane Letz
+ 
+ faust2webaudio is distributed under the terms the MIT or GPL2 Licenses.
+ Choose the license that best suits your project. The text of the MIT and GPL
+ licenses are at the root directory.
+ 
+ Additional code : GRAME 2014
+*/
+
+'use strict';
+
+var faust = faust || {};
+
+// Polyphonic DSP : has to have 'freq', 'gate', 'gain' parameters to be possibly triggered with keyOn, keyOff events.
+
+var DSP_poly_constructor = Module.cwrap('DSP_poly_constructor', 'number', ['number', 'number']);
+var DSP_poly_destructor = Module.cwrap('DSP_poly_destructor', null, ['number']);
+var DSP_poly_compute = Module.cwrap('DSP_poly_compute', null, ['number', 'number', 'number', 'number']);
+var DSP_poly_getNumInputs = Module.cwrap('DSP_poly_getNumInputs', 'number', ['number']);
+var DSP_poly_getNumOutputs = Module.cwrap('DSP_poly_getNumOutputs', 'number', ['number']);
+var DSP_poly_getJSON = Module.cwrap('DSP_poly_getJSON', 'number', ['number']);
+var DSP_poly_setValue = Module.cwrap('DSP_poly_setValue', null, ['number', 'number', 'number']);
+var DSP_poly_getValue = Module.cwrap('DSP_poly_getValue', 'number', ['number', 'number']);
+var DSP_poly_keyOn = Module.cwrap('DSP_poly_keyOn', null, ['number', 'number', 'number', 'number']);
+var DSP_poly_keyOff = Module.cwrap('DSP_poly_keyOff', null, ['number', 'number', 'number', 'number']);
+var DSP_poly_allNotesOff = Module.cwrap('DSP_poly_allNotesOff', null, ['number']);
+var DSP_poly_ctrlChange = Module.cwrap('DSP_poly_ctrlChange', null, ['number', 'number', 'number', 'number']);
+var DSP_poly_pitchWheel = Module.cwrap('DSP_poly_pitchWheel', null, ['number', 'number', 'number']);
+var DSP_poly_pitchBend = Module.cwrap('DSP_poly_pitchBend', null, ['number', 'number', 'number', 'number']);
+
+faust.DSP_poly = function (context, buffer_size, max_polyphony, callback) {
+  
+    var handler = null;
+    var ins, outs;
+    var numIn, numOut;
+    var compute_callback = callback;
+    
+    var scriptProcessor;
+    
+    var dspInChannnels = [];
+    var dspOutChannnels = [];
+    
+    // Path string
+    var path_ptr = Module._malloc(512);
+    
+    // bargraph
+    var ouputs_timer = 5;
+    var ouputs_items = [];
+    
+    // input items
+    var inputs_items = [];
+    
+    var ptr = DSP_poly_constructor(context.sampleRate, max_polyphony);
+     
+    function update_outputs () 
+    {
+        if (ouputs_items.length > 0 && handler && ouputs_timer-- === 0) {
+            ouputs_timer = 5;
+            for (var i = 0; i < ouputs_items.length; i++) {
+                Module.writeStringToMemory(ouputs_items[i], path_ptr);
+                handler(ouputs_items[i], DSP_poly_getValue(ptr, path_ptr));
+            }
+        }
+    }
+    
+    // JSON parsing
+    function parse_ui (ui) 
+    {
+        for (var i = 0; i < ui.length; i++) {
+            parse_group(ui[i]);
+        }
+    }
+    
+    function parse_group (group) 
+    {
+        if (group.items) {
+            parse_items(group.items);
+        }
+    }
+    
+    function parse_items (items) 
+    {
+        for (var i = 0; i < items.length; i++) {
+            parse_item(items[i]);
+        }
+    }
+    
+    function parse_item (item) 
+    {
+        if (item.type === "vgroup" || item.type === "hgroup" || item.type === "tgroup") {
+            parse_items(item.items);
+        } else if (item.type === "hbargraph" || item.type === "vbargraph") {
+            // Keep bargraph adresses
+            ouputs_items.push(item.address);
+        } else if (item.type === "vslider" || item.type === "hslider" || item.type === "button" || item.type === "checkbox" || item.type === "nentry") {
+            // Keep inputs adresses
+            inputs_items.push(item.address);
+        }
+    }
+    
+    function compute (e) 
+    {
+        // Read inputs
+        for (var i = 0; i < numIn; i++) {
+            var input = e.inputBuffer.getChannelData(i);
+            var dspInput = dspInChannnels[i];
+            for (var j = 0; j < input.length; j++) {
+                dspInput[j] = input[j];
+            }
+        }
+        
+        // Possibly call an externally given callback (for instance to play a MIDIFile...)
+        if (compute_callback) {
+            compute_callback(buffer_size);
+        }
+        
+        // Compute
+        DSP_poly_compute(ptr, buffer_size, ins, outs);
+        
+        // Update bargraph
+        update_outputs();
+        
+        // Write outputs
+        for (var i = 0; i < numOut; i++) {
+            var output = e.outputBuffer.getChannelData(i);
+            var dspOutput = dspOutChannnels[i];
+            for (var j = 0; j < output.length; j++) {
+                output[j] = dspOutput[j];
+            }
+        }
+    }
+    
+    function init ()
+    {
+        var i;
+        var ptr_size = 4; //assuming pointer in emscripten are 32bits
+        var sample_size = 4;
+        
+        // Get input / output counts
+        numIn = DSP_poly_getNumInputs(ptr);
+        numOut = DSP_poly_getNumOutputs(ptr);
+        
+        // Setup web audio context
+        scriptProcessor = context.createScriptProcessor(buffer_size, numIn, numOut);
+        scriptProcessor.onaudioprocess = compute;
+        
+        if (numIn > 0) {
+            ins = Module._malloc(ptr_size * numIn);
+            for (i = 0; i < numIn; i++) { 
+                HEAP32[(ins >> 2) + i] = Module._malloc(buffer_size * sample_size); 
+            }
+            
+            // Prepare Ins buffer tables
+            var dspInChans = HEAP32.subarray(ins >> 2, (ins + numIn * ptr_size) >> 2);
+            for (i = 0; i < numIn; i++) {
+                dspInChannnels[i] = HEAPF32.subarray(dspInChans[i] >> 2, (dspInChans[i] + buffer_size * sample_size) >> 2);
+            }
+        }
+        
+        if (numOut > 0) {
+        
+            outs = Module._malloc(ptr_size * numOut); 
+            for (i = 0; i < numOut; i++) { 
+                HEAP32[(outs >> 2) + i] = Module._malloc(buffer_size * sample_size);
+            }
+           
+            // Prepare Outs buffer tables
+            var dspOutChans = HEAP32.subarray(outs >> 2, (outs + numOut * ptr_size) >> 2);
+            for (i = 0; i < numOut; i++) {
+                dspOutChannnels[i] = HEAPF32.subarray(dspOutChans[i] >> 2, (dspOutChans[i] + buffer_size * sample_size) >> 2);
+            }
+        }
+        
+        // bargraph
+        parse_ui(JSON.parse(Pointer_stringify(DSP_poly_getJSON(ptr))).ui);
+    }
+    
+    init();
+    
+    // External API
+    return {
+    
+        getNumInputs : function () 
+        {
+            return DSP_poly_getNumInputs(ptr);
+        },
+        
+        getNumOutputs : function() 
+        {
+            return DSP_poly_getNumOutputs(ptr);
+        },
+        
+        keyOn : function (channel, pitch, velocity)
+        {
+            DSP_poly_keyOn(ptr, channel, pitch, velocity);
+        },
+        
+        keyOff : function (channel, pitch, velocity)
+        {
+            DSP_poly_keyOff(ptr, channel, pitch, velocity);
+        },
+        
+        allNotesOff : function ()
+        {
+            DSP_poly_allNotesOff(ptr);
+        },
+        
+        ctrlChange : function (channel, ctrl, value)
+        {
+            DSP_poly_ctrlChange(ptr, channel, ctrl, value);
+        },
+        
+        pitchWheel : function (channel, pitchWheel)
+        {
+            DSP_poly_pitchWheel(ptr, channel, pitchWheel);
+        },
+        
+        pitchBend : function (channel, refPitch, pitch)
+        {
+            DSP_poly_pitchBend(ptr, channel, refPitch, pitch);
+        },
+        
+        destroy : function ()
+        {
+            DSP_poly_destructor(ptr);
+            
+            if (numIn > 0) {
+                for (var i = 0; i < numIn; i++) { 
+                    Module._free(HEAP32[(ins >> 2) + i]); 
+                }
+                Module._free(ins);
+            }
+             
+            if (numOut > 0) {
+                for (var i = 0; i < numOut; i++) { 
+                    Module._free(HEAP32[(outs >> 2) + i]);
+                }
+                Module._free(outs);
+            }
+            
+            Module._free(path_ptr);
+        },
+    
+        // Connect/disconnect to another node
+        connect : function (node) 
+        {
+            if (node.getProcessor !== undefined) {
+                scriptProcessor.connect(node.getProcessor());
+            } else {
+                scriptProcessor.connect(node);
+            }
+        },
+
+        disconnect : function (node) 
+        {
+            if (node.getProcessor !== undefined) {
+                scriptProcessor.disconnect(node.getProcessor());
+            } else {
+                scriptProcessor.disconnect(node);
+            }
+        },
+    
+        setHandler: function (hd)
+        {
+            handler = hd;
+        },
+       
+        start : function () 
+        {
+            scriptProcessor.connect(context.destination);
+        },
+        
+        stop : function () 
+        {
+            scriptProcessor.disconnect(context.destination);
+        },
+        
+        setValue : function (path, val) 
+        {
+            Module.writeStringToMemory(path, path_ptr);
+            DSP_poly_setValue(ptr, path_ptr, val);
+        },
+        
+        getValue : function (path) 
+        {
+            Module.writeStringToMemory(path, path_ptr);
+            return DSP_poly_getValue(ptr, path_ptr);
+        },
+                
+        controls : function ()
+        {
+            return inputs_items;
+        },
+        
+        json : function ()
+        {
+            return Pointer_stringify(DSP_poly_getJSON(ptr));
+        },
+        
+        getSampleRate : function ()
+        {
+            return context.sampleRate;
+        },
+        
+        setComputeCallback : function (callback) {
+            compute_callback = callback;
+        },
+        
+        getComputeCallback : function () {
+            return compute_callback;
+        },
+        
+        getProcessor : function ()
+        {
+            return scriptProcessor;
+        }
+    };
+};
+
diff --git a/architecture/webaudio/webaudio-asm-poly-footer.html b/architecture/webaudio/webaudio-asm-poly-footer.html
new file mode 100644
index 0000000..ad82b40
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm-poly-footer.html
@@ -0,0 +1,207 @@
+
+
+<script>
+
+var isWebKitAudio = (typeof (webkitAudioContext) !== "undefined");
+var audio_context = (isWebKitAudio) ? new webkitAudioContext() : new AudioContext();
+var max_polyphony = 16;
+var audio_input = null;
+var midi_input = [];
+var DSP_poly = null;
+var faustsvg = null;
+
+function changeBufferSize(buffer_size)
+{
+    var new_buffer_size = buffer_size.options[buffer_size.selectedIndex].value;
+    console.log(new_buffer_size);
+    startNewDSP(new_buffer_size);
+}
+
+// MIDI input handling
+
+function keyOn(channel, pitch, velocity)
+{
+    if (DSP_poly) {
+        DSP_poly.keyOn(channel, pitch, velocity);
+    }
+}
+
+function keyOff(channel, pitch)
+{
+    if (DSP_poly) {
+        DSP_poly.keyOff(channel, pitch);
+    }
+}
+
+function pitchWheel(channel, wheel)
+{
+    if (DSP_poly) {
+        DSP_poly.pitchWheel(channel, wheel);
+    }
+}
+
+function ctrlChange(channel, ctrl, value)
+{
+    if (DSP_poly) {
+        DSP_poly.ctrlChange(channel, ctrl, value);
+    }
+}
+
+function midiMessageReceived(ev) 
+{
+    var cmd = ev.data[0] >> 4;
+    var channel = ev.data[0] & 0xf;
+    var data1 = ev.data[1];
+    var data2 = ev.data[2];
+    
+    //console.log(ev);
+
+    if (channel === 9) {
+        return;
+    } else if (cmd === 8 || ((cmd === 9) && (data2 === 0))) { 
+        keyOff(channel, data1);
+    } else if (cmd === 9) {
+        keyOn(channel, data1, data2);
+    } else if (cmd === 11) {
+        ctrlChange(channel, data1, data2);
+    } else if (cmd === 14) {
+        pitchWheel(channel, ((data2 * 128.0 + data1)-8192)/8192.0);
+    }  
+}
+
+function onerrorcallback(error) 
+{
+     console.log(error);
+}
+
+function onsuccesscallbackJazz(access) 
+{
+    var inputs = access.getInputs();
+    for (var i = 0; i <inputs.length; i++) {
+        var input = access.getInput(inputs[i]);
+        midi_input.push(input);
+        input.onmessage = midiMessageReceived;
+    }
+}
+
+function onsuccesscallbackStandard(access) 
+{
+    for (var input of access.inputs.values()) {
+        midi_input.push(input);
+        input.onmidimessage = midiMessageReceived;
+        console.log(input.name);
+    }
+}
+ 
+function activateMIDIInput()
+{
+    console.log("activateMIDIInput");
+    if (typeof (navigator.requestMIDIAccess) !== "undefined") {
+        if (navigator.requestMIDIAccess() != undefined) {
+            navigator.requestMIDIAccess().then(onsuccesscallbackStandard, onerrorcallback);
+        } else{
+            navigator.requestMIDIAccess(onsuccesscallbackJazz, onerrorcallback);
+        }
+     } else {
+        alert("MIDI input cannot be activated, either your browser still does't have it, or you need to explicitly activate it.");
+    }
+}
+
+// Audio input handling
+
+function activateAudioInput()
+{
+    if (!navigator.getUserMedia) {
+        navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
+    }
+   
+    if (navigator.getUserMedia) {
+        navigator.getUserMedia({audio:true}, getDevice, function(e) {
+                alert('Error getting audio input');
+                console.log(e);
+        });
+    } else {
+        alert('Audio input API not available');
+    }
+}
+
+function getDevice(device) 
+{
+    // Create an AudioNode from the stream.
+    audio_input = audio_context.createMediaStreamSource(device);
+    
+    // Connect it to the destination.
+    audio_input.connect(DSP_poly.getProcessor());
+}
+
+function startDSPAux(buffer_size) 
+{
+    activateMIDIInput();
+    if (DSP_poly) {
+        if (audio_input) {
+            audio_input.disconnect(DSP_poly.getProcessor());
+        }
+        _f4u$t.hard_delete(faustsvg);
+        DSP_poly.stop();
+        DSP_poly.destroy();
+    }
+    DSP_poly = faust.DSP_poly(audio_context, buffer_size, max_polyphony);
+    DSP_poly.start();
+    
+    console.log(DSP_poly.json());
+    
+    // kludge...ideally, this needs to not be part of the imported JS
+    _f4u$t.main_loop = function() {}
+    
+    faustsvg = $('<div />');
+    $('body').append(faustsvg);
+    var handler = _f4u$t.main(DSP_poly.json(), faustsvg, DSP_poly.setValue);
+    DSP_poly.setHandler(handler);
+}
+
+function startDSP() 
+{
+    startDSPAux(1024);
+}
+
+function startNewDSP(buffer_size) 
+{
+    startDSPAux(buffer_size);
+}
+
+// To activate audio on iOS
+window.addEventListener('touchstart', function() {
+
+	// create empty buffer
+	var buffer = audio_context.createBuffer(1, 1, 22050);
+	var source = audio_context.createBufferSource();
+	source.buffer = buffer;
+
+	// connect to output (your speakers)
+	source.connect(audio_context.destination);
+
+	// play the file
+	source.noteOn(0);
+
+}, false);
+
+// Polyphonic instrument
+
+$(startDSP);
+
+</script>
+
+<P>
+<center>
+<form method="POST" name="menu" >
+  <select name="selectedBuffer" 
+    onChange="changeBufferSize(this.form.selectedBuffer)">
+    <option value = 256 > 256 </option>
+    <option value = 512> 512 </option>
+    <option selected value = 1024> 1024 </option>
+    <option value = 2048> 2048 </option>
+    <option value = 4096> 4096 </option>
+    <option value = 8192> 8192 </option>
+  </select>
+</form>
+</center>
diff --git a/architecture/webaudio/webaudio-asm-poly.cpp b/architecture/webaudio/webaudio-asm-poly.cpp
new file mode 100644
index 0000000..69d7d3e
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm-poly.cpp
@@ -0,0 +1,81 @@
+/*
+ faust2webaudio
+ 
+ Primarily written by Myles Borins
+ During the Spring 2013 offering of Music 420b with Julius Smith
+ A bit during the Summer of 2013 with the help of Joshua Kit Clayton
+ And finally a sprint during the late fall of 2013 to get everything working
+ A Special thanks to Yann Orlarey and Stéphane Letz
+ 
+ faust2webaudio is distributed under the terms the MIT or GPL2 Licenses.
+ Choose the license that best suits your project. The text of the MIT and GPL
+ licenses are at the root directory.
+ 
+ Additional code : GRAME 2014
+
+*/
+
+// Adapted From https://gist.github.com/camupod/5640386
+// compile using "C" linkage to avoid name obfuscation
+
+#include <emscripten.h>
+#include <vector>
+#include <map>
+#include <string>
+#include <math.h>
+
+#include "faust/gui/JSONUI.h"
+#include "faust/gui/MapUI.h"
+#include "faust/audio/dsp.h"
+
+// "mydsp" part will be replaced by the actual '-cn' parameter
+
+// Usage : faust -i -uim -a webaudio/webaudio-asm-poly.cpp -cn karplus karplus.dsp -o karplus.cpp
+
+inline int max(unsigned int a, unsigned int b) { return (a>b) ? a : b; }
+inline int max(int a, int b)	{ return (a>b) ? a : b; }
+
+inline long max(long a, long b) { return (a>b) ? a : b; }
+inline long max(int a, long b) 	{ return (a>b) ? a : b; }
+inline long max(long a, int b) 	{ return (a>b) ? a : b; }
+
+inline float max(float a, float b) { return (a>b) ? a : b; }
+inline float max(int a, float b) 	{ return (a>b) ? a : b; }
+inline float max(float a, int b) 	{ return (a>b) ? a : b; }
+inline float max(long a, float b) 	{ return (a>b) ? a : b; }
+inline float max(float a, long b) 	{ return (a>b) ? a : b; }
+
+inline double max(double a, double b) 	{ return (a>b) ? a : b; }
+inline double max(int a, double b)      { return (a>b) ? a : b; }
+inline double max(double a, int b)      { return (a>b) ? a : b; }
+inline double max(long a, double b) 	{ return (a>b) ? a : b; }
+inline double max(double a, long b) 	{ return (a>b) ? a : b; }
+inline double max(float a, double b) 	{ return (a>b) ? a : b; }
+inline double max(double a, float b) 	{ return (a>b) ? a : b; }
+
+inline int	min(int a, int b)	{ return (a<b) ? a : b; }
+
+inline long min(long a, long b) { return (a<b) ? a : b; }
+inline long min(int a, long b) 	{ return (a<b) ? a : b; }
+inline long min(long a, int b) 	{ return (a<b) ? a : b; }
+
+inline float min(float a, float b) { return (a<b) ? a : b; }
+inline float min(int a, float b) 	{ return (a<b) ? a : b; }
+inline float min(float a, int b) 	{ return (a<b) ? a : b; }
+inline float min(long a, float b) 	{ return (a<b) ? a : b; }
+inline float min(float a, long b) 	{ return (a<b) ? a : b; }
+
+inline double min(double a, double b) 	{ return (a<b) ? a : b; }
+inline double min(int a, double b)      { return (a<b) ? a : b; }
+inline double min(double a, int b)      { return (a<b) ? a : b; }
+inline double min(long a, double b) 	{ return (a<b) ? a : b; }
+inline double min(double a, long b) 	{ return (a<b) ? a : b; }
+inline double min(float a, double b) 	{ return (a<b) ? a : b; }
+inline double min(double a, float b) 	{ return (a<b) ? a : b; }
+
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+#include "faust/dsp/poly-dsp.h"
+
diff --git a/architecture/webaudio/webaudio-asm.cpp b/architecture/webaudio/webaudio-asm.cpp
new file mode 100644
index 0000000..2fec871
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm.cpp
@@ -0,0 +1,148 @@
+/*
+ faust2webaudio
+ 
+ Primarily written by Myles Borins
+ During the Spring 2013 offering of Music 420b with Julius Smith
+ A bit during the Summer of 2013 with the help of Joshua Kit Clayton
+ And finally a sprint during the late fall of 2013 to get everything working
+ A Special thanks to Yann Orlarey and Stéphane Letz
+ 
+ faust2webaudio is distributed under the terms the MIT or GPL2 Licenses.
+ Choose the license that best suits your project. The text of the MIT and GPL
+ licenses are at the root directory.
+ 
+ Additional code : GRAME 2014
+
+*/
+
+// Adapted From https://gist.github.com/camupod/5640386
+// compile using "C" linkage to avoid name obfuscation
+
+#include <emscripten.h>
+#include <vector>
+#include <map>
+#include <string>
+#include <math.h>
+
+#include "faust/gui/JSONUI.h"
+#include "faust/gui/MapUI.h"
+#include "faust/audio/dsp.h"
+
+// "mydsp" part will be replaced by the actual '-cn' parameter
+
+// Usage : faust -i -uim -a webaudio/webaudio-asm.cpp -cn karplus karplus.dsp -o karplus.cpp
+
+inline int max(unsigned int a, unsigned int b) { return (a>b) ? a : b; }
+inline int max(int a, int b)	{ return (a>b) ? a : b; }
+
+inline long max(long a, long b) { return (a>b) ? a : b; }
+inline long max(int a, long b) 	{ return (a>b) ? a : b; }
+inline long max(long a, int b) 	{ return (a>b) ? a : b; }
+
+inline float max(float a, float b) { return (a>b) ? a : b; }
+inline float max(int a, float b) 	{ return (a>b) ? a : b; }
+inline float max(float a, int b) 	{ return (a>b) ? a : b; }
+inline float max(long a, float b) 	{ return (a>b) ? a : b; }
+inline float max(float a, long b) 	{ return (a>b) ? a : b; }
+
+inline double max(double a, double b) 	{ return (a>b) ? a : b; }
+inline double max(int a, double b)      { return (a>b) ? a : b; }
+inline double max(double a, int b)      { return (a>b) ? a : b; }
+inline double max(long a, double b) 	{ return (a>b) ? a : b; }
+inline double max(double a, long b) 	{ return (a>b) ? a : b; }
+inline double max(float a, double b) 	{ return (a>b) ? a : b; }
+inline double max(double a, float b) 	{ return (a>b) ? a : b; }
+
+inline int	min(int a, int b)	{ return (a<b) ? a : b; }
+
+inline long min(long a, long b) { return (a<b) ? a : b; }
+inline long min(int a, long b) 	{ return (a<b) ? a : b; }
+inline long min(long a, int b) 	{ return (a<b) ? a : b; }
+
+inline float min(float a, float b) { return (a<b) ? a : b; }
+inline float min(int a, float b) 	{ return (a<b) ? a : b; }
+inline float min(float a, int b) 	{ return (a<b) ? a : b; }
+inline float min(long a, float b) 	{ return (a<b) ? a : b; }
+inline float min(float a, long b) 	{ return (a<b) ? a : b; }
+
+inline double min(double a, double b) 	{ return (a<b) ? a : b; }
+inline double min(int a, double b)      { return (a<b) ? a : b; }
+inline double min(double a, int b)      { return (a<b) ? a : b; }
+inline double min(long a, double b) 	{ return (a<b) ? a : b; }
+inline double min(double a, long b) 	{ return (a<b) ? a : b; }
+inline double min(float a, double b) 	{ return (a<b) ? a : b; }
+inline double min(double a, float b) 	{ return (a<b) ? a : b; }
+
+<<includeIntrinsic>>
+
+<<includeclass>>
+
+extern "C" {
+    
+    // Just inherit from both classes...
+    struct mydsp_wrap : public mydsp, public MapUI
+    {
+        std::string fJSON;
+        
+        mydsp_wrap(int sample_rate) 
+        {
+            // Init it with sample_rate supplied...
+            init(sample_rate);
+            buildUserInterface(this);
+            
+            // Creates JSON
+            JSONUI builder(getNumInputs(), getNumOutputs());
+            mydsp::metadata(&builder);
+            buildUserInterface(&builder);
+            fJSON = builder.JSON();
+        }
+        
+        const char* getJSON()
+        {
+            return fJSON.c_str();
+        }
+    };
+    
+    
+    // C like API
+    mydsp_wrap* mydsp_constructor(int sample_rate) 
+    {
+        return new mydsp_wrap(sample_rate);
+    }
+    
+    void mydsp_destructor(mydsp_wrap* n) 
+    {
+        delete n;
+    }
+
+    void mydsp_compute(mydsp_wrap* n, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) 
+    {
+        n->compute(count, inputs, outputs);
+    }
+    
+    int mydsp_getNumInputs(mydsp_wrap* n)
+    {
+        return n->getNumInputs();
+    }
+    
+    int mydsp_getNumOutputs(mydsp_wrap* n)
+    {
+        return n->getNumOutputs();
+    }
+      
+    const char* mydsp_getJSON(mydsp_wrap* n)
+    {
+        return n->getJSON();
+    }
+    
+    void mydsp_setValue(mydsp_wrap* n, const char* path, float value)
+    {
+        n->setValue(path, value);
+    }
+    
+    float mydsp_getValue(mydsp_wrap* n, const char* path)
+    {
+        return n->getValue(path);
+    }
+    
+}
\ No newline at end of file
diff --git a/architecture/webaudio/webaudio-asm.html b/architecture/webaudio/webaudio-asm.html
new file mode 100644
index 0000000..922bf6d
--- /dev/null
+++ b/architecture/webaudio/webaudio-asm.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>FAUST DSP</title>
+        <!-- I am so Meta -->
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <meta name="description" content="FAUST DSP">
+        <meta name="author" content="Myles Borins, GRAME">
+        <!-- OpenGraph Meta -->
+        <meta property="og:title" content="FAUST DSP"/>
+        <!-- <meta property="og:url" content=""/> -->
+        <meta property="og:site_name" content="FAUST DSP"/>
+        <!-- <meta property="og:image" content="Some Image"/> -->
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/jquery-1.7.1.min.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/jquerysvg/jquery.svg.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_load_external_file.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_mobile.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_proto.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_jquery_svg_backend.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_ui_audio_bridge.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_server_communication.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_ui_builder.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_ui_inits.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_ui_interact.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/svg/faust_ui_objects.js"></script>
+        <script  src="file://localhost/usr/local/lib/faust/js/faust_webaudio_tools.js"></script> 
+        <link rel="stylesheet" type="text/css" href="file://localhost/usr/local/lib/faust/js/svg/faust_css.css"></link>
+    </head>
+
+    <body>
+        <script src = "DSP.js"></script>
+        <script>
+        
+        var isWebKitAudio = (typeof (webkitAudioContext) !== "undefined");
+        var context = (isWebKitAudio) ? new webkitAudioContext() : new AudioContext();
+        var buffer_size = 1024;
+        var DSP = faust.DSP(context, buffer_size, _f4u$t.update_value_at_address);
+        DSP.start();
+        console.log(DSP.json());
+        // kludge...ideally, this needs to not be part of the imported JS
+        _f4u$t.main_loop = function() {}
+        _f4u$t.main(DSP.json(), null, DSP.update);
+        </script>
+    </body>
+</html>
diff --git a/architecture/windowsdll.cpp b/architecture/windowsdll.cpp
index 90c9fbc..ed13e62 100644
--- a/architecture/windowsdll.cpp
+++ b/architecture/windowsdll.cpp
@@ -47,9 +47,9 @@
 
 using namespace std;
 
-#include "gui/GUI.h"
-#include "misc.h"
-#include "audio/dsp.h"
+#include "faust/gui/GUI.h"
+#include "faust/misc.h"
+#include "faust/audio/dsp.h"
 
 /********************END ARCHITECTURE SECTION (part 1/2)****************/
 
diff --git a/benchmark/20121009-Bench-Faust-template.ots b/benchmark/20121009-Bench-Faust-template.ots
new file mode 100644
index 0000000..b5ccf8a
Binary files /dev/null and b/benchmark/20121009-Bench-Faust-template.ots differ
diff --git a/benchmark/Makefile b/benchmark/Makefile
index 8b432e9..5d11bf0 100644
--- a/benchmark/Makefile
+++ b/benchmark/Makefile
@@ -12,8 +12,8 @@ MYICCFLAGS := '-O3 -xHost -ftz -fno-alias -fp-model fast=2'
 VSIZE := 1024
 
 all : icc gcc
-icc : ialsascal ialsavec ialsavec2 ialsaomp2 ialsasch ialsasch2
-gcc : galsascal galsavec galsavec2 galsaomp2 galsasch galsasch2
+icc : ialsascal ialsavec ialsavec2 ialsavec4 ialsaomp2 ialsasch ialsasch2
+gcc : galsascal galsavec galsavec2 galsavec4 galsaomp2 galsasch galsasch2
 osx : gcoreaudioscal gcoreaudiovec1 gcoreaudiovec2 gcoreaudiovec3 gcoreaudiovec4 gcoreaudiosch gcoreaudiosch2
 
 
@@ -47,6 +47,10 @@ ialsavec3 :
 	install -d ialsavec3dir
 	$(MAKE) DEST='ialsavec3dir/' ARCH='alsa-gtk-bench.cpp' VEC='-vec -g -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
+ialsavec4 :
+	install -d ialsavec4dir
+	$(MAKE) DEST='ialsavec4dir/' ARCH='alsa-gtk-bench.cpp' VEC='-vec -g -vs 16' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
 ialsaomp :
 	install -d ialsaompdir
 	$(MAKE) DEST='ialsaompdir/' ARCH='alsa-gtk-bench.cpp' VEC='-omp -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
@@ -87,6 +91,10 @@ galsavec3 :
 	install -d galsavec3dir
 	$(MAKE) DEST='galsavec3dir/' ARCH='alsa-gtk-bench.cpp' VEC='-vec -g -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
 
+galsavec4 :
+	install -d galsavec4dir
+	$(MAKE) DEST='galsavec4dir/' ARCH='alsa-gtk-bench.cpp' VEC='-vec -g -vs 16' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
 galsaomp :
 	install -d galsaompdir
 	$(MAKE) DEST='galsaompdir/' ARCH='alsa-gtk-bench.cpp' VEC='-omp -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='g++' CXXFLAGS='-fopenmp '$(MYGCCFLAGS) -f Makefile.compile
diff --git a/benchmark/alsa-gtk-bench.cpp b/benchmark/alsa-gtk-bench.cpp
index aaf828d..62479a4 100644
--- a/benchmark/alsa-gtk-bench.cpp
+++ b/benchmark/alsa-gtk-bench.cpp
@@ -103,7 +103,7 @@ bool setRealtimePriority ()
     uid = getuid ();
     pw = getpwnam ("root");
     setuid (pw->pw_uid); 
-    param.sched_priority = 99; /* 0 to 99  */
+    param.sched_priority = 89; /* 0 to 99  */
     err = sched_setscheduler(0, SCHED_FIFO, &param); 
     setuid (uid);
     return (err != -1);
@@ -399,7 +399,7 @@ class AudioInterface : public AudioParam
 		snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
 		snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
 
-		printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs);
+		//printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs);
 
 		// enregistrement des parametres d'entree-sortie
 		
@@ -1655,8 +1655,12 @@ int main(int argc, char *argv[] )
 	pthread_create(&guithread, NULL, run_ui, interface);
 	
 	bool rt = setRealtimePriority();
-	printf(rt?"RT : ":"NRT: "); audio.shortinfo();
-	if (fopt(argc, argv, "--verbose", "-v")) audio.longinfo();
+	if (rt == false) {
+		cerr << "WARNING : not running with realtime priority" << endl;
+	}
+	if (fopt(argc, argv, "--verbose", "-v")) {
+		audio.longinfo();
+	}
 	bool running = true;
 	audio.write();
 	audio.write();
@@ -1675,6 +1679,9 @@ int main(int argc, char *argv[] )
 #ifdef BENCHMARKMODE
     printstats(argv[0], audio.buffering(), DSP.getNumInputs(), DSP.getNumOutputs());
 #endif       
+	if (fopt(argc, argv, "--verbose", "-v")) {
+		cout << "CLOCKSPERSEC = " << rdtscpersec() << endl;
+	}
 
   	return 0;
 }
diff --git a/benchmark/coreaudio-gtk-bench.cpp b/benchmark/coreaudio-gtk-bench.cpp
index 481df42..be48e9c 100644
--- a/benchmark/coreaudio-gtk-bench.cpp
+++ b/benchmark/coreaudio-gtk-bench.cpp
@@ -24,16 +24,14 @@
 #include <vector>
 #include <algorithm>
 
-#include <AudioToolbox/AudioConverter.h>
-#include <CoreAudio/CoreAudio.h>
-#include <AudioUnit/AudioUnit.h>
-#include <CoreServices/CoreServices.h>
-
+#include "faust/audio/coreaudio-dsp.h"
+#include "faust/gui/FUI.h"
+#include "faust/misc.h"
+#include "faust/gui/faustgtk.h"
 
 using namespace std;
 
 // handle 32/64 bits int size issues
-
 #ifdef __x86_64__
 
 #define uint32	unsigned int
@@ -52,31 +50,10 @@ using namespace std;
 #endif
 
 // check 32/64 bits issues are correctly handled
-
 #define CHECKINTSIZE \
 	assert(sizeof(int32)==4);\
 	assert(sizeof(int64)==8);
 
-
-
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
-    #include <xmmintrin.h>
-    #ifdef __SSE2__
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
-    #else
-        #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
-    #endif
-#else
-    #define AVOIDDENORMALS 
-#endif
-
-//#define BENCHMARKMODE
-
-// g++ -Wall -O3 -lm -lpthread -lasound `gtk-config --cflags --libs` test.cpp -o test
-
 #define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); }
 #define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); }
 #define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); }
@@ -84,32 +61,9 @@ using namespace std;
 #define max(x,y) (((x)>(y)) ? (x) : (y))
 #define min(x,y) (((x)<(y)) ? (x) : (y))
 
-// abs is now predefined
-//template<typename T> T abs (T a)			{ return (a<T(0)) ? -a : a; }
-
-
-inline int		lsr (int x, int n)			{ return int(((unsigned int)x) >> n); }
-
-
-inline int int2pow2 (int x)	{ int r=0; while ((1<<r)<x) r++; return r; }
-
-
-/******************************************************************************
-*******************************************************************************
-
-							       VECTOR INTRINSICS
-
-*******************************************************************************
-*******************************************************************************/
-
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
-
 <<includeIntrinsic>>
 
 #define BENCHMARKMODE
-
 #ifdef BENCHMARKMODE
 
 /**
@@ -124,7 +78,6 @@ static __inline__ uint64 rdtsc(void)
 	} count;
 	
 	__asm__ __volatile__("rdtsc" : "=a" (count.i32[0]), "=d" (count.i32[1]));
-
      return count.i64;
 }
 
@@ -149,16 +102,16 @@ struct timeval 		tv2;
 
 void openMesure()
 {
-	struct timezone 	tz;
+	struct timezone tz;
 	gettimeofday(&tv1, &tz);
-	firstRDTSC  = rdtsc();
+	firstRDTSC = rdtsc();
 }
 
 void closeMesure()
 {
-	struct timezone 	tz;
+	struct timezone tz;
 	gettimeofday(&tv2, &tz);
-	lastRDTSC  = rdtsc();
+	lastRDTSC = rdtsc();
 }
 	
 /**
@@ -180,22 +133,20 @@ int64 rdtscpersec()
         return (lastRDTSC-firstRDTSC) / (tv2.tv_sec - tv1.tv_sec) ;
     }   
 }
-
     
 /**
  * Converts a duration, expressed in RDTSC clocks, into seconds
  */
-double rdtsc2sec( uint64 clk)
+double rdtsc2sec(uint64 clk)
 {
 	return double(clk) / double(rdtscpersec());
 }
 
-double rdtsc2sec( double clk)
+double rdtsc2sec(double clk)
 {
 	return clk / double(rdtscpersec());
 }
 
-    
 /**
  * Converts RDTSC clocks into Megabytes/seconds according to the
  * number of frames processed during the period, the number of channels
@@ -203,9 +154,8 @@ double rdtsc2sec( double clk)
  */
 double megapersec(int frames, int chans, uint64 clk)
 {
-	return double(frames*chans*4)/double(1024*1024*rdtsc2sec(clk));
+	return double(frames) * double(chans) * 4 / double(1024 * 1024 * rdtsc2sec(clk));
 }
-
     
 /**
  * Compute the mean value of a vector of measures
@@ -234,14 +184,20 @@ void printstats(const char* applname, int bsize, int ichans, int ochans)
     sort(V.begin(), V.end());
   
     // Mean of 10 best values (gives relatively stable results)
-    uint64 meavalx = meanValue(V.begin(), V.begin() + 10);			
+    uint64 meaval00 = meanValue(V.begin(), V.begin()+ 5);			
+    uint64 meaval25 = meanValue(V.begin()+KMESURE/4 - 2, V.begin()+KMESURE/4 + 3);			
+    uint64 meaval50 = meanValue(V.begin()+KMESURE/2 - 2, V.begin()+KMESURE/2 + 3);			
+    uint64 meaval75 = meanValue(V.begin()+3*KMESURE/4 - 2, V.begin()+3*KMESURE/4 + 3);			
+    uint64 meaval100 = meanValue(V.end() - 5, V.end());			
   
     //printing
-    cout << megapersec(bsize, ichans+ochans, meavalx) << "\tMB/s"
-         << '\t' << applname
-         << '\t' << "(clocks/sec : " << rdtscpersec() << ")"
+    cout << applname
+         << '\t' << megapersec(bsize, ichans+ochans, meaval00) 
+         << '\t' << megapersec(bsize, ichans+ochans, meaval25) 
+         << '\t' << megapersec(bsize, ichans+ochans, meaval50) 
+         << '\t' << megapersec(bsize, ichans+ochans, meaval75) 
+         << '\t' << megapersec(bsize, ichans+ochans, meaval100) 
          << endl;
-    
 }
 
 #else
@@ -250,1428 +206,137 @@ void printstats(const char* applname, int bsize, int ichans, int ochans)
 #define STOPMESURE
 
 #endif
+		
+<<includeclass>>
 
+bool running = true;
 
+class TMeasureTCoreAudioRenderer : public TCoreAudioRenderer {
 
-/******************************************************************************
-*******************************************************************************
-
-								GRAPHIC USER INTERFACE (v2)
-								  abstract interfaces
-
-*******************************************************************************
-*******************************************************************************/
-
-#include <map>
-#include <list>
-
-using namespace std;
+    protected:
 
-struct Meta : map<const char*, const char*>
-{
-    void declare (const char* key, const char* value) { (*this)[key]=value; }
+        virtual void compute(int inNumberFrames)
+        {
+            STARTMESURE
+            fDSP->compute(inNumberFrames, fInChannel, fOutChannel);
+            STOPMESURE
+            running = mesure <= (KMESURE + KSKIP);
+        }
 };
+                    
+class measure_coreaudio : public audio {
+    
+    TMeasureTCoreAudioRenderer audio_device;
+	long fSampleRate, fFramesPerBuf;
 
-
-struct uiItem;
-typedef void (*uiCallback)(float val, void* data);
-
-/**
- * Graphic User Interface : abstract definition
- */
-
-class UI 
-{
-	typedef list<uiItem*> clist;
-	typedef map<float*, clist*> zmap;
-	
- private:
- 	static list<UI*>	fGuiList;
-	zmap				fZoneMap;
-	bool				fStopped;
-	
  public:
-		
-	UI() : fStopped(false) {	
-		fGuiList.push_back(this);
-	}
-	
-	virtual ~UI() {
-		// suppression de this dans fGuiList
-	}
-
-	// -- zone management
-	
-	void registerZone(float* z, uiItem* c)
-	{
-		if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist();
-		fZoneMap[z]->push_back(c);
-	} 	
-
-	// -- saveState(filename) : save the value of every zone to a file
-	
-	void saveState(const char* filename)	
-	{
-		ofstream f(filename);
-		
-		for (zmap::iterator i=fZoneMap.begin(); i!=fZoneMap.end(); i++) { 
-			f << *(i->first) << ' ';
-		} 
-		
-		f << endl;
-		f.close();
-	}
-
-	// -- recallState(filename) : load the value of every zone from a file
-	
-	void recallState(const char* filename)	
-	{
-		ifstream f(filename);
-		if (f.good()) {
-			for (zmap::iterator i=fZoneMap.begin(); i!=fZoneMap.end(); i++) { 
-				f >> *(i->first);
-			} 
-		}
-		f.close();
-	}
-	
-	void updateAllZones();
-	
-	void updateZone(float* z);
-	
-	static void updateAllGuis()
-	{
-		list<UI*>::iterator g;
-		for (g = fGuiList.begin(); g != fGuiList.end(); g++) {
-			(*g)->updateAllZones();
+			 measure_coreaudio(long srate, long fpb) : fSampleRate(srate), fFramesPerBuf(fpb) {}
+	virtual ~measure_coreaudio() {}
+
+	virtual bool init(const char* /*name*/, dsp* DSP) {
+		DSP->init(fSampleRate);
+		if (audio_device.OpenDefault(DSP, DSP->getNumInputs(), DSP->getNumOutputs(), fFramesPerBuf, fSampleRate) < 0) {
+			printf("Cannot open CoreAudio device\n");
+			return false;
 		}
-	}
-	
-	// -- active widgets
-	
-	virtual void addButton(const char* label, float* zone) = 0;
-	virtual void addToggleButton(const char* label, float* zone) = 0;
-	virtual void addCheckButton(const char* label, float* zone) = 0;
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-	
-	// -- passive widgets
-	
-	virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
-	virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
-	virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-	
-	void addCallback(float* zone, uiCallback foo, void* data);
-	
-	// -- widget's layouts
-	
-	virtual void openFrameBox(const char* label) = 0;
-	virtual void openTabBox(const char* label) = 0;
-	virtual void openHorizontalBox(const char* label) = 0;
-	virtual void openVerticalBox(const char* label) = 0;
-	virtual void closeBox() = 0;
-	
-	virtual void show() = 0;
-	virtual void run() = 0;
-	
-	void stop()		{ fStopped = true; }
-	bool stopped() 	{ return fStopped; }
-
-    virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
-
-/**
- * User Interface Item: abstract definition
- */
-
-class uiItem
-{
-  protected :
-		  
-	UI*		fGUI;
-	float*		fZone;
-	float		fCache;
-	
-	uiItem (UI* ui, float* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321) 
-	{ 
-		ui->registerZone(zone, this); 
-	}
-	
-	
-  public :
-	
-	virtual ~uiItem() {}
+        return true;
+    }
 
-	void modifyZone(float v) 	
-	{ 
-		fCache = v;
-		if (*fZone != v) {
-			*fZone = v;
-			fGUI->updateZone(fZone);
+	virtual bool start() {
+		if (audio_device.Start() < 0) {
+			printf("Cannot start CoreAudio device\n");
+			return false;
 		}
+ 		return true;
 	}
-		  	
-	float			cache()			{ return fCache; }
-	virtual void 	reflectZone() 	= 0;	
-};
-
-
-/**
- * Callback Item
- */
-
-struct uiCallbackItem : public uiItem
-{
-	uiCallback	fCallback;
-	void*		fData;
-	
-	uiCallbackItem(UI* ui, float* zone, uiCallback foo, void* data) 
-			: uiItem(ui, zone), fCallback(foo), fData(data) {}
-	
-	virtual void 	reflectZone() {		
-		float 	v = *fZone;
-		fCache = v; 
-		fCallback(v, fData);	
-	}
-};
-
-/**
- * Update all user items reflecting zone z
- */
-
-inline void UI::updateZone(float* z)
-{
-	float 	v = *z;
-	clist* 	l = fZoneMap[z];
-	for (clist::iterator c = l->begin(); c != l->end(); c++) {
-		if ((*c)->cache() != v) (*c)->reflectZone();
-	}
-}
-
-
-/**
- * Update all user items not up to date
- */
 
-inline void UI::updateAllZones()
-{
-	for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) {
-		float* 	z = m->first;
-		clist*	l = m->second;
-		float	v = *z;
-		for (clist::iterator c = l->begin(); c != l->end(); c++) {
-			if ((*c)->cache() != v) (*c)->reflectZone();
-		}
+	virtual void stop() {
+		audio_device.Stop();
+		audio_device.Close();
 	}
-}
-
-inline void UI::addCallback(float* zone, uiCallback foo, void* data) 
-{ 
-	new uiCallbackItem(this, zone, foo, data); 
-};
-
-
-/******************************************************************************
-*******************************************************************************
-
-								GRAPHIC USER INTERFACE
-								  gtk interface
-
-*******************************************************************************
-*******************************************************************************/
-
-#include <gtk/gtk.h>
-
-#define stackSize 256
 
-// Insertion modes
-
-#define kSingleMode 0
-#define kBoxMode 1
-#define kTabMode 2
-
-
-class GTKUI : public UI
-{
- private :
- 	static bool			fInitialized;
- 	static list<UI*>	fGuiList;
-	
- protected :
-	GtkWidget* 	fWindow;
-	int			fTop;
-	GtkWidget* 	fBox[stackSize];
-	int 		fMode[stackSize];
-	bool		fStopped;
-
-	GtkWidget* addWidget(const char* label, GtkWidget* w);
-	virtual void pushBox(int mode, GtkWidget* w);
-
-		
- public :
-	
- 	static const gboolean expand = TRUE;
-	static const gboolean fill = TRUE;
-	static const gboolean homogene = FALSE;
-		 
-	GTKUI(char * name, int* pargc, char*** pargv);
-	
-	// -- layout groups
-	
-	virtual void openFrameBox(const char* label);	
-	virtual void openTabBox(const char* label = "");
-	virtual void openHorizontalBox(const char* label = "");
-	virtual void openVerticalBox(const char* label = "");
-	
-	virtual void closeBox();
-	
-	// -- active widgets
-	
-	virtual void addButton(const char* label, float* zone);
-	virtual void addToggleButton(const char* label, float* zone);
-	virtual void addCheckButton(const char* label, float* zone);
-	virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);	
-	virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);	
-	virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
-	
-	// -- passive display widgets
-	
-	virtual void addNumDisplay(const char* label, float* zone, int precision);
-	virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max);
-	virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
-	virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
-	
-	virtual void show();
-	virtual void run();
-		
 };
 
+mydsp DSP;
 
+list<GUI*> GUI::fGuiList;
 
 /******************************************************************************
 *******************************************************************************
 
-								GRAPHIC USER INTERFACE (v2)
-								  gtk implementation
+								MAIN PLAY THREAD
 
 *******************************************************************************
 *******************************************************************************/
-
-// global static fields
-
-bool		GTKUI::fInitialized = false;
-list<UI*>	UI::fGuiList;
-
-
-
-static gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
-{
-    return FALSE; 
-}
-
-static void destroy_event( GtkWidget *widget, gpointer data )
+		
+// sopt : Scan Command Line string Arguments
+const char* sopt(int argc, char *argv[], const char* longname, const char* shortname, const char* def) 
 {
-    gtk_main_quit ();
+	for (int i=2; i<argc; i++) 
+		if (strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0) 
+			return argv[i];
+	return def;
 }
-
-		 
-GTKUI::GTKUI(char * name, int* pargc, char*** pargv) 
-{
-	if (!fInitialized) {
-		gtk_init(pargc, pargv);
-		fInitialized = true;
-	}
 	
-	fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-	//gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10);
-	gtk_window_set_title (GTK_WINDOW (fWindow), name);
-	gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);
-	gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL);
-
-	fTop = 0;
-	fBox[fTop] = gtk_vbox_new (homogene, 4);
-	fMode[fTop] = kBoxMode;
-	gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]);
-	fStopped = false;
-}
-
-// empilement des boites
-
-void GTKUI::pushBox(int mode, GtkWidget* w)
-{
-	assert(++fTop < stackSize);
-	fMode[fTop] 	= mode;
-	fBox[fTop] 		= w;
-}
-
-void GTKUI::closeBox()
-{
-	assert(--fTop >= 0);
-}
-
-
-// les differentes boites
-
-void GTKUI::openFrameBox(const char* label)
-{
-	GtkWidget * box = gtk_frame_new (label);
-	//gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-			
-	pushBox(kSingleMode, addWidget(label, box));
-}
-
-void GTKUI::openTabBox(const char* label)
-{
-	pushBox(kTabMode, addWidget(label, gtk_notebook_new ()));
-}
-
-void GTKUI::openHorizontalBox(const char* label)
-{	
-	GtkWidget * box = gtk_hbox_new (homogene, 4);
-	gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-			
-	if (fMode[fTop] != kTabMode && label[0] != 0) {
-		GtkWidget * frame = addWidget(label, gtk_frame_new (label));
-		gtk_container_add (GTK_CONTAINER(frame), box);
-		gtk_widget_show(box);
-		pushBox(kBoxMode, box);
-	} else {
-		pushBox(kBoxMode, addWidget(label, box));
-	}
-}
-
-void GTKUI::openVerticalBox(const char* label)
+// fopt : Scan Command Line flag option (without argument), return true if the flag
+bool fopt(int argc, char *argv[], const char* longname, const char* shortname) 
 {
-	GtkWidget * box = gtk_vbox_new (homogene, 4);
-	gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-			
-	if (fMode[fTop] != kTabMode && label[0] != 0) {
-		GtkWidget * frame = addWidget(label, gtk_frame_new (label));
-		gtk_container_add (GTK_CONTAINER(frame), box);
-		gtk_widget_show(box);
-		pushBox(kBoxMode, box);
-	} else {
-		pushBox(kBoxMode, addWidget(label, box));
-	}
-}
-	
-GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w)
-{ 
-	switch (fMode[fTop]) {
-		case kSingleMode	: gtk_container_add (GTK_CONTAINER(fBox[fTop]), w); 							break;
-		case kBoxMode 		: gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0); 				break;
-		case kTabMode 		: gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break;
-	}
-	gtk_widget_show (w);
-	return w;
+	for (int i=1; i<argc; i++) 
+		if (strcmp(argv[i], shortname) == 0 || strcmp(argv[i], longname) == 0) 
+			return true;
+	return false;
 }
-
-// --------------------------- Press button ---------------------------
-
-struct uiButton : public uiItem
-{
-	GtkButton* 	fButton;
-	
-	uiButton (UI* ui, float* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {}
-	
-	static void pressed( GtkWidget *widget, gpointer   data )
-	{
-		uiItem* c = (uiItem*) data;
-		c->modifyZone(1.0);
-	}
-
-	static void released( GtkWidget *widget, gpointer   data )
-	{
-		uiItem* c = (uiItem*) data;
-		c->modifyZone(0.0);
-	}
-
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v; 
-		if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton);
-	}
-};
-
-void GTKUI::addButton(const char* label, float* zone)
-{
-	*zone = 0.0;
-	GtkWidget* 	button = gtk_button_new_with_label (label);
-	addWidget(label, button);
-	
-	uiButton* c = new uiButton(this, zone, GTK_BUTTON(button));
 	
-	gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c);
-	gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c);
-
-}
-
-// ---------------------------	Toggle Buttons ---------------------------
+//-------------------------------------------------------------------------
+// 									MAIN
+//-------------------------------------------------------------------------
 
-struct uiToggleButton : public uiItem
-{
-	GtkToggleButton* fButton;
-	
-	uiToggleButton(UI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
+pthread_t guithread;
 	
-	static void toggled (GtkWidget *widget, gpointer data)
-	{
-    	float	v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; 
-    	((uiItem*)data)->modifyZone(v);
-	}
-
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v; 
-		gtk_toggle_button_set_active(fButton, v > 0.0);	
-	}
-};
-
-void GTKUI::addToggleButton(const char* label, float* zone)
+void* run_ui(void* ptr)
 {
-	*zone = 0.0;
-	GtkWidget* 	button = gtk_toggle_button_new_with_label (label);
-	addWidget(label, button);
-	
-	uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button));
-	gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c);
+	GUI* interface = (GUI*)ptr;
+	interface->run();
+	pthread_exit(0);
+	return 0;
 }
 
-
-// ---------------------------	Check Button ---------------------------
-
-struct uiCheckButton : public uiItem
+int main(int argc, char *argv[])
 {
-	GtkToggleButton* fButton;
-	
-	uiCheckButton(UI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
+	CHECKINTSIZE;
 	
-	static void toggled (GtkWidget *widget, gpointer data)
-	{
-    	float	v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; 
-    	((uiItem*)data)->modifyZone(v);
-	}
-
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v; 
-		gtk_toggle_button_set_active(fButton, v > 0.0);	
-	}
-};
-
-void GTKUI::addCheckButton(const char* label, float* zone)
-{
-	*zone = 0.0;
-	GtkWidget* 	button = gtk_check_button_new_with_label (label);
-	addWidget(label, button);
-	
-	uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button));
-	gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c);
-}
-
-
-// ---------------------------	Adjustmenty based widgets ---------------------------
-
-struct uiAdjustment : public uiItem
-{
-	GtkAdjustment* fAdj;
-	
-	uiAdjustment(UI* ui, float* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {}
-	
-	static void changed (GtkWidget *widget, gpointer data)
-	{
-    	float	v = GTK_ADJUSTMENT (widget)->value; 
-    	((uiItem*)data)->modifyZone(v);
-	}
-
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v; 
-		gtk_adjustment_set_value(fAdj, v);	
-	}
-};
-
-static int precision(double n)
-{
-	if (n < 0.009999) return 3;
-	else if (n < 0.099999) return 2;
-	else if (n < 0.999999) return 1;
-	else return 0;
-}
-
-// -------------------------- Vertical Slider -----------------------------------
-
-void GTKUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
-	*zone = init;
-	GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-	
-	uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-	gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-	
-	GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj));
-	gtk_range_set_inverted (GTK_RANGE(slider), TRUE);
-	gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
-	gtk_widget_set_usize(slider, -1, 160);
-	
-	openFrameBox(label);
-	addWidget(label, slider);
-	closeBox();
-}
-
-// -------------------------- Horizontal Slider -----------------------------------
-
-void GTKUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
-	*zone = init;
-	GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-	
-	uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-	gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-	
-	GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj));
-	gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
-	gtk_widget_set_usize(slider, 160, -1);
-	
-	openFrameBox(label);
-	addWidget(label, slider);
-	closeBox();
-}
-
-
-// ------------------------------ Num Entry -----------------------------------
-
-void GTKUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-{
-	*zone = init;
-	GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step);
-	
-	uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
-	gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-	
-	GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step));
-
-	//gtk_widget_set_usize(slider, 160, -1);
-	openFrameBox(label);
-	addWidget(label, spinner);
-	closeBox();
-}
-
-
-// ==========================	passive widgets ===============================
-
-
-// ------------------------------ Progress Bar -----------------------------------
-
-struct uiBargraph : public uiItem
-{
-	GtkProgressBar*		fProgressBar;
-	float				fMin;
-	float				fMax;
-	
-	uiBargraph(UI* ui, float* zone, GtkProgressBar* pbar, float lo, float hi) 
-			: uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {}
-
-	float scale(float v) 		{ return (v-fMin)/(fMax-fMin); }
-	
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v; 
-		gtk_progress_bar_set_fraction(fProgressBar, scale(v));	
-	}
-};
-
-	
-
-void GTKUI::addVerticalBargraph(const char* label, float* zone, float lo, float hi)
-{
-	GtkWidget* pb = gtk_progress_bar_new();
-	gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP);
-	gtk_widget_set_size_request(pb, 8, -1);
-	new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
-	openFrameBox(label);
-	addWidget(label, pb);
-	closeBox();
-}
-	
-
-void GTKUI::addHorizontalBargraph(const char* label, float* zone, float lo, float hi)
-{
-	GtkWidget* pb = gtk_progress_bar_new();
-	gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT);
-	gtk_widget_set_size_request(pb, -1, 8);
-	new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
-	openFrameBox(label);
-	addWidget(label, pb);
-	closeBox();
-}
-
-
-// ------------------------------ Num Display -----------------------------------
-
-struct uiNumDisplay : public uiItem
-{
-	GtkLabel* fLabel;
-	int	fPrecision;
-	
-	uiNumDisplay(UI* ui, float* zone, GtkLabel* label, int precision) 
-			: uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
-
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v;
-		char s[64]; 
-		if (fPrecision <= 0) { 
-			snprintf(s, 63, "%d", int(v)); 
-		} else if (fPrecision>3) {
-			snprintf(s, 63, "%f", v);
-		} else {
-			const char* format[] = {"%.1f", "%.2f", "%.3f"};
-			snprintf(s, 63, format[fPrecision-1], v);
-		}
-		gtk_label_set_text(fLabel, s);
-	}
-};
-	
-
-void GTKUI::addNumDisplay(const char* label, float* zone, int precision )
-{
-	GtkWidget* lw = gtk_label_new("");
-	new uiNumDisplay(this, zone, GTK_LABEL(lw), precision);
-	openFrameBox(label);
-	addWidget(label, lw);
-	closeBox();
-}
-
-
-// ------------------------------ Text Display -----------------------------------
-
-struct uiTextDisplay : public uiItem
-{
-	GtkLabel* 	fLabel;
-	char**		fNames;
-	float		fMin;
-	float		fMax;
-	int			fNum;
-	
-	
-	uiTextDisplay (UI* ui, float* zone, GtkLabel* label, char* names[], float lo, float hi) 
-			: uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi)  
-	{
-		fNum = 0;
-		while (fNames[fNum] != 0) fNum++;
-	}
-
-	virtual void reflectZone() 	
-	{ 
-		float 	v = *fZone;
-		fCache = v;
-		
-		int idx = int(fNum*(v-fMin)/(fMax-fMin));
-		
-		if 		(idx < 0) 		idx = 0; 
-		else if (idx >= fNum) 	idx = fNum-1;
-				
-		gtk_label_set_text(fLabel, fNames[idx]); 
-	}
-};
-	
-
-void GTKUI::addTextDisplay(const char* label, float* zone, char* names[], float lo, float hi )
-{
-	GtkWidget* lw = gtk_label_new("");
-	new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi);
-	openFrameBox(label);
-	addWidget(label, lw);
-	closeBox();
-}
-
-
-
-void GTKUI::show() 
-{
-	assert(fTop == 0);
-	gtk_widget_show  (fBox[0]);
-	gtk_widget_show  (fWindow);
-}
-
-
-/**
- * Update all user items reflecting zone z
- */
-	
-static gboolean callUpdateAllGuis(gpointer)
-{ 
-	UI::updateAllGuis(); 
-	return TRUE;
-}
-
-
-void GTKUI::run() 
-{
-	assert(fTop == 0);
-	gtk_widget_show  (fBox[0]);
-	gtk_widget_show  (fWindow);
-	gtk_timeout_add(40, callUpdateAllGuis, 0);
-	gtk_main ();
-	stop();
-}
-
-
-/******************************************************************************
-*******************************************************************************
-
-								DSP
-
-*******************************************************************************
-*******************************************************************************/
-
-
-//----------------------------------------------------------------
-//  Definition of a Faust Digital Signal Processor
-//----------------------------------------------------------------
-			
-class dsp {
- protected:
-	int fSamplingFreq;
-        int fThreadNum;
- public:
-	dsp() {}
-	virtual ~dsp() {}
-	
-	virtual int getNumInputs() 										= 0;
-	virtual int getNumOutputs() 									= 0;
-    virtual void buildUserInterface(UI* interface) 					= 0;
-    virtual void init(int samplingRate) 							= 0;
- 	virtual void compute(int len, float** inputs, float** outputs) 	= 0;
- 	virtual void conclude() 										{}
-};
-		
-		
-<<includeclass>>
-
-						
-mydsp	DSP;
-
-
-
-/******************************************************************************
- *******************************************************************************
- 
- COREAUDIO INTERFACE
- 
- *******************************************************************************
- *******************************************************************************/
-
-
-//----------------------------------------------------------------------------
-// 	number of physical input and output channels of the CA device
-//----------------------------------------------------------------------------
-
-int	gDevNumInChans;
-int	gDevNumOutChans;
-
-bool running = true;
-
-//----------------------------------------------------------------------------
-// tables of noninterleaved input and output channels for FAUST
-//----------------------------------------------------------------------------
-
-float* 	gInChannel[256];
-float* 	gOutChannel[256];
-
-#define OPEN_ERR -1
-#define NO_ERR 0
-
-class TCoreAudioRenderer
-{
-
-    private:
-
-		AudioBufferList* fInputData;
-		AudioDeviceID fDeviceID;
-		AudioUnit fAUHAL;
-		
-		OSStatus GetDefaultDevice(int inChan, int outChan, AudioDeviceID* id);
-  
-		static	OSStatus Render(void *inRefCon,
-                               AudioUnitRenderActionFlags *ioActionFlags,
-                               const AudioTimeStamp *inTimeStamp,
-                               UInt32 inBusNumber,
-                               UInt32 inNumberFrames,
-                               AudioBufferList *ioData);
-
-    public:
-
-        TCoreAudioRenderer()
-        {}
-        virtual ~TCoreAudioRenderer()
-        {}
-
-        long OpenDefault(long inChan, long outChan, long bufferSize, long sampleRate);
-        long Close();
-
-        long Start();
-        long Stop();
-
-};
-
-typedef TCoreAudioRenderer * TCoreAudioRendererPtr;
-
-static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
-{
-    printf("- - - - - - - - - - - - - - - - - - - -\n");
-    printf("  Sample Rate:%f\n", inDesc->mSampleRate);
-    printf("  Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID);
-    printf("  Format Flags:%lX\n", inDesc->mFormatFlags);
-    printf("  Bytes per Packet:%ld\n", inDesc->mBytesPerPacket);
-    printf("  Frames per Packet:%ld\n", inDesc->mFramesPerPacket);
-    printf("  Bytes per Frame:%ld\n", inDesc->mBytesPerFrame);
-    printf("  Channels per Frame:%ld\n", inDesc->mChannelsPerFrame);
-    printf("  Bits per Channel:%ld\n", inDesc->mBitsPerChannel);
-    printf("- - - - - - - - - - - - - - - - - - - -\n");
-}
-
-static void printError(OSStatus err)
-{
-    switch (err) {
-        case kAudioHardwareNoError:
-            printf("error code : kAudioHardwareNoError\n");
-            break;
-		case kAudioConverterErr_FormatNotSupported:
-            printf("error code : kAudioConverterErr_FormatNotSupported\n");
-            break;
-        case kAudioConverterErr_OperationNotSupported:
-            printf("error code : kAudioConverterErr_OperationNotSupported\n");
-            break;
-        case kAudioConverterErr_PropertyNotSupported:
-            printf("error code : kAudioConverterErr_PropertyNotSupported\n");
-            break;
-        case kAudioConverterErr_InvalidInputSize:
-            printf("error code : kAudioConverterErr_InvalidInputSize\n");
-            break;
-        case kAudioConverterErr_InvalidOutputSize:
-            printf("error code : kAudioConverterErr_InvalidOutputSize\n");
-            break;
-        case kAudioConverterErr_UnspecifiedError:
-            printf("error code : kAudioConverterErr_UnspecifiedError\n");
-            break;
-        case kAudioConverterErr_BadPropertySizeError:
-            printf("error code : kAudioConverterErr_BadPropertySizeError\n");
-            break;
-        case kAudioConverterErr_RequiresPacketDescriptionsError:
-            printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n");
-            break;
-        case kAudioConverterErr_InputSampleRateOutOfRange:
-            printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n");
-            break;
-        case kAudioConverterErr_OutputSampleRateOutOfRange:
-            printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n");
-            break;
-		case kAudioHardwareNotRunningError:
-            printf("error code : kAudioHardwareNotRunningError\n");
-            break;
-        case kAudioHardwareUnknownPropertyError:
-            printf("error code : kAudioHardwareUnknownPropertyError\n");
-            break;
-        case kAudioHardwareIllegalOperationError:
-            printf("error code : kAudioHardwareIllegalOperationError\n");
-            break;
-        case kAudioHardwareBadDeviceError:
-            printf("error code : kAudioHardwareBadDeviceError\n");
-            break;
-        case kAudioHardwareBadStreamError:
-            printf("error code : kAudioHardwareBadStreamError\n");
-            break;
-        case kAudioDeviceUnsupportedFormatError:
-            printf("error code : kAudioDeviceUnsupportedFormatError\n");
-            break;
-        case kAudioDevicePermissionsError:
-            printf("error code : kAudioDevicePermissionsError\n");
-            break;
-        default:
-            printf("error code : unknown\n");
-            break;
-    }
-}
-
-OSStatus TCoreAudioRenderer::Render(void *inRefCon,
-                                     AudioUnitRenderActionFlags *ioActionFlags,
-                                     const AudioTimeStamp *inTimeStamp,
-                                     UInt32,
-                                     UInt32 inNumberFrames,
-                                     AudioBufferList *ioData)
-{
-    TCoreAudioRendererPtr renderer = (TCoreAudioRendererPtr)inRefCon;
-    AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fInputData);
-    for (int i = 0; i < gDevNumInChans; i++) {
-        gInChannel[i] = (float*)renderer->fInputData->mBuffers[i].mData;
-    }
-    for (int i = 0; i < gDevNumOutChans; i++) {
-        gOutChannel[i] = (float*)ioData->mBuffers[i].mData;
-    }
-    STARTMESURE
-    DSP.compute((int)inNumberFrames, gInChannel, gOutChannel);
-    STOPMESURE	 
- 	running = mesure <= (KMESURE + KSKIP);
-	return 0;
-}
-
-OSStatus TCoreAudioRenderer::GetDefaultDevice(int inChan, int outChan, AudioDeviceID* id)
-{
-    UInt32 theSize = sizeof(UInt32);
-    AudioDeviceID inDefault;
-    AudioDeviceID outDefault;
-	OSStatus res;
-
-    if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
-                                        &theSize, &inDefault)) != noErr)
-        return res;
-
-    if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
-                                        &theSize, &outDefault)) != noErr)
-        return res;
-	
-	// Duplex mode
-	if (inChan > 0 && outChan > 0) {
-		// Get the device only if default input and output are the same
-		if (inDefault == outDefault) {
-			*id = inDefault;
-			return noErr;
-		} else {
-			printf("GetDefaultDevice : error input = %ld and output = %ld are not the same\n", inDefault, outDefault);
-			return kAudioHardwareBadDeviceError;
-		}
-	} else if (inChan > 0) {
-		*id = inDefault;
-		return noErr;
-	} else if (outChan > 0) {
-		*id = outDefault;
-		return noErr;
-	} else {
-		return kAudioHardwareBadDeviceError;
-	}
-	
-	return noErr;
-}
-
-long TCoreAudioRenderer::OpenDefault(long inChan, long outChan, long bufferSize, long samplerate)
-{
-	OSStatus err = noErr;
-    ComponentResult err1;
-    UInt32 outSize;
-    UInt32 enableIO;
-	Boolean isWritable;
-	AudioStreamBasicDescription srcFormat, dstFormat, sampleRate;
-    long in_nChannels, out_nChannels;
-    
-    printf("OpenDefault inChan = %ld outChan = %ld bufferSize = %ld samplerate = %ld\n", inChan, outChan, bufferSize, samplerate);
-	
-	if (GetDefaultDevice(inChan, outChan, &fDeviceID) != noErr) {
-		printf("Cannot open default device\n");
-		return OPEN_ERR;
-	}
-	
-	// Setting buffer size
-    outSize = sizeof(UInt32);
-    err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &bufferSize);
-    if (err != noErr) {
-        printf("Cannot set buffer size %ld\n", bufferSize);
-        printError(err);
-        return OPEN_ERR;
-    }
-
-    // Setting sample rate
-    outSize = sizeof(AudioStreamBasicDescription);
-    err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &outSize, &sampleRate);
-    if (err != noErr) {
-        printf("Cannot get current sample rate\n");
-        printError(err);
-        return OPEN_ERR;
-    }
-
-    if (samplerate != long(sampleRate.mSampleRate)) {
-        sampleRate.mSampleRate = (Float64)(samplerate);
-        err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyStreamFormat, outSize, &sampleRate);
-        if (err != noErr) {
-            printf("Cannot set sample rate = %ld\n", samplerate);
-            printError(err);
-            return OPEN_ERR;
-        }
-    }
-
-    // AUHAL
-    ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
-    Component HALOutput = FindNextComponent(NULL, &cd);
-
-    err1 = OpenAComponent(HALOutput, &fAUHAL);
-    if (err1 != noErr) {
-		printf("Error calling OpenAComponent\n");
-        printError(err1);
-        goto error;
-	}
-
-    err1 = AudioUnitInitialize(fAUHAL);
-    if (err1 != noErr) {
-		printf("Cannot initialize AUHAL unit\n");
-		printError(err1);
-        goto error;
-	}
-    
-    enableIO = 1;
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n");
-        printError(err1);
-        goto error;
-    }
-    
-    enableIO = 1;
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n");
-        printError(err1);
-        goto error;
-    }
-    
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32));
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
-        printError(err1);
-        goto error;
-    }
-
-    err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable);
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 1\n");
-        printError(err1);
-    }
-
-    in_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0;
-    printf("in_nChannels = %ld\n", in_nChannels);
-
-    err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable);
-    if (err1 != noErr) {
-        printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 0\n");
-        printError(err1);
-    }
-
-    out_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0;
-    printf("out_nChannels = %ld\n", out_nChannels);
-
-    /*
-    Just ignore this case : seems to work without any further change...
-     
-    if (outChan > out_nChannels) {
-        printf("This device hasn't required output channels\n");
-        goto error;
-    }
-    if (inChan > in_nChannels) {
-        printf("This device hasn't required input channels\n");
-        goto error;
-    }
-    */
-
-    if (outChan < out_nChannels) {
-        SInt32 chanArr[out_nChannels];
-        for (int i = 0;	i < out_nChannels; i++) {
-            chanArr[i] = -1;
-        }
-        for (int i = 0; i < outChan; i++) {
-            chanArr[i] = i;
-        }
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n");
-            printError(err1);
-        }
-    }
-
-    if (inChan < in_nChannels) {
-        SInt32 chanArr[in_nChannels];
-        for (int i = 0; i < in_nChannels; i++) {
-            chanArr[i] = -1;
-        }
-        for (int i = 0; i < inChan; i++) {
-            chanArr[i] = i;
-        }
-        AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n");
-            printError(err1);
-        }
-    }
-	
-    if (inChan > 0) {
-        outSize = sizeof(AudioStreamBasicDescription);
-        err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-        PrintStreamDesc(&srcFormat);
-        
-        srcFormat.mSampleRate = samplerate;
-        srcFormat.mFormatID = kAudioFormatLinearPCM;
-        srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
-        srcFormat.mBytesPerPacket = sizeof(float);
-        srcFormat.mFramesPerPacket = 1;
-        srcFormat.mBytesPerFrame = sizeof(float);
-        srcFormat.mChannelsPerFrame = inChan;
-        srcFormat.mBitsPerChannel = 32;
-        
-        PrintStreamDesc(&srcFormat);
-        
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-    }
-	
-    if (outChan > 0) {
-        outSize = sizeof(AudioStreamBasicDescription);
-        err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize);
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-        PrintStreamDesc(&dstFormat);
-        
-        dstFormat.mSampleRate = samplerate;
-        dstFormat.mFormatID = kAudioFormatLinearPCM;
-        dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
-        dstFormat.mBytesPerPacket = sizeof(float);
-        dstFormat.mFramesPerPacket = 1;
-        dstFormat.mBytesPerFrame = sizeof(float);
-        dstFormat.mChannelsPerFrame = outChan;
-        dstFormat.mBitsPerChannel = 32;
-        
-        PrintStreamDesc(&dstFormat);
-
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
-            printError(err1);
-        }
-    }
-
-    if (inChan > 0 && outChan == 0) {
-        AURenderCallbackStruct output;
-        output.inputProc = Render;
-        output.inputProcRefCon = this;
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n");
-            printError(err1);
-            goto error;
-        }
-    } else {
-        AURenderCallbackStruct output;
-        output.inputProc = Render;
-        output.inputProcRefCon = this;
-        err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output));
-        if (err1 != noErr) {
-            printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n");
-            printError(err1);
-            goto error;
-        }
-    }
-
-    fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inChan * sizeof(AudioBuffer));
-    if (fInputData == 0) {
-		printf("Cannot allocate memory for input buffers\n");
-        goto error;
-	}
-    fInputData->mNumberBuffers = inChan;
-
-    // Prepare buffers
-    for (int i = 0; i < inChan; i++) {
-        fInputData->mBuffers[i].mNumberChannels = 1;
-        fInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(float));
-        fInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(float);
-    }
- 	
-    return NO_ERR;
-
-error:
-    AudioUnitUninitialize(fAUHAL);
-    CloseComponent(fAUHAL);
-    return OPEN_ERR;
-}
-
-long TCoreAudioRenderer::Close()
-{
-    for (int i = 0; i < gDevNumInChans; i++) {
-        free(fInputData->mBuffers[i].mData);
-    }
-	free(fInputData);
-	AudioUnitUninitialize(fAUHAL);
-    CloseComponent(fAUHAL);
-    return NO_ERR;
-}
-
-long TCoreAudioRenderer::Start()
-{
-	OSStatus err = AudioOutputUnitStart(fAUHAL);
-  
-    if (err != noErr) {
-        printf("Error while opening device : device open error \n");
-        return OPEN_ERR;
-    } else {
-        return NO_ERR;
-	}
-}
-
-long TCoreAudioRenderer::Stop()
-{
-    OSStatus err = AudioOutputUnitStop(fAUHAL);
-
-    if (err != noErr) {
-        printf("Error while closing device : device close error \n");
-        return OPEN_ERR;
-    } else {
-        return NO_ERR;
-	}
-}
-
-
-/******************************************************************************
-*******************************************************************************
-
-								MAIN PLAY THREAD
-
-*******************************************************************************
-*******************************************************************************/
-	
-// lopt : Scan Command Line long int Arguments
-
-/*
-long lopt (int argc, char *argv[], const char* longname, const char* shortname, long def) 
-{
-	for (int i=2; i<argc; i++) 
-		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 ) 
-			return atoi(argv[i]);
-	return def;
-}
-*/
-
-long lopt (char *argv[], const char *name, long def) 
-{
-	int	i;
-	for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
-	return def;
-}
-	
-// sopt : Scan Command Line string Arguments
-
-const char* sopt (int argc, char *argv[], const char* longname, const char* shortname, const char* def) 
-{
-	for (int i=2; i<argc; i++) 
-		if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 ) 
-			return argv[i];
-	return def;
-}
-	
-// fopt : Scan Command Line flag option (without argument), return true if the flag
-
-bool fopt (int argc, char *argv[], const char* longname, const char* shortname) 
-{
-	for (int i=1; i<argc; i++) 
-		if ( strcmp(argv[i], shortname) == 0 || strcmp(argv[i], longname) == 0 ) 
-			return true;
-	return false;
-}
-	
-
-//-------------------------------------------------------------------------
-// 									MAIN
-//-------------------------------------------------------------------------
-
-pthread_t	guithread;
-	
-void* run_ui(void* ptr)
-{
-	UI* interface = (UI*) ptr;
-	interface->run();
-	pthread_exit(0);
-	return 0;
-}
-
-int main(int argc, char *argv[] )
-{
-	CHECKINTSIZE;
-
-	UI* 	interface = new GTKUI(argv[0], &argc, &argv);
- 	
-	// compute rcfilename to (re)store application state
-	char	rcfilename[256];
-	char* 	home = getenv("HOME");
-	snprintf(rcfilename, 255, "%s/.%src", home, basename(argv[0]));
-    
-    TCoreAudioRenderer audio_device;
-	
-	long srate = (long)lopt(argv, "--frequency", 44100);
-    int	fpb = lopt(argv, "--buffer", 512);
-    
-	AVOIDDENORMALS;
-	
-    DSP.init(srate);
-    DSP.buildUserInterface(interface);
-    
-    gDevNumInChans = DSP.getNumInputs();
-    gDevNumOutChans = DSP.getNumOutputs();
-	
-	interface->recallState(rcfilename);
-   
-	pthread_create(&guithread, NULL, run_ui, interface);
+	// compute rcfilename to (re)store application state
+    char name[256];
+	char rcfilename[256];
+	char* home = getenv("HOME");
+    snprintf(name, 255, "%s", basename(argv[0]));
+	snprintf(rcfilename, 255, "%s/.%src", home, basename(argv[0]));
+    
+	long srate = (long)lopt(argv, "--frequency", 44100);
+    int	fpb = lopt(argv, "--buffer", 512);
+    
+    UI* interface = new GTKUI(argv[0], &argc, &argv);
+ 	
+    DSP.init(srate);
+    DSP.buildUserInterface(interface);
+    
+    pthread_create(&guithread, NULL, run_ui, interface);
 	
     openMesure();
     
-	if (audio_device.OpenDefault(gDevNumInChans, gDevNumOutChans, fpb, srate) < 0) {
-        printf("Cannot open CoreAudio device\n");
-        return 0;
-    }
+    measure_coreaudio audio(srate, fpb);
+    audio.init(name, &DSP);
+    audio.start();
     
-    if (audio_device.Start() < 0) {
-        printf("Cannot start CoreAudio device\n");
-        return 0;
-    }
     while(running) {
         usleep(100000);
     }
 	closeMesure();
-	interface->saveState(rcfilename);
 
 #ifdef BENCHMARKMODE
     printstats(argv[0], fpb, DSP.getNumInputs(), DSP.getNumOutputs());
 #endif       
 
+    audio.stop();
   	return 0;
 }
diff --git a/benchmark/filterseq2x8.dsp b/benchmark/filterseq2x8.dsp
new file mode 100644
index 0000000..0ca8a67
--- /dev/null
+++ b/benchmark/filterseq2x8.dsp
@@ -0,0 +1,4 @@
+import("filter.lib");
+
+// two sequences of 8 lowpass filters
+process = par(j, 2, seq(i, 8, lowpass(3,1000)));
diff --git a/compiler/Makefile.unix b/compiler/Makefile.unix
old mode 100755
new mode 100644
index 22f9b89..b656321
--- a/compiler/Makefile.unix
+++ b/compiler/Makefile.unix
@@ -15,14 +15,20 @@ else
 ARCHFLAGS 	:= 
 endif
 
-##CXXFLAGS ?= -O1 -g -Wall -Wuninitialized 
+## On Windows (mingw32) we must link against the socket library.
+ifneq ($(findstring MINGW32, $(system)),)
+LIBS = -lwsock32
+EXE = .exe
+endif
+
 CXXFLAGS ?= -O3 -Wall -Wuninitialized $(ARCHFLAGS)
 CXXFLAGS += -Wno-parentheses $(addprefix -I, $(subprojects)) -DINSTALL_PREFIX='"$(prefix)"'
+CXXFLAGS += -I../architecture
 
 all : faust
 
 faust : $(objects)
-	$(CXX) $(CXXFLAGS) $(objects) -o faust
+	$(CXX) $(CXXFLAGS) $(objects) -o faust $(LIBS)
 
 
 .PHONY: clean depend ctags parser
@@ -32,7 +38,7 @@ parser :
 	flex -I -oparser/faustlexer.cpp parser/faustlexer.l
 
 clean :
-	rm -f $(objects) faust *.il *.dpi *.spi */*.il */*.dpi */*.spi *~ */*~
+	rm -f $(objects) faust$(EXE) *.il *.dpi *.spi */*.il */*.dpi */*.spi *~ */*~
 	rm -rf doc
 
 depend :
@@ -51,10 +57,11 @@ main.o: tlib/list.hh tlib/shlysis.hh signals/binop.hh signals/sigtype.hh tlib/sm
 main.o: signals/sigtyperules.hh signals/sigprint.hh normalize/simplify.hh normalize/privatise.hh
 main.o: generator/compile_scal.hh generator/compile.hh generator/klass.hh generator/uitree.hh tlib/property.hh
 main.o: parallelize/loop.hh parallelize/graphSorting.hh generator/Text.hh generator/description.hh
-main.o: generator/occurences.hh generator/compile_vect.hh generator/compile_sched.hh propagate/propagate.hh
-main.o: boxes/boxes.hh errors/errormsg.hh boxes/ppbox.hh parser/enrobage.hh evaluate/eval.hh parser/sourcereader.hh
-main.o: evaluate/environment.hh generator/floats.hh documentator/doc.hh draw/schema/schema.h draw/device/device.h
-main.o: draw/drawschema.hh errors/timing.hh
+main.o: ../architecture/faust/gui/JSONUI.h ../architecture/faust/gui/PathUI.h ../architecture/faust/gui/UI.h
+main.o: ../architecture/faust/gui/meta.h generator/occurences.hh generator/compile_vect.hh generator/compile_sched.hh
+main.o: propagate/propagate.hh boxes/boxes.hh errors/errormsg.hh boxes/ppbox.hh parser/enrobage.hh evaluate/eval.hh
+main.o: parser/sourcereader.hh evaluate/environment.hh generator/floats.hh documentator/doc.hh draw/schema/schema.h
+main.o: draw/device/device.h draw/drawschema.hh errors/timing.hh
 boxes/boxcomplexity.o: extended/xtended.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
 boxes/boxcomplexity.o: tlib/list.hh tlib/shlysis.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 boxes/boxcomplexity.o: generator/klass.hh generator/uitree.hh tlib/property.hh parallelize/loop.hh
@@ -74,7 +81,17 @@ boxes/ppbox.o: tlib/list.hh tlib/symbol.hh tlib/tree.hh tlib/node.hh boxes/boxes
 boxes/ppbox.o: tlib/shlysis.hh signals/signals.hh signals/binop.hh boxes/ppbox.hh signals/prim2.hh signals/sigtype.hh
 boxes/ppbox.o: tlib/smartpointer.hh signals/interval.hh extended/xtended.hh generator/klass.hh generator/uitree.hh
 boxes/ppbox.o: tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh signals/sigvisitor.hh
-boxes/ppbox.o: documentator/lateq.hh
+boxes/ppbox.o: documentator/lateq.hh generator/Text.hh
+documentator/doc.o: boxes/ppbox.hh boxes/boxes.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
+documentator/doc.o: tlib/list.hh tlib/shlysis.hh signals/signals.hh signals/binop.hh signals/prim2.hh
+documentator/doc.o: signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh documentator/doc.hh evaluate/eval.hh
+documentator/doc.o: parser/sourcereader.hh evaluate/environment.hh errors/errormsg.hh documentator/doc_Text.hh
+documentator/doc.o: signals/sigprint.hh propagate/propagate.hh parser/enrobage.hh draw/drawschema.hh utils/names.hh
+documentator/doc.o: normalize/simplify.hh normalize/privatise.hh signals/recursivness.hh documentator/lateq.hh
+documentator/doc.o: documentator/doc_compile.hh signals/sigtyperules.hh generator/occurences.hh tlib/property.hh
+documentator/doc.o: generator/Text.hh generator/description.hh generator/uitree.hh documentator/doc_lang.hh
+documentator/doc.o: documentator/doc_notice.hh documentator/doc_autodoc.hh tlib/compatibility.hh utils/files.hh
+documentator/doc_Text.o: documentator/doc_Text.hh tlib/compatibility.hh generator/floats.hh
 documentator/doc_autodoc.o: documentator/doc_autodoc.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh
 documentator/doc_autodoc.o: tlib/num.hh tlib/list.hh tlib/shlysis.hh boxes/boxes.hh signals/signals.hh signals/binop.hh
 documentator/doc_autodoc.o: documentator/doc.hh evaluate/eval.hh parser/sourcereader.hh evaluate/environment.hh
@@ -88,15 +105,6 @@ documentator/doc_compile.o: signals/prim2.hh extended/xtended.hh generator/klass
 documentator/doc_compile.o: parallelize/graphSorting.hh signals/sigvisitor.hh tlib/compatibility.hh signals/ppsig.hh
 documentator/doc_compile.o: utils/names.hh propagate/propagate.hh boxes/boxes.hh documentator/doc.hh evaluate/eval.hh
 documentator/doc_compile.o: parser/sourcereader.hh evaluate/environment.hh documentator/doc_notice.hh
-documentator/doc.o: boxes/ppbox.hh boxes/boxes.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
-documentator/doc.o: tlib/list.hh tlib/shlysis.hh signals/signals.hh signals/binop.hh signals/prim2.hh
-documentator/doc.o: signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh documentator/doc.hh evaluate/eval.hh
-documentator/doc.o: parser/sourcereader.hh evaluate/environment.hh errors/errormsg.hh documentator/doc_Text.hh
-documentator/doc.o: signals/sigprint.hh propagate/propagate.hh parser/enrobage.hh draw/drawschema.hh utils/names.hh
-documentator/doc.o: normalize/simplify.hh normalize/privatise.hh signals/recursivness.hh documentator/lateq.hh
-documentator/doc.o: documentator/doc_compile.hh signals/sigtyperules.hh generator/occurences.hh tlib/property.hh
-documentator/doc.o: generator/Text.hh generator/description.hh generator/uitree.hh documentator/doc_lang.hh
-documentator/doc.o: documentator/doc_notice.hh documentator/doc_autodoc.hh tlib/compatibility.hh
 documentator/doc_lang.o: documentator/doc_lang.hh documentator/doc_notice.hh documentator/doc_autodoc.hh
 documentator/doc_lang.o: documentator/doc_metadatas.hh documentator/lateq.hh parser/enrobage.hh tlib/compatibility.hh
 documentator/doc_metadatas.o: documentator/doc_metadatas.hh documentator/doc.hh tlib/tlib.hh tlib/symbol.hh
@@ -109,7 +117,6 @@ documentator/doc_sharing.o: tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
 documentator/doc_sharing.o: signals/binop.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 documentator/doc_sharing.o: generator/occurences.hh tlib/property.hh documentator/lateq.hh generator/Text.hh
 documentator/doc_sharing.o: documentator/doc_Text.hh generator/description.hh generator/uitree.hh signals/sigprint.hh
-documentator/doc_Text.o: documentator/doc_Text.hh tlib/compatibility.hh generator/floats.hh
 documentator/lateq.o: documentator/lateq.hh generator/Text.hh
 draw/drawschema.o: boxes/boxes.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 draw/drawschema.o: tlib/shlysis.hh signals/signals.hh signals/binop.hh boxes/ppbox.hh signals/prim2.hh
@@ -118,7 +125,7 @@ draw/drawschema.o: draw/device/SVGDev.h draw/device/device.h draw/device/PSDev.h
 draw/drawschema.o: generator/uitree.hh tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh
 draw/drawschema.o: signals/sigvisitor.hh documentator/lateq.hh tlib/occurrences.hh boxes/boxcomplexity.h
 draw/drawschema.o: draw/schema/schema.h draw/drawschema.hh tlib/compatibility.hh utils/names.hh propagate/propagate.hh
-draw/drawschema.o: generator/description.hh
+draw/drawschema.o: generator/description.hh utils/files.hh
 draw/sigToGraph.o: signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 draw/sigToGraph.o: tlib/shlysis.hh signals/binop.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 draw/sigToGraph.o: signals/sigtyperules.hh extended/xtended.hh generator/klass.hh generator/uitree.hh tlib/property.hh
@@ -126,7 +133,7 @@ draw/sigToGraph.o: parallelize/loop.hh parallelize/graphSorting.hh signals/sigvi
 draw/sigToGraph.o: draw/sigToGraph.hh
 errors/errormsg.o: errors/errormsg.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 errors/errormsg.o: tlib/shlysis.hh boxes/boxes.hh signals/signals.hh signals/binop.hh boxes/ppbox.hh
-errors/timing.o: errors/timing.hh
+errors/timing.o: tlib/compatibility.hh errors/timing.hh
 evaluate/environment.o: evaluate/environment.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
 evaluate/environment.o: tlib/list.hh tlib/shlysis.hh errors/errormsg.hh boxes/boxes.hh signals/signals.hh
 evaluate/environment.o: signals/binop.hh boxes/ppbox.hh utils/names.hh propagate/propagate.hh
@@ -240,17 +247,22 @@ extended/tanprim.o: tlib/shlysis.hh signals/sigtype.hh tlib/smartpointer.hh sign
 extended/tanprim.o: generator/uitree.hh tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh
 extended/tanprim.o: signals/sigvisitor.hh signals/signals.hh signals/binop.hh documentator/lateq.hh generator/Text.hh
 extended/tanprim.o: generator/floats.hh
+generator/Text.o: generator/Text.hh tlib/compatibility.hh generator/floats.hh
 generator/compile.o: errors/timing.hh generator/compile.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh
 generator/compile.o: tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/binop.hh generator/klass.hh
 generator/compile.o: signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh generator/uitree.hh tlib/property.hh
 generator/compile.o: parallelize/loop.hh parallelize/graphSorting.hh generator/Text.hh generator/description.hh
-generator/compile.o: generator/floats.hh signals/sigprint.hh signals/ppsig.hh signals/sigtyperules.hh
-generator/compile.o: normalize/simplify.hh normalize/privatise.hh
+generator/compile.o: ../architecture/faust/gui/JSONUI.h ../architecture/faust/gui/PathUI.h
+generator/compile.o: ../architecture/faust/gui/UI.h ../architecture/faust/gui/meta.h generator/floats.hh
+generator/compile.o: signals/sigprint.hh signals/ppsig.hh signals/sigtyperules.hh normalize/simplify.hh
+generator/compile.o: normalize/privatise.hh
 generator/compile_scal.o: generator/compile_scal.hh generator/compile.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh
 generator/compile_scal.o: tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/binop.hh
 generator/compile_scal.o: generator/klass.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 generator/compile_scal.o: generator/uitree.hh tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh
-generator/compile_scal.o: generator/Text.hh generator/description.hh signals/sigtyperules.hh generator/occurences.hh
+generator/compile_scal.o: generator/Text.hh generator/description.hh ../architecture/faust/gui/JSONUI.h
+generator/compile_scal.o: ../architecture/faust/gui/PathUI.h ../architecture/faust/gui/UI.h
+generator/compile_scal.o: ../architecture/faust/gui/meta.h signals/sigtyperules.hh generator/occurences.hh
 generator/compile_scal.o: errors/timing.hh generator/floats.hh signals/sigprint.hh signals/recursivness.hh
 generator/compile_scal.o: normalize/simplify.hh normalize/privatise.hh signals/prim2.hh extended/xtended.hh
 generator/compile_scal.o: signals/sigvisitor.hh documentator/lateq.hh tlib/compatibility.hh signals/ppsig.hh
@@ -260,14 +272,18 @@ generator/compile_sched.o: generator/compile.hh signals/signals.hh tlib/tlib.hh
 generator/compile_sched.o: tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/binop.hh generator/klass.hh
 generator/compile_sched.o: signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh generator/uitree.hh
 generator/compile_sched.o: tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh generator/Text.hh
-generator/compile_sched.o: generator/description.hh signals/sigtyperules.hh generator/occurences.hh generator/floats.hh
-generator/compile_sched.o: signals/ppsig.hh
+generator/compile_sched.o: generator/description.hh ../architecture/faust/gui/JSONUI.h
+generator/compile_sched.o: ../architecture/faust/gui/PathUI.h ../architecture/faust/gui/UI.h
+generator/compile_sched.o: ../architecture/faust/gui/meta.h signals/sigtyperules.hh generator/occurences.hh
+generator/compile_sched.o: generator/floats.hh signals/ppsig.hh
 generator/compile_vect.o: generator/compile_vect.hh generator/compile_scal.hh generator/compile.hh signals/signals.hh
 generator/compile_vect.o: tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 generator/compile_vect.o: tlib/shlysis.hh signals/binop.hh generator/klass.hh signals/sigtype.hh tlib/smartpointer.hh
 generator/compile_vect.o: signals/interval.hh generator/uitree.hh tlib/property.hh parallelize/loop.hh
 generator/compile_vect.o: parallelize/graphSorting.hh generator/Text.hh generator/description.hh
-generator/compile_vect.o: signals/sigtyperules.hh generator/occurences.hh generator/floats.hh signals/ppsig.hh
+generator/compile_vect.o: ../architecture/faust/gui/JSONUI.h ../architecture/faust/gui/PathUI.h
+generator/compile_vect.o: ../architecture/faust/gui/UI.h ../architecture/faust/gui/meta.h signals/sigtyperules.hh
+generator/compile_vect.o: generator/occurences.hh generator/floats.hh signals/ppsig.hh
 generator/contextor.o: generator/contextor.hh
 generator/description.o: generator/description.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh
 generator/description.o: tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/binop.hh tlib/smartpointer.hh
@@ -284,9 +300,9 @@ generator/sharing.o: generator/compile_vect.hh generator/compile_scal.hh generat
 generator/sharing.o: tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh
 generator/sharing.o: signals/binop.hh generator/klass.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 generator/sharing.o: generator/uitree.hh tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh
-generator/sharing.o: generator/Text.hh generator/description.hh signals/sigtyperules.hh generator/occurences.hh
-generator/sharing.o: signals/sigprint.hh
-generator/Text.o: generator/Text.hh tlib/compatibility.hh generator/floats.hh
+generator/sharing.o: generator/Text.hh generator/description.hh ../architecture/faust/gui/JSONUI.h
+generator/sharing.o: ../architecture/faust/gui/PathUI.h ../architecture/faust/gui/UI.h ../architecture/faust/gui/meta.h
+generator/sharing.o: signals/sigtyperules.hh generator/occurences.hh signals/sigprint.hh
 generator/uitree.o: generator/uitree.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 generator/uitree.o: tlib/shlysis.hh
 normalize/aterm.o: normalize/aterm.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
@@ -317,7 +333,7 @@ parallelize/graphSorting.o: parallelize/graphSorting.hh parallelize/loop.hh tlib
 parallelize/graphSorting.o: tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh
 parallelize/loop.o: parallelize/loop.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 parallelize/loop.o: tlib/shlysis.hh
-parser/enrobage.o: parser/enrobage.hh tlib/compatibility.hh
+parser/enrobage.o: parser/enrobage.hh tlib/compatibility.hh parser/sourcefetcher.hh
 parser/faustlexer.o: tlib/tree.hh tlib/symbol.hh tlib/node.hh parser/faustparser.hpp
 parser/faustparser.o: tlib/tree.hh tlib/symbol.hh tlib/node.hh extended/xtended.hh tlib/tlib.hh tlib/num.hh
 parser/faustparser.o: tlib/list.hh tlib/shlysis.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
@@ -325,9 +341,10 @@ parser/faustparser.o: generator/klass.hh generator/uitree.hh tlib/property.hh pa
 parser/faustparser.o: parallelize/graphSorting.hh signals/sigvisitor.hh signals/signals.hh signals/binop.hh
 parser/faustparser.o: documentator/lateq.hh boxes/boxes.hh signals/prim2.hh errors/errormsg.hh parser/sourcereader.hh
 parser/faustparser.o: documentator/doc.hh evaluate/eval.hh evaluate/environment.hh boxes/ppbox.hh
+parser/sourcefetcher.o: tlib/compatibility.hh parser/sourcefetcher.hh
 parser/sourcereader.o: parser/sourcereader.hh boxes/boxes.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh
-parser/sourcereader.o: tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/signals.hh signals/binop.hh parser/enrobage.hh
-parser/sourcereader.o: boxes/ppbox.hh
+parser/sourcereader.o: tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/signals.hh signals/binop.hh
+parser/sourcereader.o: parser/sourcefetcher.hh parser/enrobage.hh boxes/ppbox.hh
 patternmatcher/patternmatcher.o: tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 patternmatcher/patternmatcher.o: tlib/shlysis.hh boxes/boxes.hh signals/signals.hh signals/binop.hh boxes/ppbox.hh
 patternmatcher/patternmatcher.o: evaluate/eval.hh parser/sourcereader.hh evaluate/environment.hh
@@ -341,11 +358,11 @@ propagate/propagate.o: generator/klass.hh generator/uitree.hh tlib/property.hh p
 propagate/propagate.o: parallelize/graphSorting.hh signals/sigvisitor.hh documentator/lateq.hh propagate/labels.hh
 propagate/propagate.o: generator/Text.hh signals/ppsig.hh utils/names.hh
 signals/binop.o: signals/binop.hh tlib/node.hh tlib/symbol.hh
-signals/ppsig.o: signals/ppsig.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
-signals/ppsig.o: tlib/list.hh tlib/shlysis.hh signals/binop.hh signals/prim2.hh signals/sigtype.hh tlib/smartpointer.hh
-signals/ppsig.o: signals/interval.hh extended/xtended.hh generator/klass.hh generator/uitree.hh tlib/property.hh
-signals/ppsig.o: parallelize/loop.hh parallelize/graphSorting.hh signals/sigvisitor.hh documentator/lateq.hh
-signals/ppsig.o: signals/recursivness.hh
+signals/ppsig.o: generator/Text.hh signals/ppsig.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh
+signals/ppsig.o: tlib/tree.hh tlib/num.hh tlib/list.hh tlib/shlysis.hh signals/binop.hh signals/prim2.hh
+signals/ppsig.o: signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh extended/xtended.hh generator/klass.hh
+signals/ppsig.o: generator/uitree.hh tlib/property.hh parallelize/loop.hh parallelize/graphSorting.hh
+signals/ppsig.o: signals/sigvisitor.hh documentator/lateq.hh signals/recursivness.hh
 signals/prim2.o: signals/prim2.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 signals/prim2.o: tlib/shlysis.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 signals/recursivness.o: signals/recursivness.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh
@@ -362,6 +379,7 @@ signals/sigprint.o: signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh
 signals/sigprint.o: tlib/shlysis.hh signals/binop.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
 signals/sigprint.o: signals/sigtyperules.hh
 signals/sigtype.o: tlib/tree.hh tlib/symbol.hh tlib/node.hh signals/sigtype.hh tlib/smartpointer.hh signals/interval.hh
+signals/sigtype.o: tlib/property.hh
 signals/sigtyperules.o: signals/sigtype.hh tlib/tree.hh tlib/symbol.hh tlib/node.hh tlib/smartpointer.hh
 signals/sigtyperules.o: signals/interval.hh signals/sigprint.hh signals/signals.hh tlib/tlib.hh tlib/num.hh
 signals/sigtyperules.o: tlib/list.hh tlib/shlysis.hh signals/binop.hh signals/ppsig.hh signals/prim2.hh
@@ -374,6 +392,7 @@ signals/sigvisitor.o: tlib/smartpointer.hh signals/interval.hh generator/klass.h
 signals/sigvisitor.o: parallelize/loop.hh parallelize/graphSorting.hh documentator/lateq.hh
 signals/subsignals.o: signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
 signals/subsignals.o: tlib/shlysis.hh signals/binop.hh tlib/property.hh
+tlib/compatibility.o: tlib/compatibility.hh
 tlib/list.o: tlib/list.hh tlib/symbol.hh tlib/tree.hh tlib/node.hh tlib/compatibility.hh
 tlib/node.o: tlib/node.hh tlib/symbol.hh
 tlib/occurrences.o: tlib/occurrences.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh tlib/list.hh
@@ -382,14 +401,16 @@ tlib/recursive-tree.o: tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tli
 tlib/shlysis.o: tlib/shlysis.hh tlib/list.hh tlib/symbol.hh tlib/tree.hh tlib/node.hh tlib/compatibility.hh
 tlib/symbol.o: tlib/symbol.hh tlib/compatibility.hh
 tlib/tree.o: tlib/tree.hh tlib/symbol.hh tlib/node.hh
+utils/files.o: utils/files.hh tlib/compatibility.hh
 utils/names.o: signals/ppsig.hh signals/signals.hh tlib/tlib.hh tlib/symbol.hh tlib/node.hh tlib/tree.hh tlib/num.hh
 utils/names.o: tlib/list.hh tlib/shlysis.hh signals/binop.hh utils/names.hh propagate/propagate.hh boxes/boxes.hh
 utils/names.o: tlib/property.hh documentator/doc_Text.hh generator/Text.hh
-draw/device/PSDev.o: draw/device/PSDev.h draw/device/device.h tlib/compatibility.hh
+draw/device/PSDev.o: tlib/compatibility.hh draw/device/PSDev.h draw/device/device.h
 draw/device/SVGDev.o: draw/device/SVGDev.h draw/device/device.h
 draw/schema/blockSchema.o: draw/schema/blockSchema.h draw/schema/schema.h draw/device/device.h
 draw/schema/cableSchema.o: draw/schema/cableSchema.h draw/schema/schema.h draw/device/device.h
 draw/schema/collector.o: draw/schema/schema.h draw/device/device.h
+draw/schema/connectorSchema.o: draw/schema/connectorSchema.h draw/schema/schema.h draw/device/device.h
 draw/schema/cutSchema.o: draw/schema/cutSchema.h draw/schema/schema.h draw/device/device.h
 draw/schema/decorateSchema.o: draw/schema/decorateSchema.h draw/schema/schema.h draw/device/device.h
 draw/schema/enlargedSchema.o: draw/schema/enlargedSchema.h draw/schema/schema.h draw/device/device.h
diff --git a/compiler/boxes/boxcomplexity.cpp b/compiler/boxes/boxcomplexity.cpp
index 01a205e..4cdbaad 100644
--- a/compiler/boxes/boxcomplexity.cpp
+++ b/compiler/boxes/boxcomplexity.cpp
@@ -103,7 +103,9 @@ int computeBoxComplexity (Tree box)
 	// simple elements 
 		 if (xt) 						return 1;
 	else if (isBoxInt(box, &i))			return 1; 
-	else if (isBoxReal(box, &r))		return 1; 
+    else if (isBoxReal(box, &r))		return 1;
+
+    else if (isBoxWaveform(box))        return 1;
 
 	else if (isBoxCut(box))				return 0; 
 	else if (isBoxWire(box))			return 0; 
diff --git a/compiler/boxes/boxes.cpp b/compiler/boxes/boxes.cpp
index 7bf6529..971c5e6 100644
--- a/compiler/boxes/boxes.cpp
+++ b/compiler/boxes/boxes.cpp
@@ -82,6 +82,20 @@ bool isBoxInt(Tree t, int* i)		{ return isInt(t->node(), i);	}
 bool isBoxReal(Tree t, double* r)	{ return isDouble(t->node(), r); }
 
 
+
+/*****************************************************************************
+							 Waveform
+*****************************************************************************/
+
+Sym BOXWAVEFORM = symbol ("BoxWaveform");
+
+Tree boxWaveform (const tvec& br)
+{
+    return tree(BOXWAVEFORM, br);
+}
+
+bool isBoxWaveform (Tree s) 				{ return isTree(s, BOXWAVEFORM); }
+
 /*****************************************************************************
 							   	Wire and Cut
 *****************************************************************************/
@@ -158,6 +172,20 @@ bool isBoxISum(Tree t, Tree& x, Tree& y, Tree& z)		{ return isTree(t, BOXISUM,
 bool isBoxIProd(Tree t, Tree& x, Tree& y, Tree& z)		{ return isTree(t, BOXIPROD, x, y, z);   }
 
 
+/*****************************************************************************
+                        Static information on Boxes
+*****************************************************************************/
+
+Sym BOXINPUTS  = symbol ("BoxInputs");
+Sym BOXOUTPUTS = symbol ("BoxOutputs");
+
+Tree boxInputs(Tree x)                                  { return tree(BOXINPUTS, x); 		}
+Tree boxOutputs(Tree x)                                 { return tree(BOXOUTPUTS, x); 		}
+
+bool isBoxInputs(Tree t, Tree& x)                       { return isTree(t, BOXINPUTS, x);   }
+bool isBoxOutputs(Tree t, Tree& x)                      { return isTree(t, BOXOUTPUTS, x);  }
+
+
 
 /*****************************************************************************
 							  Lambda-Calculus of Boxes
@@ -185,6 +213,7 @@ Tree buildBoxAbstr	(Tree largs, Tree body)
 		return buildBoxAbstr(tl(largs), boxAbstr(hd(largs), body));
 	}
 }
+
 #if 0
 Tree buildBoxAppl 	(Tree fun, Tree revarglist)
 {
@@ -481,6 +510,7 @@ static Tree preparePattern(Tree box)
         else if (isBoxAbstr(box,arg,body))	return box;
         else if (isBoxInt(box))             return box;
         else if (isBoxReal(box, &r))		return box;
+        else if (isBoxWaveform(box)) 		return box;
         else if (isBoxCut(box))				return box;
         else if (isBoxWire(box))			return box;
         else if (isBoxPrim0(box, &p0))		return box;
@@ -513,6 +543,10 @@ static Tree preparePattern(Tree box)
         else if (isBoxISum(box, t1, t2, t3)) 	return boxISum ( t1, t2, preparePattern(t3) );
         else if (isBoxIProd(box, t1, t2, t3)) 	return boxIProd( t1, t2, preparePattern(t3) );
 
+        // static information
+        else if (isBoxInputs(box, t1))          return boxInputs ( preparePattern(t1) );
+        else if (isBoxOutputs(box, t1))         return boxOutputs( preparePattern(t1) );
+
         // user interface
         else if (isBoxButton(box, label))       return box;
         else if (isBoxCheckbox(box, label))     return box;
diff --git a/compiler/boxes/boxes.hh b/compiler/boxes/boxes.hh
index fd52d17..bd8aa85 100644
--- a/compiler/boxes/boxes.hh
+++ b/compiler/boxes/boxes.hh
@@ -77,6 +77,16 @@ bool  isBoxReal(Tree t, double* r);
 
 
 /*****************************************************************************
+							    	Waveform
+	waveform {1,2,3,...}
+	an object with 2 outputs : the size of the waveform, the actual waveform.
+	A Waveform is in is all its values are int. It is float otherwise.
+*****************************************************************************/
+
+Tree boxWaveform(const tvec& br);
+bool  isBoxWaveform(Tree t);
+
+/*****************************************************************************
 							   	Wire and Cut
 *****************************************************************************/
 
@@ -133,6 +143,17 @@ bool isBoxIProd(Tree t, Tree& x, Tree& y, Tree& z);
 
 
 /*****************************************************************************
+                        Static information on Boxes
+*****************************************************************************/
+
+Tree boxInputs  (Tree x);
+Tree boxOutputs (Tree x);
+
+bool isBoxInputs  (Tree t, Tree& x);
+bool isBoxOutputs (Tree t, Tree& x);
+
+
+/*****************************************************************************
 							  Lambda-Calculus of Boxes
 *****************************************************************************/
 
diff --git a/compiler/boxes/boxtype.cpp b/compiler/boxes/boxtype.cpp
index 6ac0704..d5a4897 100644
--- a/compiler/boxes/boxtype.cpp
+++ b/compiler/boxes/boxtype.cpp
@@ -108,6 +108,9 @@ static bool infereBoxType (Tree t, int* inum, int* onum)
 	if (p) 						{ *inum = p->arity(); *onum = 1; }
 	else if (isBoxInt(t)) 		{ *inum = 0; *onum = 1; } 
 	else if (isBoxReal(t)) 		{ *inum = 0; *onum = 1; } 
+	
+	else if (isBoxWaveform(t)) 	{ *inum = 0; *onum = 2; } 
+
 	else if (isBoxWire(t)) 		{ *inum = 1; *onum = 1; }
 	else if (isBoxCut(t)) 		{ *inum = 1; *onum = 0; } 
 
diff --git a/compiler/boxes/ppbox.cpp b/compiler/boxes/ppbox.cpp
index 9464a1e..394c11c 100644
--- a/compiler/boxes/ppbox.cpp
+++ b/compiler/boxes/ppbox.cpp
@@ -27,293 +27,368 @@
 #include "signals.hh"
 #include "prim2.hh"
 #include "xtended.hh"
+#include "Text.hh"
 
+extern int gFloatSize;
 
 const char * prim0name(CTree *(*ptr) ())
 {
-	return "prim0???";
+    return "prim0???";
 }
 
 const char * prim1name(CTree *(*ptr) (CTree *))
 {
-	if (ptr == sigDelay1) return "mem";
-	if (ptr == sigIntCast) return "int";
-	if (ptr == sigFloatCast) return "float";
-	return "prim1???";
+    if (ptr == sigDelay1) return "mem";
+    if (ptr == sigIntCast) return "int";
+    if (ptr == sigFloatCast) return "float";
+    return "prim1???";
 }
 
 const char * prim2name(CTree *(*ptr) (CTree *, CTree *))
 {
-	if (ptr == sigAdd) return "+";
-	if (ptr == sigSub) return "-";
-	if (ptr == sigMul) return "*";
-	if (ptr == sigDiv) return "/";
-	if (ptr == sigRem) return "%";
-
-	if (ptr == sigAND) return "&";
-	if (ptr == sigOR ) return "|";
-	if (ptr == sigXOR) return "^";
-
-	if (ptr == sigLeftShift ) return "<<";
-	if (ptr == sigRightShift) return ">>";
-
-	if (ptr == sigLT) return "<";
-	if (ptr == sigLE) return "<=";
-	if (ptr == sigGT) return ">";
-	if (ptr == sigGE) return ">=";
-	if (ptr == sigEQ) return "==";
-	if (ptr == sigNE) return "!=";
-
-	if (ptr == sigFixDelay) return "@";
-	if (ptr == sigPrefix) 	return "prefix";
-	if (ptr == sigAttach) 	return "attach";
-
-	return "prim2???";
+    if (ptr == sigAdd) return "+";
+    if (ptr == sigSub) return "-";
+    if (ptr == sigMul) return "*";
+    if (ptr == sigDiv) return "/";
+    if (ptr == sigRem) return "%";
+
+    if (ptr == sigAND) return "&";
+    if (ptr == sigOR ) return "|";
+    if (ptr == sigXOR) return "^";
+
+    if (ptr == sigLeftShift ) return "<<";
+    if (ptr == sigRightShift) return ">>";
+
+    if (ptr == sigLT) return "<";
+    if (ptr == sigLE) return "<=";
+    if (ptr == sigGT) return ">";
+    if (ptr == sigGE) return ">=";
+    if (ptr == sigEQ) return "==";
+    if (ptr == sigNE) return "!=";
+
+    if (ptr == sigFixDelay) return "@";
+    if (ptr == sigPrefix) 	return "prefix";
+    if (ptr == sigAttach) 	return "attach";
+
+    return "prim2???";
 }
 
 const char * prim3name(CTree *(*ptr) (CTree *, CTree *, CTree *))
 {
-	if (ptr == sigReadOnlyTable) 	return "rdtable";
-	if (ptr == sigSelect2) 			return "select2";
-	return "prim3???";
+    if (ptr == sigReadOnlyTable) 	return "rdtable";
+    if (ptr == sigSelect2) 			return "select2";
+    return "prim3???";
 }
 
 const char * prim4name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *))
 {
-	if (ptr == sigSelect3) 			return "select3";
-	return "prim4???";
+    if (ptr == sigSelect3) 			return "select3";
+    return "prim4???";
 }
 
 const char * prim5name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *, CTree *))
 {
-	if (ptr == sigWriteReadTable) 	return "wrtable";
-	return "prim5???";
+    if (ptr == sigWriteReadTable) 	return "rwtable";
+    return "prim5???";
 }
 
 
 static void streambinop(ostream& fout, Tree t1, const char* op, Tree t2, int curPriority, int upPriority)
 {
-	if (upPriority > curPriority) fout << '(';
-	fout << boxpp(t1,curPriority) << op << boxpp(t2,curPriority);
-	if (upPriority > curPriority) fout << ')';
+    if (upPriority > curPriority) fout << '(';
+    fout << boxpp(t1,curPriority) << op << boxpp(t2,curPriority);
+    if (upPriority > curPriority) fout << ')';
 }
 
 static void printRule(ostream& fout, Tree rule)
 {
-	Tree lhs = left(rule);
-	Tree rhs = right(rule);
-	char sep = '('; while (!isNil(lhs)) { fout << sep << boxpp(hd(lhs)); sep=','; lhs=tl(lhs); }
-	fout << ") => " << boxpp(rhs) << "; ";
+    Tree lhs = left(rule);
+    Tree rhs = right(rule);
+    char sep = '(';
+    while (!isNil(lhs)) {
+        fout << sep << boxpp(hd(lhs));
+        sep=',';
+        lhs=tl(lhs);
+    }
+    fout << ") => " << boxpp(rhs) << "; ";
 }
 
 /*****************************************************************************
 	 affichage d'une expression box comme en entree
 *****************************************************************************/
 
+static string type2str(int type)
+{
+	switch (type) {
+    
+        case 0:
+            return "int";
+            
+        case 1:
+            return "float";
+            
+        default:
+            return "";
+
+    }
+}	
+
+// if t has a node of type symbol, return its name otherwise error		
+
 ostream& boxpp::print (ostream& fout) const
 {
-	int		i, id;
-	double	r;
-	prim0	p0;
-	prim1	p1;
-	prim2	p2;
-	prim3	p3;
-	prim4	p4;
-	prim5	p5;
-
-	Tree	t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
-			body, fun, args, abstr, genv, vis, lenv, ldef, slot,
-			ident, rules;
-
-	const char* str;
-
-	xtended* xt = (xtended*) getUserData(box);
-
-
-	// primitive elements
-		 if (xt) 						fout << xt->name();
-	else if (isBoxInt(box, &i))			fout << i;
-	else if (isBoxReal(box, &r))		fout << r;
-	else if (isBoxCut(box))				fout << '!';
-	else if (isBoxWire(box))			fout << '_';
-	else if (isBoxIdent(box, &str))		fout << str;
-	else if (isBoxPrim0(box, &p0))		fout << prim0name(p0);
-	else if (isBoxPrim1(box, &p1))		fout << prim1name(p1);
-	else if (isBoxPrim2(box, &p2))		fout << prim2name(p2);
-	else if (isBoxPrim3(box, &p3))		fout << prim3name(p3);
-	else if (isBoxPrim4(box, &p4))		fout << prim4name(p4);
-	else if (isBoxPrim5(box, &p5))		fout << prim5name(p5);
-
-	else if (isBoxAbstr(box,arg,body))	fout << "\\" << boxpp(arg) << ".(" << boxpp(body) << ")";
-	else if (isBoxAppl(box, fun, args))	fout << boxpp(fun) << boxpp(args) ;
-
-	else if (isBoxWithLocalDef(box, body, ldef))	fout << boxpp(body) << " with { " << envpp(ldef) << " }";
-
-	// foreign elements
-	else if (isBoxFFun(box, ff))		fout << "ffunction(" << ffname(ff) << ')';
-    else if (isBoxFConst(box, type, name, file))
-                                        fout << "fconstant(" /*<< tree2str(type) */<< tree2str(name) << ')';
+    int		i, id;
+    double	r;
+    prim0	p0;
+    prim1	p1;
+    prim2	p2;
+    prim3	p3;
+    prim4	p4;
+    prim5	p5;
+
+    Tree	t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
+            body, fun, args, abstr, genv, vis, lenv, ldef, slot,
+            ident, rules;
+
+    const char* str;
+
+    xtended* xt = (xtended*) getUserData(box);
+
+    // primitive elements
+    if (xt) 						fout << xt->name();
+    else if (isBoxInt(box, &i))			fout << i;
+    else if (isBoxReal(box, &r))		fout << T(r);
+    else if (isBoxCut(box))				fout << '!';
+    else if (isBoxWire(box))			fout << '_';
+    else if (isBoxIdent(box, &str))		fout << str;
+    else if (isBoxPrim0(box, &p0))		fout << prim0name(p0);
+    else if (isBoxPrim1(box, &p1))		fout << prim1name(p1);
+    else if (isBoxPrim2(box, &p2))		fout << prim2name(p2);
+    else if (isBoxPrim3(box, &p3))		fout << prim3name(p3);
+    else if (isBoxPrim4(box, &p4))		fout << prim4name(p4);
+    else if (isBoxPrim5(box, &p5))		fout << prim5name(p5);
+
+    else if (isBoxAbstr(box,arg,body))	fout << "\\" << boxpp(arg) << ".(" << boxpp(body) << ")";
+    else if (isBoxAppl(box, fun, args))	fout << boxpp(fun) << boxpp(args) ;
+
+    else if (isBoxWithLocalDef(box, body, ldef))	fout << boxpp(body) << " with { " << envpp(ldef) << " }";
+
+    // foreign elements
+    else if (isBoxFFun(box, ff)) {
+        fout << "ffunction(" << type2str(ffrestype(ff));
+        Tree namelist = nth(ffsignature(ff),1);
+        char sep = ' ';
+        for (int i = 0; i < gFloatSize; i++) {
+            fout << sep << tree2str(nth(namelist,i));
+            sep = '|';
+        }
+        sep = '(';
+        for (int i = 0; i < ffarity(ff); i++) {
+            fout << sep << type2str(ffargtype(ff, i));
+            sep = ',';
+        }
+        fout << ')';
+        fout << ',' << ffincfile(ff) << ',' << fflibfile(ff) << ')';
+    } else if (isBoxFConst(box, type, name, file))
+        fout << "fconstant(" << type2str(tree2int(type)) << ' ' << tree2str(name) << ", " << tree2str(file) << ')';
     else if (isBoxFVar(box, type, name, file))
-                                        fout << "fvariable(" << tree2str(name) << ')';
-
-	// block diagram binary operator
-	else if (isBoxSeq(box, t1, t2))		streambinop(fout, t1, ":", t2, 1, priority);
-	else if (isBoxSplit(box, t1, t2))	streambinop(fout, t1, "<:", t2, 1, priority);
-	else if (isBoxMerge(box, t1, t2)) 	streambinop(fout, t1, ":>", t2, 1, priority);
-	else if (isBoxPar(box, t1, t2)) 	streambinop(fout, t1,",",t2, 2, priority);
-	else if (isBoxRec(box, t1, t2)) 	streambinop(fout, t1,"~",t2, 4, priority);
-
-	// iterative block diagram construction
-	else if (isBoxIPar(box, t1, t2, t3)) 	fout << "par(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
-	else if (isBoxISeq(box, t1, t2, t3)) 	fout << "seq(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
-	else if (isBoxISum(box, t1, t2, t3)) 	fout << "sum(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
-	else if (isBoxIProd(box, t1, t2, t3)) 	fout << "prod(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
-
-	// user interface
-	else if (isBoxButton(box, label))	fout << "button(" << tree2str(label) << ')';
-	else if (isBoxCheckbox(box, label))	fout << "checkbox(" << tree2str(label) << ')';
-	else if (isBoxVSlider(box, label, cur, min, max, step)) 	{
-		fout << "vslider("
-			 << tree2str(label) << ", "
-			 << boxpp(cur) << ", "
-			 << boxpp(min) << ", "
-			 << boxpp(max) << ", "
-			 << boxpp(step)<< ')';
-	}
-	else if (isBoxHSlider(box, label, cur, min, max, step)) 	{
-		fout << "hslider("
-			 << tree2str(label) << ", "
-			 << boxpp(cur) << ", "
-			 << boxpp(min) << ", "
-			 << boxpp(max) << ", "
-			 << boxpp(step)<< ')';
-	}
-	else if (isBoxVGroup(box, label, t1)) {
-		fout << "vgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
-	}
-	else if (isBoxHGroup(box, label, t1)) {
-		fout << "hgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
-	}
-	else if (isBoxTGroup(box, label, t1)) {
-		fout << "tgroup(" << tree2str(label) << ", " << boxpp(t1, 0) << ')';
-	}
-	else if (isBoxHBargraph(box, label, min, max)) 	{
-		fout << "hbargraph("
-			 << tree2str(label) << ", "
-			 << boxpp(min) << ", "
-			 << boxpp(max) << ')';
-	}
-	else if (isBoxVBargraph(box, label, min, max)) 	{
-		fout << "vbargraph("
-			 << tree2str(label) << ", "
-			 << boxpp(min) << ", "
-			 << boxpp(max) << ')';
-	}
-	else if (isBoxNumEntry(box, label, cur, min, max, step)) 	{
-		fout << "nentry("
-			 << tree2str(label) << ", "
-			 << boxpp(cur) << ", "
-			 << boxpp(min) << ", "
-			 << boxpp(max) << ", "
-			 << boxpp(step)<< ')';
-	}
-	else if (isNil(box)) {
-		fout << "()" ;
-	}
-	else if (isList(box)) {
-
-		Tree l = box;
-		char sep = '(';
-
-		do {
-			fout << sep << boxpp(hd(l));
-			sep = ',';
-			l = tl(l);
-		} while (isList(l));
-
-		fout << ')';
-
-	}
-    else if (isBoxEnvironment(box)) {
-        fout << "environment";
+        fout << "fvariable(" << type2str(tree2int(type)) << ' ' << tree2str(name) << ", " << tree2str(file) << ')';
+
+    // block diagram binary operator
+    else if (isBoxSeq(box, t1, t2))		streambinop(fout, t1, " : ", t2, 1, priority);
+    else if (isBoxSplit(box, t1, t2))	streambinop(fout, t1, "<:", t2, 1, priority);
+    else if (isBoxMerge(box, t1, t2)) 	streambinop(fout, t1, ":>", t2, 1, priority);
+    else if (isBoxPar(box, t1, t2)) 	streambinop(fout, t1,",",t2, 2, priority);
+    else if (isBoxRec(box, t1, t2)) 	streambinop(fout, t1,"~",t2, 4, priority);
+
+    // iterative block diagram construction
+    else if (isBoxIPar(box, t1, t2, t3)) 	fout << "par(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
+    else if (isBoxISeq(box, t1, t2, t3)) 	fout << "seq(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
+    else if (isBoxISum(box, t1, t2, t3)) 	fout << "sum(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
+    else if (isBoxIProd(box, t1, t2, t3)) 	fout << "prod(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
+
+    else if (isBoxInputs(box, t1))          fout << "inputs(" << boxpp(t1) << ")";
+    else if (isBoxOutputs(box, t1))         fout << "outputs(" << boxpp(t1) << ")";
+
+    // user interface
+    else if (isBoxButton(box, label))	fout << "button(" << tree2quotedstr(label) << ')';
+    else if (isBoxCheckbox(box, label))	fout << "checkbox(" << tree2quotedstr(label) << ')';
+    else if (isBoxVSlider(box, label, cur, min, max, step)) 	{
+        fout << "vslider("
+             << tree2quotedstr(label) << ", "
+             << boxpp(cur) << ", "
+             << boxpp(min) << ", "
+             << boxpp(max) << ", "
+             << boxpp(step)<< ')';
+    }
+    else if (isBoxHSlider(box, label, cur, min, max, step)) 	{
+        fout << "hslider("
+             << tree2quotedstr(label) << ", "
+             << boxpp(cur) << ", "
+             << boxpp(min) << ", "
+             << boxpp(max) << ", "
+             << boxpp(step)<< ')';
     }
-    else if (isClosure(box, abstr, genv, vis, lenv)) {
+    else if (isBoxVGroup(box, label, t1)) {
+        fout << "vgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')';
+    }
+    else if (isBoxHGroup(box, label, t1)) {
+        fout << "hgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')';
+    }
+    else if (isBoxTGroup(box, label, t1)) {
+        fout << "tgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')';
+    }
+    else if (isBoxHBargraph(box, label, min, max)) 	{
+        fout << "hbargraph("
+             << tree2quotedstr(label) << ", "
+             << boxpp(min) << ", "
+             << boxpp(max) << ')';
+    }
+    else if (isBoxVBargraph(box, label, min, max)) 	{
+        fout << "vbargraph("
+             << tree2quotedstr(label) << ", "
+             << boxpp(min) << ", "
+             << boxpp(max) << ')';
+    }
+    else if (isBoxNumEntry(box, label, cur, min, max, step)) 	{
+        fout << "nentry("
+             << tree2quotedstr(label) << ", "
+             << boxpp(cur) << ", "
+             << boxpp(min) << ", "
+             << boxpp(max) << ", "
+             << boxpp(step)<< ')';
+    }
+    else if (isNil(box)) {
+        fout << "()" ;
+    }
+    else if (isList(box)) {
+
+        Tree l = box;
+        char sep = '(';
+
+        do {
+            fout << sep << boxpp(hd(l));
+            sep = ',';
+            l = tl(l);
+        } while (isList(l));
+
+        fout << ')';
+
+    } else if (isBoxWaveform(box)) {
+    
+        fout << "waveform";
+        char sep = '{';
+        for (int i=0; i<box->arity(); i++) {
+            fout << sep << boxpp(box->branch(i));
+            sep = ',';
+        }
+        fout << '}';
+
+        /*
+        size_t n = box->arity();
+
+        if (n < 6) {
+            // small waveform, print all data
+            fout << "waveform";
+            char sep = '{';
+            for (size_t i=0; i<n; i++) {
+                fout << sep << boxpp(box->branch(i));
+                sep = ',';
+            }
+            fout << '}';
+        } else {
+            // large waveform print only first and last values
+            fout << "waveform{" << box->branch(0) << ", ..<" << n-2 << ">..," << box->branch(n-1) << "}";
+        }
+        */
+
+    } else if (isBoxEnvironment(box)) {
+        fout << "environment";
+
+    } else if (isClosure(box, abstr, genv, vis, lenv)) {
         fout << "closure[" << boxpp(abstr)
-            << ", genv = " << envpp(genv)
-            << ", lenv = " << envpp(lenv)
-            << "]";
+             << ", genv = " << envpp(genv)
+             << ", lenv = " << envpp(lenv)
+             << "]";
+    }
+    else if (isBoxComponent(box, label)) {
+        fout << "component("
+             << tree2quotedstr(label) << ')';
+    }
+    else if (isBoxAccess(box, t1, t2)) {
+        fout << boxpp(t1) << '.' << boxpp(t2);
+    }
+    else if (isImportFile(box, label)) {
+        fout << "import("
+             << tree2quotedstr(label) << ')';
+    }
+    else if (isBoxSlot(box, &id)) {
+        //fout << "#" << id;
+        fout << "x" << id;
+    }
+    else if (isBoxSymbolic(box, slot, body)) {
+        fout << "\\(" << boxpp(slot) << ").(" << boxpp(body) << ")";
+    }
+
+    // Pattern Matching Extensions
+    else if (isBoxCase(box, rules)) {
+        fout << "case {";
+        while (!isNil(rules)) {
+            printRule(fout, hd(rules));
+            rules = tl(rules);
+        }
+        fout << "}";
     }
-	else if (isBoxComponent(box, label)) {
-		fout << "component("
-			<< tree2str(label) << ')';
-	}
-	else if (isBoxAccess(box, t1, t2)) {
-		fout << boxpp(t1) << '.' << boxpp(t2);
-	}
-	else if (isImportFile(box, label)) {
-		fout << "import("
-			<< tree2str(label) << ')';
-	}
-	else if (isBoxSlot(box, &id)) {
-		fout << "#" << id;
-	}
-	else if (isBoxSymbolic(box, slot, body)) {
-		fout << "[" << boxpp(slot) << ">" << boxpp(body) << "]";
-	}
-	
-	// Pattern Matching Extensions
-	else if (isBoxCase(box, rules)) {
-		fout << "case {";
-		while (!isNil(rules)) { printRule(fout, hd(rules)); rules = tl(rules); }
-		fout << "}";	 
-	}
 #if 1
-	// more useful for debugging output
-	else if (isBoxPatternVar(box, ident)) {
-		fout << "<" << boxpp(ident) << ">";	
-	}
+    // more useful for debugging output
+    else if (isBoxPatternVar(box, ident)) {
+        fout << "<" << boxpp(ident) << ">";
+    }
 #else
-	// beautify messages involving lhs patterns
-	else if (isBoxPatternVar(box, ident)) {
-		fout << boxpp(ident);	
-	}
+    // beautify messages involving lhs patterns
+    else if (isBoxPatternVar(box, ident)) {
+        fout << boxpp(ident);
+    }
 #endif
 
-	else if (isBoxPatternMatcher(box)) {
-		fout << "PM[" << box << "]";	
-	}
-
-	else if (isBoxError(box)) {
-		fout << "ERROR";	
-	}
+    else if (isBoxPatternMatcher(box)) {
+        fout << "PM[" << box << "]";
+    }
 
-	
-	// None of the previous tests succeded, then it is not a valid box
-	else {
+    else if (isBoxError(box)) {
+        fout << "ERROR";
+    }
+   
+    //else if (isImportFile(box, filename)) {
+    //    printf("filename %s\n", tree2str(filename));
+    //    fout << tree2quotedstr(filename);
+    //}
+   
+    // None of the previous tests succeded, then it is not a valid box
+    else {
         cerr << "Error in box::print() : " << *box << " is not a valid box" << endl;
-		exit(1);
-	}
+        exit(1);
+    }
 
-	return fout;
+    return fout;
 }
 
-
 /*****************************************************************************
 	 affichage d'un environnement
 *****************************************************************************/
 
 ostream& envpp::print (ostream& fout) const
 {
-		const char* 	sep = "";
-		Tree 	l = fEnv;
-
-		fout << '{';
-		while (isList(l)) {
-			fout << sep << boxpp(hd(hd(l))) << "=" << boxpp(tl(hd(l)));
-			sep = ", ";
-			l = tl(l);
-		}
-		fout << '}';
-	return fout;
+    const char* 	sep = "";
+    Tree 	l = fEnv;
+
+    fout << '{';
+    while (isList(l)) {
+        fout << sep << boxpp(hd(hd(l))) << "=" << boxpp(tl(hd(l)));
+        sep = ", ";
+        l = tl(l);
+    }
+    fout << '}';
+    return fout;
 }
 
diff --git a/compiler/boxes/ppbox.hh b/compiler/boxes/ppbox.hh
index 33eaa14..6280180 100644
--- a/compiler/boxes/ppbox.hh
+++ b/compiler/boxes/ppbox.hh
@@ -57,11 +57,13 @@ const char * prim5name(CTree *(*ptr) (CTree *, CTree *, CTree *, CTree *, CTree
 
 class boxpp
 {
+
+protected:
 	Tree 	box;
 	int		priority;
 public:
 	boxpp(Tree b, int p=0) : box(b), priority(p) {}
-	ostream& print (ostream& fout) const;
+	virtual ostream& print (ostream& fout) const;
 };
 
 inline ostream& operator << (ostream& file, const boxpp& bpp) { return bpp.print(file); }
diff --git a/compiler/compiler.pro b/compiler/compiler.pro
old mode 100755
new mode 100644
index dfa6736..53a5235
--- a/compiler/compiler.pro
+++ b/compiler/compiler.pro
@@ -1,238 +1,227 @@
-# #####################################################################
-# Automatically generated by qmake (2.01a) sam. dc. 12 07:45:30 2009
-# #####################################################################
+######################################################################
+# Automatically generated by qmake (3.0) mar. oct. 21 06:24:19 2014
+######################################################################
+
 TEMPLATE = app
-CONFIG += console \
-    debug
+CONFIG += console debug
+CONFIG -= app_bundle
 TARGET = faust
 OBJECTS_DIR = binaries
-QT -= core \
-    gui
-VERSION = -0.9.10.1
-QMAKE_CXXFLAGS_WARN_ON += -Wno-parentheses \
-    -Wno-unused-parameter
-DEPENDPATH += . \
-    boxes \
-    documentator \
-    draw \
-    errors \
-    evaluate \
-    extended \
-    generator \
-    normalize \
-    parallelize \
-    parser \
-    patternmatcher \
-    propagate \
-    signals \
-    tlib \
-    utils \
-    draw/device \
-    draw/schema
+QT -= core gui
+
+QMAKE_CXXFLAGS_WARN_ON += -Wno-parentheses -Wno-unused-parameter
+
 INCLUDEPATH += . \
-    tlib \
-    signals \
-    normalize \
-    generator \
-    parallelize \
-    propagate \
-    boxes \
-    errors \
-    parser \
-    evaluate \
-    documentator \
-    draw/schema \
-    draw/device \
-    draw \
-    extended \
-    utils \
-    patternmatcher
+			   ../architecture \
+               tlib \
+               signals \
+               normalize \
+               generator \
+               parallelize \
+               propagate \
+               boxes \
+               errors \
+               parser \
+               evaluate \
+               documentator \
+               draw/schema \
+               draw/device \
+               draw \
+               extended \
+               utils \
+               patternmatcher
 
 # Input
 HEADERS += boxes/boxcomplexity.h \
-    boxes/boxes.hh \
-    boxes/ppbox.hh \
-    documentator/doc.hh \
-    documentator/doc_autodoc.hh \
-    documentator/doc_compile.hh \
-    documentator/doc_lang.hh \
-    documentator/doc_notice.hh \
-    documentator/doc_metadatas.hh \
-    documentator/doc_Text.hh \
-    documentator/lateq.hh \
-    draw/drawschema.hh \
-    errors/errormsg.hh \
-    errors/timing.hh \
-    evaluate/eval.hh \
-    evaluate/loopDetector.hh \
-    extended/xtended.hh \
-    generator/compile.hh \
-    generator/compile_scal.hh \
-    generator/compile_vect.hh \
-    generator/compile_sched.hh \
-    generator/contextor.hh \
-    generator/description.hh \
-    generator/floats.hh \
-    generator/klass.hh \
-    generator/occurences.hh \
-    generator/Text.hh \
-    generator/uitree.hh \
-    normalize/aterm.hh \
-    normalize/mterm.hh \
-    normalize/normalize.hh \
-    normalize/privatise.hh \
-    normalize/simplify.hh \
-    parallelize/colorize.h \
-    parallelize/graphSorting.hh \
-    parallelize/loop.hh \
-    parser/enrobage.hh \
-    parser/faustparser.hpp \
-    parser/sourcereader.hh \
-    patternmatcher/patternmatcher.hh \
-    propagate/labels.hh \
-    propagate/propagate.hh \
-    signals/binop.hh \
-    signals/interval.hh \
-    signals/ppsig.hh \
-    signals/prim2.hh \
-    signals/recursivness.hh \
-    signals/signals.hh \
-    signals/sigorderrules.hh \
-    signals/sigprint.hh \
-    signals/sigtype.hh \
-    signals/sigtyperules.hh \
-    signals/sigvisitor.hh \
-    tlib/compatibility.hh \
-    tlib/list.hh \
-    tlib/node.hh \
-    tlib/num.hh \
-    tlib/occurrences.hh \
-    tlib/property.hh \
-    tlib/shlysis.hh \
-    tlib/smartpointer.hh \
-    tlib/symbol.hh \
-    tlib/tlib.hh \
-    tlib/tree.hh \
-    utils/names.hh \
-    draw/device/device.h \
-    draw/device/devLib.h \
-    draw/device/PSDev.h \
-    draw/device/SVGDev.h \
-    draw/schema/blockSchema.h \
-    draw/schema/cableSchema.h \
-    draw/schema/cutSchema.h \
-    draw/schema/decorateSchema.h \
-    draw/schema/enlargedSchema.h \
-    draw/schema/mergeSchema.h \
-    draw/schema/parSchema.h \
-    draw/schema/recSchema.h \
-    draw/schema/schema.h \
-    draw/schema/seqSchema.h \
-    draw/schema/splitSchema.h \
-    draw/schema/topSchema.h \
-    evaluate/environment.hh \
-    draw/schema/inverterSchema.h \
-    draw/sigToGraph.hh
+           boxes/boxes.hh \
+           boxes/ppbox.hh \
+           documentator/doc.hh \
+           documentator/doc_autodoc.hh \
+           documentator/doc_compile.hh \
+           documentator/doc_lang.hh \
+           documentator/doc_metadatas.hh \
+           documentator/doc_notice.hh \
+           documentator/doc_Text.hh \
+           documentator/lateq.hh \
+           draw/drawschema.hh \
+           draw/sigToGraph.hh \
+           errors/errormsg.hh \
+           errors/timing.hh \
+           evaluate/environment.hh \
+           evaluate/eval.hh \
+           evaluate/loopDetector.hh \
+           extended/xtended.hh \
+           generator/compile.hh \
+           generator/compile_scal.hh \
+           generator/compile_sched.hh \
+           generator/compile_vect.hh \
+           generator/contextor.hh \
+           generator/description.hh \
+           generator/floats.hh \
+           generator/klass.hh \
+           generator/occurences.hh \
+           generator/Text.hh \
+           generator/uitree.hh \
+           normalize/aterm.hh \
+           normalize/mterm.hh \
+           normalize/normalize.hh \
+           normalize/privatise.hh \
+           normalize/simplify.hh \
+           parallelize/colorize.h \
+           parallelize/graphSorting.hh \
+           parallelize/loop.hh \
+           parser/enrobage.hh \
+           parser/faustparser.hpp \
+           parser/sourcefetcher.hh \
+           parser/sourcereader.hh \
+           patternmatcher/patternmatcher.hh \
+           propagate/labels.hh \
+           propagate/propagate.hh \
+           signals/binop.hh \
+           signals/interval.hh \
+           signals/ppsig.hh \
+           signals/prim2.hh \
+           signals/recursivness.hh \
+           signals/signals.hh \
+           signals/sigorderrules.hh \
+           signals/sigprint.hh \
+           signals/sigtype.hh \
+           signals/sigtyperules.hh \
+           signals/sigvisitor.hh \
+           tlib/compatibility.hh \
+           tlib/list.hh \
+           tlib/node.hh \
+           tlib/num.hh \
+           tlib/occurrences.hh \
+           tlib/property.hh \
+           tlib/shlysis.hh \
+           tlib/smartpointer.hh \
+           tlib/symbol.hh \
+           tlib/tlib.hh \
+           tlib/tree.hh \
+           utils/files.hh \
+           utils/names.hh \
+           draw/device/device.h \
+           draw/device/devLib.h \
+           draw/device/PSDev.h \
+           draw/device/SVGDev.h \
+           draw/schema/blockSchema.h \
+           draw/schema/cableSchema.h \
+           draw/schema/connectorSchema.h \
+           draw/schema/cutSchema.h \
+           draw/schema/decorateSchema.h \
+           draw/schema/enlargedSchema.h \
+           draw/schema/inverterSchema.h \
+           draw/schema/mergeSchema.h \
+           draw/schema/parSchema.h \
+           draw/schema/recSchema.h \
+           draw/schema/schema.h \
+           draw/schema/seqSchema.h \
+           draw/schema/splitSchema.h \
+           draw/schema/topSchema.h
 SOURCES += main.cpp \
-    boxes/boxcomplexity.cpp \
-    boxes/boxes.cpp \
-    boxes/boxtype.cpp \
-    boxes/ppbox.cpp \
-    documentator/doc.cpp \
-    documentator/doc_autodoc.cpp \
-    documentator/doc_compile.cpp \
-    documentator/doc_lang.cpp \
-    documentator/doc_metadatas.cpp \
-    documentator/doc_notice.cpp \
-    documentator/doc_sharing.cpp \
-    documentator/doc_Text.cpp \
-    documentator/lateq.cpp \
-    draw/drawschema.cpp \
-    errors/errormsg.cpp \
-    errors/timing.cpp \
-    evaluate/eval.cpp \
-    evaluate/loopDetector.cpp \
-    extended/absprim.cpp \
-    extended/acosprim.cpp \
-    extended/asinprim.cpp \
-    extended/atan2prim.cpp \
-    extended/atanprim.cpp \
-    extended/ceilprim.cpp \
-    extended/cosprim.cpp \
-    extended/expprim.cpp \
-    extended/floorprim.cpp \
-    extended/fmodprim.cpp \
-    extended/log10prim.cpp \
-    extended/logprim.cpp \
-    extended/maxprim.cpp \
-    extended/minprim.cpp \
-    extended/powprim.cpp \
-    extended/remainderprim.cpp \
-    extended/rintprim.cpp \
-    extended/sinprim.cpp \
-    extended/sqrtprim.cpp \
-    extended/tanprim.cpp \
-    generator/compile.cpp \
-    generator/compile_scal.cpp \
-    generator/compile_vect.cpp \
-    generator/compile_sched.cpp \
-    generator/contextor.cpp \
-    generator/description.cpp \
-    generator/floats.cpp \
-    generator/klass.cpp \
-    generator/occurences.cpp \
-    generator/sharing.cpp \
-    generator/Text.cpp \
-    generator/uitree.cpp \
-    normalize/aterm.cpp \
-    normalize/mterm.cpp \
-    normalize/normalize.cpp \
-    normalize/privatise.cpp \
-    normalize/simplify.cpp \
-    parallelize/colorize.cpp \
-    parallelize/graphSorting.cpp \
-    parallelize/loop.cpp \
-    parser/enrobage.cpp \
-    parser/faustlexer.cpp \
-    parser/faustparser.cpp \
-    parser/sourcereader.cpp \
-    patternmatcher/patternmatcher.cpp \
-    propagate/labels.cpp \
-    propagate/propagate.cpp \
-    signals/binop.cpp \
-    signals/ppsig.cpp \
-    signals/prim2.cpp \
-    signals/recursivness.cpp \
-    signals/signals.cpp \
-    signals/sigorderrules.cpp \
-    signals/sigprint.cpp \
-    signals/sigtype.cpp \
-    signals/sigtyperules.cpp \
-    signals/sigvisitor.cpp \
-    signals/subsignals.cpp \
-    tlib/compatibility.cpp \
-    tlib/list.cpp \
-    tlib/node.cpp \
-    tlib/occurrences.cpp \
-    tlib/recursive-tree.cpp \
-    tlib/shlysis.cpp \
-    tlib/symbol.cpp \
-    tlib/tree.cpp \
-    utils/names.cpp \
-    draw/device/PSDev.cpp \
-    draw/device/SVGDev.cpp \
-    draw/schema/blockSchema.cpp \
-    draw/schema/cableSchema.cpp \
-    draw/schema/cutSchema.cpp \
-    draw/schema/decorateSchema.cpp \
-    draw/schema/enlargedSchema.cpp \
-    draw/schema/mergeSchema.cpp \
-    draw/schema/parSchema.cpp \
-    draw/schema/recSchema.cpp \
-    draw/schema/seqSchema.cpp \
-    draw/schema/splitSchema.cpp \
-    draw/schema/topSchema.cpp \
-    evaluate/environment.cpp \
-    draw/schema/collector.cpp \
-    draw/schema/inverterSchema.cpp \
-    draw/sigToGraph.cpp
+           boxes/boxcomplexity.cpp \
+           boxes/boxes.cpp \
+           boxes/boxtype.cpp \
+           boxes/ppbox.cpp \
+           documentator/doc.cpp \
+           documentator/doc_autodoc.cpp \
+           documentator/doc_compile.cpp \
+           documentator/doc_lang.cpp \
+           documentator/doc_metadatas.cpp \
+           documentator/doc_notice.cpp \
+           documentator/doc_sharing.cpp \
+           documentator/doc_Text.cpp \
+           documentator/lateq.cpp \
+           draw/drawschema.cpp \
+           draw/sigToGraph.cpp \
+           errors/errormsg.cpp \
+           errors/timing.cpp \
+           evaluate/environment.cpp \
+           evaluate/eval.cpp \
+           evaluate/loopDetector.cpp \
+           extended/absprim.cpp \
+           extended/acosprim.cpp \
+           extended/asinprim.cpp \
+           extended/atan2prim.cpp \
+           extended/atanprim.cpp \
+           extended/ceilprim.cpp \
+           extended/cosprim.cpp \
+           extended/expprim.cpp \
+           extended/floorprim.cpp \
+           extended/fmodprim.cpp \
+           extended/log10prim.cpp \
+           extended/logprim.cpp \
+           extended/maxprim.cpp \
+           extended/minprim.cpp \
+           extended/powprim.cpp \
+           extended/remainderprim.cpp \
+           extended/rintprim.cpp \
+           extended/sinprim.cpp \
+           extended/sqrtprim.cpp \
+           extended/tanprim.cpp \
+           generator/compile.cpp \
+           generator/compile_scal.cpp \
+           generator/compile_sched.cpp \
+           generator/compile_vect.cpp \
+           generator/contextor.cpp \
+           generator/description.cpp \
+           generator/floats.cpp \
+           generator/klass.cpp \
+           generator/occurences.cpp \
+           generator/sharing.cpp \
+           generator/Text.cpp \
+           generator/uitree.cpp \
+           normalize/aterm.cpp \
+           normalize/mterm.cpp \
+           normalize/normalize.cpp \
+           normalize/privatise.cpp \
+           normalize/simplify.cpp \
+           parallelize/colorize.cpp \
+           parallelize/graphSorting.cpp \
+           parallelize/loop.cpp \
+           parser/enrobage.cpp \
+           parser/faustlexer.cpp \
+           parser/faustparser.cpp \
+           parser/sourcefetcher.cpp \
+           parser/sourcereader.cpp \
+           patternmatcher/patternmatcher.cpp \
+           propagate/labels.cpp \
+           propagate/propagate.cpp \
+           signals/binop.cpp \
+           signals/ppsig.cpp \
+           signals/prim2.cpp \
+           signals/recursivness.cpp \
+           signals/signals.cpp \
+           signals/sigorderrules.cpp \
+           signals/sigprint.cpp \
+           signals/sigtype.cpp \
+           signals/sigtyperules.cpp \
+           signals/sigvisitor.cpp \
+           signals/subsignals.cpp \
+           tlib/compatibility.cpp \
+           tlib/list.cpp \
+           tlib/node.cpp \
+           tlib/occurrences.cpp \
+           tlib/recursive-tree.cpp \
+           tlib/shlysis.cpp \
+           tlib/symbol.cpp \
+           tlib/tree.cpp \
+           utils/files.cpp \
+           utils/names.cpp \
+           draw/device/PSDev.cpp \
+           draw/device/SVGDev.cpp \
+           draw/schema/blockSchema.cpp \
+           draw/schema/cableSchema.cpp \
+           draw/schema/collector.cpp \
+           draw/schema/connectorSchema.cpp \
+           draw/schema/cutSchema.cpp \
+           draw/schema/decorateSchema.cpp \
+           draw/schema/enlargedSchema.cpp \
+           draw/schema/inverterSchema.cpp \
+           draw/schema/mergeSchema.cpp \
+           draw/schema/parSchema.cpp \
+           draw/schema/recSchema.cpp \
+           draw/schema/seqSchema.cpp \
+           draw/schema/splitSchema.cpp \
+           draw/schema/topSchema.cpp
diff --git a/compiler/documentator/doc.cpp b/compiler/documentator/doc.cpp
index 00c956e..0d232a6 100644
--- a/compiler/documentator/doc.cpp
+++ b/compiler/documentator/doc.cpp
@@ -77,7 +77,7 @@
 #include "doc_notice.hh"
 #include "doc_autodoc.hh"
 #include "compatibility.hh"
-
+#include "files.hh"
 
 
 #define MAXIDCHARS 5				///< max numbers (characters) to represent ids (e.g. for directories).
@@ -104,7 +104,6 @@ extern SourceReader				gReader;
 
 extern string 					gDocName;				///< Contains the filename for out documentation.
 static const char* 				gDocDevSuffix;			///< ".tex" (or .??? - used to choose output device).
-static string 					gCurrentDir;			///< Room to save current directory name.
 static const string				gLatexheaderfilename = "latexheader.tex";
 
 vector<Tree> 					gDocVector;				///< Contains <mdoc> parsed trees: DOCTXT, DOCEQN, DOCDGM.
@@ -152,21 +151,12 @@ static void		initCompilationDate();
 static struct tm* getCompilationDate();
 
 /* Files functions */
-static int		cholddir ();
-static int		mkchdir(const char* dirname);
-static int		makedir(const char* dirname);
-static void		getCurrentDir();
 static istream* openArchFile (const string& filename);
-static char*	legalFileName(const Tree t, int n, char* dst);
-static string	rmExternalDoubleQuotes(const string& s);
-static void		copyFaustSources(const char* projname, const vector<string>& pathnames);
+static char*    legalFileName(const Tree t, int n, char* dst);
+static void     copyFaustSources(const char* projname, const vector<string>& pathnames);
 vector<string>& docCodeSlicer(const string& faustfile, vector<string>& codeSlices);
-static void		printdocCodeSlices(const string& code, ostream& docout);
-static bool		doesFileBeginWithCode(const string& faustfile);
-
-//static void		declareAutoDoc();
-
-
+static void     printdocCodeSlices(const string& code, ostream& docout);
+static bool     doesFileBeginWithCode(const string& faustfile);
 
 /*****************************************************************************
 					Types of Documentation Elements
@@ -206,10 +196,6 @@ Sym DOCMTD = symbol ("DocMtd");
 Tree docMtd(Tree x) 				{ return tree(DOCMTD, x); 		}
 bool isDocMtd(Tree t, Tree& x) 		{ return isTree(t, DOCMTD, x); 	}
 
-//string getDocTxt(Tree t) 			{ return hd(t)->branch(0); }
-
-
-
 /*****************************************************************************
 				Main Printing Function for the Documentation
  *****************************************************************************/
@@ -272,8 +258,6 @@ void printDoc(const char* projname, const char* docdev, const char* faustversion
 	printlatexfooter(docout);										///< Static LaTeX footer.
 }
 
-
-
 /*****************************************************************************
 			LaTeX basic printing functions of the Documentation
  *****************************************************************************/
@@ -320,7 +304,7 @@ static void printDocMetadata(const Tree expr, ostream& docout)
 		set<Tree> mset = gMetaDataSet[expr];
 		
 		for (set<Tree>::iterator j = mset.begin(); j != mset.end(); j++) {
-			docout << sep << rmExternalDoubleQuotes(tree2str(*j));
+			docout << sep << unquote(tree2str(*j));
 			sep = ", ";
 		}
 	}
@@ -977,74 +961,6 @@ static bool doesFileBeginWithCode(const string& faustfile)
 
 
 /**
- * Create a new directory in the current one.
- */
-static int makedir(const char* dirname)
-{
-	char	buffer[FAUST_PATH_MAX];
-	gCurrentDir = getcwd (buffer, FAUST_PATH_MAX);
-	
-	if ( gCurrentDir.c_str() != 0) {
-		int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-		if (status == 0 || errno == EEXIST) {
-			return 0;
-		}
-	}
-	perror("makedir");
-	exit(errno);
-}
-
-
-/**
- * Create a new directory in the current one, 
- * then 'cd' into this new directory.
- * 
- * @remark
- * The current directory is saved to be later restaured.
- */
-static int mkchdir(const char* dirname)
-{
-	char	buffer[FAUST_PATH_MAX];
-	gCurrentDir = getcwd (buffer, FAUST_PATH_MAX);
-
-	if ( gCurrentDir.c_str() != 0) {
-		int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-		if (status == 0 || errno == EEXIST) {
-			if (chdir(dirname) == 0) {
-				return 0;
-			}
-		}
-	}
-	perror("mkchdir");
-	exit(errno);
-}
-
-
-/**
- * Switch back to the previously stored current directory
- */
-static int cholddir ()
-{
-	if (chdir(gCurrentDir.c_str()) == 0) {
-		return 0;
-	} else {
-		perror("cholddir");
-		exit(errno);
-	}
-}
-
-
-/**
- * Get current directory and store it in gCurrentDir.
- */
-static void getCurrentDir ()
-{
-	char	buffer[FAUST_PATH_MAX];
-    gCurrentDir = getcwd (buffer, FAUST_PATH_MAX);
-}
-
-
-/**
  * Open architecture file.
  */
 static istream* openArchFile (const string& filename)
@@ -1098,23 +1014,6 @@ static string calcNumberedName(const char* base, int i)
 	return subst("$0$1", base, nb);
 }
 
-/**
- * Remove the leading and trailing double quotes of a string
- * (but not those in the middle of the string)
- */
-static string rmExternalDoubleQuotes(const string& s)
-{
-    size_t i = s.find_first_not_of("\"");
-    size_t j = s.find_last_not_of("\"");
-	
-    if ( (i != string::npos) & (j != string::npos) ) {
-        return s.substr(i, 1+j-i);
-    } else {
-        return "";
-    }
-}
-
-
 /** 
  * Copy all Faust source files into an 'src' subdirectory.
  *
@@ -1144,7 +1043,6 @@ static void copyFaustSources(const char* projname, const vector<string>& pathnam
 
 //------------------------ date managment -------------------------
 
-
 static void initCompilationDate()
 {
 	time_t now;
diff --git a/compiler/documentator/doc_Text.cpp b/compiler/documentator/doc_Text.cpp
index 4194b7f..f7ce37e 100644
--- a/compiler/documentator/doc_Text.cpp
+++ b/compiler/documentator/doc_Text.cpp
@@ -31,6 +31,7 @@
 #include <sstream>
 #include <assert.h>
 #include <cmath>
+#include <stdlib.h>
 
 #include "floats.hh"
 
@@ -143,7 +144,7 @@ bool isPiPower (double n, string& s)
 {
     assert(n>0);
     stringstream ss (stringstream::out|stringstream::in);
-    int k = floor(log(n)/log(M_PI));
+    int k = (int)floor(log(n)/log(M_PI));
     if ( AlmostEqual(n, exp(k * log(M_PI))) && (k!=0) && (abs(k)<5.0) ) {
         ss << "\\pi";
         if (k!=1)  ss << "^{"<< k <<"}";
@@ -163,7 +164,7 @@ bool isExpPower (double n, string& s)
 {
     assert(n>0);
     stringstream ss (stringstream::out|stringstream::in);
-    int k = floor(log(n));
+    int k = (int)floor(log(n));
     if ( AlmostEqual(n, exp(k)) && (k!=0) && (abs(k)<5.0) ) {
         ss << "e";
         if (k!=1)  ss << "^{"<< k <<"}";
diff --git a/compiler/documentator/doc_autodoc.cpp b/compiler/documentator/doc_autodoc.cpp
index 3e905f0..fb35301 100644
--- a/compiler/documentator/doc_autodoc.cpp
+++ b/compiler/documentator/doc_autodoc.cpp
@@ -19,7 +19,6 @@
  ************************************************************************
  ************************************************************************/
 
-
 #include <iostream>
 #include <string>
 #include <set>
@@ -31,7 +30,6 @@
 #include "boxes.hh"
 #include "doc.hh"
 
-
 extern SourceReader				gReader;
 extern string					gDocName;
 extern map<Tree, set<Tree> > 	gMetaDataSet;
@@ -42,9 +40,6 @@ set<string>				gDocAutodocKeySet;
 
 static void				initDocAutodocKeySet();
 
-
-
-
 /*****************************************************************************
 						Public functions
  *****************************************************************************/
@@ -96,7 +91,6 @@ void declareAutoDoc()
 	/** The latex maketitle macro. */
 	autodoc = cons(docTxt("\\maketitle\n"), autodoc);
 
-	
 	/** Insert all declared metadatas in a latex tabular environment. */
 	if (! gMetaDataSet.empty()) {
 		autodoc = cons(docTxt("\\begin{tabular}{ll}\n"), autodoc);
@@ -118,7 +112,6 @@ void declareAutoDoc()
 		autodoc = cons(docTxt("\\bigskip\n"), autodoc);
 	}
 
-
 	/** Autodoc's "body", with equation and diagram of process, and notice and listing. */
 	
 	string autoPresentationTxt = "\n\\bigskip\n" + gDocAutodocStringMap["thisdoc"] + "\n\n";
@@ -154,7 +147,6 @@ void declareAutoDoc()
 	declareDoc(autodoc);
 }
 
-
 /** 
  * Dispatch initialization of autodoc container.
  */
@@ -163,13 +155,10 @@ void initDocAutodoc()
 	initDocAutodocKeySet();
 }
 
-
-
 /*****************************************************************************
 						Static functions
  *****************************************************************************/
 
-
 /** 
  * Initialize gDocAutodocKeySet, a set containing all the keywords.
  */
@@ -193,7 +182,7 @@ static void initDocAutodocKeySet() {
 	gDocAutodocKeySet.insert("autolsttext2");
 }
 
-
+#if 0
 /** 
  * Simple trace function.
  */
@@ -207,4 +196,4 @@ static void printDocAutodocStringMapContent() {
 			cout << i++ << ".\tgDocNoticeStringMap[" << it->first << "] \t= '" << it->second << "'" << endl;
 	}
 }
-
+#endif
diff --git a/compiler/documentator/doc_autodoc.hh b/compiler/documentator/doc_autodoc.hh
index 9a3ecda..8170d09 100644
--- a/compiler/documentator/doc_autodoc.hh
+++ b/compiler/documentator/doc_autodoc.hh
@@ -19,17 +19,12 @@
  ************************************************************************
  ************************************************************************/
 
-
 #ifndef _DOCAUTODOC_
 #define _DOCAUTODOC_
 
-
 using namespace std;
 
-
 void initDocAutodoc();
 void declareAutoDoc();
 
-
-
 #endif
diff --git a/compiler/documentator/doc_compile.cpp b/compiler/documentator/doc_compile.cpp
index a713eb7..f0375c7 100644
--- a/compiler/documentator/doc_compile.cpp
+++ b/compiler/documentator/doc_compile.cpp
@@ -59,9 +59,6 @@ extern map<string, string>		gDocMathStringMap;
 
 extern bool		getSigListNickName(Tree t, Tree& id);
 
-static const unsigned int MAX_RIGHT_MEMBER	= 20;
-static const unsigned int MAX_SUB_EXPR		= 10;
-
 
 /*****************************************************************************
 						getFreshID
diff --git a/compiler/documentator/lateq.cpp b/compiler/documentator/lateq.cpp
index d7b0a75..3c54fba 100644
--- a/compiler/documentator/lateq.cpp
+++ b/compiler/documentator/lateq.cpp
@@ -85,14 +85,14 @@ void Lateq::println(ostream& docout)
 	/* 1. Make titles of sub-sets of formulas. */
 	string suchthat		= gDocMathStringMap["suchthat"];
 	
-	string sInputs		= makeItemTitle(fInputSigsFormulas.size(), "inputsigtitle") + makeSignamesList(fInputSigsFormulas, "");
-	string sOutputs		= makeItemTitle(fOutputSigsFormulas.size(), "outputsigtitle") + makeSignamesList(fOutputSigsFormulas, suchthat);
-	string sConstants	= makeItemTitle(fConstSigsFormulas.size(), "constsigtitle") + makeSignamesList(fConstSigsFormulas, suchthat);
+	string sInputs		= makeItemTitle((const unsigned int)fInputSigsFormulas.size(), "inputsigtitle") + makeSignamesList(fInputSigsFormulas, "");
+	string sOutputs		= makeItemTitle((const unsigned int)fOutputSigsFormulas.size(), "outputsigtitle") + makeSignamesList(fOutputSigsFormulas, suchthat);
+	string sConstants	= makeItemTitle((const unsigned int)fConstSigsFormulas.size(), "constsigtitle") + makeSignamesList(fConstSigsFormulas, suchthat);
 	
 	vector<list<string> > UISignamesVector = makeUISignamesVector(fUISigsFormulas);
-	string sUIElements	= makeItemTitle(fUISigsFormulas.size(), "uisigtitle") + makeSignamesList(UISignamesVector, suchthat);
+	string sUIElements	= makeItemTitle((const unsigned int)fUISigsFormulas.size(), "uisigtitle") + makeSignamesList(UISignamesVector, suchthat);
 
-	unsigned int internalSigsCount = fParamSigsFormulas.size() + fStoreSigsFormulas.size() + fRecurSigsFormulas.size() + fRDTblSigsFormulas.size() + fRWTblSigsFormulas.size() + fSelectSigsFormulas.size() + fPrefixSigsFormulas.size();
+	unsigned int internalSigsCount = (unsigned int)(fParamSigsFormulas.size() + fStoreSigsFormulas.size() + fRecurSigsFormulas.size() + fRDTblSigsFormulas.size() + fRWTblSigsFormulas.size() + fSelectSigsFormulas.size() + fPrefixSigsFormulas.size());
 	
 	vector<list<string> > internalSigsFormulasList;
 	if( ! fParamSigsFormulas.empty() )	internalSigsFormulasList.push_back(fParamSigsFormulas);
diff --git a/compiler/draw/device/PSDev.cpp b/compiler/draw/device/PSDev.cpp
index 14ab303..d91471b 100644
--- a/compiler/draw/device/PSDev.cpp
+++ b/compiler/draw/device/PSDev.cpp
@@ -19,16 +19,15 @@
  ************************************************************************
  ************************************************************************/
  
- 
- 
 // PSDev.cpp
 
-#include "PSDev.h"
-#include "string.h"
-#include "math.h"
-#include "compatibility.hh"
+#include <string.h>
+#include <math.h>
 #include <iostream>
 
+#include "compatibility.hh"
+#include "PSDev.h"
+
 using namespace std;
 
 static int gFileNum = 0;
@@ -55,7 +54,8 @@ PSDev::PSDev(const char* ficName, double largeur, double hauteur)
 {
 	if ((fic_repr = fopen(addFileNum(ficName),"w+")) == NULL) { 
 	//if ((fic_repr = fopen(ficName,"w+")) == NULL) { 
-		cout<<"Impossible de creer ou d'ouvrir "<<ficName<<endl; 
+		cout<<"Impossible to create or open "<<ficName<<endl;
+        return;
 	}
 
 	if(largeur<hauteur)
diff --git a/compiler/draw/device/SVGDev.cpp b/compiler/draw/device/SVGDev.cpp
old mode 100755
new mode 100644
index 12b5a66..b04dda1
--- a/compiler/draw/device/SVGDev.cpp
+++ b/compiler/draw/device/SVGDev.cpp
@@ -19,16 +19,16 @@
  ************************************************************************
  ************************************************************************/
 
-
-
 // SVGDev.cpp
 
 #include "SVGDev.h"
-#include "stdio.h"
+#include <stdio.h>
 #include <iostream>
+
 using namespace std;
 
 extern bool gShadowBlur;
+extern bool gScaledSVG;
 
 static char* xmlcode(const char* name, char* name2)
 {
@@ -51,18 +51,23 @@ static char* xmlcode(const char* name, char* name2)
 	return name2;
 }
 
-SVGDev::SVGDev(const char* ficName,double largeur, double hauteur)
+SVGDev::SVGDev(const char* ficName, double largeur, double hauteur)
 {
 	double gScale = 0.5;
 	if ((fic_repr = fopen(ficName,"w+")) == NULL) {
-		cout<<"Impossible de creer ou d'ouvrir "<<ficName<<endl;
+		cout<<"Impossible to create or open "<<ficName<<endl;
+        return;
 	}
 
 	// representation file:
 	fprintf(fic_repr,"<?xml version=\"1.0\"?>\n");
 	// + DTD ...
 	// viewBox:
-	fprintf(fic_repr,"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 %f %f\" width=\"%fmm\" height=\"%fmm\" version=\"1.1\">\n", largeur, hauteur, largeur*gScale, hauteur*gScale);
+    if (gScaledSVG) {
+        fprintf(fic_repr,"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 %f %f\" width=\"100%%\" height=\"100%%\" version=\"1.1\">\n", largeur, hauteur);
+    } else {
+        fprintf(fic_repr,"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 %f %f\" width=\"%fmm\" height=\"%fmm\" version=\"1.1\">\n", largeur, hauteur, largeur*gScale, hauteur*gScale);
+    }
 
     if (gShadowBlur) {
 		 fprintf(fic_repr,
@@ -121,13 +126,13 @@ void SVGDev::triangle(double x,double y,double l,double h, const char* color, co
     float r = 1.5; // circle radius
     float x0, x1, x2;
     if (leftright) {
-        x0 = x;
-        x1 = x+l-2*r;
-        x2 = x+l-r;
+        x0 = (float)x;
+        x1 = (float)(x+l-2*r);
+        x2 = (float)(x+l-r);
     } else {
-        x0 = x+l;
-        x1 = x+2*r;
-        x2 = x+r;
+        x0 = (float)(x+l);
+        x1 = (float)(x+2*r);
+        x2 = (float)(x+r);
     }
     fprintf(fic_repr,"<polygon fill=\"%s\" stroke=\"black\" stroke-width=\".25\" points=\"%f,%f %f,%f %f,%f\"/>\n", color, x0,y, x1,y+h/2.0, x0,y+h);
     fprintf(fic_repr,"<circle  fill=\"%s\" stroke=\"black\" stroke-width=\".25\" cx=\"%f\" cy=\"%f\" r=\"%f\"/>\n", color, x2, y+h/2.0, r);
diff --git a/compiler/draw/device/SVGDev.h b/compiler/draw/device/SVGDev.h
old mode 100755
new mode 100644
diff --git a/compiler/draw/drawschema.cpp b/compiler/draw/drawschema.cpp
index 6e3624c..9c36b45 100644
--- a/compiler/draw/drawschema.cpp
+++ b/compiler/draw/drawschema.cpp
@@ -59,8 +59,7 @@
 #include "names.hh"
 #include "description.hh"
 #include "property.hh"
-
-
+#include "files.hh"
 
 #if 0
 #define linkcolor "#b3d1dc"
@@ -132,7 +131,6 @@ static bool				sFoldingFlag;		// true with complex block-diagrams
 static stack<Tree>		gPendingExp;		// Expressions that need to be drawn
 static set<Tree>		gDrawnExp;			// Expressions drawn or scheduled so far
 static const char* 		gDevSuffix;			// .svg or .ps used to choose output device
-static char 			gCurrentDir[512];	// room to save current directory name
 static string			gSchemaFileName;	// name of schema file beeing generated
 static map<Tree,string>	gBackLink;			// link to enclosing file for sub schema
 
@@ -148,8 +146,9 @@ static schema* 	generateInputSlotSchema(Tree a);
 static schema* 	generateBargraphSchema(Tree t);
 static schema* 	generateUserInterfaceSchema(Tree t);
 static char* 	legalFileName(Tree t, int n, char* dst);
-static int 		cholddir ();
-static int 		mkchdir(const char* dirname);
+
+static schema*  addSchemaInputs(int ins, schema* x);
+static schema*  addSchemaOutputs(int outs, schema* x);
 
 
 
@@ -221,10 +220,12 @@ static void writeSchemaFile(Tree bd)
 {
 	Tree			id;
 	schema* 		ts;
+    int             ins, outs;
 
 	char 			temp[1024];
 
 	gOccurrences = new Occurrences(bd);
+    getBoxType (bd, &ins, &outs);
 
 	bool hasname = getDefNameProperty(bd, id); 
 
@@ -241,7 +242,7 @@ static void writeSchemaFile(Tree bd)
 	// generate the label of the schema
 	stringstream s2; s2 << tree2str(id);
 	string link = gBackLink[bd];
-	ts = makeTopSchema(generateInsideSchema(bd), 20, s2.str(), link);
+    ts = makeTopSchema(addSchemaOutputs(outs, addSchemaInputs(ins, generateInsideSchema(bd))), 20, s2.str(), link);
 	// draw to the device defined by gDevSuffix
 	if (strcmp(gDevSuffix, "svg") == 0) {
 		SVGDev dev(s1.str().c_str(), ts->width(), ts->height());
@@ -261,42 +262,6 @@ static void writeSchemaFile(Tree bd)
 }
 
 
-
-/**
- * Create a new directory in the current one to store the diagrams.
- * The current directory is saved to be later restaured.
- */
-static int mkchdir(const char* dirname)
-{
-	//cerr << "mkchdir of " << dirname << endl;
-	if (getcwd(gCurrentDir, 512) != 0) {
-		int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-		if (status == 0 || errno == EEXIST) {
-			if (chdir(dirname) == 0) {
-				return 0;
-			}
-		}
-	}
-	perror("mkchdir");
-	exit(errno);
-	//return errno;
-}
-
-
-/**
- *Switch back to the previously stored current directory
- */
-static int cholddir ()
-{
-	if (chdir(gCurrentDir) == 0) {
-		return 0;
-	} else {
-		perror("cholddir");
-		exit(errno);
-	}
-}
-
-
 /**
  * Transform the definition name property of tree <t> into a
  * legal file name.  The resulting file name is stored in
@@ -322,7 +287,6 @@ static char* legalFileName(Tree t, int n, char* dst)
 }
 
 
-
 //------------------------ generating the schema -------------------------
 
 
@@ -452,7 +416,8 @@ static schema* generateInsideSchema(Tree t)
 
 	else if (isBoxInt(t, &i))		{ stringstream 	s; s << i; return makeBlockSchema(0, 1, s.str(), numcolor, "" ); }
 	else if (isBoxReal(t, &r)) 		{ stringstream 	s; s << r; return makeBlockSchema(0, 1, s.str(), numcolor, "" ); }
-	else if (isBoxWire(t)) 			{ return makeCableSchema(); }
+	else if (isBoxWaveform(t))      { return makeBlockSchema(0, 2, "waveform{...}", normalcolor, ""); }
+    else if (isBoxWire(t)) 			{ return makeCableSchema(); }
 	else if (isBoxCut(t)) 			{ return makeCutSchema();  }
 
 	else if (isBoxPrim0(t, &p0)) 	{ return makeBlockSchema(0, 1, prim0name(p0), normalcolor, ""); }
@@ -632,3 +597,39 @@ static schema* generateAbstractionSchema(schema* x, Tree t)
 	return makeSeqSchema(x, generateDiagramSchema(t));
 }
 
+static schema* addSchemaInputs(int ins, schema* x)
+{
+    if (ins==0) {
+        return x;
+    } else {
+        schema* y = 0;
+        do {
+            schema* z = makeConnectorSchema();
+            if (y != 0) {
+                y = makeParSchema(y,z);
+            } else {
+                y = z;
+            }
+        } while (--ins);
+        return makeSeqSchema(y,x);
+    }
+}
+
+
+static schema* addSchemaOutputs(int outs, schema* x)
+{
+    if (outs==0) {
+        return x;
+    } else {
+        schema* y = 0;
+        do {
+            schema* z = makeConnectorSchema();
+            if (y != 0) {
+                y = makeParSchema(y,z);
+            } else {
+                y = z;
+            }
+        } while (--outs);
+        return makeSeqSchema(x,y);
+    }
+}
diff --git a/compiler/draw/schema/blockSchema.cpp b/compiler/draw/schema/blockSchema.cpp
index ca5ff55..d07a244 100644
--- a/compiler/draw/schema/blockSchema.cpp
+++ b/compiler/draw/schema/blockSchema.cpp
@@ -31,6 +31,7 @@ static double quantize(int n)
 	return dLetter * (q *((n+q-1)/q));
 }
 
+
 /**
  * Build a simple colored blockSchema with a certain number of
  * inputs and outputs, a text to be displayed, and an optional link.
@@ -38,19 +39,20 @@ static double quantize(int n)
  * and the maximum number of ports.
  */
 schema* makeBlockSchema (	unsigned int inputs,
-							unsigned int outputs,
-							const string& text,
-							const string& color,
-							const string& link )
+                            unsigned int outputs,
+                            const string& text,
+                            const string& color,
+                            const string& link )
 {
-	// determine the optimal size of the box
-	double minimal = 3*dWire;
-	double w = 2*dHorz + max( minimal, quantize(text.size()) );
-	double h = 2*dVert + max( minimal, max(inputs, outputs) * dWire );
+    // determine the optimal size of the box
+    double minimal = 3*dWire;
+    double w = 2*dHorz + max( minimal, quantize((int)text.size()) );
+    double h = 2*dVert + max( minimal, max(inputs, outputs) * dWire );
 
-	return new blockSchema(inputs, outputs, w, h, text, color, link);
+    return new blockSchema(inputs, outputs, w, h, text, color, link);
 }
 
+
 /**
  * Build a simple colored blockSchema with a certain number of
  * inputs and outputs, a text to be displayed, and an optional link.
@@ -63,17 +65,18 @@ blockSchema::blockSchema (	unsigned int inputs,
 							double height,
 							const string& text,
 							const string& color,
-							const string& link )
+                            const string& link)
 
 	: 	schema( inputs, outputs, width, height ),
 	  	fText(text),
 	  	fColor(color),
-	  	fLink(link)
+        fLink(link)
 {
     for (unsigned int i=0; i<inputs; i++) 	fInputPoint.push_back(point(0,0));
     for (unsigned int i=0; i<outputs; i++) 	fOutputPoint.push_back(point(0,0));
 }
 
+
 /**
  * Define the graphic position of the blockSchema. Computes the graphic
  * position of all the elements, in particular the inputs and outputs.
@@ -89,6 +92,7 @@ void blockSchema::place(double x, double y, int orientation)
 	endPlace();
 }
 
+
 /**
  * Returns an input point
  */
@@ -99,6 +103,7 @@ point blockSchema::inputPoint(unsigned int i) const
 	return fInputPoint[i];
 }
 
+
 /**
  * Returns an output point
  */
@@ -109,6 +114,7 @@ point blockSchema::outputPoint(unsigned int i) const
 	return fOutputPoint[i];
 }
 
+
 /**
  * Computes the input points according to the position and the
  * orientation of the blockSchema
@@ -177,9 +183,8 @@ void blockSchema::draw(device& dev)
 
 	drawRectangle(dev);
 	drawText(dev);
-	drawOrientationMark(dev);
-    drawInputWires(dev);
-    drawOutputWires(dev);
+    drawOrientationMark(dev);
+    drawInputArrows(dev);
 }
 
 /**
@@ -228,36 +233,20 @@ void blockSchema::drawOrientationMark(device& dev)
 
 	dev.markSens( px, py, orientation() );
 }
-#if 1
 /**
  * Draw horizontal arrows from the input points to the
  * blockSchema rectangle
  */
-void blockSchema::drawInputWires(device& dev)
+void blockSchema::drawInputArrows(device& dev)
 {
     double dx = (orientation() == kLeftRight) ? dHorz : -dHorz;
 
     for (unsigned int i=0; i<inputs(); i++) {
         point p = fInputPoint[i];
-        //dev.trait(p.x, p.y, p.x+dx, p.y);
         dev.fleche(p.x+dx, p.y, 0, orientation());
     }
 }
 
-/**
- * Draw horizontal line from the blockSchema rectangle to the
- * output points
- */
-void blockSchema::drawOutputWires(device& dev)
-{
-    //double dx = (orientation() == kLeftRight) ? dHorz : -dHorz;
-
-    for (unsigned int i=0; i<outputs(); i++) {
-        point p = fOutputPoint[i];
-        //dev.trait(p.x, p.y, p.x-dx, p.y);
-    }
-}
-#endif
 
 /**
  * Draw horizontal arrows from the input points to the
diff --git a/compiler/draw/schema/blockSchema.h b/compiler/draw/schema/blockSchema.h
index 3a9a307..9bc20c6 100644
--- a/compiler/draw/schema/blockSchema.h
+++ b/compiler/draw/schema/blockSchema.h
@@ -37,7 +37,7 @@ class blockSchema : public schema
   protected:
 	const string	fText;			///< Text to be displayed
 	const string	fColor;			///< color of the box
-	const string	fLink;			///< option URL link
+    const string	fLink;			///< option URL link
 
 	// fields only defined after place() is called
 	vector<point>	fInputPoint;	///< input connection points
@@ -45,22 +45,23 @@ class blockSchema : public schema
 
 
   public:
-  	friend schema* makeBlockSchema (	unsigned int inputs,
-  										unsigned int outputs,
-  										const string& name,
-  										const string& color,
-  										const string& link);
+    friend schema*  makeBlockSchema (	unsigned int inputs,
+                                        unsigned int outputs,
+                                        const string& name,
+                                        const string& color,
+                                        const string& link);
 
 	virtual void 	place(double x, double y, int orientation);
 	virtual void 	draw(device& dev);
 	virtual point	inputPoint(unsigned int i) const;
 	virtual point 	outputPoint(unsigned int i) const;
+    virtual void    collectTraits(collector& c);
 
   protected:
 	blockSchema (	unsigned int inputs, unsigned int outputs,
 					double width, double height,
   					const string& name, const string& color,
-  					const string& link);
+                    const string& link);
 
 	void placeInputPoints();
 	void placeOutputPoints();
@@ -68,10 +69,9 @@ class blockSchema : public schema
   	void drawRectangle(device& dev);
 	void drawText(device& dev);
 	void drawOrientationMark(device& dev);
-    void drawInputWires(device& dev);
-    void drawOutputWires(device& dev);
+    void drawInputArrows(device& dev);
+//    void drawOutputWires(device& dev);
 
-    void collectTraits(collector& c);
     void collectInputWires(collector& c);
     void collectOutputWires(collector& c);
 
diff --git a/compiler/draw/schema/cableSchema.h b/compiler/draw/schema/cableSchema.h
index 46100e4..8a24923 100644
--- a/compiler/draw/schema/cableSchema.h
+++ b/compiler/draw/schema/cableSchema.h
@@ -36,7 +36,7 @@ class cableSchema : public schema
 	vector<point>	fPoint;
 
   public:
-  	friend schema* makeCableSchema (unsigned int n);
+    friend schema*  makeCableSchema (unsigned int n);
 
 	virtual void 	place(double x, double y, int orientation);
 	virtual void 	draw(device& dev);
diff --git a/compiler/draw/schema/connectorSchema.cpp b/compiler/draw/schema/connectorSchema.cpp
new file mode 100644
index 0000000..df3ecbe
--- /dev/null
+++ b/compiler/draw/schema/connectorSchema.cpp
@@ -0,0 +1,193 @@
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+
+#include "connectorSchema.h"
+#include <assert.h>
+
+using namespace std;
+
+
+/**
+ * Connectors are used to ensure unused inputs and outputs
+ * are drawn
+ */
+schema* makeConnectorSchema (	)
+{
+    return new connectorSchema();
+}
+
+/**
+ * A connector is an invisible square fo dWire size
+ * with 1 input and 1 output
+ */
+connectorSchema::connectorSchema () : schema(1, 1, dWire, dWire)
+{
+    fInputPoint.push_back(point(0,0));
+    fOutputPoint.push_back(point(0,0));
+}
+
+/**
+ * Define the graphic position of the connectorSchema. Computes the graphic
+ * position of all the elements, in particular the inputs and outputs.
+ * This method must be called before draw(), otherwise draw is not allowed
+ */
+void connectorSchema::place(double x, double y, int orientation)
+{
+    beginPlace(x, y, orientation);
+
+    placeInputPoints();
+    placeOutputPoints();
+
+    endPlace();
+}
+
+/**
+ * Returns an input point
+ */
+point connectorSchema::inputPoint(unsigned int i) const
+{
+    assert (placed());
+    assert (i < inputs());
+    return fInputPoint[i];
+}
+
+/**
+ * Returns an output point
+ */
+point connectorSchema::outputPoint(unsigned int i) const
+{
+    assert (placed());
+    assert (i < outputs());
+    return fOutputPoint[i];
+}
+
+/**
+ * Computes the input points according to the position and the
+ * orientation of the connectorSchema
+ */
+void connectorSchema::placeInputPoints()
+{
+    int		N = inputs();
+
+    if (orientation() == kLeftRight) {
+
+        double 	px = x();
+        double 	py = y() + (height() - dWire*(N-1))/2;
+
+        for (int i=0; i<N; i++) {
+            fInputPoint[i] = point(px, py+i*dWire);
+        }
+
+    } else {
+
+        double px = x() + width();
+        double py = y() + height() - (height() - dWire*(N-1))/2;
+
+        for (int i=0; i<N; i++) {
+            fInputPoint[i] = point(px, py-i*dWire);
+        }
+    }
+}
+
+
+/**
+ * Computes the output points according to the position and the
+ * orientation of the connectorSchema
+ */
+void connectorSchema::placeOutputPoints()
+{
+    int N = outputs();
+
+    if (orientation() == kLeftRight) {
+
+        double px = x() + width();
+        double py = y() + (height() - dWire*(N-1))/2;
+
+        for (int i=0; i<N; i++) {
+            fOutputPoint[i] = point(px, py + i*dWire);
+        }
+
+    } else {
+
+        double px = x();
+        double py = y() + height() - (height() - dWire*(N-1))/2;
+
+        for (int i=0; i<N; i++) {
+            fOutputPoint[i] = point(px, py - i*dWire);
+        }
+    }
+}
+
+
+/**
+ * Draw the connectorSchema on the device. This methos can only
+ * be called after the connectorSchema have been placed
+ */
+void connectorSchema::draw(device& dev)
+{
+    assert(placed());
+    // nothing to do
+}
+
+/**
+ * Draw horizontal arrows from the input points to the
+ * connectorSchema rectangle
+ */
+void connectorSchema::collectTraits(collector& c)
+{
+    collectInputWires(c);
+    collectOutputWires(c);
+}
+
+
+/**
+ * Draw horizontal arrows from the input points to the
+ * connectorSchema rectangle
+ */
+void connectorSchema::collectInputWires(collector& c)
+{
+    double dx = (orientation() == kLeftRight) ? dHorz : -dHorz;
+
+    for (unsigned int i=0; i<inputs(); i++) {
+        point p = fInputPoint[i];
+        c.addTrait(trait(point(p.x, p.y), point(p.x+dx, p.y)));     // in->out direction
+        c.addInput(point(p.x+dx, p.y));
+    }
+}
+
+
+/**
+ * Draw horizontal line from the connectorSchema rectangle to the
+ * output points
+ */
+void connectorSchema::collectOutputWires(collector& c)
+{
+    double dx = (orientation() == kLeftRight) ? dHorz : -dHorz;
+
+    for (unsigned int i=0; i<outputs(); i++) {
+        point p = fOutputPoint[i];
+        c.addTrait(trait(point(p.x-dx, p.y), point(p.x, p.y)));     // in->out direction
+        c.addOutput(point(p.x-dx, p.y));
+    }
+}
+
+
diff --git a/compiler/draw/schema/connectorSchema.h b/compiler/draw/schema/connectorSchema.h
new file mode 100644
index 0000000..e35f64f
--- /dev/null
+++ b/compiler/draw/schema/connectorSchema.h
@@ -0,0 +1,64 @@
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __connectorSchema__
+#define __connectorSchema__
+
+
+#include "schema.h"
+#include <vector>
+#include <string>
+
+/**
+ * A simple rectangular box with a text and inputs and outputs.
+ * The constructor is private in order to make sure
+ * makeconnectorSchema is used instead
+ */
+class connectorSchema : public schema
+{
+  protected:
+    // fields only defined after place() is called
+    vector<point>	fInputPoint;	///< input connection points
+    vector<point>	fOutputPoint;	///< output connection points
+
+
+  public:
+    friend schema*  makeConnectorSchema ();
+
+    virtual void 	place(double x, double y, int orientation);
+    virtual void 	draw(device& dev);
+    virtual point	inputPoint(unsigned int i) const;
+    virtual point 	outputPoint(unsigned int i) const;
+    virtual void    collectTraits(collector& c);
+
+  protected:
+    connectorSchema ();
+
+    void placeInputPoints();
+    void placeOutputPoints();
+    void collectInputWires(collector& c);
+    void collectOutputWires(collector& c);
+
+};
+
+#endif
+
+
diff --git a/compiler/draw/schema/cutSchema.h b/compiler/draw/schema/cutSchema.h
index a218048..6e67c84 100644
--- a/compiler/draw/schema/cutSchema.h
+++ b/compiler/draw/schema/cutSchema.h
@@ -34,7 +34,7 @@ class cutSchema : public schema
 	point	fPoint;
 
   public:
-  	friend schema* makeCutSchema ();
+    friend schema*  makeCutSchema ();
 	virtual void 	place(double x, double y, int orientation);
 	virtual void 	draw(device& dev);
 	virtual point	inputPoint(unsigned int i)	const;
diff --git a/compiler/draw/schema/decorateSchema.h b/compiler/draw/schema/decorateSchema.h
index 16c1c6c..f541319 100644
--- a/compiler/draw/schema/decorateSchema.h
+++ b/compiler/draw/schema/decorateSchema.h
@@ -40,13 +40,13 @@ class decorateSchema : public schema
 	vector<point>	fOutputPoint;
 
   public:
-	friend schema* makeDecorateSchema (schema* s1, double margin, const string& text);
+    friend schema*  makeDecorateSchema (schema* s1, double margin, const string& text);
 
 	virtual void 	place(double ox, double oy, int orientation);
 	virtual void 	draw(device& dev);
-    virtual void    collectTraits(collector& c);
     virtual point	inputPoint(unsigned int i)	const;
 	virtual point 	outputPoint(unsigned int i)	const;
+    virtual void    collectTraits(collector& c);
 
   private:
 	decorateSchema (schema* s1, double margin, const string& text);
diff --git a/compiler/draw/schema/inverterSchema.cpp b/compiler/draw/schema/inverterSchema.cpp
index 7004752..1e2729a 100644
--- a/compiler/draw/schema/inverterSchema.cpp
+++ b/compiler/draw/schema/inverterSchema.cpp
@@ -29,6 +29,7 @@ using namespace std;
 
 //#define invcolor "#f44444"
 
+
 /**
  * Build n cables in parallel
  */
diff --git a/compiler/draw/schema/mergeSchema.h b/compiler/draw/schema/mergeSchema.h
index 5b56ea4..7fb8b73 100644
--- a/compiler/draw/schema/mergeSchema.h
+++ b/compiler/draw/schema/mergeSchema.h
@@ -38,7 +38,7 @@ class mergeSchema : public schema
 
   public:
 
-	friend schema* makeMergeSchema (schema* s1, schema* s2);
+    friend schema*  makeMergeSchema (schema* s1, schema* s2);
 
 	virtual void 	place(double ox, double oy, int orientation);
 	virtual void 	draw(device& dev);
diff --git a/compiler/draw/schema/recSchema.cpp b/compiler/draw/schema/recSchema.cpp
index df96f4d..8a72f45 100644
--- a/compiler/draw/schema/recSchema.cpp
+++ b/compiler/draw/schema/recSchema.cpp
@@ -123,9 +123,8 @@ point recSchema::outputPoint(unsigned int i) const
 
 
 /**
- * Draw the two subschema s1 and s2 as well as the feedback
- * connections between s1 and s2, and the feedfrom connections
- * beetween s2 and s1.
+ * Draw the two subschema s1 and s2 as well as the implicit feedback
+ * delays between s1 and s2.
  */
 void recSchema::draw(device& dev)
 {
@@ -135,33 +134,15 @@ void recSchema::draw(device& dev)
     fSchema1->draw(dev);
     fSchema2->draw(dev);
 
-    // draw the output lines
-    for (unsigned int i=0; i<outputs(); i++) {
-        point p = fSchema1->outputPoint(i);
-        point q = outputPoint(i);
-        //dev.trait(p.x, p.y, q.x, q.y);
-    }
-
-    // draw the input lines
-    unsigned int skip = fSchema2->outputs();
-    for (unsigned int i=0; i<inputs(); i++) {
-        point p = fSchema1->inputPoint(i+skip);
-        point q = inputPoint(i);
-        //dev.trait(p.x, p.y, q.x, q.y);
-    }
-
-    // draw the feedback connections to each fSchema2 input
+    // draw the implicit feedback delay to each fSchema2 input
+    double dw = (orientation()==kLeftRight) ? dWire : -dWire;
     for (unsigned int i=0; i<fSchema2->inputs(); i++) {
-        drawFeedback(dev, fSchema1->outputPoint(i), fSchema2->inputPoint(i), i*dWire);
-    }
+        const point& p = fSchema1->outputPoint(i);
+        drawDelaySign(dev, p.x + i*dw, p.y, dw/2);
 
-    // draw the feedfront connections from each fSchema2 output
-    for (unsigned int i=0; i<fSchema2->outputs(); i++) {
-        drawFeedfront(dev, fSchema2->outputPoint(i), fSchema1->inputPoint(i), i*dWire);
     }
 }
 
-
 /**
  * Draw the delay sign of a feedback connection
  */
@@ -218,22 +199,6 @@ void recSchema::collectTraits(collector& c)
  * Draw a feedback connection between two points with an horizontal
  * displacement dx
  */
-void recSchema::drawFeedback(device& dev, const point& src, const point& dst, double dx)
-{
-    double	ox = src.x + ((orientation()==kLeftRight) ? dx : -dx);
-    double	ct = (orientation()==kLeftRight) ? dWire/2 : -dWire/2;
-
-    drawDelaySign(dev, ox, src.y, ct);
-    //dev.trait(ox, src.y-ct, ox, dst.y);
-    //dev.trait(ox, dst.y, dst.x, dst.y);
-}
-
-
-
-/**
- * Draw a feedback connection between two points with an horizontal
- * displacement dx
- */
 void recSchema::collectFeedback(collector& c, const point& src, const point& dst, double dx, const point& out)
 {
     double	ox = src.x + ((orientation()==kLeftRight) ? dx : -dx);
@@ -258,20 +223,6 @@ void recSchema::collectFeedback(collector& c, const point& src, const point& dst
  * Draw a feedfrom connection between two points with an horizontal
  * displacement dx
  */
-void recSchema::drawFeedfront(device& dev, const point& src, const point& dst, double dx)
-{
-//    double	ox = src.x + ((orientation()==kLeftRight) ? -dx : dx);
-
-//	dev.trait(ox, src.y, src.x, src.y);
-//	dev.trait(ox, src.y, ox, dst.y);
-//	dev.trait(ox, dst.y, dst.x, dst.y);
-}
-
-
-/**
- * Draw a feedfrom connection between two points with an horizontal
- * displacement dx
- */
 void recSchema::collectFeedfront(collector& c, const point& src, const point& dst, double dx)
 {
     double	ox = src.x + ((orientation()==kLeftRight) ? -dx : dx);
diff --git a/compiler/draw/schema/recSchema.h b/compiler/draw/schema/recSchema.h
index 1f6b046..7881a59 100644
--- a/compiler/draw/schema/recSchema.h
+++ b/compiler/draw/schema/recSchema.h
@@ -38,7 +38,7 @@ class recSchema : public schema
 	vector<point>	fOutputPoint;
 
   public:
-	friend schema* makeRecSchema (schema* s1, schema* s2);
+    friend schema*  makeRecSchema (schema* s1, schema* s2);
 
 	virtual void 	place(double ox, double oy, int orientation);
 	virtual void 	draw(device& dev);
@@ -49,8 +49,6 @@ class recSchema : public schema
   private:
 	recSchema (schema* s1, schema* s2, double width);
 	void 			drawDelaySign(device& dev, double x, double y, double size);
-    void 			drawFeedback(device& dev, const point& src, const point& dst, double dx);
-    void 			drawFeedfront(device& dev, const point& src, const point& dst, double dx);
 
     void 			collectFeedback(collector& c, const point& src, const point& dst, double dx, const point& out);
     void 			collectFeedfront(collector& c, const point& src, const point& dst, double dx);
diff --git a/compiler/draw/schema/schema.h b/compiler/draw/schema/schema.h
index dff27b0..de40c26 100644
--- a/compiler/draw/schema/schema.h
+++ b/compiler/draw/schema/schema.h
@@ -143,9 +143,9 @@ class schema
  	// abstract interface for subclasses
 	virtual void 	place(double x, double y, int orientation) 	= 0;
     virtual void 	draw(device& dev) 							= 0;
-    virtual void 	collectTraits(collector& c)					= 0;
     virtual point	inputPoint(unsigned int i) const			= 0;
 	virtual point 	outputPoint(unsigned int i)const			= 0;
+    virtual void 	collectTraits(collector& c)					= 0;
 };
 
 // various functions to create schemas
@@ -155,7 +155,6 @@ schema* makeBlockSchema 	(unsigned int inputs,
   							 const string& name,
 							 const string& color,
 							 const string& link);
-
 schema* makeCableSchema 	(unsigned int n=1);
 schema* makeInverterSchema 	(const string& color);
 schema* makeCutSchema 		();
@@ -167,6 +166,7 @@ schema* makeSplitSchema 	(schema* s1, schema* s2);
 schema* makeRecSchema 		(schema* s1, schema* s2);
 schema* makeTopSchema 		(schema* s1, double margin, const string& text, const string& link);
 schema* makeDecorateSchema 	(schema* s1, double margin, const string& text);
+schema* makeConnectorSchema ();
 
 
 
diff --git a/compiler/draw/schema/splitSchema.h b/compiler/draw/schema/splitSchema.h
index e7a0e7b..bf20959 100644
--- a/compiler/draw/schema/splitSchema.h
+++ b/compiler/draw/schema/splitSchema.h
@@ -38,7 +38,7 @@ class splitSchema : public schema
 
  public:
 
- 	friend schema* makeSplitSchema (schema* s1, schema* s2);
+    friend schema*  makeSplitSchema (schema* s1, schema* s2);
 
 	virtual void 	place(double ox, double oy, int orientation);
 	virtual void 	draw(device& dev);
diff --git a/compiler/draw/schema/topSchema.h b/compiler/draw/schema/topSchema.h
index 9f4f1c5..ddcfbd4 100644
--- a/compiler/draw/schema/topSchema.h
+++ b/compiler/draw/schema/topSchema.h
@@ -41,7 +41,7 @@ class topSchema : public schema
 	vector<point>	fOutputPoint;
 
   public:
-	friend schema* makeTopSchema (schema* s1, double margin, const string& text, const string& link);
+    friend schema*  makeTopSchema (schema* s1, double margin, const string& text, const string& link);
 
 	virtual void 	place(double ox, double oy, int orientation);
 	virtual void 	draw(device& dev);
diff --git a/compiler/draw/sigToGraph.cpp b/compiler/draw/sigToGraph.cpp
index 8a7a277..4086167 100644
--- a/compiler/draw/sigToGraph.cpp
+++ b/compiler/draw/sigToGraph.cpp
@@ -96,8 +96,10 @@ static void recdraw(Tree sig, set<Tree>& drawn, ofstream& fout )
             n = getSubSignals(sig, subsig);
             if (n > 0) {
                 if (n==1 && isList(subsig[0])) {
-                    Tree id, body;
+					Tree id, body;
                     assert(isRec(sig,id,body));
+					if (!isRec(sig,id,body)) {
+					}
                     // special recursion case, recreate a vector of subsignals instead of the
                     // list provided by getSubSignal
                     Tree L = subsig[0];
@@ -192,6 +194,8 @@ static string sigLabel(Tree sig)
          if (p)                                     { fout << p->name(); }
     else if ( isSigInt(sig, &i) )                   { fout << i;	}
     else if ( isSigReal(sig, &r) )                  { fout << r;	}
+    else if ( isSigWaveform(sig))                   { fout << "waveform";  }
+
     else if ( isSigInput(sig, &i) )                 { fout << "INPUT_" << i; }
     else if ( isSigOutput(sig, &i, x) )             { fout << "OUTPUT_" << i; }
 
diff --git a/compiler/errors/errormsg.cpp b/compiler/errors/errormsg.cpp
index 443d085..b5694e4 100644
--- a/compiler/errors/errormsg.cpp
+++ b/compiler/errors/errormsg.cpp
@@ -31,7 +31,7 @@ const char* yyfilename = "????";
 int 		gErrorCount = 0;
 Tree 		DEFLINEPROP = tree(symbol("DefLineProp"));
 
-void yyerror(char* msg) 
+void yyerror(const char* msg) 
 { 
 	fprintf(stderr, "%s:%d:%s\n", yyfilename, yylineno, msg); 
 	gErrorCount++;
diff --git a/compiler/errors/errormsg.hh b/compiler/errors/errormsg.hh
index 196d641..b35b595 100644
--- a/compiler/errors/errormsg.hh
+++ b/compiler/errors/errormsg.hh
@@ -37,7 +37,7 @@ const char* getDefFileProp(Tree sym);
 int 		getDefLineProp(Tree sym);
 
 // Parsing error
-void 		yyerror(char* msg);
+void 		yyerror(const char* msg);
 
 // three levels or errors, warnings and remarks are provided during evaluation
 void 		evalerror(const char* filename, int linenum, const char* msg, Tree exp);
diff --git a/compiler/errors/timing.cpp b/compiler/errors/timing.cpp
index ac35163..60af6f7 100644
--- a/compiler/errors/timing.cpp
+++ b/compiler/errors/timing.cpp
@@ -3,19 +3,20 @@
 #ifndef WIN32
 #include <sys/time.h>
 #endif
+#include "compatibility.hh"
 #include "timing.hh"
 
 using namespace std;
 
+extern bool gTimingSwitch;
 
-#if 0
+#if 1
 double mysecond()
 {
         struct timeval tp;
         struct timezone tzp;
-        int i;
 
-        i = gettimeofday(&tp,&tzp);
+        gettimeofday(&tp,&tzp);
         return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
 }
 
@@ -31,16 +32,20 @@ static void tab (int n, ostream& fout)
 
 void startTiming (const char* msg)
 {
-	assert(lIndex < 1023);
-	tab(lIndex, cerr); cerr << "start " << msg << endl;
-	lStartTime[lIndex++] = mysecond();
+    if (gTimingSwitch) {
+        assert(lIndex < 1023);
+        tab(lIndex, cerr); cerr << "start " << msg << endl;
+        lStartTime[lIndex++] = mysecond();
+    }
 }
 
 void endTiming (const char* msg)
 {
-	assert(lIndex>0);
-	lEndTime[--lIndex] = mysecond();
-	tab(lIndex, cerr); cerr << "end " << msg << " (duration : " << lEndTime[lIndex] - lStartTime[lIndex] << ")" << endl;
+    if (gTimingSwitch) {
+        assert(lIndex>0);
+        lEndTime[--lIndex] = mysecond();
+        tab(lIndex, cerr); cerr << "end " << msg << " (duration : " << lEndTime[lIndex] - lStartTime[lIndex] << ")" << endl;
+    }
 }
 
 #else
diff --git a/compiler/evaluate/eval.cpp b/compiler/evaluate/eval.cpp
index ae688b1..1a975a1 100644
--- a/compiler/evaluate/eval.cpp
+++ b/compiler/evaluate/eval.cpp
@@ -42,9 +42,8 @@
 #include "property.hh"
 #include "names.hh"
 #include "compatibility.hh"
-
-
 #include <assert.h>
+
 extern SourceReader	gReader;
 extern int  gMaxNameSize;
 extern bool	gSimpleNames;
@@ -204,6 +203,10 @@ static Tree real_a2sb(Tree exp)
 		if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
 		return result;
 
+    } else if (isBoxWaveform(exp)) {
+        // A waveform is always in Normal Form, nothing to evaluate
+        return exp;
+
 	} else {
 		// it is a constructor : transform each branches
         unsigned int    ar = exp->arity();
@@ -329,7 +332,8 @@ static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
 			isBoxPrim0(exp) || isBoxPrim1(exp) || 
 			isBoxPrim2(exp) || isBoxPrim3(exp) || 
 			isBoxPrim4(exp) || isBoxPrim5(exp) ||
-			isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) ) {
+            isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) ||
+            isBoxWaveform(exp)) {
 		return exp;
 
 	// block-diagram constructors
@@ -476,7 +480,8 @@ static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
 		return evalIdDef(exp, visited, localValEnv);
 
 	} else if (isBoxWithLocalDef(exp, body, ldef)) {
-		return eval(body, visited, pushMultiClosureDefs(ldef, visited, localValEnv));
+        Tree expandedldef = gReader.expandlist(ldef);
+        return eval(body, visited, pushMultiClosureDefs(expandedldef, visited, localValEnv));
 	
 	} else if (isBoxAppl(exp, fun, arg)) {
         return applyList( eval(fun, visited, localValEnv),
@@ -518,10 +523,32 @@ static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
 		int n = eval2int(num, visited, localValEnv);
 		return iterateSum(var, n, body, visited, localValEnv);
 
-	} else if (isBoxIProd(exp, var, num, body)) {
-		int n = eval2int(num, visited, localValEnv);
-		return iterateProd(var, n, body, visited, localValEnv);
-		
+    } else if (isBoxIProd(exp, var, num, body)) {
+        int n = eval2int(num, visited, localValEnv);
+        return iterateProd(var, n, body, visited, localValEnv);
+
+    // static
+    } else if (isBoxInputs(exp, body)) {
+        int ins, outs;
+        Tree b = a2sb(eval(body, visited, localValEnv));
+        if (getBoxType (b, &ins, &outs)) {
+            return boxInt(ins);
+        } else {
+            cerr << "ERROR : can't evaluate ' : " << *exp << endl;
+            assert(false);
+        }
+
+    } else if (isBoxOutputs(exp, body)) {
+        int ins, outs;
+        Tree b = a2sb(eval(body, visited, localValEnv));
+        if (getBoxType (b, &ins, &outs)) {
+            return boxInt(outs);
+        } else {
+            cerr << "ERROR : can't evaluate ' : " << *exp << endl;
+            assert(false);
+        }
+
+
 	} else if (isBoxSlot(exp)) 		{ 
 		return exp; 
 	
@@ -547,6 +574,7 @@ static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
 		cerr << "ERROR : EVAL don't intercept : " << *exp << endl;
 		assert(false);
 	}
+	return NULL;
 }
 
 /* Deconstruct a (BDA) op pattern (YO). */
@@ -605,11 +633,13 @@ static bool isBoxNumeric (Tree in, Tree& out)
     int 	numInputs, numOutputs;
     double 	x;
     int		i;
-    Tree 	v;
+    Tree 	v, abstr, genv, vis, lenv, var, body;
 
     if (isBoxInt(in, &i) || isBoxReal(in, &x)) {
         out = in;
         return true;
+    } else if (isClosure(in, abstr, genv, vis, lenv) && isBoxAbstr(abstr, var, body)) {
+        return false;
     } else {
         v = a2sb(in);
         if ( getBoxType(v, &numInputs, &numOutputs) && (numInputs == 0) && (numOutputs == 1) ) {
@@ -715,72 +745,89 @@ static bool isIdentChar(char c)
 
 const char* Formats [] = {"%d", "%1d", "%2d", "%3d", "%4d"};
 
-static char* writeIdentValue(char* dst, int format, const char* ident, Tree visited, Tree localValEnv)
+static void writeIdentValue(std::string& dst, const std::string& format, const std::string& ident, Tree visited, Tree localValEnv)
 {
-	int n = eval2int(boxIdent(ident), visited, localValEnv);
-    int i = min(4,max(format,0));
+    int     f = atoi(format.c_str());
+    int     n = eval2int(boxIdent(ident.c_str()), visited, localValEnv);
+    int     i = min(4,max(f,0));
+    char    val[256];
     
-	return dst + sprintf(dst, Formats[i], n);
+    snprintf(val, 250, Formats[i], n);
+    dst += val;
 }
 
-static const char * evalLabel (const char* label, Tree visited, Tree localValEnv)
+
+/**
+ * evallabel replace "...%2i..." occurences in label with value of i
+ */
+static const char * evalLabel (const char* src, Tree visited, Tree localValEnv)
 {
-	char 		res[2000];
-	char 		ident[64];
-
-	const char* src = &label[0];
-	char*		dst = &res[0];
-	char*		id  = &ident[0];
-
-	bool		parametric = false;
-	int 		state = 0; int format = 0;
-	char		c;
-
-	while ((c=*src++)) {
-		if (state == 0) {
-			// outside ident mode
-			if (c == '%') {
-				// look ahead for next char
-				if (*src == '%') {
-					*dst++ = *src++; 		// copy escape char and skip one char
-				} else {
-					state = 1;				// prepare ident mode
-                    format = 0;
-					parametric = true;
-					id  = &ident[0];
-				}
-			} else {
-				*dst++ = c;					// copy char
-			}
-		} else if (state == 1) {
-            // read the format 
-            if (isDigitChar(c)) {
-                format = format*10 + (c-'0');
+    //std::cerr << "Eval Label : " << src;
+
+    int             state = 0;  // current state
+    std::string     dst;        // label once evaluated
+    std::string     ident;      // current identifier
+    std::string     format;     // current format
+
+    while (state != -1) {
+
+        char c = *src++;
+
+        if (state == 0) {
+
+            if (c == 0) {
+                state = -1;
+            } else if (c == '%') {
+                ident = "";
+                format = "";
+                state = 1;
             } else {
+                dst+=c;
+                state = 0;
+            }
+
+        } else if (state == 1) {
+
+            if (c == 0) {
+                // fin et pas d'indentifiant, abandon
+                dst += '%';
+                dst += format;
+                state = -1;
+            } else if (isDigitChar(c)) {
+                format += c;
+                state = 1;
+            } else if (isIdentChar(c)) {
+                ident += c;
                 state = 2;
-                --src; // unread !!!
+            } else {
+                // caractere de ponctuation et pas d'indentifiant, abandon
+                dst += '%';
+                dst += format;
+                src--;
+                state = 0;
+            }
+
+        } else if (state == 2) {
+
+            if (isIdentChar(c)) {
+                ident += c;
+                state = 2;
+            } else {
+                writeIdentValue(dst, format, ident, visited, localValEnv);
+                src--;
+                state = 0;
             }
 
         } else {
-            
-			// within ident mode
-			if (isIdentChar(c)) {
-				*id++ = c;
-			} else {
-				*id = 0;
-				dst = writeIdentValue(dst, format, ident, visited, localValEnv);
-				state = 0;
-				src -= 1;
-			}
-		}
-	}
 
-	if (state == 2) {
-		*id = 0;
-		dst = writeIdentValue(dst, format, ident, visited, localValEnv);
-	}
-	*dst = 0;
-	return (parametric) ? strdup(res) : label;
+            std::cerr << "internal error in evallabel : undefined state " << state << std::endl;
+            exit(1);
+        }
+    }
+
+    const char* val = strdup(dst.c_str());
+    //std::cerr << "  ===> " << val << std::endl;
+    return val;
 }
 
 
@@ -1280,7 +1327,7 @@ static void list2vec(Tree l, vector<Tree>& v)
 static Tree vec2list(const vector<Tree>& v)
 {
 	Tree l = nil;
-	int	 n = v.size();
+	int	 n = (int)v.size();
 	while (n--) { l = cons(v[n],l); }
 	return l;
 }
diff --git a/compiler/extended/fmodprim.cpp b/compiler/extended/fmodprim.cpp
index 38cdf9b..5f0e4ab 100644
--- a/compiler/extended/fmodprim.cpp
+++ b/compiler/extended/fmodprim.cpp
@@ -9,7 +9,7 @@ class FmodPrim : public xtended
 
  public:
  
- 	FmodPrim() : xtended("fmodf") {}
+   FmodPrim() : xtended("fmod") {}
 	
 	virtual unsigned int 	arity () { return 2; }
 	
@@ -18,7 +18,14 @@ class FmodPrim : public xtended
 	virtual Type 	infereSigType (const vector<Type>& args)
 	{
 		assert (args.size() == arity());
-		return floatCast(args[0]|args[1]);
+        interval i = args[0]->getInterval();
+        interval j = args[1]->getInterval();
+
+        if (j.haszero()) {
+            // potential division by zero
+            //std::cerr << "potential division by zero in fmod(" << i << ", " << j << ")" << std::endl;
+        }
+        return castInterval(floatCast(args[0]|args[1]), fmod(i,j));
 	}
 	
 	virtual void 	sigVisit (Tree sig, sigvisitor* visitor) {}	
diff --git a/compiler/extended/log10prim.cpp b/compiler/extended/log10prim.cpp
index f93cc93..6514c5b 100644
--- a/compiler/extended/log10prim.cpp
+++ b/compiler/extended/log10prim.cpp
@@ -10,7 +10,7 @@ class Log10Prim : public xtended
 
  public:
  
- 	Log10Prim() : xtended("log10f") {}
+    Log10Prim() : xtended("log10") {}
 	
 	virtual unsigned int arity () { return 1; }
 	
diff --git a/compiler/extended/maxprim.cpp b/compiler/extended/maxprim.cpp
index 9c58ca7..b3fee7f 100644
--- a/compiler/extended/maxprim.cpp
+++ b/compiler/extended/maxprim.cpp
@@ -69,14 +69,42 @@ class MaxPrim : public xtended
 	{
 		assert (args.size() == arity());
 		assert (types.size() == arity());
-		
-		Type t = infereSigType(types);
-		if (t->nature() == kReal) {
-			return subst("max($0, $1)", args[0], args[1]);
-		} else {
-			return subst("max($0, $1)", args[0], args[1]);
-		} 			
-	}
+			
+        // generates code compatible with overloaded max
+		int n0 = types[0]->nature();
+		int n1 = types[1]->nature();
+        if (n0==kReal) {
+            if (n1==kReal) {
+                // both are floats, no need to cast
+                return subst("max($0, $1)", args[0], args[1]);
+            } else {
+                assert(n1==kInt); // second argument is not float, cast it to float
+                return subst("max($0, $2$1)", args[0], args[1], icast());
+            }
+        } else if (n1==kReal) {
+            assert(n0==kInt); // first not float but second is, cast first to float
+            return subst("max($2$0, $1)", args[0], args[1], icast());
+        } else {
+            assert(n0==kInt);  assert(n1==kInt);   // both are integers, check for booleans
+            int b0 = types[0]->boolean();
+            int b1 = types[1]->boolean();
+            if (b0==kNum) {
+                if (b1==kNum) {
+                    // both are integers, no need to cast
+                    return subst("max($0, $1)", args[0], args[1]);
+                } else {
+                    assert(b1==kBool);    // second is boolean, cast to int
+                    return subst("max($0, (int)$1)", args[0], args[1]);
+                }
+            } else if (b1==kNum) {
+                assert(b0==kBool);    // first is boolean, cast to int
+                return subst("max((int)$0, $1)", args[0], args[1], icast());
+            } else {
+                assert(b0==kBool); assert(b1==kBool);   // both are booleans, no need to cast
+                return subst("max((int)$0, (int)$1)", args[0], args[1]);
+            }
+        }
+    }
 	
 	virtual string 	generateLateq (Lateq* lateq, const vector<string>& args, const vector<Type>& types)
 	{
diff --git a/compiler/extended/minprim.cpp b/compiler/extended/minprim.cpp
index dd56392..9be8d57 100644
--- a/compiler/extended/minprim.cpp
+++ b/compiler/extended/minprim.cpp
@@ -29,7 +29,7 @@ class MinPrim : public xtended
 	virtual int infereSigOrder (const vector<int>& args) 
 	{
 		assert (args.size() == arity());
-		return max(args[0], args[1]);
+        return max(args[0], args[1]);
 	}
 
 	
@@ -65,19 +65,73 @@ class MinPrim : public xtended
 		}
 	}
 		
-	virtual string 	generateCode (Klass* klass, const vector<string>& args, const vector<Type>& types)
-	{
-		assert (args.size() == arity());
-		assert (types.size() == arity());
-		
-		Type t = infereSigType(types);
-		if (t->nature() == kReal) {
-			return subst("min($0, $1)", args[0], args[1]);
-		} else {
-			return subst("min($0, $1)", args[0], args[1]);
-		} 			
-	}
-	
+//	virtual string 	generateCode (Klass* klass, const vector<string>& args, const vector<Type>& types)
+//	{
+//		assert (args.size() == arity());
+//		assert (types.size() == arity());
+////
+////		Type t = infereSigType(types);
+////		if (t->nature() == kReal) {
+////			return subst("min($0, $1)", args[0], args[1]);
+////		} else {
+////			return subst("min($0, $1)", args[0], args[1]);
+////		}
+
+//		// generates code compatible with overloaded min
+//		int n0 = types[0]->nature();
+//		int n1 = types[1]->nature();
+//		if (n0==n1) {
+//			return subst("min($0, $1)", args[0], args[1]);
+//		} else {
+//			if (n0==kInt) {
+//				return subst("min($2$0, $1)", args[0], args[1], icast());
+//			} else {
+//				return subst("min($0, $2$1)", args[0], args[1], icast());
+//			}
+//		}
+//	}
+
+    virtual string 	generateCode (Klass* klass, const vector<string>& args, const vector<Type>& types)
+    {
+        assert (args.size() == arity());
+        assert (types.size() == arity());
+
+        // generates code compatible with overloaded min
+        int n0 = types[0]->nature();
+        int n1 = types[1]->nature();
+        if (n0==kReal) {
+            if (n1==kReal) {
+                // both are floats, no need to cast
+                return subst("min($0, $1)", args[0], args[1]);
+            } else {
+                assert(n1==kInt); // second argument is not float, cast it to float
+                return subst("min($0, $2$1)", args[0], args[1], icast());
+            }
+        } else if (n1==kReal) {
+            assert(n0==kInt); // first not float but second is, cast first to float
+            return subst("min($2$0, $1)", args[0], args[1], icast());
+        } else {
+            assert(n0==kInt);  assert(n1==kInt);   // both are integers, check for booleans
+            int b0 = types[0]->boolean();
+            int b1 = types[1]->boolean();
+            if (b0==kNum) {
+                if (b1==kNum) {
+                    // both are integers, no need to cast
+                    return subst("min($0, $1)", args[0], args[1]);
+                } else {
+                    assert(b1==kBool);    // second is boolean, cast to int
+                    return subst("min($0, (int)$1)", args[0], args[1]);
+                }
+            } else if (b1==kNum) {
+                assert(b0==kBool);    // first is boolean, cast to int
+                return subst("min((int)$0, $1)", args[0], args[1], icast());
+            } else {
+                assert(b0==kBool); assert(b1==kBool);   // both are booleans, no need to cast
+                return subst("min((int)$0, (int)$1)", args[0], args[1]);
+            }
+        }
+    }
+
 	virtual string 	generateLateq (Lateq* lateq, const vector<string>& args, const vector<Type>& types)
 	{
 		assert (args.size() == arity());
diff --git a/compiler/extended/powprim.cpp b/compiler/extended/powprim.cpp
index bf81b71..c681c9f 100644
--- a/compiler/extended/powprim.cpp
+++ b/compiler/extended/powprim.cpp
@@ -9,7 +9,7 @@ class PowPrim : public xtended
 
  public:
  
- 	PowPrim() : xtended("powf") {}
+    PowPrim() : xtended("pow") {}
 	
 	virtual unsigned int arity () { return 2; }
 	
@@ -19,7 +19,12 @@ class PowPrim : public xtended
 	{
 		assert (args.size() == arity());
         //return castInterval(floatCast(args[0]|args[1]), interval()); // temporary !!!
-        return castInterval(args[0]|args[1], interval()); // temporary !!!
+        //return castInterval(args[0]|args[1], interval()); // temporary !!!
+        
+        interval i = args[0]->getInterval();
+		interval j = args[1]->getInterval();
+		return castInterval(args[0]|args[1], pow(i,j));
+
     }
 	
 	virtual void 	sigVisit (Tree sig, sigvisitor* visitor) {}	
@@ -45,7 +50,7 @@ class PowPrim : public xtended
 		assert (args.size() == arity());
 		assert (types.size() == arity());
 
-        if (types[1]->nature() == kInt) {
+        if ((types[1]->nature() == kInt) && (types[1]->variability() == kKonst) && (types[1]->computability() == kComp)) {
             klass->rememberNeedPowerDef();
             return subst("faustpower<$1>($0)", args[0], args[1]);
         } else {
diff --git a/compiler/extended/rintprim.cpp b/compiler/extended/rintprim.cpp
index b3c148d..ee33eef 100644
--- a/compiler/extended/rintprim.cpp
+++ b/compiler/extended/rintprim.cpp
@@ -5,16 +5,6 @@
 
 #include "floats.hh"
 
-#if defined(WIN32) && ! defined(__MINGW32__) 
-/* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */
-inline double rint(double nr)
-{
-    double f = floor(nr);
-    double c = ceil(nr);
-    return (((c -nr) >= (nr - f)) ? f : c);
-}
-#endif
-
 class RintPrim : public xtended
 {
 
diff --git a/compiler/generator/Text.cpp b/compiler/generator/Text.cpp
index 33f22a9..c91322f 100644
--- a/compiler/generator/Text.cpp
+++ b/compiler/generator/Text.cpp
@@ -134,7 +134,7 @@ string subst (const string& model, const string& a0, const string& a1, const str
 static string substitution (const string& model, const vector<string>& args)
 {
     char 	c;
-    int 	i=0, ilast = model.length()-1;
+    int 	i=0, ilast = (int)model.length()-1;
     string 	result;
 
     while (i < ilast) {
@@ -213,10 +213,7 @@ string unquote(const string& s)
  */
 string quote(const string& s)
 {
-	string q("\"");
-	q += s;
-	q += "\"";
-	return q;
+ 	return "\"" + s + "\"";
 }
 
 string rmWhiteSpaces(const string& s)
diff --git a/compiler/generator/compile.cpp b/compiler/generator/compile.cpp
index 770afcb..608ce79 100644
--- a/compiler/generator/compile.cpp
+++ b/compiler/generator/compile.cpp
@@ -35,29 +35,18 @@ Compile a list of FAUST signals into a C++ class .
 ******************************************************************************
 *****************************************************************************/
 
-
-
 #include "timing.hh"
 #include "compile.hh"
 #include "floats.hh"
 #include "sigtype.hh"
 
 #include <stdio.h>
-//#include <iostream>
-
 #include "sigprint.hh"
 #include "ppsig.hh"
 
 #include "sigtyperules.hh"
 #include "simplify.hh"
 #include "privatise.hh"
-//#include "factorize.hh"
-
-//#include "grouper.hh"
-//#include "sigvisitor.hh"
-
-
-
 
 /*****************************************************************************
 ******************************************************************************
@@ -69,9 +58,7 @@ Compile a list of FAUST signals into a C++ class .
 
 extern int 		gDetailsSwitch;
 extern string 	gMasterName;
-
-
-
+extern map<Tree, set<Tree> > gMetaDataSet;
 
 /*****************************************************************************
 ******************************************************************************
@@ -82,27 +69,22 @@ extern string 	gMasterName;
 *****************************************************************************/
 
 
-
-
-
-
-
 /*****************************************************************************
 							   constructor
 *****************************************************************************/
 
 Compiler::Compiler(const string& name, const string& super, int numInputs, int numOutputs, bool vec)
-		: fClass(new Klass(name, super, numInputs, numOutputs, vec)),
-		  fNeedToDeleteClass(true), 
-		  fUIRoot(uiFolder(cons(tree(0), tree(subst("$0", gMasterName))))),
-		  fDescription(0)
+                : fClass(new Klass(name, super, numInputs, numOutputs, vec)),
+                fNeedToDeleteClass(true), 
+                fUIRoot(uiFolder(cons(tree(0), tree("")))),
+                fDescription(0),fJSON(numInputs, numOutputs)
 {}
 
 Compiler::Compiler(Klass* k)
-		: fClass(k),
-		  fNeedToDeleteClass(false), 
-		  fUIRoot(uiFolder(cons(tree(0), tree(subst("$0", gMasterName))))),
-		  fDescription(0)
+                : fClass(k),
+                  fNeedToDeleteClass(false), 
+                  fUIRoot(uiFolder(cons(tree(0), tree("")))),
+                  fDescription(0),fJSON(k->inputs(), k->outputs())
 {}
 
 
@@ -111,8 +93,6 @@ Compiler::~Compiler()
 	if (fNeedToDeleteClass) delete fClass;
 }
 
-
-
 /*****************************************************************************
 							user interface elements
 *****************************************************************************/
@@ -125,10 +105,9 @@ void Compiler::addUIWidget(Tree path, Tree widget)
 	fUIRoot = putSubFolder(fUIRoot, path, widget);
 }
 
-
 /**
  * Remove fake root folder if not needed (that is if the UI
- * is completely enclosed in one folder
+ * is completely enclosed in one folder)
  */
 Tree Compiler::prepareUserInterfaceTree(Tree t)
 {
@@ -154,22 +133,49 @@ static string wdel(const string& s)
     return s.substr(i,j-i);
 }
 
-
 //================================= BUILD USER INTERFACE METHOD =================================
 
+void Compiler::generateMetaData()
+{
+    // Add global metadata
+    for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
+        if (i->first != tree("author")) {
+            stringstream str1, str2;
+            str1 << *(i->first);
+            str2 << **(i->second.begin());
+            fJSON.declare(str1.str().c_str(), unquote(str2.str()).c_str());
+        } else {
+            for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); j++) {
+                if (j == i->second.begin()) {
+                    stringstream str1, str2;
+                    str1 << *(i->first);
+                    str2 << **j;
+                    fJSON.declare(str1.str().c_str(), unquote(str2.str()).c_str());
+                } else {
+                    stringstream str2;
+                    str2 << **j;
+                    fJSON.declare("contributor", unquote(str2.str()).c_str());
+                }
+            }
+        }
+    }
+}
+
 /**
  * Generate buildUserInterface C++ lines of code corresponding 
  * to user interface element t
  */
 void Compiler::generateUserInterfaceTree(Tree t)
 {
-	Tree 	label, elements, varname, sig;
-
+	Tree label, elements, varname, sig;
+    
+    
 	if (isUiFolder(t, label, elements)) {
-		const int		orient = tree2int(left(label));
-		const char * 	str = tree2str(right(label));
-        const char * 	model;
-
+		const int orient = tree2int(left(label));
+        // Empty labels will be renamed with a 0xABCD (address) kind of name that is ignored and not displayed by UI architectures
+        const char* str = tree2str(right(label));  
+        const char* model;
+          
         // extract metadata from group label str resulting in a simplifiedLabel
 		// and metadata declarations for fictive zone at address 0
         string  simplifiedLabel;
@@ -182,22 +188,23 @@ void Compiler::generateUserInterfaceTree(Tree t)
             const set<string>& values = i->second;
             for (set<string>::const_iterator j = values.begin(); j != values.end(); j++) {
                 fClass->addUICode(subst("interface->declare($0, \"$1\", \"$2\");", "0", wdel(key) ,wdel(*j)));
+                fJSON.declare(NULL, wdel(key).c_str(), wdel(*j).c_str());
             }
         }
+        
         //-----------------
-
-
 		switch (orient) {
-			case 0 : model = "interface->openVerticalBox(\"$0\");"; break;
-			case 1 : model = "interface->openHorizontalBox(\"$0\");"; break;
-			case 2 : model = "interface->openTabBox(\"$0\");"; break;
+			case 0 : model = "interface->openVerticalBox(\"$0\");"; fJSON.openVerticalBox(checkNullLabel(t, simplifiedLabel).c_str()); break;
+			case 1 : model = "interface->openHorizontalBox(\"$0\");"; fJSON.openHorizontalBox(checkNullLabel(t, simplifiedLabel).c_str()); break;
+			case 2 : model = "interface->openTabBox(\"$0\");"; fJSON.openTabBox(checkNullLabel(t, simplifiedLabel).c_str()); break;
 			default :
-					fprintf(stderr, "error in user interface generation 1\n");
+                fprintf(stderr, "error in user interface generation 1\n");
 				exit(1);
 		}
-        fClass->addUICode(subst(model, simplifiedLabel));
+        fClass->addUICode(subst(model, checkNullLabel(t, simplifiedLabel)));
 		generateUserInterfaceElements(elements);
 		fClass->addUICode("interface->closeBox();");
+        fJSON.closeBox();
 
 	} else if (isUiWidget(t, label, varname, sig)) {
 
@@ -231,7 +238,7 @@ void Compiler::generateWidgetCode(Tree fulllabel, Tree varname, Tree sig)
 	Tree path, c, x, y, z;
     string label;
     map<string, set<string> >   metadata;
-
+   
     extractMetadata(tree2str(fulllabel), label, metadata);
 
     // add metadata if any
@@ -239,64 +246,72 @@ void Compiler::generateWidgetCode(Tree fulllabel, Tree varname, Tree sig)
         const string& key = i->first;
         const set<string>& values = i->second;
         for (set<string>::const_iterator j = values.begin(); j != values.end(); j++) {
-            fClass->addUICode(subst("interface->declare(&$0, \"$1\", \"$2\");", tree2str(varname), wdel(key) ,wdel(*j)));
+            fClass->addUICode(subst("interface->declare(&$0, \"$1\", \"$2\");", tree2str(varname), wdel(key), wdel(*j)));
+             fJSON.declare(NULL, wdel(key).c_str(), wdel(*j).c_str());
         }
     }
 
 	if ( isSigButton(sig, path) ) 					{
         fClass->incUIActiveCount();
-		fClass->addUICode(subst("interface->addButton(\"$0\", &$1);", label, tree2str(varname)));
+		fClass->addUICode(subst("interface->addButton(\"$0\", &$1);", checkNullLabel(varname, label), tree2str(varname)));
+        fJSON.addButton(checkNullLabel(varname, label).c_str(), NULL);
 
 	} else if ( isSigCheckbox(sig, path) ) 			{
         fClass->incUIActiveCount();
-		fClass->addUICode(subst("interface->addCheckButton(\"$0\", &$1);", label, tree2str(varname)));
+		fClass->addUICode(subst("interface->addCheckButton(\"$0\", &$1);", checkNullLabel(varname, label), tree2str(varname)));
+        fJSON.addCheckButton(checkNullLabel(varname, label).c_str(), NULL);
 
 	} else if ( isSigVSlider(sig, path,c,x,y,z) )	{
         fClass->incUIActiveCount();
 		fClass->addUICode(subst("interface->addVerticalSlider(\"$0\", &$1, $2, $3, $4, $5);",
-				label,
-				tree2str(varname),
-				T(tree2float(c)),
-				T(tree2float(x)),
-				T(tree2float(y)),
-				T(tree2float(z))));
+                                checkNullLabel(varname, label),
+                                tree2str(varname),
+                                T(tree2float(c)),
+                                T(tree2float(x)),
+                                T(tree2float(y)),
+                                T(tree2float(z))));
+        fJSON.addVerticalSlider(checkNullLabel(varname, label).c_str(), NULL, tree2float(c), tree2float(x), tree2float(y), tree2float(z));
 
 	} else if ( isSigHSlider(sig, path,c,x,y,z) )	{
         fClass->incUIActiveCount();
 		fClass->addUICode(subst("interface->addHorizontalSlider(\"$0\", &$1, $2, $3, $4, $5);",
-				label,
-				tree2str(varname),
-				T(tree2float(c)),
-				T(tree2float(x)),
-				T(tree2float(y)),
-				T(tree2float(z))));
+                                checkNullLabel(varname, label),
+                                tree2str(varname),
+                                T(tree2float(c)),
+                                T(tree2float(x)),
+                                T(tree2float(y)),
+                                T(tree2float(z))));
+        fJSON.addHorizontalSlider(checkNullLabel(varname, label).c_str(), NULL, tree2float(c), tree2float(x), tree2float(y), tree2float(z));
 
 	} else if ( isSigNumEntry(sig, path,c,x,y,z) )	{
         fClass->incUIActiveCount();
 		fClass->addUICode(subst("interface->addNumEntry(\"$0\", &$1, $2, $3, $4, $5);",
-				label,
-				tree2str(varname),
-				T(tree2float(c)),
-				T(tree2float(x)),
-				T(tree2float(y)),
-				T(tree2float(z))));
+                                checkNullLabel(varname, label),
+                                tree2str(varname),
+                                T(tree2float(c)),
+                                T(tree2float(x)),
+                                T(tree2float(y)),
+                                T(tree2float(z))));
+        fJSON.addNumEntry(checkNullLabel(varname, label).c_str(), NULL, tree2float(c), tree2float(x), tree2float(y), tree2float(z));
 
 	} else if ( isSigVBargraph(sig, path,x,y,z) )	{
         fClass->incUIPassiveCount();
 		fClass->addUICode(subst("interface->addVerticalBargraph(\"$0\", &$1, $2, $3);",
-				label,
-				tree2str(varname),
-				T(tree2float(x)),
-				T(tree2float(y))));
+                                checkNullLabel(varname, label, true),
+                                tree2str(varname),
+                                T(tree2float(x)),
+                                T(tree2float(y))));
+        fJSON.addVerticalBargraph(checkNullLabel(varname, label).c_str(), NULL, tree2float(x), tree2float(y));
 
 	} else if ( isSigHBargraph(sig, path,x,y,z) )	{
         fClass->incUIPassiveCount();
 		fClass->addUICode(subst("interface->addHorizontalBargraph(\"$0\", &$1, $2, $3);",
-                label,
-				tree2str(varname),
-				T(tree2float(x)),
-				T(tree2float(y))));
-
+                                checkNullLabel(varname, label, true),
+                                tree2str(varname),
+                                T(tree2float(x)),
+                                T(tree2float(y))));
+        fJSON.addHorizontalBargraph(checkNullLabel(varname, label).c_str(), NULL, tree2float(x), tree2float(y));
+        
 	} else {
 		fprintf(stderr, "Error in generating widget code\n");
 		exit(1);
@@ -332,7 +347,6 @@ void Compiler::generateMacroInterfaceTree(const string& pathname, Tree t)
 	}
 }
 
-
 /**
  * Iterate generateMacroInterfaceTree on a list of user interface elements
  */
@@ -344,7 +358,6 @@ void Compiler::generateMacroInterfaceElements(const string& pathname, Tree eleme
 	}
 }
 
-
 /**
  * Generate user interface macros corresponding 
  * to a user interface widget
diff --git a/compiler/generator/compile.hh b/compiler/generator/compile.hh
index e0167f6..d92ee2f 100644
--- a/compiler/generator/compile.hh
+++ b/compiler/generator/compile.hh
@@ -35,6 +35,7 @@
 #include <map>
 
 #include "description.hh"
+#include "faust/gui/JSONUI.h"
 
 ////////////////////////////////////////////////////////////////////////
 /**
@@ -54,6 +55,7 @@ protected:
 	bool			fNeedToDeleteClass;
 	Tree			fUIRoot;
 	Description*	fDescription;
+    JSONUI          fJSON;
 
 public:
 	Compiler (const string& name, const string& super, int numInputs, int numOutputs, bool vec);
@@ -80,6 +82,7 @@ protected:
 // gestion de la description arborescente de l'IU
 	void 		addUIWidget(Tree path, Tree widget);
 	void 		generateWidgetCode(Tree fulllabel, Tree varname, Tree sig);
+    void        generateMetaData();
 	void 		generateUserInterfaceTree(Tree t);
 	void 		generateUserInterfaceElements(Tree elements);
 	Tree 		prepareUserInterfaceTree(Tree t);
diff --git a/compiler/generator/compile_scal.cpp b/compiler/generator/compile_scal.cpp
index 5cee6fa..2f642ec 100644
--- a/compiler/generator/compile_scal.cpp
+++ b/compiler/generator/compile_scal.cpp
@@ -53,24 +53,28 @@
 
 using namespace std;
 
+extern bool     gInPlace;
+extern bool     gDrawSignals;
+extern bool     gPrintJSONSwitch;
 extern bool     gDrawSignals;
-extern bool     gLessTempSwitch;
 extern int      gMaxCopyDelay;
 extern string   gClassName;
 extern string   gMasterDocument;
 
-static Klass* signal2klass (const string& name, Tree sig)
+string makeDrawPath();
+
+static Klass* signal2klass (Klass* parent, const string& name, Tree sig)
 {
 	Type t = getCertifiedSigType(sig); //, NULLENV);
 	if (t->nature() == kInt) {
 
-		ScalarCompiler C( new SigIntGenKlass(name) );
+        ScalarCompiler C( new SigIntGenKlass(parent, name) );
 		C.compileSingleSignal(sig);
 		return C.getClass();
 
 	} else {
 
-		ScalarCompiler C( new SigFloatGenKlass(name) );
+        ScalarCompiler C( new SigFloatGenKlass(parent, name) );
 		C.compileSingleSignal(sig);
 		return C.getClass();
 
@@ -128,9 +132,10 @@ startTiming("ScalarCompiler::prepare");
 endTiming("ScalarCompiler::prepare");
 
     if (gDrawSignals) {
-        ofstream dotfile(subst("$0-sig.dot", gMasterDocument).c_str());
+        ofstream dotfile(subst("$0-sig.dot", makeDrawPath()).c_str());
         sigToGraph(L3, dotfile);
     }
+    
   	return L3;
 }
 
@@ -157,6 +162,9 @@ void ScalarCompiler::compileMultiSignal (Tree L)
 
     for (int i = 0; i < fClass->inputs(); i++) {
         fClass->addZone3(subst("$1* input$0 = input[$0];", T(i), xfloat()));
+        if (gInPlace) {
+        	CS(sigInput(i));
+        }
     }
     for (int i = 0; i < fClass->outputs(); i++) {
         fClass->addZone3(subst("$1* output$0 = output[$0];", T(i), xfloat()));
@@ -166,11 +174,18 @@ void ScalarCompiler::compileMultiSignal (Tree L)
 		Tree sig = hd(L);
 		fClass->addExecCode(subst("output$0[i] = $2$1;", T(i), CS(sig), xcast()));
 	}
+    
+    generateMetaData();
 	generateUserInterfaceTree(prepareUserInterfaceTree(fUIRoot));
 	generateMacroInterfaceTree("", prepareUserInterfaceTree(fUIRoot));
 	if (fDescription) {
 		fDescription->ui(prepareUserInterfaceTree(fUIRoot));
 	}
+    
+    if (gPrintJSONSwitch) {
+        ofstream xout(subst("$0.json", makeDrawPath()).c_str());
+        xout << fJSON.JSON();
+    } 
 }
 
 
@@ -263,13 +278,14 @@ string	ScalarCompiler::generateCode (Tree sig)
 
 	int 	i;
 	double	r;
-	Tree 	c, sel, x, y, z, label, id, ff, largs, type, name, file;
+    Tree 	c, sel, x, y, z, label, id, ff, largs, type, name, file;
 
 	//printf("compilation of %p : ", sig); print(sig); printf("\n");
 
 		 if ( getUserData(sig) ) 					{ return generateXtended(sig); }
 	else if ( isSigInt(sig, &i) ) 					{ return generateNumber(sig, T(i)); }
 	else if ( isSigReal(sig, &r) ) 					{ return generateNumber(sig, T(r)); }
+    else if ( isSigWaveform(sig) )                  { return generateWaveform(sig); }
 	else if ( isSigInput(sig, &i) ) 				{ return generateInput 	(sig, T(i)); 			}
 	else if ( isSigOutput(sig, &i, x) ) 			{ return generateOutput 	(sig, T(i), CS(x));}
 
@@ -373,7 +389,12 @@ string ScalarCompiler::generateFVar (Tree sig, const string& file, const string&
 
 string ScalarCompiler::generateInput (Tree sig, const string& idx)
 {
-	return generateCacheCode(sig, subst("$1input$0[i]", idx, icast()));
+    if (gInPlace) {
+        // inputs must be cached for in-place transformations
+        return forceCacheCode(sig, subst("$1input$0[i]", idx, icast()));
+    } else {
+        return generateCacheCode(sig, subst("$1input$0[i]", idx, icast()));
+    }
 }
 
 
@@ -391,7 +412,32 @@ string ScalarCompiler::generateOutput (Tree sig, const string& idx, const string
 
 string ScalarCompiler::generateBinOp(Tree sig, int opcode, Tree arg1, Tree arg2)
 {
-	return generateCacheCode(sig, subst("($0 $1 $2)", CS(arg1), gBinOpTable[opcode]->fName, CS(arg2)));
+    if (opcode == kDiv) {
+        // special handling for division, we always want a float division
+        Type        t1 = getCertifiedSigType(arg1);
+        Type        t2 = getCertifiedSigType(arg2);
+
+        interval    j = t2->getInterval();
+
+        if (j.haszero()) {
+            // potential division by zero
+            // interval    i = t1->getInterval();
+            //std::cerr << "WARNING : potential division by zero (" << i << "/" << j << ") in " << ppsig(sig) << std::endl;
+        }
+
+
+        if (t1->nature()==kInt && t2->nature()==kInt ) {
+            return generateCacheCode(sig, subst("($3($0) $1 $3($2))", CS(arg1), gBinOpTable[opcode]->fName, CS(arg2), ifloat()));
+        } else if (t1->nature()==kInt && t2->nature()==kReal ) {
+            return generateCacheCode(sig, subst("($3($0) $1 $2)", CS(arg1), gBinOpTable[opcode]->fName, CS(arg2), ifloat()));
+        } else if (t1->nature()==kReal && t2->nature()==kInt ) {
+            return generateCacheCode(sig, subst("($0 $1 $3($2))", CS(arg1), gBinOpTable[opcode]->fName, CS(arg2), ifloat()));
+        } else  {
+            return generateCacheCode(sig, subst("($0 $1 $2)", CS(arg1), gBinOpTable[opcode]->fName, CS(arg2), ifloat()));
+        }
+    } else {
+        return generateCacheCode(sig, subst("($0 $1 $2)", CS(arg1), gBinOpTable[opcode]->fName, CS(arg2)));
+    }
 }
 
 
@@ -467,6 +513,30 @@ string ScalarCompiler::generateCacheCode(Tree sig, const string& exp)
 	return "Error in generateCacheCode";
 }
 
+// like generateCacheCode but we force caching like if sharing was always > 1
+string ScalarCompiler::forceCacheCode(Tree sig, const string& exp)
+{
+	string 		vname, ctype, code;
+	Occurences* o = fOccMarkup.retrieve(sig);
+
+	// check reentrance
+    if (getCompiledExpression(sig, code)) {
+        return code;
+    }
+
+	// check for expression occuring in delays
+	if (o->getMaxDelay()>0) {
+
+        getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname);
+        return generateDelayVec(sig, generateVariableStore(sig,exp), ctype, vname, o->getMaxDelay());
+
+	} else  {
+
+        return generateVariableStore(sig, exp);
+
+	}
+}
+
 
 string ScalarCompiler::generateVariableStore(Tree sig, const string& exp)
 {
@@ -524,7 +594,9 @@ string ScalarCompiler::generateButton(Tree sig, Tree path)
 	fClass->addDeclCode(subst("$1 \t$0;", varname, xfloat()));
 	fClass->addInitCode(subst("$0 = 0.0;", varname));
 	addUIWidget(reverse(tl(path)), uiWidget(hd(path), tree(varname), sig));
-	return generateCacheCode(sig, varname);
+
+    //return generateCacheCode(sig, varname);
+    return generateCacheCode(sig, subst("$1($0)", varname, ifloat()));
 }
 
 string ScalarCompiler::generateCheckbox(Tree sig, Tree path)
@@ -533,7 +605,9 @@ string ScalarCompiler::generateCheckbox(Tree sig, Tree path)
 	fClass->addDeclCode(subst("$1 \t$0;", varname, xfloat()));
 	fClass->addInitCode(subst("$0 = 0.0;", varname));
 	addUIWidget(reverse(tl(path)), uiWidget(hd(path), tree(varname), sig));
-	return generateCacheCode(sig, varname);
+
+    //return generateCacheCode(sig, varname);
+    return generateCacheCode(sig, subst("$1($0)", varname, ifloat()));
 }
 
 
@@ -543,7 +617,9 @@ string ScalarCompiler::generateVSlider(Tree sig, Tree path, Tree cur, Tree min,
 	fClass->addDeclCode(subst("$1 \t$0;", varname, xfloat()));
 	fClass->addInitCode(subst("$0 = $1;", varname, T(tree2float(cur))));
 	addUIWidget(reverse(tl(path)), uiWidget(hd(path), tree(varname), sig));
-	return generateCacheCode(sig, varname);
+
+    //return generateCacheCode(sig, varname);
+    return generateCacheCode(sig, subst("$1($0)", varname, ifloat()));
 }
 
 string ScalarCompiler::generateHSlider(Tree sig, Tree path, Tree cur, Tree min, Tree max, Tree step)
@@ -552,7 +628,9 @@ string ScalarCompiler::generateHSlider(Tree sig, Tree path, Tree cur, Tree min,
 	fClass->addDeclCode(subst("$1 \t$0;", varname, xfloat()));
 	fClass->addInitCode(subst("$0 = $1;", varname, T(tree2float(cur))));
 	addUIWidget(reverse(tl(path)), uiWidget(hd(path), tree(varname), sig));
-	return generateCacheCode(sig, varname);
+
+    //return generateCacheCode(sig, varname);
+    return generateCacheCode(sig, subst("$1($0)", varname, ifloat()));
 }
 
 string ScalarCompiler::generateNumEntry(Tree sig, Tree path, Tree cur, Tree min, Tree max, Tree step)
@@ -561,7 +639,9 @@ string ScalarCompiler::generateNumEntry(Tree sig, Tree path, Tree cur, Tree min,
 	fClass->addDeclCode(subst("$1 \t$0;", varname, xfloat()));
 	fClass->addInitCode(subst("$0 = $1;", varname, T(tree2float(cur))));
 	addUIWidget(reverse(tl(path)), uiWidget(hd(path), tree(varname), sig));
-	return generateCacheCode(sig, varname);
+
+    //return generateCacheCode(sig, varname);
+    return generateCacheCode(sig, subst("$1($0)", varname, ifloat()));
 }
 
 
@@ -636,7 +716,7 @@ string ScalarCompiler::generateSigGen(Tree sig, Tree content)
 	string klassname = getFreshID("SIG");
 	string signame = getFreshID("sig");
 
-	fClass->addSubKlass(signal2klass(klassname, content));
+    fClass->addSubKlass(signal2klass(fClass, klassname, content));
 	fClass->addInitCode(subst("$0 $1;", klassname, signame));
     fInstanceInitProperty.set(content, pair<string,string>(klassname,signame));
 
@@ -648,7 +728,7 @@ string ScalarCompiler::generateStaticSigGen(Tree sig, Tree content)
 	string klassname = getFreshID("SIG");
 	string signame = getFreshID("sig");
 
-	fClass->addSubKlass(signal2klass(klassname, content));
+    fClass->addSubKlass(signal2klass(fClass, klassname, content));
 	fClass->addStaticInitCode(subst("$0 $1;", klassname, signame));
     fStaticInitProperty.set(content, pair<string,string>(klassname,signame));
 
@@ -1048,7 +1128,7 @@ string ScalarCompiler::generateXtended 	(Tree sig)
  */
 void ScalarCompiler::setVectorNameProperty(Tree sig, const string& vecname)
 {
-        fVectorProperty.set(sig, vecname);
+    fVectorProperty.set(sig, vecname);
 }
 
 
@@ -1112,13 +1192,18 @@ string ScalarCompiler::generateFixDelay (Tree sig, Tree exp, Tree delay)
     //cerr << "ScalarCompiler::generateFixDelay exp = " << *exp << endl;
     //cerr << "ScalarCompiler::generateFixDelay del = " << *delay << endl;
 
-    CS(exp); // ensure exp is compiled to have a vector name
+    string code = CS(exp); // ensure exp is compiled to have a vector name
 
 	mxd = fOccMarkup.retrieve(exp)->getMaxDelay();
 
 	if (! getVectorNameProperty(exp, vecname)) {
-        cerr << "No vector name for : " << ppsig(exp) << endl;
-        assert(0);
+        if (mxd == 0) {
+            //cerr << "it is a pure zero delay : " << code << endl;
+            return code;
+        } else {
+            cerr << "No vector name for : " << ppsig(exp) << endl;
+            assert(0);
+        }
     }
 
     if (mxd == 0) {
@@ -1188,7 +1273,7 @@ string ScalarCompiler::generateDelayVecNoTemp(Tree sig, const string& exp, const
     } else {
 
         // generate code for a long delay : we use a ring buffer of size N = 2**x > mxd
-        int     N = pow2limit(mxd+1);
+        int N = pow2limit(mxd+1);
 
         // we need a iota index
         ensureIotaCode();
@@ -1237,7 +1322,7 @@ void ScalarCompiler::generateDelayLine(const string& ctype, const string& vname,
     } else {
 
         // generate code for a long delay : we use a ring buffer of size N = 2**x > mxd
-        int     N = pow2limit(mxd+1);
+        int N = pow2limit(mxd+1);
 
         // we need a iota index
         ensureIotaCode();
@@ -1257,10 +1342,51 @@ void ScalarCompiler::generateDelayLine(const string& ctype, const string& vname,
  */
 void ScalarCompiler::ensureIotaCode()
 {
-	if (!fHasIota) {
-		fHasIota = true;
-		fClass->addDeclCode("int \tIOTA;");
-		fClass->addInitCode("IOTA = 0;");
-		fClass->addPostCode("IOTA = IOTA+1;");
-	}
+    if (!fHasIota) {
+        fHasIota = true;
+        fClass->addDeclCode("int \tIOTA;");
+        fClass->addInitCode("IOTA = 0;");
+        fClass->addPostCode("IOTA = IOTA+1;");
+    }
+}
+
+/**
+ * Generate code for a waveform. The waveform will be declared as a static field.
+ * The name of the waveform is returned in vname and its size in size.
+ */
+void ScalarCompiler::declareWaveform(Tree sig, string& vname, int& size)
+{
+    // computes C type and unique name for the waveform
+    string ctype;
+    getTypedNames(getCertifiedSigType(sig), "Wave", ctype, vname);
+
+    size = sig->arity();
+
+    // Converts waveform into a string : "{a,b,c,...}"
+    stringstream content;
+
+    char sep = '{';
+    for (int i = 0; i < size; i++) {
+        content << sep << ppsig(sig->branch(i));
+        sep = ',';
+    }
+    content << '}';
+  
+    // Declares the Waveform
+    fClass->addDeclCode(subst("static $0 \t$1[$2];", ctype, vname, T(size)));
+    fClass->addDeclCode(subst("int \tidx$0;", vname));
+    fClass->addInitCode(subst("idx$0 = 0;", vname));
+    fClass->getTopParentKlass()->addStaticFields(
+                subst("$0 \t$1::$2[$3] = ", ctype, fClass->getFullClassName(), vname, T(size) )
+                + content.str() + ";");
+}
+
+string ScalarCompiler::generateWaveform(Tree sig)
+{
+    string  vname;
+    int     size;
+
+    declareWaveform(sig, vname, size);
+    fClass->addPostCode(subst("idx$0 = (idx$0 + 1) % $1;", vname, T(size)));
+    return generateCacheCode(sig, subst("$0[idx$0]", vname));
 }
diff --git a/compiler/generator/compile_scal.hh b/compiler/generator/compile_scal.hh
index 6eaae2e..ce555c9 100644
--- a/compiler/generator/compile_scal.hh
+++ b/compiler/generator/compile_scal.hh
@@ -72,6 +72,7 @@ class ScalarCompiler : public Compiler
     virtual string      CS (Tree sig);
     virtual string      generateCode (Tree sig);
     virtual string      generateCacheCode(Tree sig, const string& exp) ;
+    virtual string      forceCacheCode(Tree sig, const string& exp) ;
 
     virtual string      generateVariableStore(Tree sig, const string& exp);
 
@@ -96,54 +97,57 @@ class ScalarCompiler : public Compiler
 	
 	// generation du code
 	
-	string 		generateXtended		(Tree sig);
+    string          generateXtended		(Tree sig);
 	virtual string 		generateFixDelay	(Tree sig, Tree arg, Tree size);
-	string 		generatePrefix 		(Tree sig, Tree x, Tree e);
-	string 		generateIota		(Tree sig, Tree arg);
-	string 		generateBinOp 		(Tree sig, int opcode, Tree arg1, Tree arg2);
+    string          generatePrefix 		(Tree sig, Tree x, Tree e);
+    string          generateIota		(Tree sig, Tree arg);
+    string          generateBinOp 		(Tree sig, int opcode, Tree arg1, Tree arg2);
 	
-	string 		generateFFun  		(Tree sig, Tree ff, Tree largs);
-	
-	string 		generateInput 		(Tree sig, const string& idx);
-	string 		generateOutput		(Tree sig, const string& idx, const string& arg1);
+    string          generateFFun  		(Tree sig, Tree ff, Tree largs);
+    virtual string      generateWaveform    (Tree sig);
+
+    string          generateInput 		(Tree sig, const string& idx);
+    string          generateOutput		(Tree sig, const string& idx, const string& arg1);
 	
-	string 		generateTable 		(Tree sig, Tree tsize, Tree content);
-	string 		generateStaticTable	(Tree sig, Tree tsize, Tree content);
-	string 		generateWRTbl 		(Tree sig, Tree tbl, Tree idx, Tree data);
-	string 		generateRDTbl 		(Tree sig, Tree tbl, Tree idx);
-	string 		generateSigGen		(Tree sig, Tree content);
-	string		generateStaticSigGen(Tree sig, Tree content);
+    string          generateTable 		(Tree sig, Tree tsize, Tree content);
+    string          generateStaticTable	(Tree sig, Tree tsize, Tree content);
+    string          generateWRTbl 		(Tree sig, Tree tbl, Tree idx, Tree data);
+    string          generateRDTbl 		(Tree sig, Tree tbl, Tree idx);
+    string          generateSigGen		(Tree sig, Tree content);
+    string          generateStaticSigGen(Tree sig, Tree content);
 	
-	string 		generateSelect2 	(Tree sig, Tree sel, Tree s1, Tree s2);
-	string 		generateSelect3 	(Tree sig, Tree sel, Tree s1, Tree s2, Tree s3);
+    string          generateSelect2 	(Tree sig, Tree sel, Tree s1, Tree s2);
+    string          generateSelect3 	(Tree sig, Tree sel, Tree s1, Tree s2, Tree s3);
 	
-	string 		generateRecProj 	(Tree sig, Tree exp, int i);
-    void        generateRec         (Tree sig, Tree var, Tree le);
+    string          generateRecProj 	(Tree sig, Tree exp, int i);
+    void            generateRec         (Tree sig, Tree var, Tree le);
 	
-	string 		generateIntCast   	(Tree sig, Tree x);
-	string 		generateFloatCast 	(Tree sig, Tree x);
+    string          generateIntCast   	(Tree sig, Tree x);
+    string          generateFloatCast 	(Tree sig, Tree x);
 	
-	string 		generateButton 		(Tree sig, Tree label);
-	string 		generateCheckbox 	(Tree sig, Tree label);
-	string 		generateVSlider 	(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step);
-	string 		generateHSlider	 	(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step);
-	string 		generateNumEntry 	(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step);
+    string          generateButton 		(Tree sig, Tree label);
+    string          generateCheckbox 	(Tree sig, Tree label);
+    string          generateVSlider 	(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step);
+    string          generateHSlider	 	(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step);
+    string          generateNumEntry 	(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step);
 	
-	string 		generateVBargraph 	(Tree sig, Tree label, Tree min, Tree max, const string& exp);
-	string 		generateHBargraph	(Tree sig, Tree label, Tree min, Tree max, const string& exp);
+    string          generateVBargraph 	(Tree sig, Tree label, Tree min, Tree max, const string& exp);
+    string          generateHBargraph	(Tree sig, Tree label, Tree min, Tree max, const string& exp);
 
-	string		generateNumber(Tree sig, const string& exp);
-    string      generateFConst (Tree sig, const string& file, const string& name);
-    string      generateFVar (Tree sig, const string& file, const string& name);
+    string          generateNumber(Tree sig, const string& exp);
+    string          generateFConst (Tree sig, const string& file, const string& name);
+    string          generateFVar (Tree sig, const string& file, const string& name);
 	
-	virtual string		generateDelayVec(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd);
-	string		generateDelayVecNoTemp(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd);
+    virtual string  generateDelayVec(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd);
+    string          generateDelayVecNoTemp(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd);
 	//string		generateDelayVecWithTemp(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd);
-    virtual void        generateDelayLine(const string& ctype, const string& vname, int mxd, const string& exp);
+    virtual void    generateDelayLine(const string& ctype, const string& vname, int mxd, const string& exp);
+
+    void            getTypedNames(Type t, const string& prefix, string& ctype, string& vname);
+    void            ensureIotaCode();
+    int             pow2limit(int x);
 
-	void 		getTypedNames(Type t, const string& prefix, string& ctype, string& vname);
-	void 		ensureIotaCode();
-    int         pow2limit(int x);
+    void            declareWaveform(Tree sig, string& vname, int& size);
 
 
 
diff --git a/compiler/generator/compile_vect.cpp b/compiler/generator/compile_vect.cpp
index ad5b04f..9a21eca 100644
--- a/compiler/generator/compile_vect.cpp
+++ b/compiler/generator/compile_vect.cpp
@@ -19,13 +19,18 @@
  ************************************************************************
  ************************************************************************/
 
-
+#include <iostream>
+#include <fstream>
+#include <sstream>
 
 #include "compile_vect.hh"
 #include "floats.hh"
 #include "ppsig.hh"
 
 extern int gVecSize;
+extern bool gPrintJSONSwitch;
+
+string makeDrawPath();
 
 void VectorCompiler::compileMultiSignal (Tree L)
 {
@@ -50,11 +55,17 @@ void VectorCompiler::compileMultiSignal (Tree L)
         fClass->closeLoop(sig);
     }
 
+    generateMetaData();
     generateUserInterfaceTree(prepareUserInterfaceTree(fUIRoot));
  	generateMacroInterfaceTree("", prepareUserInterfaceTree(fUIRoot));
     if (fDescription) {
         fDescription->ui(prepareUserInterfaceTree(fUIRoot));
     }
+    
+    if (gPrintJSONSwitch) {
+        ofstream xout(subst("$0.json", makeDrawPath()).c_str());
+        xout << fJSON.JSON();
+    }
 }
 
 
@@ -346,13 +357,18 @@ string VectorCompiler::generateFixDelay (Tree sig, Tree exp, Tree delay)
 
     //cerr << "VectorCompiler::generateFixDelay " << ppsig(sig) << endl;
 
-    CS(exp); // ensure exp is compiled to have a vector name
+    string code = CS(exp); // ensure exp is compiled to have a vector name
 
     mxd = fOccMarkup.retrieve(exp)->getMaxDelay();
 
     if (! getVectorNameProperty(exp, vecname)) {
-        cerr << "ERROR no vector name for " << ppsig(exp) << endl;
-        exit(1);
+        if (mxd == 0) {
+            //cerr << "it is a pure zero delay : " << code << endl;
+            return code;
+        } else {
+            cerr << "No vector name for : " << ppsig(exp) << endl;
+            assert(0);
+        }
     }
 
     if (mxd == 0) {
@@ -520,3 +536,13 @@ void  VectorCompiler::dlineLoop (const string& tname, const string& dlname, int
     }
 }
 
+
+string VectorCompiler::generateWaveform(Tree sig)
+{
+    string  vname;
+    int     size;
+
+    declareWaveform(sig, vname, size);
+    fClass->addPostCode(subst("idx$0 = (idx$0 + count) % $1;", vname, T(size)) );
+    return generateCacheCode(sig, subst("$0[(idx$0+i)%$1]", vname, T(size)));
+}
diff --git a/compiler/generator/compile_vect.hh b/compiler/generator/compile_vect.hh
index 4fc31d4..606d54d 100644
--- a/compiler/generator/compile_vect.hh
+++ b/compiler/generator/compile_vect.hh
@@ -64,6 +64,7 @@ protected:
     virtual string      generateDelayVec(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd);
     virtual void        vectorLoop (const string& tname, const string& dlname, const string& cexp);
     virtual void        dlineLoop ( const string& tname, const string& dlname, int delay, const string& cexp);
+    virtual string      generateWaveform(Tree sig);
 
     bool    needSeparateLoop(Tree sig);
     
diff --git a/compiler/generator/description.cpp b/compiler/generator/description.cpp
index eacd9a0..f28127a 100644
--- a/compiler/generator/description.cpp
+++ b/compiler/generator/description.cpp
@@ -155,6 +155,7 @@ void Description::print(int n, ostream& fout)
 		tab(n+1,fout);	fout << "<copyright>" 	<< xmlize(fCopyright) 	<< "</copyright>";
 		tab(n+1,fout);	fout << "<license>" 	<< xmlize(fLicense) 	<< "</license>";
 		tab(n+1,fout);	fout << "<version>" 	<< xmlize(fVersion) 	<< "</version>";
+		tab(n+1,fout);	fout << "<classname>" 	<< xmlize(fClassName) 	<< "</classname>";
 		tab(n+1,fout);	fout << "<inputs>" 	    << fInputs 		        << "</inputs>";
 		tab(n+1,fout);	fout << "<outputs>" 	<< fOutputs 	        << "</outputs>";
 
@@ -210,11 +211,10 @@ void Description::addGroup(int level, Tree t)
 	if (isUiFolder(t, label, elements)) {
 
 		const int		orient = tree2int(left(label));
-		const char * 	str = tree2str(right(label));
 
 		addLayoutLine(level, subst("<group type=\"$0\">", groupnames[orient]));
-		addLayoutLine(level+1, subst("<label>$0</label>", xmlize(str)));
-		while (!isNil(elements)) {
+        addLayoutLine(level+1, subst("<label>$0</label>", checkNullLabel(t, xmlize(tree2str(right(label))), false) ));
+        while (!isNil(elements)) {
 			addGroup(level+1, right(hd(elements)));
 			elements = tl(elements);
 		}
@@ -250,7 +250,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fActiveWidgetCount++;
 		addActiveLine(subst("<widget type=\"button\" id=\"$0\">", T(fWidgetID)));
-			addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
+            addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true)  ));
 			addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
 		addActiveLine("</widget>");
 
@@ -259,7 +259,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fActiveWidgetCount++;
 		addActiveLine(subst("<widget type=\"checkbox\" id=\"$0\">", T(fWidgetID)));
-			addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
+            addActiveLine(subst("\t<label>$0</label>", checkNullLabel(sig, xmlize(tree2str(label)), true) ));
 			addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
 		addActiveLine("</widget>");
 
@@ -268,7 +268,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fActiveWidgetCount++;
 		addActiveLine(subst("<widget type=\"vslider\" id=\"$0\">", T(fWidgetID)));
-			addActiveLine(subst("\t<label>$0</label>", 		xmlize(tree2str(label))));
+            addActiveLine(subst("\t<label>$0</label>", 		checkNullLabel(sig, xmlize(tree2str(label)), true) ));
 			addActiveLine(subst("\t<varname>$0</varname>", 	tree2str(varname)));
 			addActiveLine(subst("\t<init>$0</init>", 		T(tree2double(c))));
 			addActiveLine(subst("\t<min>$0</min>", 			T(tree2double(x))));
@@ -281,7 +281,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fActiveWidgetCount++;
 		addActiveLine(subst("<widget type=\"hslider\" id=\"$0\">", T(fWidgetID)));
-			addActiveLine(subst("\t<label>$0</label>", 		xmlize(tree2str(label))));
+            addActiveLine(subst("\t<label>$0</label>", 		checkNullLabel(sig, xmlize(tree2str(label)), true) ));
 			addActiveLine(subst("\t<varname>$0</varname>", 	tree2str(varname)));
 			addActiveLine(subst("\t<init>$0</init>", 		T(tree2double(c))));
 			addActiveLine(subst("\t<min>$0</min>", 			T(tree2double(x))));
@@ -294,7 +294,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fActiveWidgetCount++;
 		addActiveLine(subst("<widget type=\"nentry\" id=\"$0\">", T(fWidgetID)));
-			addActiveLine(subst("\t<label>$0</label>", 		xmlize(tree2str(label))));
+            addActiveLine(subst("\t<label>$0</label>", 		checkNullLabel(sig, xmlize(tree2str(label)), true) ));
 			addActiveLine(subst("\t<varname>$0</varname>", 	tree2str(varname)));
 			addActiveLine(subst("\t<init>$0</init>", 		T(tree2double(c))));
 			addActiveLine(subst("\t<min>$0</min>", 			T(tree2double(x))));
@@ -310,7 +310,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fPassiveWidgetCount++;
 		addPassiveLine(subst("<widget type=\"vbargraph\" id=\"$0\">", T(fWidgetID)));
-			addPassiveLine(subst("\t<label>$0</label>", 	xmlize(tree2str(label))));
+            addPassiveLine(subst("\t<label>$0</label>", 	checkNullLabel(sig, xmlize(tree2str(label)), true) ));
 			addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
 			addPassiveLine(subst("\t<min>$0</min>", 		T(tree2double(x))));
 			addPassiveLine(subst("\t<max>$0</max>", 		T(tree2double(y))));
@@ -321,7 +321,7 @@ int Description::addWidget(Tree label, Tree varname, Tree sig)
 		fWidgetID++;
 		fPassiveWidgetCount++;
 		addPassiveLine(subst("<widget type=\"hbargraph\" id=\"$0\">", T(fWidgetID)));
-			addPassiveLine(subst("\t<label>$0</label>", 	xmlize(tree2str(label))));
+            addPassiveLine(subst("\t<label>$0</label>", 	checkNullLabel(sig, xmlize(tree2str(label)), true) ));
 			addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
 			addPassiveLine(subst("\t<min>$0</min>", 		T(tree2double(x))));
 			addPassiveLine(subst("\t<max>$0</max>", 		T(tree2double(y))));
diff --git a/compiler/generator/description.hh b/compiler/generator/description.hh
index 67d15d2..12d70d5 100644
--- a/compiler/generator/description.hh
+++ b/compiler/generator/description.hh
@@ -27,7 +27,8 @@ class Description
 	string 			fCopyright;
 	string 			fLicense;
 	string 			fVersion;
-	
+
+	string			fClassName;
 	int				fInputs;
 	int				fOutputs;
 	int				fWidgetID;
@@ -60,6 +61,7 @@ class Description
 	Description*	license(const string& s) 		{ fLicense = s; return this; }
 	Description*	version(const string& s) 		{ fVersion = s; return this; }
 	
+	Description*	className(const string& s)		{ fClassName = s; return this; }
 	Description*	inputs(int n) 					{ fInputs = n; 	return this; }
 	Description*	outputs(int n) 					{ fOutputs = n; return this; }
 	
diff --git a/compiler/generator/floats.cpp b/compiler/generator/floats.cpp
index 42187de..5752fdc 100644
--- a/compiler/generator/floats.cpp
+++ b/compiler/generator/floats.cpp
@@ -36,7 +36,7 @@ extern int  gFloatSize;
 
 
 const char* mathsuffix[] = {"", "f", "", "l"};                                  // suffix for math functions
-const char* numsuffix[]  = {"", "f", "", ""};                                   // suffix for numeric constants
+const char* numsuffix[]  = {"", "f", "", "L"};                                   // suffix for numeric constants
 const char* floatname[]  = {FLOATMACRO, "float", "double", "quad"};      // float types
 const char* castname[]   = {FLOATCAST, "(float)", "(double)", "(quad)"}; // float castings
 
@@ -55,5 +55,5 @@ void printfloatdef (std::ostream& fout)
     fout << "#define " << FLOATMACRO << " " << "float" << std::endl;
     fout << "#endif  " << std::endl;
     fout << std::endl;
-    fout << "typedef long double quad;" << std::endl;
+    if (gFloatSize == 3) fout << "typedef long double quad;" << std::endl;
 }
diff --git a/compiler/generator/klass.cpp b/compiler/generator/klass.cpp
index e956a22..af3db10 100644
--- a/compiler/generator/klass.cpp
+++ b/compiler/generator/klass.cpp
@@ -51,6 +51,7 @@
 #include "recursivness.hh"
 
 
+extern int  gFloatSize;
 extern bool gVectorSwitch;
 extern bool gDeepFirstSwitch;
 extern bool gOpenMPSwitch;
@@ -217,12 +218,17 @@ void Klass::printAdditionalCode(ostream& fout)
 {
     if (fNeedPowerDef) {
         // Add faustpower definition to C++ code
+        fout << "#ifndef FAUSTPOWER" << endl;
+        fout << "#define FAUSTPOWER" << endl;
         fout << "#include <cmath>" << endl;
-        fout << "template <int N> inline float faustpower(float x) 		{ return powf(x,N); } " << endl;
-        fout << "template <int N> inline double faustpower(double x) 	{ return pow(x,N); }"  << endl;
-        fout << "template <int N> inline int faustpower(int x) 			{ return faustpower<N/2>(x) * faustpower<N-N/2>(x); } " << endl;
-        fout << "template <> 	 inline int faustpower<0>(int x) 		{ return 1; }" << endl;
-        fout << "template <> 	 inline int faustpower<1>(int x) 		{ return x; }" << endl;
+        fout << "template <int N> inline float faustpower(float x)          { return powf(x,N); } " << endl;
+        fout << "template <int N> inline double faustpower(double x)        { return pow(x,N); }"  << endl;
+        if (gFloatSize == 3) fout << "template <int N> inline long double faustpower(long double x) 	{ return powl(x,N); }"  << endl;
+        fout << "template <int N> inline int faustpower(int x)              { return faustpower<N/2>(x) * faustpower<N-N/2>(x); } " << endl;
+        fout << "template <> 	 inline int faustpower<0>(int x)            { return 1; }" << endl;
+        fout << "template <> 	 inline int faustpower<1>(int x)            { return x; }" << endl;
+        fout << "template <> 	 inline int faustpower<2>(int x)            { return x*x; }" << endl;
+        fout << "#endif" << endl;
     }
 
 }
@@ -233,11 +239,13 @@ void Klass::printAdditionalCode(ostream& fout)
 void Klass::printMetadata(int n, const map<Tree, set<Tree> >& S, ostream& fout)
 {
     tab(n,fout); fout   << "static void metadata(Meta* m) \t{ ";
-
+    
+    // We do not want to accumulate metadata from all hierachical levels, so the upper level only is kept
     for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
         if (i->first != tree("author")) {
             tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **(i->second.begin()) << ");";
         } else {
+            // But the "author" meta data is accumulated, the upper level becomes the main author and sub-levels become "contributor"
             for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); j++) {
                 if (j == i->second.begin()) {
                      tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **j << ");" ;
@@ -295,7 +303,7 @@ static void computeUseCount(Loop* l)
  */
 static void groupSeqLoops(Loop* l)
 {
-	int n = l->fBackwardLoopDependencies.size();
+	int n = (int)l->fBackwardLoopDependencies.size();
 	if (n==0) {
 		return;
 	} else if (n==1) {
@@ -336,14 +344,14 @@ void Klass::buildTasksList()
     addDeclCode("FAUSTFLOAT** input;");
     addDeclCode("FAUSTFLOAT** output;");
     addDeclCode("volatile bool fIsFinished;");
-    addDeclCode("int fFullCount;");
+    addDeclCode("int fCount;");
     addDeclCode("int fIndex;");
     addDeclCode("DSPThreadPool* fThreadPool;");
     addDeclCode("int fStaticNumThreads;");
     addDeclCode("int fDynamicNumThreads;");
 
     // Compute forward dependencies
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
             for (lset::const_iterator p1 = (*p)->fBackwardLoopDependencies.begin(); p1!=(*p)->fBackwardLoopDependencies.end(); p1++) {
                 (*p1)->fForwardLoopDependencies.insert((*p));
@@ -355,7 +363,7 @@ void Klass::buildTasksList()
 
     // Compute ready tasks list
     vector<int> task_num;
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         lset::const_iterator next;
         for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
             if ((*p)->fBackwardLoopDependencies.size() == 0) {
@@ -371,7 +379,7 @@ void Klass::buildTasksList()
         addZone3("if (cur_thread == 0) {");
 
         Loop* keep = NULL;
-        for (int l=G.size()-1; l>=0; l--) {
+        for (int l=(int)G.size()-1; l>=0; l--) {
             lset::const_iterator next;
             for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
                 if ((*p)->fBackwardLoopDependencies.size() == 0) {
@@ -419,7 +427,7 @@ void Klass::buildTasksList()
 
     // Compute init section
     addZone2c("// Only initialize taks with more than one input");
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
             if ((*p)->fBackwardLoopDependencies.size() > 1)  { // Only initialize taks with more than 1 input, since taks with one input are "directly" activated.
                 addZone2c(subst("fGraph.InitTask($0,$1);", T(START_TASK_INDEX + gTaskCount++), T((int)(*p)->fBackwardLoopDependencies.size())));
@@ -460,7 +468,7 @@ void Klass::printLoopGraphVector(int n, ostream& fout)
 #endif
 
     // normal mode
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
         for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
             (*p)->println(n, fout);
@@ -482,9 +490,9 @@ void Klass::printLoopGraphOpenMP(int n, ostream& fout)
     sortGraph(fTopLoop, G);
 
     // OpenMP mode : add OpenMP directives
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         tab(n, fout); fout << "// SECTION : " << G.size() - l;
-        printLoopLevelOpenMP(n, G.size() - l, G[l], fout);
+        printLoopLevelOpenMP(n, (int)G.size() - l, G[l], fout);
     }
 }
 
@@ -502,12 +510,12 @@ void Klass::printLoopGraphScheduler(int n, ostream& fout)
     sortGraph(fTopLoop, G);
 
     // OpenMP mode : add OpenMP directives
-    for (int l=G.size()-1; l>0; l--) {
+    for (int l=(int)G.size()-1; l>0; l--) {
         tab(n, fout); fout << "// SECTION : " << G.size() - l;
-        printLoopLevelScheduler(n, G.size() - l, G[l], fout);
+        printLoopLevelScheduler(n, (int)G.size() - l, G[l], fout);
     }
 
-    printLastLoopLevelScheduler(n, G.size(), G[0], fout);
+    printLastLoopLevelScheduler(n, (int)G.size(), G[0], fout);
 }
 
 
@@ -525,7 +533,7 @@ void Klass::printGraphDotFormat(ostream& fout)
 
     int lnum = 0;       // used for loop numbers
     // for each level of the graph
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         // for each task in the level
         for (lset::const_iterator t =G[l].begin(); t!=G[l].end(); t++) {
             // print task label "Lxxx : 0xffffff"
@@ -549,7 +557,7 @@ void Klass::printLoopGraphInternal(int n, ostream& fout)
     sortGraph(fTopLoop, G);
 
     // normal mode
-    for (int l=G.size()-1; l>=0; l--) {
+    for (int l=(int)G.size()-1; l>=0; l--) {
         if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
         for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
             (*p)->printoneln(n, fout);
@@ -733,7 +741,9 @@ void Klass::println(int n, ostream& fout)
 {
 	list<Klass* >::iterator k;
 
-    tab(n,fout); fout << "#define FAUSTCLASS "<< fKlassName << endl;
+    tab(n,fout); fout << "#ifndef FAUSTCLASS " << endl;
+    fout << "#define FAUSTCLASS "<< fKlassName << endl;
+    fout << "#endif" << endl;
 
     if (gSchedulerSwitch) {
         tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << ", public Runnable {";
@@ -847,12 +857,14 @@ void Klass::printComputeMethodVectorFaster(int n, ostream& fout)
 {
     // in vector mode we need to split loops in smaller pieces not larger
     // than gVecSize
-    tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
+    tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
         printlines(n+2, fZone1Code, fout);
         printlines(n+2, fZone2Code, fout);
         printlines(n+2, fZone2bCode, fout);
 
         tab(n+2,fout); fout << "int index;";
+		tab(n+2,fout); fout << "int fullcount = count;";
+		
         tab(n+2,fout); fout << "for (index = 0; index <= fullcount - " << gVecSize << "; index += " << gVecSize << ") {";
             tab(n+3,fout); fout << "// compute by blocks of " << gVecSize << " samples";
             tab(n+3,fout); fout << "const int count = " << gVecSize << ";";
@@ -876,11 +888,13 @@ void Klass::printComputeMethodVectorSimple(int n, ostream& fout)
 {
     // in vector mode we need to split loops in smaller pieces not larger
     // than gVecSize
-    tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
+    tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
         printlines(n+2, fZone1Code, fout);
         printlines(n+2, fZone2Code, fout);
         printlines(n+2, fZone2bCode, fout);
-        tab(n+2,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
+		
+        tab(n+2,fout); fout << "int fullcount = count;";
+		tab(n+2,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
             tab(n+3,fout); fout << "int count = min("<< gVecSize << ", fullcount-index);";
             printlines (n+3, fZone3Code, fout);
             printLoopGraphVector(n+3,fout);
@@ -947,9 +961,10 @@ void Klass::printComputeMethodOpenMP(int n, ostream& fout)
 {
     // in openMP mode we need to split loops in smaller pieces not larger
     // than gVecSize and add OpenMP pragmas
-    tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
+    tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
         printlines(n+2, fZone1Code, fout);
         printlines(n+2, fZone2Code, fout);
+        tab(n+2,fout); fout << "int fullcount = count;";
         tab(n+2,fout); fout << "#pragma omp parallel";
         printdecllist(n+3, "firstprivate", fFirstPrivateDecl, fout);
 
@@ -1048,7 +1063,7 @@ void Klass::printComputeMethodScheduler (int n, ostream& fout)
         tab(n+2,fout); fout << "fGraph.Display();";
     tab(n+1,fout); fout << "}";
 
-    tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
+    tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
 
         tab(n+2,fout); fout << "GetRealTime();";
 
@@ -1056,10 +1071,12 @@ void Klass::printComputeMethodScheduler (int n, ostream& fout)
         tab(n+2,fout); fout << "this->output = output;";
 
         tab(n+2,fout); fout << "StartMeasure();";
+        
+        tab(n+2,fout); fout << "int fullcount = count;";
 
         tab(n+2,fout); fout << "for (fIndex = 0; fIndex < fullcount; fIndex += " << gVecSize << ") {";
 
-        tab(n+3,fout); fout << "fFullCount = min ("<< gVecSize << ", fullcount-fIndex);";
+        tab(n+3,fout); fout << "fCount = min ("<< gVecSize << ", fullcount-fIndex);";
         tab(n+3,fout); fout << "TaskQueue::Init();";
         printlines (n+3, fZone2cCode, fout);
 
@@ -1075,6 +1092,9 @@ void Klass::printComputeMethodScheduler (int n, ostream& fout)
     tab(n+1,fout); fout << "}";
 
     tab(n+1,fout); fout << "void computeThread(int cur_thread) {";
+    
+        tab(n+2,fout); fout << "int count = fCount;";
+        
         printlines (n+2, fZone1Code, fout);
         printlines (n+2, fZone2Code, fout);
 
@@ -1083,8 +1103,7 @@ void Klass::printComputeMethodScheduler (int n, ostream& fout)
         tab(n+2,fout); fout << "{";
             tab(n+3,fout); fout << "TaskQueue taskqueue(cur_thread);";
             tab(n+3,fout); fout << "int tasknum = -1;";
-            tab(n+3,fout); fout << "int count = fFullCount;";
-
+    
             // Init input and output
             tab(n+3,fout); fout << "// Init input and output";
             printlines (n+3, fZone3Code, fout);
@@ -1140,6 +1159,7 @@ void SigIntGenKlass::println(int n, ostream& fout)
 
 		tab(n+1,fout); fout << "void init(int samplingFreq) {";
 			tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
+            printlines(n+2, fInitCode, fout);
 		tab(n+1,fout); fout << "}";
 
 		tab(n+1,fout); fout << "void fill (int count, int output[]) {";
diff --git a/compiler/generator/klass.hh b/compiler/generator/klass.hh
index 079e6c3..e21b8ee 100644
--- a/compiler/generator/klass.hh
+++ b/compiler/generator/klass.hh
@@ -63,8 +63,9 @@ protected:
 
  protected:
     
-	string			fKlassName;
-	string			fSuperKlassName;
+    Klass*			fParentKlass;               ///< Klass in which this Klass is embedded, void if toplevel Klass
+    string			fKlassName;
+    string			fSuperKlassName;
 	int				fNumInputs;
 	int				fNumOutputs;
     int             fNumActives;                ///< number of active controls in the UI (sliders, buttons, etc.)
@@ -106,19 +107,27 @@ protected:
  public:
 
 	Klass (const string& name, const string& super, int numInputs, int numOutputs, bool __vec = false)
-	  : 	fKlassName(name), fSuperKlassName(super), fNumInputs(numInputs), fNumOutputs(numOutputs),
+      : 	fParentKlass(0), fKlassName(name), fSuperKlassName(super), fNumInputs(numInputs), fNumOutputs(numOutputs),
             fNumActives(0), fNumPassives(0),
             fTopLoop(new Loop(0, "count")), fVec(__vec)
 	{}
 
 	virtual ~Klass() 						{}
 
+    void    setParentKlass(Klass* parent)       { std::cerr << this << " setParentKlass(" << parent << ")" << std::endl;
+                                                  fParentKlass=parent; }
+    Klass*  getParentKlass()                    { return fParentKlass; }
+    Klass*  getTopParentKlass()                 { return (fParentKlass != 0) ? fParentKlass->getTopParentKlass() : this; }
+    string  getFullClassName()                  { return (fParentKlass!=0) ? fParentKlass->getFullClassName() + "::" + getClassName() : getClassName(); }    ///< Returns the name of the class
+
+
     void    openLoop(const string& size);
     void    openLoop(Tree recsymbol, const string& size);
     void    closeLoop(Tree sig);
 
     void    setLoopProperty(Tree sig, Loop* l);     ///< Store the loop used to compute a signal
     bool    getLoopProperty(Tree sig, Loop*& l);    ///< Returns the loop used to compute a signal
+
     const string&    getClassName() const { return fKlassName; }    ///< Returns the name of the class
 
     Loop*   topLoop()   { return fTopLoop; }
@@ -135,13 +144,13 @@ protected:
 
 	void collectLibrary(set<string>& S);
 
-	void addSubKlass (Klass* son)			{ fSubClassList.push_back(son); }
+    void addSubKlass (Klass* son)			{ fSubClassList.push_back(son); }
 
 	void addDeclCode (const string& str) 	{ fDeclCode.push_back(str); }
 
 	void addInitCode (const string& str)	{ fInitCode.push_back(str); }
 
-	void addStaticInitCode (const string& str)	{ fStaticInitCode.push_back(str); }
+    void addStaticInitCode (const string& str)	{ fStaticInitCode.push_back(str); }
 
 	void addStaticFields (const string& str)	{ fStaticFields.push_back(str); }
 
@@ -205,7 +214,7 @@ class SigIntGenKlass : public Klass {
     
  public:
 
-	SigIntGenKlass (const string& name) : Klass(name, "", 0, 1, false)	{}
+    SigIntGenKlass (Klass* parent, const string& name) : Klass(name, "", 0, 1, false) { fParentKlass = parent; }
 
 	virtual void println(int n, ostream& fout);
 };
@@ -214,7 +223,7 @@ class SigFloatGenKlass : public Klass {
     
  public:
 
-	SigFloatGenKlass (const string& name) : Klass(name, "", 0, 1, false)	{}
+    SigFloatGenKlass (Klass* parent, const string& name) : Klass(name, "", 0, 1, false)	{ fParentKlass = parent; }
 
 	virtual void println(int n, ostream& fout);
 };
diff --git a/compiler/generator/occurences.cpp b/compiler/generator/occurences.cpp
index d0e64d9..90969cf 100644
--- a/compiler/generator/occurences.cpp
+++ b/compiler/generator/occurences.cpp
@@ -158,6 +158,7 @@ void OccMarkup::setOcc(Tree t, Occurences* occ)
 }
 
 
+#if 0
 
 /**
  * return the position of a signal in the current recursive environment
@@ -171,3 +172,4 @@ static int position (Tree env, Tree t, int p)
 	if (hd(env) == t) return p;
 	else return position (tl(env), t, p+1);
 }
+#endif
\ No newline at end of file
diff --git a/compiler/generator/uitree.cpp b/compiler/generator/uitree.cpp
index 92a51c0..1aceba5 100644
--- a/compiler/generator/uitree.cpp
+++ b/compiler/generator/uitree.cpp
@@ -21,6 +21,7 @@
  
  
  
+#include <sstream>
 #include "uitree.hh"
 
 
@@ -213,3 +214,15 @@ AJOUTER (Dossier[(l1,d1)...(ln,dn)], (lx,dx)) -> Dossier[(l1,d1)...(lx,dx)...(ln
 
 AJOUTER (Dossier[(l1,d1)...(lx,dx)...(ln,dn)], (lx,dx')) -> Dossier[(l1,d1)...(lx,dx')...(ln,dn)]
 */
+
+
+// Handle empty labels in a consistent way
+string ptrToHex(Tree ptr)
+{
+    stringstream res; res << hex << ptr; return res.str();
+}
+
+string checkNullLabel(Tree t, const string& label, bool bargraph)
+{
+    return (label == "") ? (bargraph ? ptrToHex(t) : string("0x00")) : label;
+}
diff --git a/compiler/generator/uitree.hh b/compiler/generator/uitree.hh
index 7cc7ee8..d523c7d 100644
--- a/compiler/generator/uitree.hh
+++ b/compiler/generator/uitree.hh
@@ -24,6 +24,7 @@
 #ifndef _UITREE_
 #define _UITREE_
 
+#include <string>
 #include "tlib.hh"
 
 Tree  	uiFolder(Tree label, Tree elements=nil);
@@ -46,6 +47,8 @@ inline Tree uiLabel (Tree t)	{ return t->branch(0); }
 	
 Tree putSubFolder(Tree folder, Tree path, Tree item);
 
+std::string ptrToHex(Tree ptr);
+std::string checkNullLabel(Tree t, const std::string& label, bool bargraph = false);
 
 #endif
 
diff --git a/compiler/main.cpp b/compiler/main.cpp
index 2b824f4..84fc307 100644
--- a/compiler/main.cpp
+++ b/compiler/main.cpp
@@ -1,7 +1,7 @@
 /************************************************************************
  ************************************************************************
     FAUST compiler
-	Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+	Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
     ---------------------------------------------------------------------
     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
@@ -18,13 +18,16 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  ************************************************************************
  ************************************************************************/
-#define FAUSTVERSION "0.9.46"
+#define FAUSTVERSION "0.9.73"
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <limits.h>
 
 #ifndef WIN32
+#include <unistd.h>
 #include <sys/time.h>
 #include "libgen.h"
 #endif
@@ -53,14 +56,11 @@
 #include <map>
 #include <string>
 #include <vector>
+#include <list>
 #include <iostream>
 #include <fstream>
 #include <sstream>
 
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
 #include "sourcereader.hh"
 
 
@@ -91,7 +91,7 @@ SourceReader	gReader;
 map<Tree, set<Tree> > gMetaDataSet;
 extern vector<Tree> gDocVector;
 extern string gDocLang;
-
+tvec gWaveForm;
 
 /****************************************************************
  				Command line tools and arguments
@@ -112,12 +112,15 @@ Tree			gExpandedDefList;
 bool			gHelpSwitch 	= false;
 bool			gVersionSwitch 	= false;
 bool            gDetailsSwitch  = false;
+bool            gTimingSwitch   = false;
 bool            gDrawSignals    = false;
 bool            gShadowBlur     = false;	// note: svg2pdf doesn't like the blur filter
+bool            gScaledSVG      = false;	// to draw scaled SVG files
 bool            gGraphSwitch 	= false;
 bool            gDrawPSSwitch 	= false;
 bool            gDrawSVGSwitch 	= false;
 bool            gPrintXMLSwitch = false;
+bool            gPrintJSONSwitch = false;
 bool            gPrintDocSwitch = false;
 bool            gLatexDocSwitch = true;		// Only LaTeX outformat is handled for the moment.
 bool			gStripDocSwitch = false;	// Strip <mdoc> content from doc listings.
@@ -141,19 +144,30 @@ int             gVectorLoopVariant = 0;
 
 bool            gOpenMPSwitch   = false;
 bool            gOpenMPLoop     = false;
-bool            gSchedulerSwitch   = false;
-bool			gGroupTaskSwitch= false;
+bool            gSchedulerSwitch = false;
+bool			gGroupTaskSwitch = false;
 
 bool            gUIMacroSwitch  = false;
 bool            gDumpNorm       = false;
 
-int             gTimeout        = 600;            // time out to abort compiler (in seconds)
+int             gTimeout        = 120;          // time out to abort compiler (in seconds)
 
-int             gFloatSize = 1;
+int             gFloatSize      = 1;
 
 bool			gPrintFileListSwitch = false;
+bool			gInlineArchSwitch = false;
 
 string			gClassName		= "mydsp";
+bool            gExportDSP      = false;
+
+list<string>    gImportDirList;                 // dir list enrobage.cpp/fopensearch() searches for imports, etc.
+string          gOutputDir;                     // output directory for additionnal generated ressources : -SVG, XML...etc...
+bool            gInPlace        = false;        // add cache to input for correct in-place computations
+
+// source file injection
+bool            gInjectFlag     = false;        // inject an external source file into the architecture file
+string          gInjectFile     = "";           // instead of a compiled dsp file
+
 
 //-- command line tools
 
@@ -167,13 +181,40 @@ static bool isCmd(const char* cmd, const char* kw1, const char* kw2)
 	return 	(strcmp(cmd, kw1) == 0) || (strcmp(cmd, kw2) == 0);
 }
 
+string makeDrawPath()
+{
+    if (gOutputDir != "") {
+        return gOutputDir + "/" + gMasterName + ".dsp";
+    } else {
+        return gMasterDocument;
+    }
+}
+
+static string makeDrawPathNoExt()
+{
+    if (gOutputDir != "") {
+        return gOutputDir + "/" + gMasterName;
+    } else if (gMasterDocument.length() >= 4 && gMasterDocument.substr(gMasterDocument.length() - 4) == ".dsp") {
+        return gMasterDocument.substr(0, gMasterDocument.length() - 4);
+    } else {
+        return gMasterDocument;
+    }
+}
+
+#ifdef WIN32
+#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
+#ifndef __MINGW32__
+#define PATH_MAX _MAX_PATH
+#endif
+#endif
+
 bool process_cmdline(int argc, char* argv[])
 {
 	int	i=1; int err=0;
 
 	while (i<argc) {
-
-		if        (isCmd(argv[i], "-h", "--help")) {
+   
+		if (isCmd(argv[i], "-h", "--help")) {
 			gHelpSwitch = true;
 			i += 1;
 
@@ -185,9 +226,14 @@ bool process_cmdline(int argc, char* argv[])
 			gDetailsSwitch = true;
 			i += 1;
 
-		} else if (isCmd(argv[i], "-a", "--architecture")) {
-			gArchFile = argv[i+1];
-			i += 2;
+        } else if (isCmd(argv[i], "-a", "--architecture")) {
+            gArchFile = argv[i+1];
+            i += 2;
+
+        } else if (isCmd(argv[i], "-inj", "--inject")) {
+            gInjectFlag = true;
+            gInjectFile = argv[i+1];
+            i += 2;
 
 		} else if (isCmd(argv[i], "-o")) {
 			gOutputFile = argv[i+1];
@@ -200,6 +246,10 @@ bool process_cmdline(int argc, char* argv[])
         } else if (isCmd(argv[i], "-xml", "--xml")) {
             gPrintXMLSwitch = true;
             i += 1;
+            
+        } else if (isCmd(argv[i], "-json", "--json")) {
+            gPrintJSONSwitch = true;
+            i += 1;
 
         } else if (isCmd(argv[i], "-tg", "--task-graph")) {
             gGraphSwitch = true;
@@ -212,6 +262,10 @@ bool process_cmdline(int argc, char* argv[])
         } else if (isCmd(argv[i], "-blur", "--shadow-blur")) {
             gShadowBlur = true;
             i += 1;
+            
+        } else if (isCmd(argv[i], "-sc", "--scaled-svg")) {
+            gScaledSVG = true;
+            i += 1;
 
 		} else if (isCmd(argv[i], "-svg", "--svg")) {
 			gDrawSVGSwitch = true;
@@ -292,7 +346,11 @@ bool process_cmdline(int argc, char* argv[])
         } else if (isCmd(argv[i], "-t", "--timeout")) {
             gTimeout = atoi(argv[i+1]);
             i += 2;
-
+            
+        } else if (isCmd(argv[i], "-time", "--compilation-time")) {
+            gTimingSwitch = true;
+            i += 1;
+            
         // double float options
         } else if (isCmd(argv[i], "-single", "--single-precision-floats")) {
             gFloatSize = 1;
@@ -330,14 +388,50 @@ bool process_cmdline(int argc, char* argv[])
 			gClassName = argv[i+1];
 			i += 2;
 
+        } else if (isCmd(argv[i], "-i", "--inline-architecture-files")) {
+            gInlineArchSwitch = true;
+            i += 1;
+            
+        } else if (isCmd(argv[i], "-e", "--export-dsp")) {
+            gExportDSP = true;
+            i += 1;
+
+        } else if (isCmd(argv[i], "-I", "--import-dir")) {
+
+            char temp[PATH_MAX+1];
+            char* path = realpath(argv[i+1], temp);
+            if (path == 0) {
+                std::cerr << "ERROR : invalid directory path " << argv[i+1] << std::endl;
+                exit(-1);
+            } else {
+                gImportDirList.push_back(path);
+                i += 2;
+            }
+         } else if (isCmd(argv[i], "-O", "--output-dir")) {
+        
+            char temp[PATH_MAX+1];
+            char* path = realpath(argv[i+1], temp);
+             if (path == 0) {
+                std::cerr << "ERROR : invalid directory path " << argv[i+1] << std::endl;
+                exit(-1);
+            } else {
+                gOutputDir = path;
+                i += 2;
+            }
+             
+         } else if (isCmd(argv[i], "-inpl", "--in-place")) {
+             gInPlace = true;
+             i += 1;
+
         } else if (argv[i][0] != '-') {
-			if (check_file(argv[i])) {
-				gInputFiles.push_back(argv[i]);
-			}
+            const char* url = argv[i];
+            if (check_url(url)) {
+                gInputFiles.push_back(url);
+            }
 			i++;
 
 		} else {
-			cerr << "faust: unrecognized option \"" << argv[i] <<"\"" << endl;
+			std::cerr << "faust: unrecognized option \"" << argv[i] <<"\"" << endl;
 			i++;
 			err++;
 		}
@@ -345,6 +439,11 @@ bool process_cmdline(int argc, char* argv[])
 
     // adjust related options
     if (gOpenMPSwitch || gSchedulerSwitch) gVectorSwitch = true;
+    
+    if (gInPlace && gVectorSwitch) {
+        std::cerr << "ERROR : 'in-place' option can only be used in scalar mode" << endl;
+        exit(-1);
+    }   
 
 	return err == 0;
 }
@@ -360,7 +459,7 @@ bool process_cmdline(int argc, char* argv[])
 void printversion()
 {
 	cout << "FAUST, DSP to C++ compiler, Version " << FAUSTVERSION << "\n";
-	cout << "Copyright (C) 2002-2012, GRAME - Centre National de Creation Musicale. All rights reserved. \n\n";
+    cout << "Copyright (C) 2002-2014, GRAME - Centre National de Creation Musicale. All rights reserved. \n\n";
 }
 
 
@@ -379,15 +478,16 @@ void printhelp()
     cout << "-tg \t\tprint the internal --task-graph in dot format file\n";
     cout << "-sg \t\tprint the internal --signal-graph in dot format file\n";
     cout << "-ps \t\tprint block-diagram --postscript file\n";
-    cout << "-svg \tprint block-diagram --svg file\n";
-    cout << "-mdoc \tprint --mathdoc of a Faust program in LaTeX format in a -mdoc directory\n";
-    cout << "-mdlang <l>\t\tload --mathdoc-lang <l> if translation file exists (<l> = en, fr, ...)\n";
-    cout << "-stripdoc \t\tapply --strip-mdoc-tags when printing Faust -mdoc listings\n";
+    cout << "-svg \t\tprint block-diagram --svg file\n";
+    cout << "-mdoc \t\tprint --mathdoc of a Faust program in LaTeX format in a -mdoc directory\n";
+    cout << "-mdlang <l> \tload --mathdoc-lang <l> if translation file exists (<l> = en, fr, ...)\n";
+    cout << "-stripdoc  \tapply --strip-mdoc-tags when printing Faust -mdoc listings\n";
     cout << "-sd \t\ttry to further --simplify-diagrams before drawing them\n";
 	cout << "-f <n> \t\t--fold <n> threshold during block-diagram generation (default 25 elements) \n";
 	cout << "-mns <n> \t--max-name-size <n> threshold during block-diagram generation (default 40 char)\n";
 	cout << "-sn \t\tuse --simple-names (without arguments) during block-diagram generation\n";
-	cout << "-xml \t\tgenerate an --xml description file\n";
+    cout << "-xml \t\tgenerate an XML description file\n";
+    cout << "-json \t\tgenerate a JSON description file\n";
     cout << "-blur \t\tadd a --shadow-blur to SVG boxes\n";
 	cout << "-lb \t\tgenerate --left-balanced expressions\n";
 	cout << "-mb \t\tgenerate --mid-balanced expressions (default)\n";
@@ -395,8 +495,11 @@ void printhelp()
 	cout << "-lt \t\tgenerate --less-temporaries in compiling delays\n";
 	cout << "-mcd <n> \t--max-copy-delay <n> threshold between copy and ring buffer implementation (default 16 samples)\n";
 	cout << "-a <file> \tC++ architecture file\n";
+	cout << "-i \t\t--inline-architecture-files \n";
 	cout << "-cn <name> \t--class-name <name> specify the name of the dsp class to be used instead of mydsp \n";
-	cout << "-o <file> \tC++ output file\n";
+	cout << "-t <sec> \t--timeout <sec>, abort compilation after <sec> seconds (default 120)\n";
+	cout << "-time \t\t--compilation-time, flag to display compilation phases timing information\n";
+    cout << "-o <file> \tC++ output file\n";
     cout << "-vec    \t--vectorize generate easier to vectorize code\n";
     cout << "-vs <n> \t--vec-size <n> size of the vector (default 32 samples)\n";
     cout << "-lv <n> \t--loop-variant [0:fastest (default), 1:simple] \n";
@@ -411,8 +514,12 @@ void printhelp()
     cout << "-quad \t\tuse --quad-precision-floats for internal computations\n";
     cout << "-flist \t\tuse --file-list used to eval process\n";
     cout << "-norm \t\t--normalized-form prints signals in normalized form and exits\n";
-
-	cout << "\nexample :\n";
+    cout << "-I <dir> \t--import-dir <dir> add the directory <dir> to the import search path\n";
+    cout << "-O <dir> \t--output-dir <dir> specify the relative directory of the generated C++ output, and the output directory of additional generated files (SVG, XML...)\n";
+    cout << "-e       \t--export-dsp export expanded DSP (all included libraries) \n";
+    cout << "-inpl    \t--in-place generates code working when input and output buffers are the same (in scalar mode only) \n";
+    cout << "-inj <f> \t--inject source file <f> into architecture file instead of compile a dsp file\n";
+  	cout << "\nexample :\n";
 	cout << "---------\n";
 
 	cout << "faust -a jack-gtk.cpp -o myfx.cpp myfx.dsp\n";
@@ -469,7 +576,7 @@ static string fxname(const string& filename)
     }
 	
 	// determine position of the last '.'
-	unsigned int p2 = filename.size();
+	unsigned int p2 = (int)filename.size();
     for (unsigned int i=p1; i<filename.size(); i++) {
         if (filename[i] == '.')  { p2 = i; }
     }
@@ -503,6 +610,10 @@ static void initFaustDirectories()
 
 int main (int argc, char* argv[])
 {
+    ostream*    dst;
+    ifstream*   injcode;
+    istream*    enrobage;
+
 
 	/****************************************************************
 	 1 - process command line
@@ -514,32 +625,77 @@ int main (int argc, char* argv[])
 	if (gVersionSwitch) 	{ printversion(); exit(0); }
 
     initFaustDirectories();
-#ifndef WIN32
     alarm(gTimeout);
-#endif
 
 
-	/****************************************************************
+    /****************************************************************
+     1.5 - Check and open some input files
+    *****************************************************************/
+    if (gOutputFile != "") {
+        string outpath = (gOutputDir != "") ? (gOutputDir + "/" + gOutputFile) : gOutputFile;
+        dst = new ofstream(outpath.c_str());
+    } else {
+        dst = &cout;
+    }
+
+    // Check for injected code (before checking for architectures)
+    if (gInjectFlag) {
+        injcode = new ifstream();
+        injcode->open(gInjectFile.c_str(), ifstream::in);
+        if ( ! injcode->is_open() ) {
+            cerr << "ERROR : can't inject \"" << gInjectFile << "\" external code file, file not found" << endl;
+            exit(1);
+        }
+    }
+
+    // Check for architecture file
+    if (gArchFile != "") {
+        if ( ! (enrobage = open_arch_stream(gArchFile.c_str())) ) {
+            cerr << "ERROR : can't open architecture file " << gArchFile << endl;
+            exit(1);
+        }
+    }
+
+
+    /****************************************************************
+     1.7 - Inject code instead of compile
+    *****************************************************************/
+
+    // Check if this is a code injection
+    if (gInjectFlag) {
+        if (gArchFile == "") {
+            cerr << "ERROR : no architecture file specified to inject \"" << gInjectFile << "\"" << endl;
+        } else {
+            streamCopyUntil(*enrobage, *dst, "<<includeIntrinsic>>");
+            streamCopyUntil(*enrobage, *dst, "<<includeclass>>");
+            streamCopy(*injcode, *dst);
+            streamCopyUntilEnd(*enrobage, *dst);
+        }
+        exit(0);
+    }
+
+    /****************************************************************
 	 2 - parse source files
 	*****************************************************************/
 
 	startTiming("parser");
 
-	
 	list<string>::iterator s;
 	gResult2 = nil;
 	yyerr = 0;
 
-	if (gInputFiles.begin() == gInputFiles.end()) {
-		cerr << "ERROR: no files specified; for help type \"faust --help\"" << endl;
+    if (! gInjectFlag && (gInputFiles.begin() == gInputFiles.end()) ) {
+        cout << "Error no input file" << endl;
 		exit(1);
 	}
 	for (s = gInputFiles.begin(); s != gInputFiles.end(); s++) {
-		if (s == gInputFiles.begin()) gMasterDocument = *s;
+		if (s == gInputFiles.begin()) {
+            gMasterDocument = *s;
+        }
 		gResult2 = cons(importFile(tree(s->c_str())), gResult2);
 	}
 	if (yyerr > 0) {
-		//fprintf(stderr, "Erreur de parsing 2, count = %d \n", yyerr);
+        cerr << "ERROR : parsing count = " <<  yyerr << endl;
 		exit(1);
 	}
 	gExpandedDefList = gReader.expandlist(gResult2);
@@ -565,11 +721,8 @@ int main (int argc, char* argv[])
 	if (gDetailsSwitch) { cerr << "process = " << boxpp(process) << ";\n"; }
 
 	if (gDrawPSSwitch || gDrawSVGSwitch) {
-		string projname = gMasterDocument;
-		if( gMasterDocument.substr(gMasterDocument.length()-4) == ".dsp" ) {
-			projname = gMasterDocument.substr(0, gMasterDocument.length()-4); 
-		}
-		if (gDrawPSSwitch) 	{ drawSchema( process, subst("$0-ps",  projname).c_str(), "ps" ); }
+		string projname = makeDrawPathNoExt();
+     	if (gDrawPSSwitch) 	{ drawSchema( process, subst("$0-ps", projname).c_str(), "ps" ); }
 		if (gDrawSVGSwitch) { drawSchema( process, subst("$0-svg", projname).c_str(), "svg" ); }
 	}
 
@@ -585,8 +738,13 @@ int main (int argc, char* argv[])
     }
 	
 	endTiming("evaluation");
-
-
+    
+    if (gExportDSP) {
+        ofstream xout(subst("$0_exp.dsp", makeDrawPathNoExt()).c_str());
+        xout << "process = " << boxpp(process) << ";" << endl;
+        return 0;
+    }
+ 
 	/****************************************************************
 	 3.5 - output file list is needed
 	*****************************************************************/
@@ -637,8 +795,7 @@ int main (int argc, char* argv[])
 
 	if (gPrintXMLSwitch) {
 		Description* 	D = C->getDescription(); assert(D);
-		//ostream* 		xout = new ofstream(subst("$0.xml", gMasterDocument).c_str());
-		ofstream 		xout(subst("$0.xml", gMasterDocument).c_str());
+		ofstream 		xout(subst("$0.xml", makeDrawPath()).c_str());
 
         if(gMetaDataSet.count(tree("name"))>0)          D->name(tree2str(*(gMetaDataSet[tree("name")].begin())));
         if(gMetaDataSet.count(tree("author"))>0)        D->author(tree2str(*(gMetaDataSet[tree("author")].begin())));
@@ -646,6 +803,7 @@ int main (int argc, char* argv[])
         if(gMetaDataSet.count(tree("license"))>0)       D->license(tree2str(*(gMetaDataSet[tree("license")].begin())));
         if(gMetaDataSet.count(tree("version"))>0)       D->version(tree2str(*(gMetaDataSet[tree("version")].begin())));
 
+		D->className(gClassName);
 		D->inputs(C->getClass()->inputs());
 		D->outputs(C->getClass()->outputs());
 
@@ -660,10 +818,7 @@ int main (int argc, char* argv[])
 
 	if (gPrintDocSwitch) {
 		if (gLatexDocSwitch) {
-			string projname = gMasterDocument;
-			if( gMasterDocument.substr(gMasterDocument.length()-4) == ".dsp" ) {
-				projname = gMasterDocument.substr(0, gMasterDocument.length()-4); }
-			printDoc( subst("$0-mdoc", projname).c_str(), "tex", FAUSTVERSION );
+            printDoc(subst("$0-mdoc", makeDrawPathNoExt()).c_str(), "tex", FAUSTVERSION);
 		}
 	}
 
@@ -674,53 +829,34 @@ int main (int argc, char* argv[])
 	 8 - generate output file
 	*****************************************************************/
 
-	ostream* dst;
-	istream* enrobage;
-	//istream* intrinsic;
-
-	if (gOutputFile != "") {
-		dst = new ofstream(gOutputFile.c_str());
-	} else {
-		dst = &cout;
-	}
+    printheader(*dst);
+    C->getClass()->printLibrary(*dst);
+    C->getClass()->printIncludeFile(*dst);
+    C->getClass()->printAdditionalCode(*dst);
 
 	if (gArchFile != "") {
-		if ( (enrobage = open_arch_stream(gArchFile.c_str())) ) {
-            printheader(*dst);
-			C->getClass()->printLibrary(*dst);
-			C->getClass()->printIncludeFile(*dst);
-            C->getClass()->printAdditionalCode(*dst);
 
-            streamCopyUntil(*enrobage, *dst, "<<includeIntrinsic>>");
+        streamCopyUntil(*enrobage, *dst, "<<includeIntrinsic>>");
 
-// 			if ( gVectorSwitch && (intrinsic = open_arch_stream("intrinsic.hh")) ) {
-// 				streamCopyUntilEnd(*intrinsic, *dst);
-// 			}
-            
-            if (gSchedulerSwitch) {
-                istream* scheduler_include = open_arch_stream("scheduler.h");
-                if (scheduler_include) {
-                    streamCopy(*scheduler_include, *dst);
-                }
+        if (gSchedulerSwitch) {
+            istream* scheduler_include = open_arch_stream("scheduler.cpp");
+            if (scheduler_include) {
+                streamCopy(*scheduler_include, *dst);
+            } else {
+                cerr << "ERROR : can't include \"scheduler.cpp\", file not found" << endl;
+                exit(1);
             }
-            
-			streamCopyUntil(*enrobage, *dst, "<<includeclass>>");
-            printfloatdef(*dst);
-            
-			C->getClass()->println(0,*dst);
-			streamCopyUntilEnd(*enrobage, *dst);
-		} else {
-			cerr << "ERROR : can't open architecture file " << gArchFile << endl;
-			return 1;
-		}
-	} else {
-        printheader(*dst);
+        }
+
+        streamCopyUntil(*enrobage, *dst, "<<includeclass>>");
         printfloatdef(*dst);
-		C->getClass()->printLibrary(*dst);
-        C->getClass()->printIncludeFile(*dst);
-        C->getClass()->printAdditionalCode(*dst);
         C->getClass()->println(0,*dst);
-	}
+        streamCopyUntilEnd(*enrobage, *dst);
+
+    } else {
+        printfloatdef(*dst);
+        C->getClass()->println(0,*dst);
+    }
 
 
     /****************************************************************
@@ -728,12 +864,9 @@ int main (int argc, char* argv[])
     *****************************************************************/
 
     if (gGraphSwitch) {
-        ofstream dotfile(subst("$0.dot", gMasterDocument).c_str());
+        ofstream dotfile(subst("$0.dot", makeDrawPath()).c_str());
         C->getClass()->printGraphDotFormat(dotfile);
     }
-
-
-
 	
 	delete C;
 	return 0;
diff --git a/compiler/normalize/privatise.cpp b/compiler/normalize/privatise.cpp
index 55549ba..eff0043 100644
--- a/compiler/normalize/privatise.cpp
+++ b/compiler/normalize/privatise.cpp
@@ -135,38 +135,16 @@ static Tree computePrivatisation(const Tree& k, const Tree& exp)
 	} else {
 		/*	On parcours les autres arbres en privatisant les branches
 		*/
-		int n = exp->arity();
-
-		switch (n) {
-
-			case 1 :
-				return tree(
-						exp->node(),
-						privatisation(k, exp->branch(0)) );
-			case 2 :
-				return tree(
-						exp->node(),
-						privatisation(k, exp->branch(0)),
-						privatisation(k, exp->branch(1)) );
-			case 3 :
-				return tree (
-						exp->node(),
-						privatisation(k, exp->branch(0)),
-						privatisation(k, exp->branch(1)),
-						privatisation(k, exp->branch(2)) );
-			case 4 :
-				return tree (
-						exp->node(),
-						privatisation(k, exp->branch(0)),
-						privatisation(k, exp->branch(1)),
-						privatisation(k, exp->branch(2)),
-						privatisation(k, exp->branch(3)) );
-		}
-		printf("erreur 2 dans computePrivatisation\n");
-		exit(1);
-	}
-	printf("situation anormale dans computePrivatisation\n");
-	return exp;
+
+        tvec br;
+        int n = exp->arity();
+        for (int i = 0; i < n; i++) {
+            br.push_back( privatisation(k,exp->branch(i)) );
+        }
+
+        return tree(exp->node(), br);
+
+    }
 }
 
 static Tree labelize(const Tree& newid, const Tree& exp)
diff --git a/compiler/normalize/simplify.cpp b/compiler/normalize/simplify.cpp
index 0b47d35..8a12771 100644
--- a/compiler/normalize/simplify.cpp
+++ b/compiler/normalize/simplify.cpp
@@ -199,28 +199,14 @@ static Tree sigMap (Tree key, tfun f, Tree t)
         return rec(id, sigMap(key, f, body));
 
     } else {
-
-        Tree r1=nil;
-        switch (t->arity()) {
-
-            case 0 :
-                r1 = t;
-                break;
-            case 1 :
-                r1 = tree(t->node(), sigMap(key,f,t->branch(0)));
-                break;
-            case 2 :
-                r1 = tree(t->node(), sigMap(key,f,t->branch(0)), sigMap(key,f,t->branch(1)));
-                break;
-            case 3 :
-                r1 = tree(t->node(), sigMap(key,f,t->branch(0)), sigMap(key,f,t->branch(1)),
-                                           sigMap(key,f,t->branch(2)));
-                break;
-            case 4 :
-                r1 = tree(t->node(), sigMap(key,f,t->branch(0)), sigMap(key,f,t->branch(1)),
-                                           sigMap(key,f,t->branch(2)), sigMap(key,f,t->branch(3)));
-                break;
+        tvec br;
+        int n = t->arity();
+        for (int i = 0; i < n; i++) {
+            br.push_back(sigMap(key,f,t->branch(i)));
         }
+
+        Tree r1 = tree(t->node(), br);
+
         Tree r2 = f(r1);
         if (r2 == t) {
             setProperty(t, key, nil);
@@ -266,31 +252,15 @@ static Tree sigMapRename (Tree key, Tree env, tfun f, Tree t)
 
     } else {
 
-        Tree r1=nil;
-        switch (t->arity()) {
-
-            case 0 :
-                r1 = t;
-                break;
-            case 1 :
-                r1 = tree(t->node(),    sigMapRename(key,env,f,t->branch(0)));
-                break;
-            case 2 :
-                r1 = tree(t->node(),    sigMapRename(key,env,f,t->branch(0)),
-                                        sigMapRename(key,env,f,t->branch(1)));
-                break;
-            case 3 :
-                r1 = tree(t->node(),    sigMapRename(key,env,f,t->branch(0)),
-                                        sigMapRename(key,env,f,t->branch(1)),
-                                        sigMapRename(key,env,f,t->branch(2)));
-                break;
-            case 4 :
-                r1 = tree(t->node(),    sigMapRename(key,env,f,t->branch(0)),
-                                        sigMapRename(key,env,f,t->branch(1)),
-                                        sigMapRename(key,env,f,t->branch(2)),
-                                        sigMapRename(key,env,f,t->branch(3)));
-                break;
+        tvec br;
+        int n = t->arity();
+        for (int i = 0; i < n; i++) {
+            br.push_back( sigMapRename(key,env,f,t->branch(i)) );
         }
+
+        Tree r1 = tree(t->node(), br);
+
+
         Tree r2 = f(r1);
         if (r2 == t) {
             setProperty(t, key, nil);
diff --git a/compiler/parallelize/colorize.cpp b/compiler/parallelize/colorize.cpp
index 3935644..838a0ea 100644
--- a/compiler/parallelize/colorize.cpp
+++ b/compiler/parallelize/colorize.cpp
@@ -190,7 +190,7 @@ static int colorsCount(Tree exp)
 	if (cset==0) {
 		return 0;
 	} else {
-		return cset->size();
+		return (int)cset->size();
 	}
 }
 
diff --git a/compiler/parser/enrobage.cpp b/compiler/parser/enrobage.cpp
index e001b72..17e7a33 100644
--- a/compiler/parser/enrobage.cpp
+++ b/compiler/parser/enrobage.cpp
@@ -19,25 +19,29 @@
  ************************************************************************
  ************************************************************************/
  
- 
- 
 #include "enrobage.hh"
 #include <vector>
+#include <list>
+#include <set>
 #include <string>
+#include <ctype.h>
 #include <limits.h>
 #include <stdlib.h>
 #include "compatibility.hh"
+#include "sourcefetcher.hh"
+#include <errno.h>
 #include <climits>
 
-extern string gFaustSuperSuperDirectory;
-extern string gFaustSuperDirectory;
-extern string gFaustDirectory;
-extern string gMasterDirectory;
-extern string gClassName;
+extern string       gFaustSuperSuperDirectory;
+extern string       gFaustSuperDirectory;
+extern string       gFaustDirectory;
+extern string       gMasterDirectory;
+extern string       gClassName;
+extern bool         gInlineArchSwitch;
+extern list<string> gImportDirList;                 // path to search for imports, components and libraries
 
 //----------------------------------------------------------------
 
-
 /**
  * Returns true is a line is blank (contains only white caracters)
  */
@@ -48,7 +52,6 @@ static bool isBlank(const string& s) {
     return true;
 }
 
-
 /**
  * Replace every occurrence of oldstr by newstr inside str. str is modified
  * and returned as reference for convenience
@@ -59,14 +62,13 @@ static string& replaceOccurences(string& str, const string& oldstr, const string
     string::size_type l2 = newstr.length();
 
     string::size_type pos = str.find(oldstr);
-    while ( pos != string::npos) {
+    while (pos != string::npos) {
         str.replace(pos, l1, newstr);
         pos = str.find(oldstr, pos + l2);
     }
     return str;
 }
 
-
 /**
  * Used when copying architecture files to replace default mydsp
  * class name with the user specified one
@@ -76,7 +78,6 @@ static string& replaceClassName(string& str)
     return replaceOccurences(str, "mydsp", gClassName);
 }
 
-
 /**
  * Copy or remove license header. Architecture files can contain a header specifying
  * the license. If this header contains an exception tag (for example "FAUST COMPILER EXCEPTION")
@@ -98,7 +99,7 @@ void streamCopyLicense(istream& src, ostream& dst, const string& exceptiontag)
     bool remove = false;
     H.push_back(s);
 
-    while (getline(src,s) && s.find("*/")==string::npos) {
+    while (getline(src,s) && s.find("*/") == string::npos) {
         H.push_back(s);
         if (s.find(exceptiontag) != string::npos) remove=true;
     }
@@ -113,6 +114,68 @@ void streamCopyLicense(istream& src, ostream& dst, const string& exceptiontag)
     }
 }
 
+/**
+ * A minimalistic parser used to recognize '#include <faust/...>' patterns when copying
+ * architecture files 
+ */
+class myparser
+{
+    string  str;
+    size_t  N;
+    size_t  p;
+public:
+    myparser(const string& s) : str(s), N(s.length()), p(0) {}
+    bool skip()                 { while ( p<N && isspace(str[p]) ) p++; return true; }
+    bool parse(const string& s)   { bool f; if ((f = (p == str.find(s, p)))) p += s.length(); return f; }
+    bool filename(string& fname) {
+        size_t saved = p;
+        if (p<N) {
+            char c = str[p++];
+            if (c== '<' | c=='"') {
+                fname = "";
+                while ( p<N && (str[p] != '>') && (str[p] != '"')) fname += str[p++];
+                p++;
+                return true;
+            }
+        }
+        p = saved;
+        return false;
+    }
+};
+
+/**
+ * True if string s match '#include <faust/fname>'
+ */
+bool isFaustInclude(const string& s, string& fname)
+{
+    myparser P(s);
+    if ( P.skip() && P.parse("#include") && P.skip() && P.filename(fname) ) {
+        myparser Q(fname);
+        return Q.parse("faust/");
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Inject file fname into dst ostream if not already done
+ */
+
+// to keep track of already injected files
+set<string> alreadyIncluded;
+
+void inject(ostream& dst, const string fname)
+{
+    if (alreadyIncluded.find(fname) == alreadyIncluded.end()) {
+        alreadyIncluded.insert(fname);
+        istream* src = open_arch_stream( fname.c_str());
+        if (src) {
+            streamCopy(*src, dst);
+        } else {
+            cerr << "NOT FOUND " << fname << endl;
+        }
+    }
+}
 
 /**
  * Copy src to dst until specific line.
@@ -120,7 +183,14 @@ void streamCopyLicense(istream& src, ostream& dst, const string& exceptiontag)
 void streamCopyUntil(istream& src, ostream& dst, const string& until)
 {
     string	s;
-    while ( getline(src,s) && (s != until) ) dst << replaceClassName(s) << endl;
+    string  fname;
+    while ( getline(src,s) && (s != until) ) {
+        if (gInlineArchSwitch && isFaustInclude(s, fname)) {
+            inject(dst, fname);
+        } else {
+            dst << replaceClassName(s) << endl;
+        }
+    }
 }
 
 /**
@@ -128,8 +198,7 @@ void streamCopyUntil(istream& src, ostream& dst, const string& until)
  */
 void streamCopy(istream& src, ostream& dst)
 { 
-	string	s;
-    while ( getline(src,s)) dst << replaceClassName(s) << endl;
+    streamCopyUntil(src, dst, "<<<FOBIDDEN LINE IN A FAUST ARCHITECTURE FILE>>>");
 }
 
 /**
@@ -137,10 +206,14 @@ void streamCopy(istream& src, ostream& dst)
  */
 void streamCopyUntilEnd(istream& src, ostream& dst)
 { 
-	string	s;
-    while ( getline(src,s) ) dst << replaceClassName(s) << endl;
+    streamCopyUntil(src, dst, "<<<FOBIDDEN LINE IN A FAUST ARCHITECTURE FILE>>>");
 }
 
+#define TRY_OPEN(filename)                      \
+    ifstream* f = new ifstream();               \
+    f->open(filename, ifstream::in);            \
+    err=chdir(old);                                 \
+    if (f->is_open()) return f; else delete f;  \
 
 /**
  * Try to open an architecture file searching in various directories
@@ -148,87 +221,106 @@ void streamCopyUntilEnd(istream& src, ostream& dst)
 ifstream* open_arch_stream(const char* filename)
 {
 	char	buffer[FAUST_PATH_MAX];
-    char*	old = getcwd (buffer, FAUST_PATH_MAX);
+    char*	old = getcwd(buffer, FAUST_PATH_MAX);
 	int		err;
 
-    {
-	    ifstream* f = new ifstream();
-	    f->open(filename, ifstream::in); if (f->is_open()) return f; else delete f;
-    }
+    TRY_OPEN(filename);
+    
     char *envpath = getenv("FAUST_LIB_PATH");
     if (envpath!=NULL) {
 		if (chdir(envpath)==0) {
-			ifstream* f = new ifstream();
-			f->open(filename, ifstream::in);
-			if (f->is_open()) return f; else delete f;
+			TRY_OPEN(filename);
 		}
     }
-	err = chdir(old);
-	if ( (chdir(gFaustDirectory.c_str())==0) && (chdir("architecture")==0) ) {
+    if ( (chdir(gFaustDirectory.c_str())==0) && (chdir("architecture")==0) ) {
 		//cout << "enrobage.cpp : 'architecture' directory found in gFaustDirectory" << endl;
-        ifstream* f = new ifstream();
-		f->open(filename, ifstream::in);
-		if (f->good()) return f; else delete f;
-	}
-	err = chdir(old);
-	if ((chdir(gFaustSuperDirectory.c_str())==0) && (chdir("architecture")==0) ) {
-		//cout << "enrobage.cpp : 'architecture' directory found in gFaustSuperDirectory" << endl;
-        ifstream* f = new ifstream();
-		f->open(filename, ifstream::in);
-		if (f->good()) return f; else delete f;
+        TRY_OPEN(filename);
 	}
-	err = chdir(old);
-	if ((chdir(gFaustSuperSuperDirectory.c_str())==0) && (chdir("architecture")==0) ) {
-		//cout << "enrobage.cpp : 'architecture' directory found in gFaustSuperSuperDirectory" << endl;
-        ifstream* f = new ifstream();
-		f->open(filename, ifstream::in);
-		if (f->good()) return f; else delete f;
+    if ((chdir(gFaustSuperDirectory.c_str())==0) && (chdir("architecture")==0) ) {
+        //cout << "enrobage.cpp : 'architecture' directory found in gFaustSuperDirectory" << endl;
+        TRY_OPEN(filename);
+    }
+    if ((chdir(gFaustSuperSuperDirectory.c_str())==0) && (chdir("architecture")==0) ) {
+        //cout << "enrobage.cpp : 'architecture' directory found in gFaustSuperSuperDirectory" << endl;
+        TRY_OPEN(filename);
 	}
 #ifdef INSTALL_PREFIX
-	err = chdir(old);
-	if (chdir(INSTALL_PREFIX "/lib/faust")==0) {
-        ifstream* f = new ifstream();
-		f->open(filename); 
-		if (f->good()) return f; else delete f;
+    if (chdir(INSTALL_PREFIX "/lib/faust")==0) {
+        TRY_OPEN(filename);
 	}
+    if (chdir(INSTALL_PREFIX "/include")==0) {
+        TRY_OPEN(filename);
+    }
 #endif
-	err = chdir(old);
-	if (chdir("/usr/local/lib/faust")==0) {
-        ifstream* f = new ifstream();
-		f->open(filename); 
-		if (f->good()) return f; else delete f;
-	}
-	err = chdir(old);
-	if (chdir("/usr/lib/faust")==0) {
-        ifstream* f = new ifstream();
-		f->open(filename); 
-		if (f->good()) return f; else delete f;
+    if (chdir("/usr/local/lib/faust")==0) {
+        TRY_OPEN(filename);
 	}
-	
+    if (chdir("/usr/lib/faust")==0) {
+        TRY_OPEN(filename);
+    }
+    if (chdir("/usr/local/include")==0) {
+        TRY_OPEN(filename);
+    }
+    if (chdir("/usr/include")==0) {
+        TRY_OPEN(filename);
+    }
+
 	return 0;
 }
 
-
-
 /*---------------------------------------------*/
 
+const char* strip_start(const char* filename)
+{
+    const char* start = "file://";
+    if (strstr(filename, start) != NULL) {
+        return &filename[strlen(start)];
+    }  else {
+        return filename;
+    }
+}
+
 /**
- * Check if a file exists.
- * @return true if the file exist, false otherwise
+ * Check if an URL exists.
+ * @return true if the URL exist, false otherwise
  */
 		
-bool check_file(const char* filename)
+bool check_url(const char* filename)
 {
-	FILE* f = fopen(filename, "r");
-	
-	if (f == NULL) {
-		fprintf(stderr, "faust: "); perror(filename);
-	} else {
-		fclose(f);
-	}
-	return f != NULL;
+    char* fileBuf = 0;
+
+	// Tries to open as an URL for a local file
+    if (strstr(filename, "file://") != 0) {
+        // Tries to open as a regular file after removing 'file://'
+        FILE* f = fopen(&filename[7], "r");
+        if (f) {
+            fclose(f);
+            return true;
+        } else {
+            cerr << "ERROR : cannot open file '" << filename << "' : " <<  strerror(errno) << "; for help type \"faust --help\"" << endl;
+            return false;
+        }
+     
+    // Tries to open as a http URL
+    } else if (strstr(filename, "http://") != 0) {
+        if (http_fetch(filename, &fileBuf) != -1) {
+            return true;
+        } else {
+            cerr << "ERROR : unable to access URL '" << filename << "' : " << http_strerror() << "; for help type \"faust --help\"" << endl;
+            return false;
+        }
+    } else {
+        // Otherwise tries to open as a regular file
+        FILE* f = fopen(filename, "r");
+        if (f) {
+            fclose(f);
+            return true;
+        } else {
+            cerr << "ERROR : cannot open file '" << filename << "' : " <<  strerror(errno) << "; for help type \"faust --help\"" << endl;
+            return false;
+        }
+    }
 }
-		
 
 /**
  * Try to open the file '<dir>/<filename>'. If it succeed, it stores the full pathname
@@ -236,24 +328,32 @@ bool check_file(const char* filename)
  */
 static FILE* fopenat(string& fullpath, const char* dir, const char* filename)
 {
-	int 		err; 
-    char        olddirbuffer[FAUST_PATH_MAX];
-    char        newdirbuffer[FAUST_PATH_MAX];
+	int err; 
+    char olddirbuffer[FAUST_PATH_MAX];
+    char newdirbuffer[FAUST_PATH_MAX];
     
-    char* 		olddir = getcwd (olddirbuffer, FAUST_PATH_MAX);
+    char* olddir = getcwd(olddirbuffer, FAUST_PATH_MAX);
 
     if (chdir(dir) == 0) {           
         FILE* f = fopen(filename, "r");
-		fullpath = getcwd (newdirbuffer, FAUST_PATH_MAX);
+	    char* newdir = getcwd(newdirbuffer, FAUST_PATH_MAX);
+        if (!newdir) {
+            cerr << "ERROR : getcwd '" << strerror(errno) << endl;
+            return 0;
+        }
+		fullpath = newdir;
 		fullpath += '/';
 		fullpath += filename;
         err = chdir(olddir);
+        if (err != 0) cerr << "ERROR : cannot change back directory to '" << olddir << "' : " <<  strerror(errno) << endl;
         return f;
     }
     err = chdir(olddir);
+    if (err != 0) cerr << "ERROR : cannot change back directory to '" << olddir << "' : " <<  strerror(errno) << endl;
     return 0;
 }
 
+
 /**
  * Try to open the file '<dir>/<filename>'. If it succeed, it stores the full pathname
  * of the file into <fullpath>
@@ -269,15 +369,21 @@ static FILE* fopenat(string& fullpath, const string& dir, const char* filename)
  */
 static FILE* fopenat(string& fullpath, const string& dir, const char* path, const char* filename)
 {
-	int			err;
-    char        olddirbuffer[FAUST_PATH_MAX];
-    char        newdirbuffer[FAUST_PATH_MAX];
+    int	err;
+    char olddirbuffer[FAUST_PATH_MAX];
+    char newdirbuffer[FAUST_PATH_MAX];
+    
+    char* olddir = getcwd(olddirbuffer, FAUST_PATH_MAX);
     
-    char* 		olddir = getcwd (olddirbuffer, FAUST_PATH_MAX);
     if (chdir(dir.c_str()) == 0) {
         if (chdir(path) == 0) {            
             FILE* f = fopen(filename, "r");
-			fullpath = getcwd (newdirbuffer, FAUST_PATH_MAX);
+			char* newdir = getcwd(newdirbuffer, FAUST_PATH_MAX);
+            if (!newdir) {
+                cerr << "ERROR : getcwd '" << strerror(errno) << endl;
+                return 0;
+            }
+            fullpath = newdir;
 			fullpath += '/';
 			fullpath += filename;
             err = chdir(olddir);
@@ -285,11 +391,10 @@ static FILE* fopenat(string& fullpath, const string& dir, const char* path, cons
         }
     }
     err = chdir(olddir);
+    if (err != 0) cerr << "ERROR : cannot change back directory to '" << olddir << "' : " <<  strerror(errno) << endl;
     return 0;
 }
 
-
-
 /**
  * Test absolute pathname.
  */
@@ -304,19 +409,23 @@ static bool isAbsolutePathname(const string& filename)
 	return false;
 }
 
-
 /**
  * Build a full pathname of <filename>.
  * <fullpath> = <currentdir>/<filename>
  */
 static void buildFullPathname(string& fullpath, const char* filename)
 {
-	char	old[FAUST_PATH_MAX];
+	char old[FAUST_PATH_MAX];
 
 	if (isAbsolutePathname(filename)) {
 		fullpath = filename;
 	} else {
-		fullpath = getcwd (old, FAUST_PATH_MAX);
+		char* newdir = getcwd(old, FAUST_PATH_MAX);
+        if (!newdir) {
+            cerr << "ERROR : getcwd '" << strerror(errno) << endl;
+            return;
+        }
+        fullpath = newdir;
 		fullpath += '/';
 		fullpath += filename;
 	}
@@ -327,43 +436,31 @@ static void buildFullPathname(string& fullpath, const char* filename)
  *  place its full pathname in the string <fullpath>
  */
 
-#ifdef WIN32
 FILE* fopensearch(const char* filename, string& fullpath)
 {   
     FILE* f;
     char* envpath;
 
+
+    // search in current directory
+
     if ((f = fopen(filename, "r"))) { 
     	buildFullPathname(fullpath, filename); 
     	return f;
     }
-    if ((f = fopenat(fullpath, gMasterDirectory, filename))) { 
-    	return f;
-    }
-    if ((envpath = getenv("FAUST_LIB_PATH")) && (f = fopenat(fullpath, envpath, filename))) {
-        return f;
-    }
-    if ((f = fopenat(fullpath, gFaustDirectory, "architecture", filename))) { 
-    	return f;
-    }
-    if ((f = fopenat(fullpath, gFaustSuperDirectory, "architecture", filename))) { 
-    	return f;
-    }
-    if ((f = fopenat(fullpath, gFaustSuperSuperDirectory, "architecture", filename))) { 
-    	return f;
-    }
-    return 0;
-}
-#else
-FILE* fopensearch(const char* filename, string& fullpath)
-{   
-    FILE* f;
-    char* envpath;
 
-    if ((f = fopen(filename, "r"))) { 
-    	buildFullPathname(fullpath, filename); 
-    	return f;
+    // search file in user supplied directory path
+
+    for (list< string >::iterator i = gImportDirList.begin(); i != gImportDirList.end(); i++) {
+        if ((f = fopenat(fullpath, *i, filename))) {
+            //std::cerr << "found file : " << fullpath << std::endl;
+            return f;
+        }
     }
+
+
+    // search in default directories
+
     if ((f = fopenat(fullpath, gMasterDirectory, filename))) { 
     	return f;
     }
@@ -392,7 +489,6 @@ FILE* fopensearch(const char* filename, string& fullpath)
     }
     return 0;
 }
-#endif
 
 
 /** 
@@ -452,7 +548,7 @@ const char* filebasename(const char* name)
 string filedirname(const string& name)
 {
     const char*         base = filebasename(name.c_str());
-    const unsigned int  size = base-name.c_str();
+    const unsigned int  size = (const unsigned int)(base-name.c_str());
     string              dirname;
 
     if (size==0) {
diff --git a/compiler/parser/enrobage.hh b/compiler/parser/enrobage.hh
index 611bbb0..b0d5e36 100644
--- a/compiler/parser/enrobage.hh
+++ b/compiler/parser/enrobage.hh
@@ -19,15 +19,12 @@
  ************************************************************************
  ************************************************************************/
  
- 
- 
 #include <stdio.h>
 #include <string.h>
 #include <string>
 #include <fstream>
 #include <iostream>
 
-
 using namespace std;
 
 void copyFirstHalf(FILE* file, FILE* dst);
@@ -35,8 +32,6 @@ void copySecondHalf(FILE* file, FILE* dst);
 void copyZeroHalf(FILE* file, FILE* dst);
 void copyFile(FILE* file, FILE* dst);
 
-
-
 void streamCopyLicense(istream& src, ostream& dst, const string& exceptiontag);
 void streamCopyUntil(istream& src, ostream& dst, const string& until);
 void streamCopyUntilEnd(istream& src, ostream& dst);
@@ -46,15 +41,9 @@ ifstream* open_arch_stream (const char* filename);
 
 FILE* fopensearch(const char* filename, string& fullpath);
 
-bool check_file(const char* filename);
+const char* strip_start(const char* filename);
+bool check_url(const char* filename);
 		
 const char* filebasename(const char* name); // returns a pointer on the basename part of name
 
 string filedirname(const string& name);        // allocate a string containing the dirname of name
-
-//static string dirname(const string& path)
-//{
-//    char s[1024];
-//    strncpy(s, path.c_str(), 1024);
-//    return string(dirname(s));
-//}
diff --git a/compiler/parser/faustlexer.cpp b/compiler/parser/faustlexer.cpp
index f113043..4203229 100644
--- a/compiler/parser/faustlexer.cpp
+++ b/compiler/parser/faustlexer.cpp
@@ -47,6 +47,7 @@ typedef int16_t flex_int16_t;
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -54,6 +55,7 @@ typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -84,8 +86,6 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! C99 */
-
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -142,15 +142,7 @@ typedef unsigned int flex_uint32_t;
 
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
 #define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
 #endif
 
 /* The state buf must be large enough to hold one state per character in the main buffer.
@@ -162,7 +154,12 @@ typedef unsigned int flex_uint32_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
-extern int yyleng;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t yyleng;
 
 extern FILE *yyin, *yyout;
 
@@ -179,7 +176,7 @@ extern FILE *yyin, *yyout;
      */
     #define  YY_LESS_LINENO(n) \
             do { \
-                int yyl;\
+                yy_size_t yyl;\
                 for ( yyl = n; yyl < yyleng; ++yyl )\
                     if ( yytext[yyl] == '\n' )\
                         --yylineno;\
@@ -201,11 +198,6 @@ extern FILE *yyin, *yyout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -223,7 +215,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -293,8 +285,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int yyleng;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t yyleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
@@ -322,7 +314,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 void *yyalloc (yy_size_t  );
 void *yyrealloc (void *,yy_size_t  );
@@ -377,13 +369,13 @@ static void yy_fatal_error (yyconst char msg[]  );
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
-	yyleng = (size_t) (yy_cp - yy_bp); \
+	yyleng = (yy_size_t) (yy_cp - yy_bp); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
 
-#define YY_NUM_RULES 134
-#define YY_END_OF_BUFFER 135
+#define YY_NUM_RULES 143
+#define YY_END_OF_BUFFER 144
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -391,58 +383,61 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[458] =
+static yyconst flex_int16_t yy_accept[482] =
     {   0,
-        0,    0,    2,    2,    0,    0,    0,    0,  135,  133,
-      132,  132,   60,  133,   45,   48,   47,   63,   64,   43,
-       41,   36,   42,   70,   44,   29,   35,   61,   53,   62,
-       55,   46,  127,   67,   69,   68,  104,   59,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,   65,   49,   66,   40,
-        2,    5,    6,    3,    9,   10,    9,  134,   27,  134,
-       26,  134,  134,  134,  134,  132,   58,    0,  128,   38,
-       33,    1,  131,   30,   29,    0,   39,    0,    0,   37,
-       51,   54,  130,    0,    0,   57,  125,   56,   52,  127,
-
-      126,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,    2,    4,    3,
-        3,    7,    0,    0,    0,    0,    0,    0,   28,    0,
-        0,    0,    0,    0,    0,  131,   30,    0,    0,   32,
-        0,    0,    0,    0,    0,  126,  107,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,   98,  127,  127,  101,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,   74,
-
-      127,  102,  109,   72,  108,  127,  116,  105,  127,  127,
-      127,  127,  127,  127,  127,  115,   99,  127,  117,  100,
-      127,  127,  127,  127,  127,   50,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,   34,    0,
-       31,  129,    0,    0,    0,    0,   94,   95,   96,  127,
-      127,  124,  113,  127,  127,  127,  127,  127,  127,  127,
-      127,  110,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  118,  127,  127,  114,  127,  127,  106,  127,  127,
-      127,  127,   71,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,   21,    0,    0,    0,    0,   97,  127,
-
-      127,  127,  127,  127,  127,  127,  127,   75,  112,  127,
-      127,  127,  127,  127,  127,  103,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,    0,    0,    0,    0,
-        0,    0,    0,    0,   22,    0,    0,    0,    0,    8,
-       93,   83,  127,  127,  127,  127,  127,  127,  127,  127,
-       89,  127,  119,  127,   87,   73,  127,  127,  127,  127,
-       90,  127,   88,  127,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  127,  127,  123,  127,
-      127,  127,  127,  127,   86,  121,   76,  127,   77,   78,
-       79,  127,   85,   20,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,    0,    0,   84,  127,  127,  127,  127,
-      127,  127,  127,  127,    0,    0,   13,    0,    0,    0,
-        0,    0,   24,    0,    0,    0,  120,  127,   81,   80,
-       82,   92,  111,   91,   16,    0,    0,    0,   11,    0,
-        0,   17,    0,    0,  127,   14,   18,   12,    0,    0,
-       15,   19,  122,    0,   25,   23,    0
+        0,    0,    2,    2,    0,    0,    0,    0,  144,  142,
+      141,  141,   66,  142,   51,   54,   53,   69,   70,   49,
+       47,   42,   48,   76,   50,   29,   41,   67,   59,   68,
+       61,   52,  136,   73,   75,   74,  110,   65,  136,  136,
+      136,  136,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,  136,  136,  136,   71,   55,   72,
+       46,    2,    5,    6,    3,    9,   10,    9,  143,   27,
+      143,   26,  143,  143,  143,  143,  141,   64,    0,  137,
+       44,   37,    1,  140,   31,   29,    0,   30,   45,    0,
+        0,   43,   57,   60,  139,    0,    0,   63,  134,   62,
+
+       58,  136,  135,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,    2,    4,    3,    3,    7,    0,    0,    0,    0,
+        0,    0,   28,    0,    0,    0,    0,    0,    0,   38,
+      140,   31,    0,   32,    0,   35,    0,    0,    0,    0,
+        0,  135,  113,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  104,  136,  136,  107,  136,  136,  136,  136,
+
+      136,  136,  136,  136,  136,  136,   80,  136,  108,  115,
+       78,  114,  136,  136,  122,  111,  136,  136,  136,  136,
+      136,  136,  136,  121,  105,  136,  123,  106,  136,  136,
+      136,  136,  136,  136,   56,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   39,    0,   33,
+       36,  138,    0,    0,    0,    0,  100,  101,  102,  136,
+      136,  133,  119,  136,  136,  136,  136,  136,  136,  136,
+      136,  116,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  124,  136,  136,  120,  136,  136,  112,
+      136,  136,  136,  136,  136,   77,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,   21,   40,   34,    0,
+        0,    0,    0,  103,  136,  136,  136,  136,  136,  136,
+      136,  136,   81,  118,  136,  136,  136,  136,  136,  136,
+      136,  109,  136,  136,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,    0,    0,    0,    0,    0,    0,
+        0,    0,   22,    0,    0,    0,    0,    8,   99,   89,
+      136,  136,  136,  136,  136,  136,  136,  136,   95,  136,
+      127,  125,  136,   93,  136,   79,  136,  136,  136,  136,
+       96,  136,   94,  136,  136,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  136,  136,  132,
+
+      136,  136,  136,  136,  136,   92,  129,  126,   82,  136,
+       83,   84,   85,  136,   91,  136,   20,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   90,  136,
+      136,  136,  136,  136,  136,  136,  136,  131,    0,    0,
+       13,    0,    0,    0,    0,    0,   24,    0,    0,    0,
+      128,  136,   87,   86,   88,   98,  117,   97,   16,    0,
+        0,    0,   11,    0,    0,   17,    0,    0,  136,   14,
+       18,   12,    0,    0,   15,   19,  130,    0,   25,   23,
+        0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -488,194 +483,206 @@ static yyconst flex_int32_t yy_meta[64] =
         1,    1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[470] =
+static yyconst flex_int16_t yy_base[494] =
     {   0,
-        0,    0,   61,   63,   65,   66,   63,   66,  603,  604,
-       75,   83,  575,  594,  604,  604,  604,  604,  604,  604,
-      572,  604,  604,   75,   88,  102,  571,  604,  109,   44,
-       55,  604,    0,  604,  604,  604,  604,    0,   62,  543,
-       98,  557,   60,  102,  102,   64,   65,  110,  556,  115,
-      113,  121,  124,  126,  551,  545,  604,  604,  604,  604,
-        0,  589,  604,  156,  604,  604,  141,  604,  604,  564,
-      604,   88,  555,  551,  537,  180,  604,  581,  604,  604,
-      171,  604,    0,  176,  183,  198,  604,    0,  168,  604,
-      604,  604,  604,  207,  548,  604,  604,  604,  604,    0,
-
-        0,  533,  536,  540,  173,  529,  529,  537,  540,  124,
-      541,  522,  527,  527,  520,  525,  524,  536,  535,  518,
-      523,  518,  513,  529,  523,  506,  516,  514,  513,  508,
-      502,  161,  504,  510,  508,  501,  127,  506,  501,  505,
-      503,  498,  513,  496,  501,  492,  493,    0,  604,  219,
-      223,  604,  497,  499,  491,  497,  500,  490,  604,  488,
-      484,  490,  486,  479,  224,    0,  229,  239,  244,  251,
-      505,  488,  480,  490,  480,    0,    0,  475,  479,  478,
-      489,  470,  483,  476,  483,  470,    0,  473,  474,    0,
-      469,  468,  126,  476,  462,  461,  463,  467,  461,    0,
-
-      457,  488,    0,    0,    0,  453,    0,    0,  465,  466,
-      468,  467,  448,  465,  460,    0,    0,  445,    0,    0,
-      449,  445,  447,  451,  451,    0,  454,  456,  436,  437,
-      435,  434,  447,  432,  432,  446,  443,  256,  261,  266,
-      271,  604,  446,  426,  426,  441,    0,    0,  457,  439,
-      427,    0,    0,  430,  425,  437,  420,  418,  432,  415,
-      416,    0,  423,  424,  410,  425,  411,  426,  442,  408,
-      415,    0,  421,  413,    0,  419,  417,    0,  399,  411,
-      397,  412,    0,  401,  407,  412,  393,  410,  401,  396,
-      391,  402,  387,  604,  398,  403,  402,  409,    0,  393,
-
-      387,  397,  385,  380,  382,  376,  375,    0,    0,  392,
-      375,  376,  385,  370,  371,    0,  363,  363,  374,  371,
-      372,  363,  366,  363,  364,  373,  374,  359,  356,  365,
-      369,  369,  367,  361,  604,  368,  351,  348,  362,  604,
-        0,    0,  351,  359,  358,  349,  360,  351,  357,  357,
-        0,  340,    0,  332,    0,    0,  350,  350,  348,  108,
-        0,  351,    0,  334,  357,  348,  339,  334,  345,  340,
-      339,  341,  335,  340,  331,  338,  315,  324,    0,  324,
-      322,  320,  322,  317,    0,    0,    0,  326,    0,    0,
-        0,  315,    0,  604,  317,  314,  320,  307,  208,  312,
-
-      304,  305,  310,  307,  301,    0,  300,  313,  298,  303,
-      310,  306,  296,  304,  318,  297,  604,  308,  319,  303,
-      288,  271,  604,  292,  220,  221,    0,  208,    0,    0,
-        0,    0,    0,    0,  604,  226,  214,  211,  604,  186,
-      189,  604,  200,  194,  132,  604,  604,  604,  105,   92,
-      604,  604,    0,   50,  604,  604,  604,  294,  300,  306,
-      312,  315,  317,   83,  323,  329,  335,   69,  337
+        0,    0,   61,   63,   65,   66,   63,   66,  628,  629,
+       75,   83,  600,  619,  629,  629,  629,  629,  629,  629,
+      597,  629,  629,   75,   88,  102,  596,  629,  109,   44,
+       55,  629,    0,  629,  629,  629,  629,    0,   62,  568,
+       98,  582,   60,  107,  102,   64,   65,  121,  581,  565,
+      110,  127,  124,  116,  132,   96,  570,  629,  629,  629,
+      629,    0,  614,  629,  159,  629,  629,  142,  629,  629,
+      589,  629,  136,  580,  576,  562,  126,  629,  606,  629,
+      629,  172,  629,    0,  177,  184,  200,  629,  629,    0,
+      187,  629,  629,  629,  629,  211,  573,  629,  629,  629,
+
+      629,    0,    0,  558,  561,  565,  179,  554,  554,  562,
+      565,  155,  566,  547,  552,  552,  545,  550,  549,  561,
+      560,  543,  548,  543,  133,  555,  549,  532,  542,  540,
+      539,  532,  533,  527,  191,  529,  535,  533,  526,  127,
+      531,  526,  530,  528,  523,  538,  521,  526,  515,  516,
+      517,    0,  629,  223,  229,  629,  521,  523,  515,  521,
+      524,  514,  629,  512,  508,  514,  510,  503,  229,  629,
+        0,  234,  244,  629,  249,  257,  529,  512,  504,  514,
+      504,    0,    0,  499,  503,  502,  513,  494,  507,  500,
+      507,  494,    0,  497,  498,    0,  493,  492,  210,  500,
+
+      486,  485,  487,  491,  485,  478,    0,  480,  511,    0,
+        0,    0,  476,  479,    0,    0,  487,  488,  490,  489,
+      470,  487,  482,    0,    0,  467,    0,    0,  471,  467,
+      469,  473,  476,  472,    0,  475,  477,  457,  458,  456,
+      455,  468,  453,  453,  467,  464,  262,  267,  272,  280,
+      629,  629,  467,  447,  447,  462,    0,    0,  478,  460,
+      448,    0,    0,  451,  446,  458,  441,  439,  453,  436,
+      437,    0,  444,  445,  431,  446,  432,  429,  446,  462,
+      428,  424,  434,    0,  440,  432,    0,  438,  436,    0,
+      418,  430,  416,  431,  428,    0,  419,  425,  430,  411,
+
+      428,  419,  414,  409,  420,  405,  629,  629,  629,  416,
+      421,  420,  427,    0,  411,  405,  415,  403,  398,  400,
+      394,  393,    0,    0,  410,  393,  394,  403,  388,  388,
+      388,    0,  380,  384,  379,  390,  387,  388,  379,  382,
+      379,  380,  389,  379,  389,  374,  371,  380,  384,  384,
+      382,  376,  629,  383,  366,  363,  377,  629,    0,    0,
+      366,  374,  373,  364,  375,  366,  372,  372,    0,  355,
+        0,    0,  347,    0,  352,    0,  364,  364,  362,  128,
+        0,  365,    0,  348,  347,  370,  361,  352,  347,  358,
+      353,  352,  354,  348,  353,  344,  351,  328,  337,    0,
+
+      337,  335,  333,  335,  330,    0,    0,    0,    0,  339,
+        0,    0,    0,  328,    0,  330,  629,  329,  326,  332,
+      319,  291,  324,  316,  311,  311,  304,  298,    0,  293,
+      280,  265,  270,  277,  273,  263,  271,    0,  285,  264,
+      629,  275,  292,  279,  268,  251,  629,  276,  249,  237,
+        0,  214,    0,    0,    0,    0,    0,    0,  629,  233,
+      216,  204,  629,  186,  171,  629,  182,  181,  132,  629,
+      629,  629,  130,  112,  629,  629,    0,   50,  629,  629,
+      629,  321,  327,  333,  339,  342,  344,   83,  350,  356,
+      362,   69,  364
+
     } ;
 
-static yyconst flex_int16_t yy_def[470] =
+static yyconst flex_int16_t yy_def[494] =
     {   0,
-      457,    1,  458,  458,  459,  459,  460,  460,  457,  457,
-      457,  457,  457,  461,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  462,  457,
-      457,  457,  463,  457,  457,  457,  457,  464,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  457,  457,  457,  457,
-      465,  457,  457,  466,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  461,  457,  457,
-      457,  457,  467,  457,  457,  457,  457,  468,  457,  457,
-      457,  457,  457,  462,   94,  457,  457,  457,  457,  463,
-
-      469,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  465,  457,  466,
-      466,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  467,  457,  457,  457,  457,
-      457,  457,  457,  457,   94,  469,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,   94,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,   94,  463,  463,
-
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  463,  463,  463,  463,
-      463,  463,  463,  463,  463,  463,  463,  463,  463,  463,
-      463,  463,  463,  457,  457,  457,  457,  457,  457,  457,
-
-      457,  457,  457,  457,  457,  463,  463,  463,  463,  463,
-      463,  463,  463,  463,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  463,  463,  463,  463,
-      463,  463,  463,  463,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  463,  457,  457,  457,  457,  457,
-      457,  457,  463,  457,  457,  457,    0,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457
+      481,    1,  482,  482,  483,  483,  484,  484,  481,  481,
+      481,  481,  481,  485,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  486,  481,
+      481,  481,  487,  481,  481,  481,  481,  488,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  481,  481,  481,
+      481,  489,  481,  481,  490,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  485,  481,
+      481,  481,  481,  491,  481,  481,  481,  481,  481,  492,
+      481,  481,  481,  481,  481,  486,   96,  481,  481,  481,
+
+      481,  487,  493,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  489,  481,  490,  490,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      491,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+       96,  493,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,   96,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  481,  481,  481,  481,
+
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,   96,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  487,  487,  487,
+
+      487,  487,  487,  487,  487,  487,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      487,  487,  487,  487,  487,  487,  487,  487,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  487,  481,
+      481,  481,  481,  481,  481,  481,  487,  481,  481,  481,
+        0,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481
+
     } ;
 
-static yyconst flex_int16_t yy_nxt[668] =
+static yyconst flex_int16_t yy_nxt[693] =
     {   0,
        10,   11,   12,   11,   11,   13,   14,   15,   16,   17,
        18,   19,   20,   21,   22,   23,   24,   25,   26,   26,
        26,   26,   26,   27,   28,   29,   30,   31,   32,   33,
        34,   35,   36,   37,   38,   39,   40,   41,   42,   43,
-       44,   33,   45,   46,   33,   47,   48,   49,   33,   50,
-       33,   51,   52,   53,   33,   54,   55,   56,   33,   57,
-       58,   59,   60,   62,   63,   62,   63,   66,   66,   69,
-       96,   97,   69,   64,  171,   64,   76,   76,   76,   76,
-       70,   98,   99,   70,   76,   76,   76,   76,  101,   71,
-       67,   67,   71,   81,   81,   81,   81,   81,  102,  103,
-
-       82,   72,  456,   73,   72,   83,   73,  112,  124,   74,
-      122,  123,   74,  125,  104,  105,   75,  113,   84,   75,
-       85,   85,   85,   85,   85,   88,   89,  160,  390,  391,
-      455,  161,   90,  107,   91,   92,   93,  108,  119,  114,
-      109,   86,  115,  120,  454,  126,  110,  116,  117,  127,
-      130,  133,  134,  128,  121,   95,  135,  118,  153,  141,
-      137,  260,  143,  131,  138,  142,  132,  144,  151,  136,
-      186,  139,  215,  152,  261,  140,  187,  216,  145,  154,
-      155,   76,   76,   76,   76,  453,  156,  157,  158,   81,
-       81,   81,   81,   81,  167,  167,  167,  167,  167,   84,
-
-      209,   85,   85,   85,   85,   85,  172,  173,  180,  210,
-      165,  169,  419,  169,  174,  168,  170,  170,  170,  170,
-      170,  452,   86,   88,  457,  420,  181,  451,  450,  449,
-      457,  457,  457,  457,   93,  151,  457,  238,  448,  238,
-      152,  447,  239,  239,  239,  239,  239,  167,  167,  167,
-      167,  167,  240,  446,  240,  445,  444,  241,  241,  241,
-      241,  241,  170,  170,  170,  170,  170,  443,  168,  170,
-      170,  170,  170,  170,  239,  239,  239,  239,  239,  239,
-      239,  239,  239,  239,  241,  241,  241,  241,  241,  241,
-      241,  241,  241,  241,   61,   61,   61,   61,   61,   61,
-
-       65,   65,   65,   65,   65,   65,   68,   68,   68,   68,
-       68,   68,   78,   78,   78,   78,   78,   78,   94,  442,
-       94,  100,  100,  148,  441,  440,  148,  148,  148,  150,
-      439,  150,  150,  150,  150,  166,  438,  166,  166,  166,
-      166,  176,  176,  437,  436,  435,  434,  433,  432,  431,
-      430,  429,  428,  427,  426,  425,  424,  423,  422,  421,
-      418,  417,  416,  415,  414,  413,  412,  411,  410,  409,
-      408,  407,  406,  405,  404,  403,  402,  401,  400,  399,
-      398,  397,  396,  395,  394,  393,  392,  389,  388,  387,
-      386,  385,  384,  383,  382,  381,  380,  379,  378,  377,
-
-      376,  375,  374,  373,  372,  371,  370,  369,  368,  367,
-      366,  365,  364,  363,  362,  361,  360,  359,  358,  357,
-      356,  355,  354,  353,  352,  351,  350,  349,  348,  347,
-      346,  345,  344,  343,  342,  341,  340,  339,  338,  337,
-      336,  335,  334,  333,  332,  331,  330,  329,  328,  327,
-      326,  325,  324,  323,  322,  321,  320,  319,  318,  317,
-      316,  315,  314,  313,  312,  311,  310,  309,  308,  307,
-      306,  305,  304,  303,  302,  301,  300,  299,  298,  297,
-      296,  295,  294,  293,  292,  291,  290,  289,  288,  287,
-      286,  285,  284,  283,  282,  281,  280,  279,  278,  277,
-
-      276,  275,  274,  273,  272,  271,  270,  269,  268,  267,
-      266,  265,  264,  263,  262,  259,  258,  257,  256,  255,
-      254,  253,  252,  251,  250,  249,  248,  247,  246,  245,
-      244,  243,  242,  237,  236,  235,  234,  233,  232,  231,
-      230,  229,  228,  227,  226,  225,  224,  223,  222,  221,
-      220,  219,  218,  217,  214,  213,  212,  211,  208,  207,
-      206,  205,  204,  203,  202,  201,  200,  199,  198,  197,
-      196,  195,  194,  193,  192,  191,  190,  189,  188,  185,
-      184,  183,  182,  179,  178,  177,  175,   79,  164,  163,
-      162,  159,  149,  147,  146,  129,  111,  106,   87,   80,
-
-       79,   77,  457,    9,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457
+       44,   33,   45,   46,   33,   47,   48,   49,   50,   51,
+       33,   52,   53,   54,   33,   55,   56,   57,   33,   58,
+       59,   60,   61,   63,   64,   63,   64,   67,   67,   70,
+       98,   99,   70,   65,  177,   65,   77,   77,   77,   77,
+       71,  100,  101,   71,   77,   77,   77,   77,  103,   72,
+       68,   68,   72,   82,   82,   82,   82,   82,  104,  105,
+
+       83,   73,  480,   74,   73,   84,   74,  114,  126,   75,
+      124,  125,   75,  127,  106,  107,   76,  115,   85,   76,
+       86,   86,   86,   86,   86,   90,   91,   77,   77,   77,
+       77,  149,   92,  109,   93,   94,   95,  110,  121,  150,
+      111,   87,   88,  122,  116,  133,  112,  117,  412,  413,
+      479,  144,  118,  119,  123,   97,  128,  145,  134,  157,
+      129,  135,  120,  140,  130,  136,  137,  141,  146,  478,
+      138,  155,  223,  147,  142,  164,  156,  224,  143,  165,
+      158,  159,  206,  139,  148,  477,  207,  160,  161,  162,
+       82,   82,   82,   82,   82,  172,  172,  172,  172,  172,
+
+       85,  192,   86,   86,   86,   86,   86,  193,  476,  475,
+      474,  169,  170,  175,  186,  175,  173,  174,  176,  176,
+      176,  176,  176,   87,   88,  178,  179,   90,  481,  473,
+      217,  472,  187,  180,  481,  481,  481,  481,   95,  218,
+      481,  155,  247,  471,  247,  270,  156,  248,  248,  248,
+      248,  248,  172,  172,  172,  172,  172,  249,  271,  249,
+      470,  469,  250,  250,  250,  250,  250,  176,  176,  176,
+      176,  176,  468,  173,  174,  176,  176,  176,  176,  176,
+      248,  248,  248,  248,  248,  248,  248,  248,  248,  248,
+      250,  250,  250,  250,  250,  443,  467,  251,  250,  250,
+
+      250,  250,  250,  466,  465,  464,  463,  308,  444,  462,
+      461,  460,  459,  458,  457,  456,  455,  454,  453,  452,
+      309,   62,   62,   62,   62,   62,   62,   66,   66,   66,
+       66,   66,   66,   69,   69,   69,   69,   69,   69,   79,
+       79,   79,   79,   79,   79,   96,  451,   96,  102,  102,
+      152,  450,  449,  152,  152,  152,  154,  448,  154,  154,
+      154,  154,  171,  447,  171,  171,  171,  171,  182,  182,
+      446,  445,  442,  441,  440,  439,  438,  437,  436,  435,
+      434,  433,  432,  431,  430,  429,  428,  427,  426,  425,
+      424,  423,  422,  421,  420,  419,  418,  417,  416,  415,
+
+      414,  411,  410,  409,  408,  407,  406,  405,  404,  403,
+      402,  401,  400,  399,  398,  397,  396,  395,  394,  393,
+      392,  391,  390,  389,  388,  387,  386,  385,  384,  383,
+      382,  381,  380,  379,  378,  377,  376,  375,  374,  373,
+      372,  371,  370,  369,  368,  367,  366,  365,  364,  363,
+      362,  361,  360,  359,  358,  357,  356,  355,  354,  353,
+      352,  351,  350,  349,  348,  347,  346,  345,  344,  343,
+      342,  341,  340,  339,  338,  337,  336,  335,  334,  333,
+      332,  331,  330,  329,  328,  327,  326,  325,  324,  323,
+      322,  321,  320,  319,  318,  317,  316,  315,  314,  313,
+
+      312,  311,  310,  307,  306,  305,  304,  303,  302,  301,
+      300,  299,  298,  297,  296,  295,  294,  293,  292,  291,
+      290,  289,  288,  287,  286,  285,  284,  283,  282,  281,
+      280,  279,  278,  277,  276,  275,  274,  273,  272,  269,
+      268,  267,  266,  265,  264,  263,  262,  261,  260,  259,
+      258,  257,  256,  255,  254,  253,  252,  246,  245,  244,
+      243,  242,  241,  240,  239,  238,  237,  236,  235,  234,
+      233,  232,  231,  230,  229,  228,  227,  226,  225,  222,
+      221,  220,  219,  216,  215,  214,  213,  212,  211,  210,
+      209,  208,  205,  204,  203,  202,  201,  200,  199,  198,
+
+      197,  196,  195,  194,  191,  190,  189,  188,  185,  184,
+      183,  181,   80,  168,  167,  166,  163,  153,  151,  132,
+      131,  113,  108,   89,   81,   80,   78,  481,    9,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481
+
     } ;
 
-static yyconst flex_int16_t yy_chk[668] =
+static yyconst flex_int16_t yy_chk[693] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -684,76 +691,80 @@ static yyconst flex_int16_t yy_chk[668] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    3,    3,    4,    4,    5,    6,    7,
-       30,   30,    8,    3,  468,    4,   11,   11,   11,   11,
-        7,   31,   31,    8,   12,   12,   12,   12,  464,    7,
+       30,   30,    8,    3,  492,    4,   11,   11,   11,   11,
+        7,   31,   31,    8,   12,   12,   12,   12,  488,    7,
         5,    6,    8,   24,   24,   24,   24,   24,   39,   39,
 
-       25,    7,  454,    7,    8,   25,    8,   43,   47,    7,
+       25,    7,  478,    7,    8,   25,    8,   43,   47,    7,
        46,   46,    8,   47,   39,   39,    7,   43,   26,    8,
-       26,   26,   26,   26,   26,   29,   29,   72,  360,  360,
-      450,   72,   29,   41,   29,   29,   29,   41,   45,   44,
-       41,   26,   44,   45,  449,   48,   41,   44,   44,   48,
-       50,   51,   51,   48,   45,   29,   51,   44,   67,   53,
-       52,  193,   54,   50,   52,   53,   50,   54,   64,   51,
-      110,   52,  137,   64,  193,   52,  110,  137,   54,   67,
-       67,   76,   76,   76,   76,  445,   67,   67,   67,   81,
-       81,   81,   81,   81,   84,   84,   84,   84,   84,   85,
-
-      132,   85,   85,   85,   85,   85,   89,   89,  105,  132,
-       81,   86,  399,   86,   89,   84,   86,   86,   86,   86,
-       86,  444,   85,   94,   94,  399,  105,  443,  441,  440,
-       94,  150,   94,   94,   94,  151,  150,  165,  438,  165,
-      151,  437,  165,  165,  165,  165,  165,  167,  167,  167,
-      167,  167,  168,  436,  168,  428,  426,  168,  168,  168,
-      168,  168,  169,  169,  169,  169,  169,  425,  167,  170,
-      170,  170,  170,  170,  238,  238,  238,  238,  238,  239,
-      239,  239,  239,  239,  240,  240,  240,  240,  240,  241,
-      241,  241,  241,  241,  458,  458,  458,  458,  458,  458,
-
-      459,  459,  459,  459,  459,  459,  460,  460,  460,  460,
-      460,  460,  461,  461,  461,  461,  461,  461,  462,  424,
-      462,  463,  463,  465,  422,  421,  465,  465,  465,  466,
-      420,  466,  466,  466,  466,  467,  419,  467,  467,  467,
-      467,  469,  469,  418,  416,  415,  414,  413,  412,  411,
-      410,  409,  408,  407,  405,  404,  403,  402,  401,  400,
-      398,  397,  396,  395,  392,  388,  384,  383,  382,  381,
-      380,  378,  377,  376,  375,  374,  373,  372,  371,  370,
-      369,  368,  367,  366,  365,  364,  362,  359,  358,  357,
-      354,  352,  350,  349,  348,  347,  346,  345,  344,  343,
-
-      339,  338,  337,  336,  334,  333,  332,  331,  330,  329,
-      328,  327,  326,  325,  324,  323,  322,  321,  320,  319,
-      318,  317,  315,  314,  313,  312,  311,  310,  307,  306,
-      305,  304,  303,  302,  301,  300,  298,  297,  296,  295,
-      293,  292,  291,  290,  289,  288,  287,  286,  285,  284,
-      282,  281,  280,  279,  277,  276,  274,  273,  271,  270,
-      269,  268,  267,  266,  265,  264,  263,  261,  260,  259,
-      258,  257,  256,  255,  254,  251,  250,  249,  246,  245,
-      244,  243,  237,  236,  235,  234,  233,  232,  231,  230,
-      229,  228,  227,  225,  224,  223,  222,  221,  218,  215,
-
-      214,  213,  212,  211,  210,  209,  206,  202,  201,  199,
-      198,  197,  196,  195,  194,  192,  191,  189,  188,  186,
-      185,  184,  183,  182,  181,  180,  179,  178,  175,  174,
-      173,  172,  171,  164,  163,  162,  161,  160,  158,  157,
-      156,  155,  154,  153,  147,  146,  145,  144,  143,  142,
-      141,  140,  139,  138,  136,  135,  134,  133,  131,  130,
-      129,  128,  127,  126,  125,  124,  123,  122,  121,  120,
-      119,  118,  117,  116,  115,  114,  113,  112,  111,  109,
-      108,  107,  106,  104,  103,  102,   95,   78,   75,   74,
-       73,   70,   62,   56,   55,   49,   42,   40,   27,   21,
-
-       14,   13,    9,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
-      457,  457,  457,  457,  457,  457,  457
+       26,   26,   26,   26,   26,   29,   29,   77,   77,   77,
+       77,   56,   29,   41,   29,   29,   29,   41,   45,   56,
+       41,   26,   26,   45,   44,   51,   41,   44,  380,  380,
+      474,   54,   44,   44,   45,   29,   48,   54,   51,   68,
+       48,   51,   44,   53,   48,   52,   52,   53,   55,  473,
+       52,   65,  140,   55,   53,   73,   65,  140,   53,   73,
+       68,   68,  125,   52,   55,  469,  125,   68,   68,   68,
+       82,   82,   82,   82,   82,   85,   85,   85,   85,   85,
+
+       86,  112,   86,   86,   86,   86,   86,  112,  468,  467,
+      465,   82,   82,   87,  107,   87,   85,   85,   87,   87,
+       87,   87,   87,   86,   86,   91,   91,   96,   96,  464,
+      135,  462,  107,   91,   96,  154,   96,   96,   96,  135,
+      154,  155,  169,  461,  169,  199,  155,  169,  169,  169,
+      169,  169,  172,  172,  172,  172,  172,  173,  199,  173,
+      460,  452,  173,  173,  173,  173,  173,  175,  175,  175,
+      175,  175,  450,  172,  172,  176,  176,  176,  176,  176,
+      247,  247,  247,  247,  247,  248,  248,  248,  248,  248,
+      249,  249,  249,  249,  249,  422,  449,  176,  250,  250,
+
+      250,  250,  250,  448,  446,  445,  444,  248,  422,  443,
+      442,  440,  439,  437,  436,  435,  434,  433,  432,  431,
+      250,  482,  482,  482,  482,  482,  482,  483,  483,  483,
+      483,  483,  483,  484,  484,  484,  484,  484,  484,  485,
+      485,  485,  485,  485,  485,  486,  430,  486,  487,  487,
+      489,  428,  427,  489,  489,  489,  490,  426,  490,  490,
+      490,  490,  491,  425,  491,  491,  491,  491,  493,  493,
+      424,  423,  421,  420,  419,  418,  416,  414,  410,  405,
+      404,  403,  402,  401,  399,  398,  397,  396,  395,  394,
+      393,  392,  391,  390,  389,  388,  387,  386,  385,  384,
+
+      382,  379,  378,  377,  375,  373,  370,  368,  367,  366,
+      365,  364,  363,  362,  361,  357,  356,  355,  354,  352,
+      351,  350,  349,  348,  347,  346,  345,  344,  343,  342,
+      341,  340,  339,  338,  337,  336,  335,  334,  333,  331,
+      330,  329,  328,  327,  326,  325,  322,  321,  320,  319,
+      318,  317,  316,  315,  313,  312,  311,  310,  306,  305,
+      304,  303,  302,  301,  300,  299,  298,  297,  295,  294,
+      293,  292,  291,  289,  288,  286,  285,  283,  282,  281,
+      280,  279,  278,  277,  276,  275,  274,  273,  271,  270,
+      269,  268,  267,  266,  265,  264,  261,  260,  259,  256,
+
+      255,  254,  253,  246,  245,  244,  243,  242,  241,  240,
+      239,  238,  237,  236,  234,  233,  232,  231,  230,  229,
+      226,  223,  222,  221,  220,  219,  218,  217,  214,  213,
+      209,  208,  206,  205,  204,  203,  202,  201,  200,  198,
+      197,  195,  194,  192,  191,  190,  189,  188,  187,  186,
+      185,  184,  181,  180,  179,  178,  177,  168,  167,  166,
+      165,  164,  162,  161,  160,  159,  158,  157,  151,  150,
+      149,  148,  147,  146,  145,  144,  143,  142,  141,  139,
+      138,  137,  136,  134,  133,  132,  131,  130,  129,  128,
+      127,  126,  124,  123,  122,  121,  120,  119,  118,  117,
+
+      116,  115,  114,  113,  111,  110,  109,  108,  106,  105,
+      104,   97,   79,   76,   75,   74,   71,   63,   57,   50,
+       49,   42,   40,   27,   21,   14,   13,    9,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481
+
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[135] =
+static yyconst flex_int32_t yy_rule_can_match_eol[144] =
     {   0,
 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -761,7 +772,8 @@ static yyconst flex_int32_t yy_rule_can_match_eol[135] =
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
+    0, 1, 0, 0,     };
 
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
@@ -783,12 +795,19 @@ char *yytext;
 #line 6 "parser/faustlexer.l"
 #include "tree.hh"
 #include "faustparser.hpp"
-#define YY_NO_UNISTD_H 1
-extern int isatty (int );
+#if defined(WIN32) && !defined(__MINGW32__)
+// We don't want to include compatibility.hh here, since it pulls in whole lot
+// of unneeded stuff which breaks other things, so here's some stuff to make
+// MSVC happy.
+#include <io.h>
+#define isatty _isatty
+#define fileno _fileno
+#define YY_NO_UNISTD_H
+#endif
 
 
 
-#line 792 "parser/faustlexer.cpp"
+#line 811 "parser/faustlexer.cpp"
 
 #define INITIAL 0
 #define comment 1
@@ -830,7 +849,7 @@ FILE *yyget_out (void );
 
 void yyset_out  (FILE * out_str  );
 
-int yyget_leng (void );
+yy_size_t yyget_leng (void );
 
 char *yyget_text (void );
 
@@ -850,8 +869,6 @@ extern int yywrap (void );
 #endif
 #endif
 
-    static void yyunput (int c,char *buf_ptr  );
-    
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
 #endif
@@ -872,12 +889,7 @@ static int input (void );
 
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
 #define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
@@ -885,7 +897,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -896,7 +908,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		yy_size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -978,11 +990,11 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
     
-#line 25 "parser/faustlexer.l"
+#line 33 "parser/faustlexer.l"
 
 
 
-#line 986 "parser/faustlexer.cpp"
+#line 998 "parser/faustlexer.cpp"
 
 	if ( !(yy_init) )
 		{
@@ -1035,13 +1047,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 458 )
+				if ( yy_current_state >= 482 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 604 );
+		while ( yy_base[yy_current_state] != 629 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -1056,7 +1068,7 @@ yy_find_action:
 
 		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
 			{
-			int yyl;
+			yy_size_t yyl;
 			for ( yyl = 0; yyl < yyleng; ++yyl )
 				if ( yytext[yyl] == '\n' )
 					   
@@ -1077,687 +1089,732 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 28 "parser/faustlexer.l"
+#line 36 "parser/faustlexer.l"
 BEGIN(comment);
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 29 "parser/faustlexer.l"
+#line 37 "parser/faustlexer.l"
 /* eat anything that's not a '*' 		*/
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 30 "parser/faustlexer.l"
+#line 38 "parser/faustlexer.l"
 /* eat up '*'s not followed by '/'s 	*/
 	YY_BREAK
 case 4:
 /* rule 4 can match eol */
 YY_RULE_SETUP
-#line 31 "parser/faustlexer.l"
+#line 39 "parser/faustlexer.l"
 /* no need to increment yylineno here 	*/
 	YY_BREAK
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 32 "parser/faustlexer.l"
+#line 40 "parser/faustlexer.l"
 /* no need to increment yylineno here 	*/
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 33 "parser/faustlexer.l"
+#line 41 "parser/faustlexer.l"
 /* no need to increment yylineno here 	*/
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 34 "parser/faustlexer.l"
+#line 42 "parser/faustlexer.l"
 BEGIN(INITIAL);
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 36 "parser/faustlexer.l"
+#line 44 "parser/faustlexer.l"
 { BEGIN(doc); return BDOC; }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 37 "parser/faustlexer.l"
+#line 45 "parser/faustlexer.l"
 return DOCCHAR; /* char by char, may be slow ?? */
 	YY_BREAK
 case 10:
 /* rule 10 can match eol */
 YY_RULE_SETUP
-#line 38 "parser/faustlexer.l"
+#line 46 "parser/faustlexer.l"
 return DOCCHAR; /* keep newline chars */
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 39 "parser/faustlexer.l"
+#line 47 "parser/faustlexer.l"
 return NOTICE;  /* autoclosing tag */
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 40 "parser/faustlexer.l"
+#line 48 "parser/faustlexer.l"
 return NOTICE;  /* autoclosing tag */
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 41 "parser/faustlexer.l"
+#line 49 "parser/faustlexer.l"
 { BEGIN(lst);		return BLST; } /* autoclosing tag */
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 42 "parser/faustlexer.l"
+#line 50 "parser/faustlexer.l"
 { BEGIN(INITIAL); 	return BEQN; }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 43 "parser/faustlexer.l"
+#line 51 "parser/faustlexer.l"
 { BEGIN(doc); 		return EEQN; }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 44 "parser/faustlexer.l"
+#line 52 "parser/faustlexer.l"
 { BEGIN(INITIAL); 	return BDGM; }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 45 "parser/faustlexer.l"
+#line 53 "parser/faustlexer.l"
 { BEGIN(doc); 		return EDGM; }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 46 "parser/faustlexer.l"
+#line 54 "parser/faustlexer.l"
 { BEGIN(INITIAL); 	return BMETADATA; }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 47 "parser/faustlexer.l"
+#line 55 "parser/faustlexer.l"
 { BEGIN(doc); 		return EMETADATA; }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 48 "parser/faustlexer.l"
+#line 56 "parser/faustlexer.l"
 { BEGIN(INITIAL); 	return EDOC; }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 50 "parser/faustlexer.l"
+#line 58 "parser/faustlexer.l"
 return LSTTRUE;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 51 "parser/faustlexer.l"
+#line 59 "parser/faustlexer.l"
 return LSTFALSE;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 52 "parser/faustlexer.l"
+#line 60 "parser/faustlexer.l"
 return LSTDEPENDENCIES;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 53 "parser/faustlexer.l"
+#line 61 "parser/faustlexer.l"
 return LSTMDOCTAGS;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 54 "parser/faustlexer.l"
+#line 62 "parser/faustlexer.l"
 return LSTDISTRIBUTED;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 55 "parser/faustlexer.l"
+#line 63 "parser/faustlexer.l"
 return LSTEQ;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 56 "parser/faustlexer.l"
+#line 64 "parser/faustlexer.l"
 return LSTQ;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 57 "parser/faustlexer.l"
+#line 65 "parser/faustlexer.l"
 { BEGIN(doc); 	return ELST; }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 60 "parser/faustlexer.l"
+#line 68 "parser/faustlexer.l"
 return INT;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 63 "parser/faustlexer.l"
+#line 70 "parser/faustlexer.l"
 return FLOAT;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 64 "parser/faustlexer.l"
+#line 71 "parser/faustlexer.l"
 return FLOAT;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 65 "parser/faustlexer.l"
+#line 72 "parser/faustlexer.l"
 return FLOAT;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 66 "parser/faustlexer.l"
+#line 73 "parser/faustlexer.l"
 return FLOAT;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 67 "parser/faustlexer.l"
+#line 74 "parser/faustlexer.l"
 return FLOAT;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 70 "parser/faustlexer.l"
-return SEQ;
+#line 75 "parser/faustlexer.l"
+return FLOAT;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 71 "parser/faustlexer.l"
-return PAR;
+#line 76 "parser/faustlexer.l"
+return FLOAT;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 72 "parser/faustlexer.l"
-return SPLIT;
+#line 77 "parser/faustlexer.l"
+return FLOAT;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 73 "parser/faustlexer.l"
-return MIX;
+#line 78 "parser/faustlexer.l"
+return FLOAT;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 74 "parser/faustlexer.l"
-return MIX;
+#line 79 "parser/faustlexer.l"
+return FLOAT;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 75 "parser/faustlexer.l"
-return REC;
+#line 80 "parser/faustlexer.l"
+return FLOAT;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 77 "parser/faustlexer.l"
-return ADD;
+#line 82 "parser/faustlexer.l"
+return SEQ;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 78 "parser/faustlexer.l"
-return SUB;
+#line 83 "parser/faustlexer.l"
+return PAR;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 79 "parser/faustlexer.l"
-return MUL;
+#line 84 "parser/faustlexer.l"
+return SPLIT;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 80 "parser/faustlexer.l"
-return DIV;
+#line 85 "parser/faustlexer.l"
+return MIX;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 81 "parser/faustlexer.l"
-return MOD;
+#line 86 "parser/faustlexer.l"
+return MIX;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 82 "parser/faustlexer.l"
-return FDELAY;
+#line 87 "parser/faustlexer.l"
+return REC;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 83 "parser/faustlexer.l"
-return DELAY1;
+#line 89 "parser/faustlexer.l"
+return ADD;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 85 "parser/faustlexer.l"
-return AND;
+#line 90 "parser/faustlexer.l"
+return SUB;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 86 "parser/faustlexer.l"
-return OR;
+#line 91 "parser/faustlexer.l"
+return MUL;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 87 "parser/faustlexer.l"
-return XOR;
+#line 92 "parser/faustlexer.l"
+return DIV;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 89 "parser/faustlexer.l"
-return LSH;
+#line 93 "parser/faustlexer.l"
+return MOD;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 90 "parser/faustlexer.l"
-return RSH;
+#line 94 "parser/faustlexer.l"
+return FDELAY;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 92 "parser/faustlexer.l"
-return LT;
+#line 95 "parser/faustlexer.l"
+return DELAY1;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 93 "parser/faustlexer.l"
-return LE;
+#line 97 "parser/faustlexer.l"
+return AND;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 94 "parser/faustlexer.l"
-return GT;
+#line 98 "parser/faustlexer.l"
+return OR;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 95 "parser/faustlexer.l"
-return GE;
+#line 99 "parser/faustlexer.l"
+return XOR;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 96 "parser/faustlexer.l"
-return EQ;
+#line 101 "parser/faustlexer.l"
+return LSH;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 97 "parser/faustlexer.l"
-return NE;
+#line 102 "parser/faustlexer.l"
+return RSH;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 99 "parser/faustlexer.l"
-return WIRE;
+#line 104 "parser/faustlexer.l"
+return LT;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 100 "parser/faustlexer.l"
-return CUT;
+#line 105 "parser/faustlexer.l"
+return LE;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 102 "parser/faustlexer.l"
-return ENDDEF;
+#line 106 "parser/faustlexer.l"
+return GT;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 103 "parser/faustlexer.l"
-return DEF;
+#line 107 "parser/faustlexer.l"
+return GE;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 104 "parser/faustlexer.l"
-return LPAR;
+#line 108 "parser/faustlexer.l"
+return EQ;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 105 "parser/faustlexer.l"
-return RPAR;
+#line 109 "parser/faustlexer.l"
+return NE;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 106 "parser/faustlexer.l"
-return LBRAQ;
+#line 111 "parser/faustlexer.l"
+return WIRE;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 107 "parser/faustlexer.l"
-return RBRAQ;
+#line 112 "parser/faustlexer.l"
+return CUT;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 108 "parser/faustlexer.l"
-return LCROC;
+#line 114 "parser/faustlexer.l"
+return ENDDEF;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 109 "parser/faustlexer.l"
-return RCROC;
+#line 115 "parser/faustlexer.l"
+return DEF;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 111 "parser/faustlexer.l"
-return LAMBDA;
+#line 116 "parser/faustlexer.l"
+return LPAR;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 112 "parser/faustlexer.l"
-return DOT;
+#line 117 "parser/faustlexer.l"
+return RPAR;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 113 "parser/faustlexer.l"
-return WITH;
+#line 118 "parser/faustlexer.l"
+return LBRAQ;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 115 "parser/faustlexer.l"
-return MEM;
+#line 119 "parser/faustlexer.l"
+return RBRAQ;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 116 "parser/faustlexer.l"
-return PREFIX;
+#line 120 "parser/faustlexer.l"
+return LCROC;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 118 "parser/faustlexer.l"
-return INTCAST;
+#line 121 "parser/faustlexer.l"
+return RCROC;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 119 "parser/faustlexer.l"
-return FLOATCAST;
+#line 123 "parser/faustlexer.l"
+return LAMBDA;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 121 "parser/faustlexer.l"
-return RDTBL;
+#line 124 "parser/faustlexer.l"
+return DOT;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 122 "parser/faustlexer.l"
-return RWTBL;
+#line 125 "parser/faustlexer.l"
+return WITH;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 124 "parser/faustlexer.l"
-return SELECT2;
+#line 127 "parser/faustlexer.l"
+return MEM;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 125 "parser/faustlexer.l"
-return SELECT3;
+#line 128 "parser/faustlexer.l"
+return PREFIX;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 127 "parser/faustlexer.l"
-return FFUNCTION; 
+#line 130 "parser/faustlexer.l"
+return INTCAST;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 128 "parser/faustlexer.l"
-return FCONSTANT; 
+#line 131 "parser/faustlexer.l"
+return FLOATCAST;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 129 "parser/faustlexer.l"
-return FVARIABLE; 
+#line 133 "parser/faustlexer.l"
+return RDTBL;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 131 "parser/faustlexer.l"
-return BUTTON;
+#line 134 "parser/faustlexer.l"
+return RWTBL;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 132 "parser/faustlexer.l"
-return CHECKBOX;
+#line 136 "parser/faustlexer.l"
+return SELECT2;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 133 "parser/faustlexer.l"
-return VSLIDER;
+#line 137 "parser/faustlexer.l"
+return SELECT3;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 134 "parser/faustlexer.l"
-return HSLIDER;
+#line 139 "parser/faustlexer.l"
+return FFUNCTION; 
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 135 "parser/faustlexer.l"
-return NENTRY;
+#line 140 "parser/faustlexer.l"
+return FCONSTANT; 
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 136 "parser/faustlexer.l"
-return VGROUP;
+#line 141 "parser/faustlexer.l"
+return FVARIABLE; 
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 137 "parser/faustlexer.l"
-return HGROUP;
+#line 143 "parser/faustlexer.l"
+return BUTTON;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 138 "parser/faustlexer.l"
-return TGROUP;
+#line 144 "parser/faustlexer.l"
+return CHECKBOX;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 139 "parser/faustlexer.l"
-return VBARGRAPH;
+#line 145 "parser/faustlexer.l"
+return VSLIDER;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 140 "parser/faustlexer.l"
-return HBARGRAPH;
+#line 146 "parser/faustlexer.l"
+return HSLIDER;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 141 "parser/faustlexer.l"
-return ATTACH;
+#line 147 "parser/faustlexer.l"
+return NENTRY;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 143 "parser/faustlexer.l"
-return ACOS;
+#line 148 "parser/faustlexer.l"
+return VGROUP;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 144 "parser/faustlexer.l"
-return ASIN;
+#line 149 "parser/faustlexer.l"
+return HGROUP;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 145 "parser/faustlexer.l"
-return ATAN;
+#line 150 "parser/faustlexer.l"
+return TGROUP;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 146 "parser/faustlexer.l"
-return ATAN2;
+#line 151 "parser/faustlexer.l"
+return VBARGRAPH;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 148 "parser/faustlexer.l"
-return COS;
+#line 152 "parser/faustlexer.l"
+return HBARGRAPH;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 149 "parser/faustlexer.l"
-return SIN;
+#line 153 "parser/faustlexer.l"
+return ATTACH;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 150 "parser/faustlexer.l"
-return TAN;
+#line 155 "parser/faustlexer.l"
+return ACOS;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 152 "parser/faustlexer.l"
-return EXP;
+#line 156 "parser/faustlexer.l"
+return ASIN;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 153 "parser/faustlexer.l"
-return LOG;
+#line 157 "parser/faustlexer.l"
+return ATAN;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 154 "parser/faustlexer.l"
-return LOG10;
+#line 158 "parser/faustlexer.l"
+return ATAN2;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 155 "parser/faustlexer.l"
-return POWOP;
+#line 160 "parser/faustlexer.l"
+return COS;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 156 "parser/faustlexer.l"
-return POWFUN;
+#line 161 "parser/faustlexer.l"
+return SIN;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 157 "parser/faustlexer.l"
-return SQRT;
+#line 162 "parser/faustlexer.l"
+return TAN;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 159 "parser/faustlexer.l"
-return ABS;
+#line 164 "parser/faustlexer.l"
+return EXP;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 160 "parser/faustlexer.l"
-return MIN;
+#line 165 "parser/faustlexer.l"
+return LOG;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 161 "parser/faustlexer.l"
-return MAX;
+#line 166 "parser/faustlexer.l"
+return LOG10;
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 163 "parser/faustlexer.l"
-return FMOD;
+#line 167 "parser/faustlexer.l"
+return POWOP;
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 164 "parser/faustlexer.l"
-return REMAINDER;
+#line 168 "parser/faustlexer.l"
+return POWFUN;
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 166 "parser/faustlexer.l"
-return FLOOR;
+#line 169 "parser/faustlexer.l"
+return SQRT;
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 167 "parser/faustlexer.l"
-return CEIL;
+#line 171 "parser/faustlexer.l"
+return ABS;
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 168 "parser/faustlexer.l"
-return RINT;
+#line 172 "parser/faustlexer.l"
+return MIN;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 170 "parser/faustlexer.l"
-return ISEQ;
+#line 173 "parser/faustlexer.l"
+return MAX;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 171 "parser/faustlexer.l"
-return IPAR;
+#line 175 "parser/faustlexer.l"
+return FMOD;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 172 "parser/faustlexer.l"
-return ISUM;
+#line 176 "parser/faustlexer.l"
+return REMAINDER;
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 173 "parser/faustlexer.l"
-return IPROD;
+#line 178 "parser/faustlexer.l"
+return FLOOR;
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 175 "parser/faustlexer.l"
-return IMPORT;
+#line 179 "parser/faustlexer.l"
+return CEIL;
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 176 "parser/faustlexer.l"
-return COMPONENT;
+#line 180 "parser/faustlexer.l"
+return RINT;
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
-#line 177 "parser/faustlexer.l"
-return LIBRARY;
+#line 182 "parser/faustlexer.l"
+return ISEQ;
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
-#line 178 "parser/faustlexer.l"
-return ENVIRONMENT;
+#line 183 "parser/faustlexer.l"
+return IPAR;
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 180 "parser/faustlexer.l"
-return DECLARE;
+#line 184 "parser/faustlexer.l"
+return ISUM;
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 182 "parser/faustlexer.l"
-return CASE;
+#line 185 "parser/faustlexer.l"
+return IPROD;
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 183 "parser/faustlexer.l"
-return ARROW;
+#line 187 "parser/faustlexer.l"
+return INPUTS;
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 185 "parser/faustlexer.l"
-return IDENT;
+#line 188 "parser/faustlexer.l"
+return OUTPUTS;
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 186 "parser/faustlexer.l"
-return IDENT;
+#line 190 "parser/faustlexer.l"
+return IMPORT;
 	YY_BREAK
 case 128:
-/* rule 128 can match eol */
 YY_RULE_SETUP
-#line 188 "parser/faustlexer.l"
-return STRING;
+#line 191 "parser/faustlexer.l"
+return COMPONENT;
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 190 "parser/faustlexer.l"
-return FSTRING;
+#line 192 "parser/faustlexer.l"
+return LIBRARY;
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 191 "parser/faustlexer.l"
-return FSTRING;
+#line 193 "parser/faustlexer.l"
+return ENVIRONMENT;
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 194 "parser/faustlexer.l"
-/* eat up one-line comments */
+#line 195 "parser/faustlexer.l"
+return WAVEFORM;
 	YY_BREAK
 case 132:
-/* rule 132 can match eol */
 YY_RULE_SETUP
-#line 196 "parser/faustlexer.l"
+#line 197 "parser/faustlexer.l"
+return DECLARE;
+	YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 199 "parser/faustlexer.l"
+return CASE;
+	YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 200 "parser/faustlexer.l"
+return ARROW;
+	YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 202 "parser/faustlexer.l"
+return IDENT;
+	YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 203 "parser/faustlexer.l"
+return IDENT;
+	YY_BREAK
+case 137:
+/* rule 137 can match eol */
+YY_RULE_SETUP
+#line 205 "parser/faustlexer.l"
+return STRING;
+	YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 207 "parser/faustlexer.l"
+return FSTRING;
+	YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 208 "parser/faustlexer.l"
+return FSTRING;
+	YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 211 "parser/faustlexer.l"
+/* eat up one-line comments */
+	YY_BREAK
+case 141:
+/* rule 141 can match eol */
+YY_RULE_SETUP
+#line 213 "parser/faustlexer.l"
 /* eat up whitespace */
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(comment):
 case YY_STATE_EOF(doc):
 case YY_STATE_EOF(lst):
-#line 198 "parser/faustlexer.l"
+#line 215 "parser/faustlexer.l"
 yyterminate();
 	YY_BREAK
-case 133:
+case 142:
 YY_RULE_SETUP
-#line 200 "parser/faustlexer.l"
+#line 217 "parser/faustlexer.l"
 printf("extra text is : %s\n", yytext); return EXTRA;
 	YY_BREAK
-case 134:
+case 143:
 YY_RULE_SETUP
-#line 203 "parser/faustlexer.l"
+#line 220 "parser/faustlexer.l"
 ECHO;
 	YY_BREAK
-#line 1761 "parser/faustlexer.cpp"
+#line 1818 "parser/faustlexer.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1941,7 +1998,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1955,7 +2012,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1986,7 +2043,7 @@ static int yy_get_next_buffer (void)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
+			(yy_n_chars), num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
 		}
@@ -2047,7 +2104,7 @@ static int yy_get_next_buffer (void)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 458 )
+			if ( yy_current_state >= 482 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2075,56 +2132,15 @@ static int yy_get_next_buffer (void)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 458 )
+		if ( yy_current_state >= 482 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 457);
+	yy_is_jam = (yy_current_state == 481);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
-    static void yyunput (int c, register char * yy_bp )
-{
-	register char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
-
-	/* undo effects of setting up yytext */
-	*yy_cp = (yy_hold_char);
-
-	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-		{ /* need to shift things up to make room */
-		/* +2 for EOB chars. */
-		register int number_to_move = (yy_n_chars) + 2;
-		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-		register char *source =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
-		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			*--dest = *--source;
-
-		yy_cp += (int) (dest - source);
-		yy_bp += (int) (dest - source);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
-		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-			YY_FATAL_ERROR( "flex scanner push-back overflow" );
-		}
-
-	*--yy_cp = (char) c;
-
-    if ( c == '\n' ){
-        --yylineno;
-    }
-
-	(yytext_ptr) = yy_bp;
-	(yy_hold_char) = *yy_cp;
-	(yy_c_buf_p) = yy_cp;
-}
-
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
     static int yyinput (void)
@@ -2149,7 +2165,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -2173,7 +2189,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( yywrap( ) )
-						return EOF;
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -2430,7 +2446,7 @@ void yypop_buffer_state (void)
  */
 static void yyensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -2522,17 +2538,16 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
  * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n;
-	int i;
+	yy_size_t n, i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -2614,7 +2629,7 @@ FILE *yyget_out  (void)
 /** Get the length of the current token.
  * 
  */
-int yyget_leng  (void)
+yy_size_t yyget_leng  (void)
 {
         return yyleng;
 }
@@ -2765,7 +2780,7 @@ void yyfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 203 "parser/faustlexer.l"
+#line 220 "parser/faustlexer.l"
 
 
 int yywrap() { return 1; }
diff --git a/compiler/parser/faustlexer.l b/compiler/parser/faustlexer.l
index 23358b4..b979e3c 100644
--- a/compiler/parser/faustlexer.l
+++ b/compiler/parser/faustlexer.l
@@ -5,8 +5,15 @@
 %{
 #include "tree.hh"
 #include "faustparser.hpp"
-#define YY_NO_UNISTD_H 1
-extern int isatty (int );
+#if defined(WIN32) && !defined(__MINGW32__)
+// We don't want to include compatibility.hh here, since it pulls in whole lot
+// of unneeded stuff which breaks other things, so here's some stuff to make
+// MSVC happy.
+#include <io.h>
+#define isatty _isatty
+#define fileno _fileno
+#define YY_NO_UNISTD_H
+#endif
 %}
 
 DIGIT    [0-9]
@@ -17,6 +24,7 @@ WSPACE   [ \t\n]
 TMACRO   \\{ID}(\[(\ *({ID}|{NUMBER}),?\ *)\])?(\{(\ *({ID}|{NUMBER}),?\ *)*\})*
 
 %option yylineno
+%option nounput
 %x comment
 %x doc
 %x lst
@@ -59,13 +67,17 @@ TMACRO   \\{ID}(\[(\ *({ID}|{NUMBER}),?\ *)\])?(\{(\ *({ID}|{NUMBER}),?\ *)*\})*
 
 {DIGIT}+    		return INT;
 
-
-{DIGIT}+"."{DIGIT}* 				return FLOAT;
-{DIGIT}+"."{DIGIT}*e[-+]?{DIGIT}+ 	return FLOAT;
-{DIGIT}+e[-+]?{DIGIT}+ 				return FLOAT;
-"."{DIGIT}+ 						return FLOAT;
-"."{DIGIT}+e[-+]?{DIGIT}+ 			return FLOAT;
-
+{DIGIT}+"f"                             return FLOAT;
+{DIGIT}+"."{DIGIT}*                     return FLOAT;
+{DIGIT}+"."{DIGIT}*"f"                  return FLOAT;
+{DIGIT}+"."{DIGIT}*e[-+]?{DIGIT}+       return FLOAT;
+{DIGIT}+"."{DIGIT}*e[-+]?{DIGIT}+"f"    return FLOAT;
+{DIGIT}+e[-+]?{DIGIT}+                  return FLOAT;
+{DIGIT}+e[-+]?{DIGIT}+"f"               return FLOAT;
+"."{DIGIT}+                             return FLOAT;
+"."{DIGIT}+"f"                          return FLOAT;
+"."{DIGIT}+e[-+]?{DIGIT}+               return FLOAT;
+"."{DIGIT}+e[-+]?{DIGIT}+"f"            return FLOAT;
 
 ":"   		return SEQ;
 ","   		return PAR;
@@ -172,11 +184,16 @@ TMACRO   \\{ID}(\[(\ *({ID}|{NUMBER}),?\ *)\])?(\{(\ *({ID}|{NUMBER}),?\ *)*\})*
 "sum"		return ISUM;
 "prod"		return IPROD;
 
+"inputs"	return INPUTS;
+"outputs"	return OUTPUTS;
+
 "import"	return IMPORT;
 "component" return COMPONENT;
 "library"   return LIBRARY;
 "environment"   return ENVIRONMENT;
 
+"waveform"   return WAVEFORM;
+
 "declare"	return DECLARE;
 
 "case"		return CASE;
diff --git a/compiler/parser/faustparser.cpp b/compiler/parser/faustparser.cpp
index 4882618..301eb7d 100644
--- a/compiler/parser/faustparser.cpp
+++ b/compiler/parser/faustparser.cpp
@@ -1,23 +1,24 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
 /* Skeleton implementation for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+
+   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 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -28,7 +29,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -46,7 +47,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "2.3"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -54,115 +55,11 @@
 /* Pure parsers.  */
 #define YYPURE 0
 
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
 /* Using locations.  */
 #define YYLSP_NEEDED 0
 
 
 
-/* Copy the first part of user declarations.  */
-
-/* Line 189 of yacc.c  */
-#line 5 "parser/faustparser.y"
-
-
-#include "tree.hh"
-#include "xtended.hh"
-#include "boxes.hh"
-#include "prim2.hh"
-#include "signals.hh"
-#include "errormsg.hh"
-#include "sourcereader.hh"
-#include "doc.hh"
-#include "ppbox.hh"
-
-#include <string>
-#include <list>
-
-#define YYDEBUG 1
-#define YYERROR_VERBOSE 1
-#define YYMAXDEPTH	100000
-	
-using namespace std;
-
-extern char* 		yytext;
-extern const char* 	yyfilename;
-extern int 			yylineno;
-extern int 			yyerr;
-extern Tree 		gResult;
-extern bool         gStripDocSwitch;
-extern bool         gLstDependenciesSwitch;
-extern bool         gLstDistributedSwitch;
-extern bool        	gLstMdocTagsSwitch;
-	
-extern map<Tree, set<Tree> > gMetaDataSet;
-extern vector<Tree> gDocVector;
-
-
-int yylex();
-
-//----------------------------------------------------------
-// unquote() : remove enclosing quotes and carriage return 
-// characters from string. Returns a Tree 
-//----------------------------------------------------------
-char replaceCR(char c)
-{
-	return (c!='\n') ? c : ' ';
-}
-
-Tree unquote(char* str)
-{
-	//-----------copy unquoted filename-------------
-	char buf[512];
-	int j=0;
-
-	if (str[0] == '"') {
-		//it is a quoted string, we remove the quotes
-		for (int i=1; j<511 && str[i];) {
-			buf[j++] = replaceCR(str[i++]);
-		}
-		// remove last quote
-		if (j>0) buf[j-1] = 0;
-	} else {
-		for (int i=0; j<511 && str[i];) {
-			buf[j++] = replaceCR(str[i++]);
-		}
-	}
-	buf[j] = 0;
-
-	return tree(buf);
-	//----------------------------------------------
-}
-
-
-
-/* Line 189 of yacc.c  */
-#line 146 "parser/faustparser.cpp"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -256,70 +153,284 @@ Tree unquote(char* str)
      COMPONENT = 342,
      LIBRARY = 343,
      ENVIRONMENT = 344,
-     IPAR = 345,
-     ISEQ = 346,
-     ISUM = 347,
-     IPROD = 348,
-     STRING = 349,
-     FSTRING = 350,
-     IDENT = 351,
-     EXTRA = 352,
-     DECLARE = 353,
-     CASE = 354,
-     ARROW = 355,
-     BDOC = 356,
-     EDOC = 357,
-     BEQN = 358,
-     EEQN = 359,
-     BDGM = 360,
-     EDGM = 361,
-     BLST = 362,
-     ELST = 363,
-     BMETADATA = 364,
-     EMETADATA = 365,
-     DOCCHAR = 366,
-     NOTICE = 367,
-     LISTING = 368,
-     LSTTRUE = 369,
-     LSTFALSE = 370,
-     LSTDEPENDENCIES = 371,
-     LSTMDOCTAGS = 372,
-     LSTDISTRIBUTED = 373,
-     LSTEQ = 374,
-     LSTQ = 375
+     WAVEFORM = 345,
+     IPAR = 346,
+     ISEQ = 347,
+     ISUM = 348,
+     IPROD = 349,
+     INPUTS = 350,
+     OUTPUTS = 351,
+     STRING = 352,
+     FSTRING = 353,
+     IDENT = 354,
+     EXTRA = 355,
+     DECLARE = 356,
+     CASE = 357,
+     ARROW = 358,
+     BDOC = 359,
+     EDOC = 360,
+     BEQN = 361,
+     EEQN = 362,
+     BDGM = 363,
+     EDGM = 364,
+     BLST = 365,
+     ELST = 366,
+     BMETADATA = 367,
+     EMETADATA = 368,
+     DOCCHAR = 369,
+     NOTICE = 370,
+     LISTING = 371,
+     LSTTRUE = 372,
+     LSTFALSE = 373,
+     LSTDEPENDENCIES = 374,
+     LSTMDOCTAGS = 375,
+     LSTDISTRIBUTED = 376,
+     LSTEQ = 377,
+     LSTQ = 378
    };
 #endif
+/* Tokens.  */
+#define WITH 258
+#define MIX 259
+#define SPLIT 260
+#define SEQ 261
+#define PAR 262
+#define REC 263
+#define NE 264
+#define GE 265
+#define GT 266
+#define EQ 267
+#define LE 268
+#define LT 269
+#define OR 270
+#define SUB 271
+#define ADD 272
+#define RSH 273
+#define LSH 274
+#define XOR 275
+#define AND 276
+#define MOD 277
+#define DIV 278
+#define MUL 279
+#define POWOP 280
+#define FDELAY 281
+#define DELAY1 282
+#define DOT 283
+#define APPL 284
+#define MEM 285
+#define PREFIX 286
+#define INTCAST 287
+#define FLOATCAST 288
+#define FFUNCTION 289
+#define FCONSTANT 290
+#define FVARIABLE 291
+#define BUTTON 292
+#define CHECKBOX 293
+#define VSLIDER 294
+#define HSLIDER 295
+#define NENTRY 296
+#define VGROUP 297
+#define HGROUP 298
+#define TGROUP 299
+#define HBARGRAPH 300
+#define VBARGRAPH 301
+#define ATTACH 302
+#define ACOS 303
+#define ASIN 304
+#define ATAN 305
+#define ATAN2 306
+#define COS 307
+#define SIN 308
+#define TAN 309
+#define EXP 310
+#define LOG 311
+#define LOG10 312
+#define POWFUN 313
+#define SQRT 314
+#define ABS 315
+#define MIN 316
+#define MAX 317
+#define FMOD 318
+#define REMAINDER 319
+#define FLOOR 320
+#define CEIL 321
+#define RINT 322
+#define RDTBL 323
+#define RWTBL 324
+#define SELECT2 325
+#define SELECT3 326
+#define INT 327
+#define FLOAT 328
+#define LAMBDA 329
+#define WIRE 330
+#define CUT 331
+#define ENDDEF 332
+#define VIRG 333
+#define LPAR 334
+#define RPAR 335
+#define LBRAQ 336
+#define RBRAQ 337
+#define LCROC 338
+#define RCROC 339
+#define DEF 340
+#define IMPORT 341
+#define COMPONENT 342
+#define LIBRARY 343
+#define ENVIRONMENT 344
+#define WAVEFORM 345
+#define IPAR 346
+#define ISEQ 347
+#define ISUM 348
+#define IPROD 349
+#define INPUTS 350
+#define OUTPUTS 351
+#define STRING 352
+#define FSTRING 353
+#define IDENT 354
+#define EXTRA 355
+#define DECLARE 356
+#define CASE 357
+#define ARROW 358
+#define BDOC 359
+#define EDOC 360
+#define BEQN 361
+#define EEQN 362
+#define BDGM 363
+#define EDGM 364
+#define BLST 365
+#define ELST 366
+#define BMETADATA 367
+#define EMETADATA 368
+#define DOCCHAR 369
+#define NOTICE 370
+#define LISTING 371
+#define LSTTRUE 372
+#define LSTFALSE 373
+#define LSTDEPENDENCIES 374
+#define LSTMDOCTAGS 375
+#define LSTDISTRIBUTED 376
+#define LSTEQ 377
+#define LSTQ 378
 
 
 
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+
+/* Copy the first part of user declarations.  */
+#line 5 "parser/faustparser.y"
+
+
+#include "tree.hh"
+#include "xtended.hh"
+#include "boxes.hh"
+#include "prim2.hh"
+#include "signals.hh"
+#include "errormsg.hh"
+#include "sourcereader.hh"
+#include "doc.hh"
+#include "ppbox.hh"
+
+#include <string>
+#include <list>
+
+#define YYDEBUG 1
+#define YYERROR_VERBOSE 1
+#define YYMAXDEPTH	100000
+	
+using namespace std;
+
+extern char* 		yytext;
+extern const char* 	yyfilename;
+extern int 			yylineno;
+extern int 			yyerr;
+extern Tree 		gResult;
+extern bool         gStripDocSwitch;
+extern bool         gLstDependenciesSwitch;
+extern bool         gLstDistributedSwitch;
+extern bool        	gLstMdocTagsSwitch;
+	
+extern map<Tree, set<Tree> > gMetaDataSet;
+extern vector<Tree>          gDocVector;
+extern tvec                  gWaveForm; 
+
+int yylex();
+
+//----------------------------------------------------------
+// unquote() : remove enclosing quotes and carriage return 
+// characters from string. Returns a Tree 
+//----------------------------------------------------------
+char replaceCR(char c)
 {
+	return (c!='\n') ? c : ' ';
+}
 
-/* Line 214 of yacc.c  */
-#line 78 "parser/faustparser.y"
+Tree unquote(char* str)
+{
+	//-----------copy unquoted filename-------------
+	char buf[512];
+	int j=0;
+
+	if (str[0] == '"') {
+		//it is a quoted string, we remove the quotes
+		for (int i=1; j<511 && str[i];) {
+			buf[j++] = replaceCR(str[i++]);
+		}
+		// remove last quote
+		if (j>0) buf[j-1] = 0;
+	} else {
+		for (int i=0; j<511 && str[i];) {
+			buf[j++] = replaceCR(str[i++]);
+		}
+	}
+	buf[j] = 0;
+
+	return tree(buf);
+	//----------------------------------------------
+}
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
 
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 78 "parser/faustparser.y"
+{
 	CTree* 	exp;
 	char* str;
 	string* cppstr;
 	bool b;
-
-
-
-/* Line 214 of yacc.c  */
-#line 311 "parser/faustparser.cpp"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c.  */
+#line 421 "parser/faustparser.cpp"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
+
 /* Copy the second part of user declarations.  */
 
 
-/* Line 264 of yacc.c  */
-#line 323 "parser/faustparser.cpp"
+/* Line 216 of yacc.c.  */
+#line 434 "parser/faustparser.cpp"
 
 #ifdef short
 # undef short
@@ -369,7 +480,7 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -394,14 +505,14 @@ typedef short int yytype_int16;
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int yyi)
+YYID (int i)
 #else
 static int
-YYID (yyi)
-    int yyi;
+YYID (i)
+    int i;
 #endif
 {
-  return yyi;
+  return i;
 }
 #endif
 
@@ -482,9 +593,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-};
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -518,12 +629,12 @@ union yyalloc
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
+# define YYSTACK_RELOCATE(Stack)					\
     do									\
       {									\
 	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 	yyptr += yynewbytes / sizeof (*yyptr);				\
       }									\
@@ -534,20 +645,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   603
+#define YYLAST   661
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  121
+#define YYNTOKENS  124
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  52
+#define YYNNTS  56
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  188
+#define YYNRULES  205
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  406
+#define YYNSTATES  443
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   375
+#define YYMAXUTOK   378
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -592,7 +703,7 @@ static const yytype_uint8 yytranslate[] =
       85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
       95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
      105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
-     115,   116,   117,   118,   119,   120
+     115,   116,   117,   118,   119,   120,   121,   122,   123
 };
 
 #if YYDEBUG
@@ -600,119 +711,130 @@ static const yytype_uint8 yytranslate[] =
    YYRHS.  */
 static const yytype_uint16 yyprhs[] =
 {
-       0,     0,     3,     5,     6,     9,    10,    13,    19,    24,
-      26,    30,    31,    34,    36,    38,    40,    42,    44,    46,
-      47,    50,    54,    58,    60,    64,    65,    68,    74,    80,
-      86,    88,    90,    94,   102,   107,   110,   112,   114,   118,
-     124,   128,   132,   136,   140,   144,   146,   150,   154,   158,
-     162,   166,   170,   174,   177,   181,   185,   189,   193,   197,
-     201,   205,   209,   213,   217,   221,   225,   230,   235,   237,
-     239,   241,   244,   247,   250,   253,   255,   257,   259,   261,
-     263,   265,   267,   269,   271,   273,   275,   277,   279,   281,
-     283,   285,   287,   289,   291,   293,   295,   297,   299,   301,
-     303,   305,   307,   309,   311,   313,   315,   317,   319,   321,
-     323,   325,   327,   329,   331,   333,   335,   337,   339,   341,
-     343,   345,   347,   349,   351,   353,   356,   360,   369,   374,
-     376,   378,   380,   385,   390,   395,   397,   399,   401,   403,
-     405,   407,   409,   411,   413,   415,   417,   419,   421,   423,
-     425,   427,   429,   433,   437,   441,   445,   449,   451,   453,
-     455,   457,   459,   468,   477,   486,   495,   504,   512,   520,
-     525,   530,   543,   556,   569,   576,   583,   590,   599,   608,
-     614,   619,   621,   623,   627,   629,   632,   639,   641
+       0,     0,     3,     5,     6,     9,    10,    13,    15,    19,
+      21,    23,    26,    29,    32,    35,    41,    46,    48,    52,
+      53,    56,    58,    60,    62,    64,    66,    68,    69,    72,
+      76,    80,    82,    86,    87,    90,    96,   102,   108,   110,
+     112,   116,   124,   129,   132,   134,   136,   140,   146,   150,
+     154,   158,   162,   166,   168,   172,   176,   180,   184,   188,
+     192,   196,   199,   203,   207,   211,   215,   219,   223,   227,
+     231,   235,   239,   243,   247,   252,   257,   259,   261,   263,
+     266,   269,   272,   275,   277,   279,   281,   283,   285,   287,
+     289,   291,   293,   295,   297,   299,   301,   303,   305,   307,
+     309,   311,   313,   315,   317,   319,   321,   323,   325,   327,
+     329,   331,   333,   335,   337,   339,   341,   343,   345,   347,
+     349,   351,   353,   355,   357,   359,   361,   363,   365,   367,
+     369,   371,   373,   375,   378,   382,   391,   396,   398,   400,
+     402,   407,   412,   417,   422,   424,   426,   428,   430,   432,
+     434,   436,   438,   440,   442,   444,   446,   448,   450,   452,
+     454,   456,   458,   460,   464,   468,   472,   476,   480,   482,
+     484,   486,   488,   490,   499,   508,   517,   526,   531,   536,
+     545,   553,   561,   566,   571,   584,   597,   610,   617,   624,
+     631,   640,   649,   655,   663,   673,   678,   685,   694,   696,
+     698,   702,   704,   707,   714,   716
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int16 yyrhs[] =
 {
-     122,     0,    -1,   123,    -1,    -1,   123,   125,    -1,    -1,
-     124,   137,    -1,    86,    79,   148,    80,    77,    -1,    98,
-     144,   147,    77,    -1,   137,    -1,   101,   126,   102,    -1,
-      -1,   126,   127,    -1,   128,    -1,   129,    -1,   130,    -1,
-     131,    -1,   132,    -1,   136,    -1,    -1,   128,   111,    -1,
-     103,   140,   104,    -1,   105,   140,   106,    -1,   112,    -1,
-     107,   133,   108,    -1,    -1,   133,   134,    -1,   116,   119,
-     120,   135,   120,    -1,   117,   119,   120,   135,   120,    -1,
-     118,   119,   120,   135,   120,    -1,   114,    -1,   115,    -1,
-     109,   144,   110,    -1,   138,    79,   145,    80,    85,   140,
-      77,    -1,   138,    85,   140,    77,    -1,     1,    77,    -1,
-     143,    -1,   143,    -1,   139,     7,   143,    -1,   140,     3,
-      81,   124,    82,    -1,   140,     7,   140,    -1,   140,     6,
-     140,    -1,   140,     5,   140,    -1,   140,     4,   140,    -1,
-     140,     8,   140,    -1,   141,    -1,   141,    17,   141,    -1,
-     141,    16,   141,    -1,   141,    24,   141,    -1,   141,    23,
-     141,    -1,   141,    22,   141,    -1,   141,    25,   141,    -1,
-     141,    26,   141,    -1,   141,    27,    -1,   141,    28,   143,
-      -1,   141,    21,   141,    -1,   141,    15,   141,    -1,   141,
-      20,   141,    -1,   141,    19,   141,    -1,   141,    18,   141,
-      -1,   141,    14,   141,    -1,   141,    13,   141,    -1,   141,
-      11,   141,    -1,   141,    10,   141,    -1,   141,    12,   141,
-      -1,   141,     9,   141,    -1,   141,    79,   145,    80,    -1,
-     141,    83,   124,    84,    -1,   142,    -1,    72,    -1,    73,
-      -1,    17,    72,    -1,    17,    73,    -1,    16,    72,    -1,
-      16,    73,    -1,    75,    -1,    76,    -1,    30,    -1,    31,
-      -1,    32,    -1,    33,    -1,    17,    -1,    16,    -1,    24,
-      -1,    23,    -1,    22,    -1,    26,    -1,    21,    -1,    15,
-      -1,    20,    -1,    19,    -1,    18,    -1,    14,    -1,    13,
-      -1,    11,    -1,    10,    -1,    12,    -1,     9,    -1,    47,
-      -1,    48,    -1,    49,    -1,    50,    -1,    51,    -1,    52,
-      -1,    53,    -1,    54,    -1,    55,    -1,    56,    -1,    57,
-      -1,    25,    -1,    58,    -1,    59,    -1,    60,    -1,    61,
-      -1,    62,    -1,    63,    -1,    64,    -1,    65,    -1,    66,
-      -1,    67,    -1,    68,    -1,    69,    -1,    70,    -1,    71,
-      -1,   143,    -1,    16,   143,    -1,    79,   140,    80,    -1,
-      74,    79,   139,    80,    28,    79,   140,    80,    -1,    99,
-      81,   170,    82,    -1,   154,    -1,   155,    -1,   156,    -1,
-      87,    79,   148,    80,    -1,    88,    79,   148,    80,    -1,
-      89,    81,   124,    82,    -1,   157,    -1,   158,    -1,   159,
-      -1,   160,    -1,   161,    -1,   162,    -1,   163,    -1,   164,
-      -1,   165,    -1,   166,    -1,   150,    -1,   151,    -1,   152,
-      -1,   153,    -1,    96,    -1,    96,    -1,   146,    -1,   145,
-       7,   146,    -1,   146,     6,   146,    -1,   146,     5,   146,
-      -1,   146,     4,   146,    -1,   146,     8,   146,    -1,   141,
-      -1,    94,    -1,    94,    -1,    94,    -1,    95,    -1,    90,
-      79,   143,     7,   146,     7,   140,    80,    -1,    91,    79,
-     143,     7,   146,     7,   140,    80,    -1,    92,    79,   143,
-       7,   146,     7,   140,    80,    -1,    93,    79,   143,     7,
-     146,     7,   140,    80,    -1,    34,    79,   167,     7,   149,
-       7,   147,    80,    -1,    35,    79,   172,   144,     7,   149,
-      80,    -1,    36,    79,   172,   144,     7,   149,    80,    -1,
-      37,    79,   148,    80,    -1,    38,    79,   148,    80,    -1,
-      39,    79,   148,     7,   146,     7,   146,     7,   146,     7,
-     146,    80,    -1,    40,    79,   148,     7,   146,     7,   146,
-       7,   146,     7,   146,    80,    -1,    41,    79,   148,     7,
-     146,     7,   146,     7,   146,     7,   146,    80,    -1,    42,
-      79,   148,     7,   140,    80,    -1,    43,    79,   148,     7,
-     140,    80,    -1,    44,    79,   148,     7,   140,    80,    -1,
-      46,    79,   148,     7,   146,     7,   146,    80,    -1,    45,
-      79,   148,     7,   146,     7,   146,    80,    -1,   172,   168,
-      79,   169,    80,    -1,   172,   168,    79,    80,    -1,    96,
-      -1,   172,    -1,   169,     7,   172,    -1,   171,    -1,   170,
-     171,    -1,    79,   145,    80,   100,   140,    77,    -1,    32,
-      -1,    33,    -1
+     125,     0,    -1,   126,    -1,    -1,   126,   130,    -1,    -1,
+     127,   142,    -1,   129,    -1,   128,     7,   129,    -1,    72,
+      -1,    73,    -1,    17,    72,    -1,    17,    73,    -1,    16,
+      72,    -1,    16,    73,    -1,    86,    79,   153,    80,    77,
+      -1,   101,   149,   152,    77,    -1,   142,    -1,   104,   131,
+     105,    -1,    -1,   131,   132,    -1,   133,    -1,   134,    -1,
+     135,    -1,   136,    -1,   137,    -1,   141,    -1,    -1,   133,
+     114,    -1,   106,   145,   107,    -1,   108,   145,   109,    -1,
+     115,    -1,   110,   138,   111,    -1,    -1,   138,   139,    -1,
+     119,   122,   123,   140,   123,    -1,   120,   122,   123,   140,
+     123,    -1,   121,   122,   123,   140,   123,    -1,   117,    -1,
+     118,    -1,   112,   149,   113,    -1,   143,    79,   150,    80,
+      85,   145,    77,    -1,   143,    85,   145,    77,    -1,     1,
+      77,    -1,   148,    -1,   148,    -1,   144,     7,   148,    -1,
+     145,     3,    81,   127,    82,    -1,   145,     7,   145,    -1,
+     145,     6,   145,    -1,   145,     5,   145,    -1,   145,     4,
+     145,    -1,   145,     8,   145,    -1,   146,    -1,   146,    17,
+     146,    -1,   146,    16,   146,    -1,   146,    24,   146,    -1,
+     146,    23,   146,    -1,   146,    22,   146,    -1,   146,    25,
+     146,    -1,   146,    26,   146,    -1,   146,    27,    -1,   146,
+      28,   148,    -1,   146,    21,   146,    -1,   146,    15,   146,
+      -1,   146,    20,   146,    -1,   146,    19,   146,    -1,   146,
+      18,   146,    -1,   146,    14,   146,    -1,   146,    13,   146,
+      -1,   146,    11,   146,    -1,   146,    10,   146,    -1,   146,
+      12,   146,    -1,   146,     9,   146,    -1,   146,    79,   150,
+      80,    -1,   146,    83,   127,    84,    -1,   147,    -1,    72,
+      -1,    73,    -1,    17,    72,    -1,    17,    73,    -1,    16,
+      72,    -1,    16,    73,    -1,    75,    -1,    76,    -1,    30,
+      -1,    31,    -1,    32,    -1,    33,    -1,    17,    -1,    16,
+      -1,    24,    -1,    23,    -1,    22,    -1,    26,    -1,    21,
+      -1,    15,    -1,    20,    -1,    19,    -1,    18,    -1,    14,
+      -1,    13,    -1,    11,    -1,    10,    -1,    12,    -1,     9,
+      -1,    47,    -1,    48,    -1,    49,    -1,    50,    -1,    51,
+      -1,    52,    -1,    53,    -1,    54,    -1,    55,    -1,    56,
+      -1,    57,    -1,    25,    -1,    58,    -1,    59,    -1,    60,
+      -1,    61,    -1,    62,    -1,    63,    -1,    64,    -1,    65,
+      -1,    66,    -1,    67,    -1,    68,    -1,    69,    -1,    70,
+      -1,    71,    -1,   148,    -1,    16,   148,    -1,    79,   145,
+      80,    -1,    74,    79,   144,    80,    28,    79,   145,    80,
+      -1,   102,    81,   177,    82,    -1,   161,    -1,   162,    -1,
+     163,    -1,    87,    79,   153,    80,    -1,    88,    79,   153,
+      80,    -1,    89,    81,   126,    82,    -1,    90,    81,   128,
+      82,    -1,   164,    -1,   165,    -1,   166,    -1,   167,    -1,
+     168,    -1,   169,    -1,   170,    -1,   171,    -1,   172,    -1,
+     173,    -1,   155,    -1,   156,    -1,   157,    -1,   158,    -1,
+     159,    -1,   160,    -1,    99,    -1,    99,    -1,   151,    -1,
+     150,     7,   151,    -1,   151,     6,   151,    -1,   151,     5,
+     151,    -1,   151,     4,   151,    -1,   151,     8,   151,    -1,
+     146,    -1,    97,    -1,    97,    -1,    97,    -1,    98,    -1,
+      91,    79,   148,     7,   151,     7,   145,    80,    -1,    92,
+      79,   148,     7,   151,     7,   145,    80,    -1,    93,    79,
+     148,     7,   151,     7,   145,    80,    -1,    94,    79,   148,
+       7,   151,     7,   145,    80,    -1,    95,    79,   145,    80,
+      -1,    96,    79,   145,    80,    -1,    34,    79,   174,     7,
+     154,     7,   152,    80,    -1,    35,    79,   179,   149,     7,
+     154,    80,    -1,    36,    79,   179,   149,     7,   154,    80,
+      -1,    37,    79,   153,    80,    -1,    38,    79,   153,    80,
+      -1,    39,    79,   153,     7,   151,     7,   151,     7,   151,
+       7,   151,    80,    -1,    40,    79,   153,     7,   151,     7,
+     151,     7,   151,     7,   151,    80,    -1,    41,    79,   153,
+       7,   151,     7,   151,     7,   151,     7,   151,    80,    -1,
+      42,    79,   153,     7,   145,    80,    -1,    43,    79,   153,
+       7,   145,    80,    -1,    44,    79,   153,     7,   145,    80,
+      -1,    46,    79,   153,     7,   151,     7,   151,    80,    -1,
+      45,    79,   153,     7,   151,     7,   151,    80,    -1,   179,
+     175,    79,   176,    80,    -1,   179,   175,    15,   175,    79,
+     176,    80,    -1,   179,   175,    15,   175,    15,   175,    79,
+     176,    80,    -1,   179,   175,    79,    80,    -1,   179,   175,
+      15,   175,    79,    80,    -1,   179,   175,    15,   175,    15,
+     175,    79,    80,    -1,    99,    -1,   179,    -1,   176,     7,
+     179,    -1,   178,    -1,   177,   178,    -1,    79,   150,    80,
+     103,   145,    77,    -1,    32,    -1,    33,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   301,   301,   304,   305,   307,   308,   311,   312,   313,
-     314,   317,   318,   321,   322,   323,   324,   325,   326,   329,
-     330,   333,   336,   339,   342,   345,   346,   349,   350,   351,
-     354,   355,   358,   361,   362,   363,   366,   369,   370,   373,
-     374,   375,   376,   377,   378,   379,   382,   383,   384,   385,
-     386,   387,   388,   389,   390,   392,   393,   394,   396,   397,
-     399,   400,   401,   402,   403,   404,   406,   407,   409,   412,
-     413,   415,   416,   418,   419,   421,   422,   424,   425,   427,
-     428,   430,   431,   432,   433,   434,   435,   437,   438,   439,
-     441,   442,   444,   445,   446,   447,   448,   449,   451,   453,
-     454,   455,   456,   457,   458,   459,   461,   462,   463,   464,
-     465,   466,   468,   469,   470,   472,   473,   475,   476,   477,
-     480,   481,   483,   484,   486,   487,   489,   490,   493,   495,
-     496,   497,   498,   499,   500,   502,   503,   504,   505,   506,
-     507,   508,   509,   510,   511,   513,   514,   515,   516,   520,
-     523,   528,   529,   532,   533,   534,   535,   536,   539,   542,
-     545,   546,   551,   555,   559,   563,   570,   574,   577,   582,
-     585,   588,   591,   594,   597,   600,   603,   607,   610,   616,
-     617,   620,   623,   624,   627,   628,   631,   635,   636
+       0,   310,   310,   313,   314,   316,   317,   324,   325,   328,
+     329,   330,   331,   332,   333,   337,   338,   339,   340,   343,
+     344,   347,   348,   349,   350,   351,   352,   355,   356,   359,
+     362,   365,   368,   371,   372,   375,   376,   377,   380,   381,
+     384,   387,   388,   389,   392,   395,   396,   399,   400,   401,
+     402,   403,   404,   405,   408,   409,   410,   411,   412,   413,
+     414,   415,   416,   418,   419,   420,   422,   423,   425,   426,
+     427,   428,   429,   430,   432,   433,   435,   438,   439,   441,
+     442,   444,   445,   447,   448,   450,   451,   453,   454,   456,
+     457,   458,   459,   460,   461,   463,   464,   465,   467,   468,
+     470,   471,   472,   473,   474,   475,   477,   479,   480,   481,
+     482,   483,   484,   485,   487,   488,   489,   490,   491,   492,
+     494,   495,   496,   498,   499,   501,   502,   503,   506,   507,
+     509,   510,   512,   513,   515,   516,   519,   521,   522,   523,
+     524,   525,   526,   527,   529,   530,   531,   532,   533,   534,
+     535,   536,   537,   538,   540,   541,   542,   543,   545,   546,
+     551,   554,   559,   560,   563,   564,   565,   566,   567,   570,
+     573,   576,   577,   582,   586,   590,   594,   599,   602,   609,
+     613,   616,   621,   624,   627,   630,   633,   636,   639,   642,
+     646,   649,   656,   657,   658,   660,   661,   662,   665,   668,
+     669,   672,   673,   676,   680,   681
 };
 #endif
 
@@ -732,20 +854,21 @@ static const char *const yytname[] =
   "REMAINDER", "FLOOR", "CEIL", "RINT", "RDTBL", "RWTBL", "SELECT2",
   "SELECT3", "INT", "FLOAT", "LAMBDA", "WIRE", "CUT", "ENDDEF", "VIRG",
   "LPAR", "RPAR", "LBRAQ", "RBRAQ", "LCROC", "RCROC", "DEF", "IMPORT",
-  "COMPONENT", "LIBRARY", "ENVIRONMENT", "IPAR", "ISEQ", "ISUM", "IPROD",
-  "STRING", "FSTRING", "IDENT", "EXTRA", "DECLARE", "CASE", "ARROW",
-  "BDOC", "EDOC", "BEQN", "EEQN", "BDGM", "EDGM", "BLST", "ELST",
-  "BMETADATA", "EMETADATA", "DOCCHAR", "NOTICE", "LISTING", "LSTTRUE",
-  "LSTFALSE", "LSTDEPENDENCIES", "LSTMDOCTAGS", "LSTDISTRIBUTED", "LSTEQ",
-  "LSTQ", "$accept", "program", "stmtlist", "deflist", "statement", "doc",
+  "COMPONENT", "LIBRARY", "ENVIRONMENT", "WAVEFORM", "IPAR", "ISEQ",
+  "ISUM", "IPROD", "INPUTS", "OUTPUTS", "STRING", "FSTRING", "IDENT",
+  "EXTRA", "DECLARE", "CASE", "ARROW", "BDOC", "EDOC", "BEQN", "EEQN",
+  "BDGM", "EDGM", "BLST", "ELST", "BMETADATA", "EMETADATA", "DOCCHAR",
+  "NOTICE", "LISTING", "LSTTRUE", "LSTFALSE", "LSTDEPENDENCIES",
+  "LSTMDOCTAGS", "LSTDISTRIBUTED", "LSTEQ", "LSTQ", "$accept", "program",
+  "stmtlist", "deflist", "vallist", "number", "statement", "doc",
   "docelem", "doctxt", "doceqn", "docdgm", "docntc", "doclst",
   "lstattrlist", "lstattrdef", "lstattrval", "docmtd", "definition",
   "defname", "params", "expression", "infixexp", "primitive", "ident",
   "name", "arglist", "argument", "string", "uqstring", "fstring", "fpar",
-  "fseq", "fsum", "fprod", "ffunction", "fconst", "fvariable", "button",
-  "checkbox", "vslider", "hslider", "nentry", "vgroup", "hgroup", "tgroup",
-  "vbargraph", "hbargraph", "signature", "fun", "typelist", "rulelist",
-  "rule", "type", 0
+  "fseq", "fsum", "fprod", "finputs", "foutputs", "ffunction", "fconst",
+  "fvariable", "button", "checkbox", "vslider", "hslider", "nentry",
+  "vgroup", "hgroup", "tgroup", "vbargraph", "hbargraph", "signature",
+  "fun", "typelist", "rulelist", "rule", "type", 0
 };
 #endif
 
@@ -766,56 +889,60 @@ static const yytype_uint16 yytoknum[] =
      345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
      355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
      365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
-     375
+     375,   376,   377,   378
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,   121,   122,   123,   123,   124,   124,   125,   125,   125,
-     125,   126,   126,   127,   127,   127,   127,   127,   127,   128,
-     128,   129,   130,   131,   132,   133,   133,   134,   134,   134,
-     135,   135,   136,   137,   137,   137,   138,   139,   139,   140,
-     140,   140,   140,   140,   140,   140,   141,   141,   141,   141,
-     141,   141,   141,   141,   141,   141,   141,   141,   141,   141,
-     141,   141,   141,   141,   141,   141,   141,   141,   141,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,   142,   142,   142,   143,
-     144,   145,   145,   146,   146,   146,   146,   146,   147,   148,
-     149,   149,   150,   151,   152,   153,   154,   155,   156,   157,
-     158,   159,   160,   161,   162,   163,   164,   165,   166,   167,
-     167,   168,   169,   169,   170,   170,   171,   172,   172
+       0,   124,   125,   126,   126,   127,   127,   128,   128,   129,
+     129,   129,   129,   129,   129,   130,   130,   130,   130,   131,
+     131,   132,   132,   132,   132,   132,   132,   133,   133,   134,
+     135,   136,   137,   138,   138,   139,   139,   139,   140,   140,
+     141,   142,   142,   142,   143,   144,   144,   145,   145,   145,
+     145,   145,   145,   145,   146,   146,   146,   146,   146,   146,
+     146,   146,   146,   146,   146,   146,   146,   146,   146,   146,
+     146,   146,   146,   146,   146,   146,   146,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     148,   149,   150,   150,   151,   151,   151,   151,   151,   152,
+     153,   154,   154,   155,   156,   157,   158,   159,   160,   161,
+     162,   163,   164,   165,   166,   167,   168,   169,   170,   171,
+     172,   173,   174,   174,   174,   174,   174,   174,   175,   176,
+     176,   177,   177,   178,   179,   179
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     1,     0,     2,     0,     2,     5,     4,     1,
-       3,     0,     2,     1,     1,     1,     1,     1,     1,     0,
-       2,     3,     3,     1,     3,     0,     2,     5,     5,     5,
-       1,     1,     3,     7,     4,     2,     1,     1,     3,     5,
-       3,     3,     3,     3,     3,     1,     3,     3,     3,     3,
-       3,     3,     3,     2,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     4,     4,     1,     1,
-       1,     2,     2,     2,     2,     1,     1,     1,     1,     1,
+       0,     2,     1,     0,     2,     0,     2,     1,     3,     1,
+       1,     2,     2,     2,     2,     5,     4,     1,     3,     0,
+       2,     1,     1,     1,     1,     1,     1,     0,     2,     3,
+       3,     1,     3,     0,     2,     5,     5,     5,     1,     1,
+       3,     7,     4,     2,     1,     1,     3,     5,     3,     3,
+       3,     3,     3,     1,     3,     3,     3,     3,     3,     3,
+       3,     2,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     4,     4,     1,     1,     1,     2,
+       2,     2,     2,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     2,     3,     8,     4,     1,
-       1,     1,     4,     4,     4,     1,     1,     1,     1,     1,
+       1,     1,     1,     2,     3,     8,     4,     1,     1,     1,
+       4,     4,     4,     4,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     3,     3,     3,     3,     3,     1,     1,     1,
-       1,     1,     8,     8,     8,     8,     8,     7,     7,     4,
-       4,    12,    12,    12,     6,     6,     6,     8,     8,     5,
-       4,     1,     1,     3,     1,     2,     6,     1,     1
+       1,     1,     1,     3,     3,     3,     3,     3,     1,     1,
+       1,     1,     1,     8,     8,     8,     8,     4,     4,     8,
+       7,     7,     4,     4,    12,    12,    12,     6,     6,     6,
+       8,     8,     5,     7,     9,     4,     6,     8,     1,     1,
+       3,     1,     2,     6,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -823,117 +950,125 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       3,     0,     0,     1,     0,     0,   149,     0,    11,     4,
-       9,     0,    36,    35,     0,   150,     0,    19,     0,     0,
-     159,     0,   158,     0,    10,     0,     0,    25,     0,    23,
-      12,    13,    14,    15,    16,    17,    18,    97,    95,    94,
-      96,    93,    92,    88,    82,    81,    91,    90,    89,    87,
-      85,    84,    83,   109,    86,    77,    78,    79,    80,     0,
+       3,     0,     0,     1,     0,     0,   160,     0,    19,     4,
+      17,     0,    44,    43,     0,   161,     0,    27,     0,     0,
+     170,     0,   169,     0,    18,     0,     0,    33,     0,    31,
+      20,    21,    22,    23,    24,    25,    26,   105,   103,   102,
+     104,   101,   100,    96,    90,    89,    99,    98,    97,    95,
+      93,    92,    91,   117,    94,    85,    86,    87,    88,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    98,    99,   100,   101,   102,   103,   104,   105,
-     106,   107,   108,   110,   111,   112,   113,   114,   115,   116,
-     117,   118,   119,   120,   121,   122,   123,    69,    70,     0,
-      75,    76,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   157,    68,   124,     0,   151,   145,   146,   147,   148,
-     129,   130,   131,   135,   136,   137,   138,   139,   140,   141,
-     142,   143,   144,     0,    45,     0,     8,     0,     0,     0,
-       0,    20,    73,    74,   125,    71,    72,     0,     0,     0,
+       0,     0,   106,   107,   108,   109,   110,   111,   112,   113,
+     114,   115,   116,   118,   119,   120,   121,   122,   123,   124,
+     125,   126,   127,   128,   129,   130,   131,    77,    78,     0,
+      83,    84,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   168,    76,   132,     0,   162,   154,
+     155,   156,   157,   158,   159,   137,   138,   139,   144,   145,
+     146,   147,   148,   149,   150,   151,   152,   153,     0,    53,
+       0,    16,     0,     0,     0,     0,    28,    81,    82,   133,
+      79,    80,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     3,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     5,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    53,     0,
-       0,     5,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    34,     7,    21,    22,    24,     0,
-       0,     0,    26,    32,   187,   188,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    61,     0,     0,     5,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    37,   126,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   184,    65,    63,    62,    64,    61,    60,    56,
-      47,    46,    59,    58,    57,    55,    50,    49,    48,    51,
-      52,    54,     0,     0,   152,     0,   155,   154,   153,   156,
-       5,    43,    42,    41,    40,    44,     0,     0,     0,     0,
-     181,     0,     0,     0,   169,   170,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   132,   133,   134,     6,
-       0,     0,     0,     0,     0,   128,   185,    66,    67,     0,
-       0,     0,     0,     0,   160,   161,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    38,     0,
-       0,     0,     0,     0,     0,    33,    39,    30,    31,     0,
-       0,     0,     0,   180,     0,   182,     0,     0,     0,     0,
-       0,   174,   175,   176,     0,     0,     0,     0,     0,     0,
-       0,     0,    27,    28,    29,     0,     0,   179,   167,   168,
+       0,     0,    42,    15,    29,    30,    32,     0,     0,     0,
+      34,    40,   204,   205,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    45,
+     134,     0,     0,     0,     0,     0,     9,    10,     0,     7,
+       0,     0,     0,     0,     0,     0,     0,     0,   201,    73,
+      71,    70,    72,    69,    68,    64,    55,    54,    67,    66,
+      65,    63,    58,    57,    56,    59,    60,    62,     0,     0,
+     163,     0,   166,   165,   164,   167,     5,    51,    50,    49,
+      48,    52,     0,     0,     0,     0,   198,     0,     0,     0,
+     182,   183,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   140,   141,   142,    13,    14,    11,    12,     0,
+     143,     0,     0,     0,     0,   177,   178,     0,   136,   202,
+      74,    75,     6,     0,     0,     0,     0,     0,   171,   172,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   166,   183,     0,     0,     0,   178,   177,   127,   162,
-     163,   164,   165,   186,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   171,   172,   173
+       0,     0,     0,    46,     0,     8,     0,     0,     0,     0,
+       0,    41,    47,    38,    39,     0,     0,     0,     0,     0,
+     195,     0,   199,     0,     0,     0,     0,     0,   187,   188,
+     189,     0,     0,     0,     0,     0,     0,     0,     0,    35,
+      36,    37,     0,     0,     0,     0,   192,   180,   181,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     179,     0,   196,     0,   200,     0,     0,     0,   191,   190,
+     135,   173,   174,   175,   176,   203,     0,   193,     0,     0,
+       0,   197,     0,     0,     0,     0,   194,     0,     0,     0,
+     184,   185,   186
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     2,   235,     9,    17,    30,    31,    32,    33,
-      34,    35,   139,   212,   339,    36,   299,    11,   230,   133,
-     111,   112,   113,    16,   114,   115,    23,    21,   316,   116,
-     117,   118,   119,   120,   121,   122,   123,   124,   125,   126,
-     127,   128,   129,   130,   131,   132,   216,   281,   344,   241,
-     242,   217
+      -1,     1,     2,   279,   248,   249,     9,    17,    30,    31,
+      32,    33,    34,    35,   144,   220,   365,    36,    10,    11,
+     238,   138,   114,   115,   116,    16,   117,   118,    23,    21,
+     340,   119,   120,   121,   122,   123,   124,   125,   126,   127,
+     128,   129,   130,   131,   132,   133,   134,   135,   136,   137,
+     224,   297,   371,   257,   258,   372
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -189
+#define YYPACT_NINF -320
 static const yytype_int16 yypact[] =
 {
-    -189,    36,     8,  -189,   -66,   -25,  -189,    -9,  -189,  -189,
-    -189,    13,  -189,  -189,    -4,  -189,     3,   178,   342,   342,
-    -189,    30,  -189,    60,  -189,   342,   342,  -189,    -9,  -189,
-    -189,    31,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,    23,   -29,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,   172,
-     183,   195,   200,   203,   205,   210,   212,   214,   220,   226,
-     248,   249,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,   252,
-    -189,  -189,   342,   253,   254,   118,   257,   270,   292,   340,
-     225,   440,  -189,  -189,    19,   296,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,    25,   440,   241,  -189,    17,    11,    61,
-     219,  -189,  -189,  -189,  -189,  -189,  -189,   101,   101,   101,
-      -4,    -4,    -4,    -4,    -4,    -4,    -4,    -4,    -4,    -4,
-     273,    43,    -4,    -4,  -189,   273,   273,   273,   273,   341,
-     342,   342,   342,   342,   342,   342,   342,   342,   342,   342,
-     342,   342,   342,   342,   342,   342,   342,   342,  -189,   273,
-     342,  -189,   342,   343,   342,   342,   342,   342,   344,   342,
-     342,   342,   342,   342,  -189,  -189,  -189,  -189,  -189,   308,
-     317,   320,  -189,  -189,  -189,  -189,   430,   349,    -9,    -9,
-     360,   367,   441,   487,   488,   489,   490,   507,   508,   509,
-      27,  -189,  -189,   437,   442,     4,   513,   514,   522,   523,
-     342,     6,  -189,   454,   454,   454,   454,   454,   454,   465,
-     465,   465,   190,   190,   190,   190,   190,   190,   190,    41,
-     209,  -189,    38,     9,   296,   342,   296,   296,    95,  -189,
-    -189,   260,   260,   133,   120,  -189,   411,   412,   414,   107,
-    -189,   456,   529,   536,  -189,  -189,   342,   342,   342,   342,
-     342,   342,   342,   342,   273,   517,  -189,  -189,  -189,  -189,
-     342,   342,   342,   342,    45,  -189,  -189,  -189,  -189,    73,
-      26,    89,    89,    89,  -189,  -189,   539,   116,   107,   107,
-     318,   495,   500,    52,    58,    67,   505,   520,  -189,   468,
-     534,   545,   550,   555,   494,  -189,  -189,  -189,  -189,   475,
-     476,   477,     3,  -189,    46,  -189,   518,   519,   342,   342,
-     342,  -189,  -189,  -189,   342,   342,   342,   342,   342,   342,
-     342,   342,  -189,  -189,  -189,   521,   101,  -189,  -189,  -189,
-     560,   565,   570,   239,   255,   168,   206,   217,   227,   250,
-     108,  -189,  -189,   342,   342,   342,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,   575,   580,   585,   342,   342,   342,
-     290,   418,   438,  -189,  -189,  -189
+    -320,    31,    20,  -320,   -26,   -15,  -320,    -8,  -320,  -320,
+    -320,   171,  -320,  -320,   -13,  -320,    39,   212,   382,   382,
+    -320,    33,  -320,    38,  -320,   382,   382,  -320,    -8,  -320,
+    -320,     3,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,    21,    82,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,    47,
+      54,   118,   156,   169,   172,   178,   190,   195,   200,   235,
+     237,   244,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,   264,
+    -320,  -320,   382,   275,   278,   208,   218,   279,   281,   282,
+     283,   284,   301,   224,   476,  -320,  -320,    16,   340,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,   332,   476,
+     138,  -320,    11,     5,   437,   268,  -320,  -320,  -320,  -320,
+    -320,  -320,   151,   151,   151,   -13,   -13,   -13,   -13,   -13,
+     -13,   -13,   -13,   -13,   -13,   192,    30,   -13,   -13,  -320,
+     188,   192,   192,   192,   192,   382,   382,   305,   382,   382,
+     382,   382,   382,   382,   382,   382,   382,   382,   382,   382,
+     382,   382,   382,   382,   382,   382,  -320,   192,   382,  -320,
+     382,   243,   382,   382,   382,   382,   260,   382,   382,   382,
+     382,   382,  -320,  -320,  -320,  -320,  -320,   288,   289,   337,
+    -320,  -320,  -320,  -320,   453,   369,    -8,    -8,   399,   400,
+     475,   504,   547,   568,   570,   571,   589,   590,    18,  -320,
+    -320,   403,   520,     4,   145,   148,  -320,  -320,    15,  -320,
+     592,   594,   631,   632,    36,    42,   382,    13,  -320,   497,
+     497,   497,   497,   497,   497,   519,   519,   519,   270,   270,
+     270,   270,   270,   270,   270,   276,   236,  -320,    19,    28,
+     340,   382,   340,   340,    68,  -320,  -320,   522,   522,    94,
+     277,  -320,   517,   518,   521,   228,  -320,    73,   635,   636,
+    -320,  -320,   382,   382,   382,   382,   382,   382,   382,   382,
+     192,   617,  -320,  -320,  -320,  -320,  -320,  -320,  -320,   188,
+    -320,   382,   382,   382,   382,  -320,  -320,    71,  -320,  -320,
+    -320,  -320,  -320,   459,    29,   213,   213,   213,  -320,  -320,
+     639,   369,   175,   228,   228,   527,   545,   556,    49,    55,
+      64,   561,   566,  -320,   569,  -320,   577,   582,   587,   599,
+     544,  -320,  -320,  -320,  -320,   526,   528,   529,    39,    74,
+    -320,    78,  -320,   573,   574,   382,   382,   382,  -320,  -320,
+    -320,   382,   382,   382,   382,   382,   382,   382,   382,  -320,
+    -320,  -320,   575,   369,   210,   151,  -320,  -320,  -320,   604,
+     609,   614,   126,   241,   134,   142,   220,   226,   233,   502,
+    -320,   578,  -320,   102,  -320,   382,   382,   382,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,   249,  -320,   619,   624,
+     629,  -320,   136,   382,   382,   382,  -320,   262,   267,   272,
+    -320,  -320,  -320
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -189,  -189,  -189,  -188,  -189,  -189,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,   -74,  -189,   598,  -189,  -189,   -13,
-     -19,  -189,    40,   -24,  -149,  -157,   261,   158,   -69,  -189,
-    -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,
-    -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,  -189,
-     361,  -147
+    -320,  -320,   481,   370,  -320,   339,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,    -3,  -320,  -247,  -320,
+    -320,     2,   -19,  -320,    22,   -24,  -133,  -123,   291,   215,
+       7,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,
+    -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,  -320,
+    -320,  -268,  -319,  -320,   404,  -151
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -943,142 +1078,154 @@ static const yytype_int16 yypgoto[] =
 #define YYTABLE_NINF -3
 static const yytype_int16 yytable[] =
 {
-     134,   218,   219,   263,   140,     4,   134,   134,    -2,     4,
-       4,    13,   137,   138,   198,   199,   200,   201,   202,   203,
-     198,   199,   200,   201,   202,   203,   192,     4,   198,   199,
-     200,   201,   202,   203,   294,   264,     3,   266,   267,   268,
-     269,   262,    12,   145,   146,   192,   198,   199,   200,   201,
-     202,   203,   192,   366,    14,   198,   199,   200,   201,   202,
-     203,   198,   199,   200,   201,   202,   203,   187,   188,   189,
-     198,   199,   200,   201,   202,   203,   198,   199,   200,   201,
-     202,   203,   310,   134,   144,   240,   298,    15,   305,   161,
-      20,   304,    18,   308,     5,   142,   143,    22,    19,   193,
-       6,   196,   204,   197,     6,     6,     7,   295,   336,     8,
-     135,   198,   199,   200,   201,   202,   203,   207,   307,     6,
-     190,   206,     6,   232,   191,   334,   367,   202,   203,   320,
-     321,   322,   351,   214,   215,   326,   327,   136,   352,   201,
-     202,   203,   141,   330,   331,   332,   333,   353,   214,   215,
-     335,   243,   244,   245,   246,   247,   248,   249,   250,   251,
-     252,   253,   254,   255,   256,   257,   258,   259,   260,   208,
-     345,   198,   199,   200,   201,   202,   203,   209,   210,   211,
-     134,   134,   134,   134,   134,   393,   271,   272,   273,   274,
-     275,   370,   371,   372,   282,   283,   343,   373,   374,   164,
-     231,   314,   315,   337,   338,   236,   237,   238,   239,   198,
-     199,   200,   201,   202,   203,   186,   187,   188,   189,   382,
-     198,   199,   200,   201,   202,   203,   394,   395,   396,   261,
-     198,   199,   200,   201,   202,   203,   188,   189,   340,   341,
-     400,   401,   402,   194,   195,   196,   134,   197,   388,   346,
-     347,   147,   309,   198,   199,   200,   201,   202,   203,   194,
-     195,   196,   148,   197,   199,   200,   201,   202,   203,   190,
-     134,   134,   134,   191,   149,    12,   323,   324,   325,   150,
-      24,    25,   151,    26,   152,    27,   389,    28,   190,   153,
-      29,   154,   191,   155,   194,   195,   196,   390,   197,   156,
-     194,   195,   196,    12,   197,   157,   169,   391,   220,   221,
-     222,   223,   224,   225,   226,   227,   228,   229,   205,   386,
-     233,   234,   194,   195,   196,   348,   197,   158,   159,   213,
-     392,   160,   162,   163,   328,   387,   165,   134,   134,   134,
-     134,   134,   134,   375,   376,   377,   378,   379,   380,   166,
-      12,    37,    38,    39,    40,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    50,    51,    52,    53,    54,     6,
-     403,   167,    55,    56,    57,    58,    59,    60,    61,    62,
+     139,   225,   226,   227,   145,     4,   139,   139,   206,   207,
+     208,   209,   210,   211,   206,   207,   208,   209,   210,   211,
+      -2,     4,   319,   200,    12,   310,   200,   142,   143,     4,
+       4,     3,   332,   206,   207,   208,   209,   210,   211,   206,
+     207,   208,   209,   210,   211,   206,   207,   208,   209,   210,
+     211,    13,   206,   207,   208,   209,   210,   211,   206,   207,
+     208,   209,   210,   211,    14,   278,   149,   206,   207,   208,
+     209,   210,   211,   369,   204,   413,   205,   280,   200,   282,
+     283,   284,   285,   139,    20,   395,   314,   332,   341,   393,
+       5,    15,   256,   147,   148,   328,   201,   320,   311,   330,
+     209,   210,   211,     6,   166,     7,     5,   432,     8,   395,
+     240,   362,   331,   140,   215,   141,   325,   146,   214,     6,
+       6,     7,   326,   327,     8,   411,   152,     6,     6,   378,
+     202,   203,   204,   153,   205,   379,    22,   206,   207,   208,
+     209,   210,   211,   395,   380,   206,   207,   208,   209,   210,
+     211,   360,   342,   394,   150,   151,   139,   139,   396,   259,
+     260,   261,   262,   263,   264,   265,   266,   267,   268,   269,
+     270,   271,   272,   273,   274,   275,   276,   254,   255,   345,
+     346,   347,   427,   222,   223,   351,   352,   239,   139,   139,
+     139,   139,   139,   250,   251,   252,   253,   154,   356,   357,
+     358,   359,   298,   299,   244,   245,   418,   222,   223,   287,
+     288,   289,   290,   291,   420,   213,   436,   315,   316,   277,
+     317,   318,   421,   206,   207,   208,   209,   210,   211,   206,
+     207,   208,   209,   210,   211,   155,   206,   207,   208,   209,
+     210,   211,   222,   223,   414,   202,   203,   204,   156,   205,
+      18,   157,   399,   400,   401,   370,    19,   158,   402,   403,
+     246,   247,   139,   196,   197,    12,   202,   203,   204,   159,
+     205,   202,   203,   204,   160,   205,   202,   203,   204,   161,
+     205,   222,   223,   333,   210,   211,   139,   139,   139,   169,
+     412,     6,   428,   429,   430,   194,   195,   196,   197,   170,
+     422,    12,   195,   196,   197,   177,   423,   348,   349,   350,
+     437,   438,   439,   424,   162,   198,   163,    24,    25,   199,
+      26,   419,    27,   164,    28,   338,   339,    29,   281,   431,
+     363,   364,   353,   366,   367,   206,   207,   208,   209,   210,
+     211,   286,   440,   165,   202,   203,   204,   441,   205,   198,
+     373,   374,   442,   199,   167,   198,    12,   168,   171,   199,
+     172,   173,   174,   175,   139,   139,   139,   139,   139,   139,
+     228,   229,   230,   231,   232,   233,   234,   235,   236,   237,
+     176,   221,   241,   242,   256,   404,   405,   406,   407,   408,
+     409,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+      46,    47,    48,    49,    50,    51,    52,    53,    54,   212,
+     292,   293,    55,    56,    57,    58,    59,    60,    61,    62,
       63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
       73,    74,    75,    76,    77,    78,    79,    80,    81,    82,
       83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
-      93,    94,    95,    96,    97,    98,    99,   100,   101,   168,
-     240,   102,   194,   195,   196,   270,   197,   276,   265,   103,
-     104,   105,   106,   107,   108,   109,   277,   279,     6,   278,
-     284,   110,   194,   195,   196,   280,   197,   285,   286,   170,
-     171,   172,   173,   174,   175,   176,   177,   178,   179,   180,
-     181,   182,   183,   184,   185,   186,   187,   188,   189,   176,
-     177,   178,   179,   180,   181,   182,   183,   184,   185,   186,
-     187,   188,   189,   179,   180,   181,   182,   183,   184,   185,
-     186,   187,   188,   189,   287,   288,   289,   290,   404,   194,
-     195,   196,   349,   197,   194,   195,   196,   350,   197,   194,
-     195,   196,   354,   197,   291,   292,   293,   296,   405,   190,
-     300,   301,   297,   191,   194,   195,   196,   355,   197,   302,
-     303,   311,   312,   190,   313,   317,   318,   191,   194,   195,
-     196,   357,   197,   319,   190,   329,   342,   356,   191,   194,
-     195,   196,   358,   197,   194,   195,   196,   359,   197,   194,
-     195,   196,   360,   197,   194,   195,   196,   383,   197,   194,
-     195,   196,   384,   197,   194,   195,   196,   385,   197,   194,
-     195,   196,   397,   197,   194,   195,   196,   398,   197,   194,
-     195,   196,   399,   197,   361,   362,   363,   364,   368,   369,
-      10,   381,   306,   365
+      93,    94,    95,    96,    97,    98,    99,   100,   101,   294,
+     295,   102,   206,   207,   208,   209,   210,   211,   296,   103,
+     104,   105,   106,   107,   108,   109,   110,   111,   112,   300,
+     301,     6,   302,   312,   113,   178,   179,   180,   181,   182,
+     183,   184,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   206,   207,   208,   209,   210,
+     211,   303,   184,   185,   186,   187,   188,   189,   190,   191,
+     192,   193,   194,   195,   196,   197,   207,   208,   209,   210,
+     211,   202,   203,   204,   375,   205,   361,   187,   188,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   216,   202,
+     203,   204,   376,   205,   304,   198,   217,   218,   219,   199,
+     202,   203,   204,   377,   205,   202,   203,   204,   381,   205,
+     202,   203,   204,   382,   205,   305,   198,   306,   307,   425,
+     199,   202,   203,   204,   384,   205,   202,   203,   204,   385,
+     205,   202,   203,   204,   386,   205,   308,   309,   198,   321,
+     313,   322,   199,   202,   203,   204,   387,   205,   202,   203,
+     204,   415,   205,   202,   203,   204,   416,   205,   202,   203,
+     204,   417,   205,   202,   203,   204,   433,   205,   202,   203,
+     204,   434,   205,   202,   203,   204,   435,   205,   323,   324,
+     335,   336,   343,   344,   337,   354,   368,   388,   383,   389,
+     243,   390,   391,   397,   398,   410,   334,   426,   355,   392,
+       0,   329
 };
 
-static const yytype_uint16 yycheck[] =
+static const yytype_int16 yycheck[] =
 {
-      19,   148,   149,   191,    28,     1,    25,    26,     0,     1,
-       1,    77,    25,    26,     3,     4,     5,     6,     7,     8,
-       3,     4,     5,     6,     7,     8,     7,     1,     3,     4,
-       5,     6,     7,     8,     7,   192,     0,   194,   195,   196,
-     197,   190,     2,    72,    73,     7,     3,     4,     5,     6,
-       7,     8,     7,     7,    79,     3,     4,     5,     6,     7,
-       8,     3,     4,     5,     6,     7,     8,    26,    27,    28,
-       3,     4,     5,     6,     7,     8,     3,     4,     5,     6,
-       7,     8,   270,   102,    44,    79,    82,    96,    82,   102,
-      94,   240,    79,    84,    86,    72,    73,    94,    85,    80,
-      96,     6,    77,     8,    96,    96,    98,    80,    82,   101,
-      80,     3,     4,     5,     6,     7,     8,   106,    80,    96,
-      79,   104,    96,    80,    83,    80,    80,     7,     8,   286,
-     287,   288,    80,    32,    33,   292,   293,    77,    80,     6,
-       7,     8,   111,   300,   301,   302,   303,    80,    32,    33,
-      77,   170,   171,   172,   173,   174,   175,   176,   177,   178,
-     179,   180,   181,   182,   183,   184,   185,   186,   187,   108,
-     317,     3,     4,     5,     6,     7,     8,   116,   117,   118,
-     199,   200,   201,   202,   203,    77,   199,   200,   201,   202,
-     203,   348,   349,   350,   218,   219,    80,   354,   355,    81,
-     160,    94,    95,   114,   115,   165,   166,   167,   168,     3,
-       4,     5,     6,     7,     8,    25,    26,    27,    28,   366,
-       3,     4,     5,     6,     7,     8,   383,   384,   385,   189,
-       3,     4,     5,     6,     7,     8,    27,    28,   312,   313,
-     397,   398,   399,     4,     5,     6,   265,     8,    80,   318,
-     319,    79,   265,     3,     4,     5,     6,     7,     8,     4,
-       5,     6,    79,     8,     4,     5,     6,     7,     8,    79,
-     289,   290,   291,    83,    79,   235,   289,   290,   291,    79,
-     102,   103,    79,   105,    79,   107,    80,   109,    79,    79,
-     112,    79,    83,    79,     4,     5,     6,    80,     8,    79,
-       4,     5,     6,   263,     8,    79,    81,    80,   150,   151,
-     152,   153,   154,   155,   156,   157,   158,   159,    77,    80,
-     162,   163,     4,     5,     6,     7,     8,    79,    79,   110,
-      80,    79,    79,    79,   294,    80,    79,   356,   357,   358,
-     359,   360,   361,   356,   357,   358,   359,   360,   361,    79,
-     310,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    96,
-      80,    79,    30,    31,    32,    33,    34,    35,    36,    37,
+      19,   152,   153,   154,    28,     1,    25,    26,     3,     4,
+       5,     6,     7,     8,     3,     4,     5,     6,     7,     8,
+       0,     1,     7,     7,     2,     7,     7,    25,    26,     1,
+       1,     0,   279,     3,     4,     5,     6,     7,     8,     3,
+       4,     5,     6,     7,     8,     3,     4,     5,     6,     7,
+       8,    77,     3,     4,     5,     6,     7,     8,     3,     4,
+       5,     6,     7,     8,    79,   198,    44,     3,     4,     5,
+       6,     7,     8,   341,     6,   394,     8,   200,     7,   202,
+     203,   204,   205,   102,    97,     7,    82,   334,    15,    15,
+      86,    99,    79,    72,    73,    82,    80,    82,    80,    80,
+       6,     7,     8,    99,   102,   101,    86,   426,   104,     7,
+      80,    82,    84,    80,   109,    77,    80,   114,   107,    99,
+      99,   101,    80,   256,   104,   393,    79,    99,    99,    80,
+       4,     5,     6,    79,     8,    80,    97,     3,     4,     5,
+       6,     7,     8,     7,    80,     3,     4,     5,     6,     7,
+       8,    80,    79,    79,    72,    73,   175,   176,    80,   178,
+     179,   180,   181,   182,   183,   184,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,   195,   175,   176,   302,
+     303,   304,    80,    32,    33,   308,   309,   165,   207,   208,
+     209,   210,   211,   171,   172,   173,   174,    79,   321,   322,
+     323,   324,   226,   227,    16,    17,    80,    32,    33,   207,
+     208,   209,   210,   211,    80,    77,    80,    72,    73,   197,
+      72,    73,    80,     3,     4,     5,     6,     7,     8,     3,
+       4,     5,     6,     7,     8,    79,     3,     4,     5,     6,
+       7,     8,    32,    33,   395,     4,     5,     6,    79,     8,
+      79,    79,   375,   376,   377,    80,    85,    79,   381,   382,
+      72,    73,   281,    27,    28,   243,     4,     5,     6,    79,
+       8,     4,     5,     6,    79,     8,     4,     5,     6,    79,
+       8,    32,    33,   281,     7,     8,   305,   306,   307,    81,
+      80,    99,   415,   416,   417,    25,    26,    27,    28,    81,
+      80,   279,    26,    27,    28,    81,    80,   305,   306,   307,
+     433,   434,   435,    80,    79,    79,    79,   105,   106,    83,
+     108,    80,   110,    79,   112,    97,    98,   115,    85,    80,
+     117,   118,   310,   336,   337,     3,     4,     5,     6,     7,
+       8,    81,    80,    79,     4,     5,     6,    80,     8,    79,
+     343,   344,    80,    83,    79,    79,   334,    79,    79,    83,
+      79,    79,    79,    79,   383,   384,   385,   386,   387,   388,
+     155,   156,   157,   158,   159,   160,   161,   162,   163,   164,
+      79,   113,   167,   168,    79,   383,   384,   385,   386,   387,
+     388,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    77,
+     122,   122,    30,    31,    32,    33,    34,    35,    36,    37,
       38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
       48,    49,    50,    51,    52,    53,    54,    55,    56,    57,
       58,    59,    60,    61,    62,    63,    64,    65,    66,    67,
-      68,    69,    70,    71,    72,    73,    74,    75,    76,    79,
-      79,    79,     4,     5,     6,    81,     8,   119,    85,    87,
-      88,    89,    90,    91,    92,    93,   119,     7,    96,   119,
-      80,    99,     4,     5,     6,    96,     8,    80,     7,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    15,
-      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    28,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,     7,     7,     7,     7,    80,     4,
-       5,     6,     7,     8,     4,     5,     6,     7,     8,     4,
-       5,     6,     7,     8,     7,     7,     7,    80,    80,    79,
-       7,     7,    80,    83,     4,     5,     6,     7,     8,     7,
-       7,   120,   120,    79,   120,    79,     7,    83,     4,     5,
-       6,     7,     8,     7,    79,    28,     7,    79,    83,     4,
-       5,     6,     7,     8,     4,     5,     6,     7,     8,     4,
-       5,     6,     7,     8,     4,     5,     6,     7,     8,     4,
-       5,     6,     7,     8,     4,     5,     6,     7,     8,     4,
-       5,     6,     7,     8,     4,     5,     6,     7,     8,     4,
-       5,     6,     7,     8,   100,   120,   120,   120,    80,    80,
-       2,    80,   241,   342
+      68,    69,    70,    71,    72,    73,    74,    75,    76,   122,
+       7,    79,     3,     4,     5,     6,     7,     8,    99,    87,
+      88,    89,    90,    91,    92,    93,    94,    95,    96,    80,
+      80,    99,     7,    80,   102,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,     3,     4,     5,     6,     7,
+       8,     7,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,     4,     5,     6,     7,
+       8,     4,     5,     6,     7,     8,    77,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,   111,     4,
+       5,     6,     7,     8,     7,    79,   119,   120,   121,    83,
+       4,     5,     6,     7,     8,     4,     5,     6,     7,     8,
+       4,     5,     6,     7,     8,     7,    79,     7,     7,    77,
+      83,     4,     5,     6,     7,     8,     4,     5,     6,     7,
+       8,     4,     5,     6,     7,     8,     7,     7,    79,     7,
+      80,     7,    83,     4,     5,     6,     7,     8,     4,     5,
+       6,     7,     8,     4,     5,     6,     7,     8,     4,     5,
+       6,     7,     8,     4,     5,     6,     7,     8,     4,     5,
+       6,     7,     8,     4,     5,     6,     7,     8,     7,     7,
+     123,   123,     7,     7,   123,    28,     7,   103,    79,   123,
+     169,   123,   123,    80,    80,    80,   286,    79,   319,   368,
+      -1,   257
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,   122,   123,     0,     1,    86,    96,    98,   101,   125,
-     137,   138,   143,    77,    79,    96,   144,   126,    79,    85,
-      94,   148,    94,   147,   102,   103,   105,   107,   109,   112,
-     127,   128,   129,   130,   131,   132,   136,     9,    10,    11,
+       0,   125,   126,     0,     1,    86,    99,   101,   104,   130,
+     142,   143,   148,    77,    79,    99,   149,   131,    79,    85,
+      97,   153,    97,   152,   105,   106,   108,   110,   112,   115,
+     132,   133,   134,   135,   136,   137,   141,     9,    10,    11,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
       22,    23,    24,    25,    26,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
@@ -1086,36 +1233,40 @@ static const yytype_uint8 yystos[] =
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    79,    87,    88,    89,    90,    91,    92,    93,
-      99,   141,   142,   143,   145,   146,   150,   151,   152,   153,
-     154,   155,   156,   157,   158,   159,   160,   161,   162,   163,
-     164,   165,   166,   140,   141,    80,    77,   140,   140,   133,
-     144,   111,    72,    73,   143,    72,    73,    79,    79,    79,
-      79,    79,    79,    79,    79,    79,    79,    79,    79,    79,
-      79,   140,    79,    79,    81,    79,    79,    79,    79,    81,
-       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      79,    83,     7,    80,     4,     5,     6,     8,     3,     4,
-       5,     6,     7,     8,    77,    77,   104,   106,   108,   116,
-     117,   118,   134,   110,    32,    33,   167,   172,   172,   172,
-     148,   148,   148,   148,   148,   148,   148,   148,   148,   148,
-     139,   143,    80,   148,   148,   124,   143,   143,   143,   143,
-      79,   170,   171,   141,   141,   141,   141,   141,   141,   141,
-     141,   141,   141,   141,   141,   141,   141,   141,   141,   141,
-     141,   143,   145,   124,   146,    85,   146,   146,   146,   146,
-      81,   140,   140,   140,   140,   140,   119,   119,   119,     7,
-      96,   168,   144,   144,    80,    80,     7,     7,     7,     7,
-       7,     7,     7,     7,     7,    80,    80,    80,    82,   137,
-       7,     7,     7,     7,   145,    82,   171,    80,    84,   140,
-     124,   120,   120,   120,    94,    95,   149,    79,     7,     7,
-     146,   146,   146,   140,   140,   140,   146,   146,   143,    28,
-     146,   146,   146,   146,    80,    77,    82,   114,   115,   135,
-     135,   135,     7,    80,   169,   172,   149,   149,     7,     7,
-       7,    80,    80,    80,     7,     7,    79,     7,     7,     7,
-       7,   100,   120,   120,   120,   147,     7,    80,    80,    80,
-     146,   146,   146,   146,   146,   140,   140,   140,   140,   140,
-     140,    80,   172,     7,     7,     7,    80,    80,    80,    80,
-      80,    80,    80,    77,   146,   146,   146,     7,     7,     7,
-     146,   146,   146,    80,    80,    80
+      94,    95,    96,   102,   146,   147,   148,   150,   151,   155,
+     156,   157,   158,   159,   160,   161,   162,   163,   164,   165,
+     166,   167,   168,   169,   170,   171,   172,   173,   145,   146,
+      80,    77,   145,   145,   138,   149,   114,    72,    73,   148,
+      72,    73,    79,    79,    79,    79,    79,    79,    79,    79,
+      79,    79,    79,    79,    79,    79,   145,    79,    79,    81,
+      81,    79,    79,    79,    79,    79,    79,    81,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    79,    83,
+       7,    80,     4,     5,     6,     8,     3,     4,     5,     6,
+       7,     8,    77,    77,   107,   109,   111,   119,   120,   121,
+     139,   113,    32,    33,   174,   179,   179,   179,   153,   153,
+     153,   153,   153,   153,   153,   153,   153,   153,   144,   148,
+      80,   153,   153,   126,    16,    17,    72,    73,   128,   129,
+     148,   148,   148,   148,   145,   145,    79,   177,   178,   146,
+     146,   146,   146,   146,   146,   146,   146,   146,   146,   146,
+     146,   146,   146,   146,   146,   146,   146,   148,   150,   127,
+     151,    85,   151,   151,   151,   151,    81,   145,   145,   145,
+     145,   145,   122,   122,   122,     7,    99,   175,   149,   149,
+      80,    80,     7,     7,     7,     7,     7,     7,     7,     7,
+       7,    80,    80,    80,    82,    72,    73,    72,    73,     7,
+      82,     7,     7,     7,     7,    80,    80,   150,    82,   178,
+      80,    84,   142,   145,   127,   123,   123,   123,    97,    98,
+     154,    15,    79,     7,     7,   151,   151,   151,   145,   145,
+     145,   151,   151,   148,    28,   129,   151,   151,   151,   151,
+      80,    77,    82,   117,   118,   140,   140,   140,     7,   175,
+      80,   176,   179,   154,   154,     7,     7,     7,    80,    80,
+      80,     7,     7,    79,     7,     7,     7,     7,   103,   123,
+     123,   123,   152,    15,    79,     7,    80,    80,    80,   151,
+     151,   151,   151,   151,   145,   145,   145,   145,   145,   145,
+      80,   175,    80,   176,   179,     7,     7,     7,    80,    80,
+      80,    80,    80,    80,    80,    77,    79,    80,   151,   151,
+     151,    80,   176,     7,     7,     7,    80,   151,   151,   151,
+      80,    80,    80
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -1189,7 +1340,7 @@ while (YYID (0))
    we won't break user code: when these are the locations we know.  */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
 #  define YY_LOCATION_PRINT(File, Loc)			\
      fprintf (File, "%d.%d-%d.%d",			\
 	      (Loc).first_line, (Loc).first_column,	\
@@ -1300,20 +1451,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
 #else
 static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
   YYFPRINTF (stderr, "\n");
 }
 
@@ -1347,11 +1495,11 @@ yy_reduce_print (yyvsp, yyrule)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
 		       		       );
-      YYFPRINTF (stderr, "\n");
+      fprintf (stderr, "\n");
     }
 }
 
@@ -1631,8 +1779,10 @@ yydestruct (yymsg, yytype, yyvaluep)
 	break;
     }
 }
+
 
 /* Prevent warnings from -Wmissing-prototypes.  */
+
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
 int yyparse (void *YYPARSE_PARAM);
@@ -1648,10 +1798,11 @@ int yyparse ();
 #endif /* ! YYPARSE_PARAM */
 
 
-/* The lookahead symbol.  */
+
+/* The look-ahead symbol.  */
 int yychar;
 
-/* The semantic value of the lookahead symbol.  */
+/* The semantic value of the look-ahead symbol.  */
 YYSTYPE yylval;
 
 /* Number of syntax errors so far.  */
@@ -1659,9 +1810,9 @@ int yynerrs;
 
 
 
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
+/*----------.
+| yyparse.  |
+`----------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1685,68 +1836,66 @@ yyparse ()
 #endif
 #endif
 {
+  
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
 
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
 
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
 
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
 
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
 
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
 
-    YYSIZE_T yystacksize;
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
 
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
 
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
 
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
-  yystacksize = YYINITDEPTH;
-
   YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
   yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
 
   /* Initialize stack pointers.
      Waste one element of value and location stack
      so that they stay on the same level as the state stack.
      The wasted elements are never initialized.  */
+
   yyssp = yyss;
   yyvsp = yyvs;
 
@@ -1776,6 +1925,7 @@ yyparse ()
 	YYSTYPE *yyvs1 = yyvs;
 	yytype_int16 *yyss1 = yyss;
 
+
 	/* Each stack pointer address is followed by the size of the
 	   data in use in that stack, in bytes.  This used to be a
 	   conditional around just the two extra args, but that might
@@ -1783,6 +1933,7 @@ yyparse ()
 	yyoverflow (YY_("memory exhausted"),
 		    &yyss1, yysize * sizeof (*yyssp),
 		    &yyvs1, yysize * sizeof (*yyvsp),
+
 		    &yystacksize);
 
 	yyss = yyss1;
@@ -1805,8 +1956,9 @@ yyparse ()
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
 	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -1817,6 +1969,7 @@ yyparse ()
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
+
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
 		  (unsigned long int) yystacksize));
 
@@ -1826,9 +1979,6 @@ yyparse ()
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
   goto yybackup;
 
 /*-----------.
@@ -1837,16 +1987,16 @@ yyparse ()
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
+     look-ahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
   yyn = yypact[yystate];
   if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1878,16 +2028,20 @@ yybackup:
       goto yyreduce;
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the lookahead token.  */
+  /* Shift the look-ahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
 
   yystate = yyn;
   *++yyvsp = yylval;
@@ -1927,1318 +2081,1028 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1455 of yacc.c  */
-#line 301 "parser/faustparser.y"
+#line 310 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); gResult = formatDefinitions((yyval.exp)); ;}
     break;
 
   case 3:
-
-/* Line 1455 of yacc.c  */
-#line 304 "parser/faustparser.y"
+#line 313 "parser/faustparser.y"
     { (yyval.exp) = nil; ;}
     break;
 
   case 4:
-
-/* Line 1455 of yacc.c  */
-#line 305 "parser/faustparser.y"
+#line 314 "parser/faustparser.y"
     { (yyval.exp) = cons ((yyvsp[(2) - (2)].exp),(yyvsp[(1) - (2)].exp)); ;}
     break;
 
   case 5:
-
-/* Line 1455 of yacc.c  */
-#line 307 "parser/faustparser.y"
+#line 316 "parser/faustparser.y"
     { (yyval.exp) = nil; ;}
     break;
 
   case 6:
-
-/* Line 1455 of yacc.c  */
-#line 308 "parser/faustparser.y"
+#line 317 "parser/faustparser.y"
     { (yyval.exp) = cons ((yyvsp[(2) - (2)].exp),(yyvsp[(1) - (2)].exp)); ;}
     break;
 
   case 7:
-
-/* Line 1455 of yacc.c  */
-#line 311 "parser/faustparser.y"
-    { (yyval.exp) = importFile((yyvsp[(3) - (5)].exp)); ;}
+#line 324 "parser/faustparser.y"
+    { gWaveForm.push_back((yyvsp[(1) - (1)].exp)); ;}
     break;
 
   case 8:
-
-/* Line 1455 of yacc.c  */
-#line 312 "parser/faustparser.y"
-    { declareMetadata((yyvsp[(2) - (4)].exp),(yyvsp[(3) - (4)].exp)); (yyval.exp) = nil; ;}
-    break;
+#line 325 "parser/faustparser.y"
+    { gWaveForm.push_back((yyvsp[(3) - (3)].exp)); ;}
+    break;
 
   case 9:
-
-/* Line 1455 of yacc.c  */
-#line 313 "parser/faustparser.y"
-    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
+#line 328 "parser/faustparser.y"
+    { (yyval.exp) = boxInt(atoi(yytext)); ;}
     break;
 
   case 10:
-
-/* Line 1455 of yacc.c  */
-#line 314 "parser/faustparser.y"
-    { declareDoc((yyvsp[(2) - (3)].exp)); (yyval.exp) = nil; /* cerr << "Yacc : doc : " << *$2 << endl; */ ;}
+#line 329 "parser/faustparser.y"
+    { (yyval.exp) = boxReal(atof(yytext)); ;}
     break;
 
   case 11:
-
-/* Line 1455 of yacc.c  */
-#line 317 "parser/faustparser.y"
-    { (yyval.exp) = nil; ;}
+#line 330 "parser/faustparser.y"
+    { (yyval.exp) = boxInt (atoi(yytext)); ;}
     break;
 
   case 12:
-
-/* Line 1455 of yacc.c  */
-#line 318 "parser/faustparser.y"
-    { (yyval.exp) = cons ((yyvsp[(2) - (2)].exp),(yyvsp[(1) - (2)].exp)); ;}
+#line 331 "parser/faustparser.y"
+    { (yyval.exp) = boxReal(atof(yytext)); ;}
     break;
 
   case 13:
-
-/* Line 1455 of yacc.c  */
-#line 321 "parser/faustparser.y"
-    { (yyval.exp) = docTxt((yyvsp[(1) - (1)].cppstr)->c_str()); delete (yyvsp[(1) - (1)].cppstr); ;}
+#line 332 "parser/faustparser.y"
+    { (yyval.exp) = boxInt ( -atoi(yytext) ); ;}
     break;
 
   case 14:
-
-/* Line 1455 of yacc.c  */
-#line 322 "parser/faustparser.y"
-    { (yyval.exp) = docEqn((yyvsp[(1) - (1)].exp)); ;}
+#line 333 "parser/faustparser.y"
+    { (yyval.exp) = boxReal( -atof(yytext) ); ;}
     break;
 
   case 15:
-
-/* Line 1455 of yacc.c  */
-#line 323 "parser/faustparser.y"
-    { (yyval.exp) = docDgm((yyvsp[(1) - (1)].exp)); ;}
+#line 337 "parser/faustparser.y"
+    { (yyval.exp) = importFile((yyvsp[(3) - (5)].exp)); ;}
     break;
 
   case 16:
-
-/* Line 1455 of yacc.c  */
-#line 324 "parser/faustparser.y"
-    { (yyval.exp) = docNtc(); ;}
+#line 338 "parser/faustparser.y"
+    { declareMetadata((yyvsp[(2) - (4)].exp),(yyvsp[(3) - (4)].exp)); (yyval.exp) = nil; ;}
     break;
 
   case 17:
-
-/* Line 1455 of yacc.c  */
-#line 325 "parser/faustparser.y"
-    { (yyval.exp) = docLst(); ;}
+#line 339 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
   case 18:
-
-/* Line 1455 of yacc.c  */
-#line 326 "parser/faustparser.y"
-    { (yyval.exp) = docMtd((yyvsp[(1) - (1)].exp)); ;}
+#line 340 "parser/faustparser.y"
+    { declareDoc((yyvsp[(2) - (3)].exp)); (yyval.exp) = nil; /* cerr << "Yacc : doc : " << *$2 << endl; */ ;}
     break;
 
   case 19:
-
-/* Line 1455 of yacc.c  */
-#line 329 "parser/faustparser.y"
-    { (yyval.cppstr) = new string(); ;}
+#line 343 "parser/faustparser.y"
+    { (yyval.exp) = nil; ;}
     break;
 
   case 20:
-
-/* Line 1455 of yacc.c  */
-#line 330 "parser/faustparser.y"
-    { (yyval.cppstr) = &((yyvsp[(1) - (2)].cppstr)->append(yytext)); ;}
+#line 344 "parser/faustparser.y"
+    { (yyval.exp) = cons ((yyvsp[(2) - (2)].exp),(yyvsp[(1) - (2)].exp)); ;}
     break;
 
   case 21:
-
-/* Line 1455 of yacc.c  */
-#line 333 "parser/faustparser.y"
-    { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
+#line 347 "parser/faustparser.y"
+    { (yyval.exp) = docTxt((yyvsp[(1) - (1)].cppstr)->c_str()); delete (yyvsp[(1) - (1)].cppstr); ;}
     break;
 
   case 22:
-
-/* Line 1455 of yacc.c  */
-#line 336 "parser/faustparser.y"
-    { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
+#line 348 "parser/faustparser.y"
+    { (yyval.exp) = docEqn((yyvsp[(1) - (1)].exp)); ;}
     break;
 
   case 23:
-
-/* Line 1455 of yacc.c  */
-#line 339 "parser/faustparser.y"
-    { ;}
+#line 349 "parser/faustparser.y"
+    { (yyval.exp) = docDgm((yyvsp[(1) - (1)].exp)); ;}
     break;
 
   case 24:
-
-/* Line 1455 of yacc.c  */
-#line 342 "parser/faustparser.y"
-    { ;}
+#line 350 "parser/faustparser.y"
+    { (yyval.exp) = docNtc(); ;}
     break;
 
   case 25:
-
-/* Line 1455 of yacc.c  */
-#line 345 "parser/faustparser.y"
-    { ;}
+#line 351 "parser/faustparser.y"
+    { (yyval.exp) = docLst(); ;}
     break;
 
   case 26:
-
-/* Line 1455 of yacc.c  */
-#line 346 "parser/faustparser.y"
-    { ;}
+#line 352 "parser/faustparser.y"
+    { (yyval.exp) = docMtd((yyvsp[(1) - (1)].exp)); ;}
     break;
 
   case 27:
-
-/* Line 1455 of yacc.c  */
-#line 349 "parser/faustparser.y"
-    { gLstDependenciesSwitch = (yyvsp[(4) - (5)].b); ;}
+#line 355 "parser/faustparser.y"
+    { (yyval.cppstr) = new string(); ;}
     break;
 
   case 28:
-
-/* Line 1455 of yacc.c  */
-#line 350 "parser/faustparser.y"
-    { gStripDocSwitch = (yyvsp[(4) - (5)].b); gStripDocSwitch==true ? gStripDocSwitch=false : gStripDocSwitch=true; ;}
+#line 356 "parser/faustparser.y"
+    { (yyval.cppstr) = &((yyvsp[(1) - (2)].cppstr)->append(yytext)); ;}
     break;
 
   case 29:
-
-/* Line 1455 of yacc.c  */
-#line 351 "parser/faustparser.y"
-    { gLstDistributedSwitch = (yyvsp[(4) - (5)].b); ;}
+#line 359 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
     break;
 
   case 30:
-
-/* Line 1455 of yacc.c  */
-#line 354 "parser/faustparser.y"
-    { (yyval.b) = true; ;}
+#line 362 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
     break;
 
   case 31:
-
-/* Line 1455 of yacc.c  */
-#line 355 "parser/faustparser.y"
-    { (yyval.b) = false; ;}
+#line 365 "parser/faustparser.y"
+    { ;}
     break;
 
   case 32:
-
-/* Line 1455 of yacc.c  */
-#line 358 "parser/faustparser.y"
-    { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
+#line 368 "parser/faustparser.y"
+    { ;}
     break;
 
   case 33:
-
-/* Line 1455 of yacc.c  */
-#line 361 "parser/faustparser.y"
-    { (yyval.exp) = cons((yyvsp[(1) - (7)].exp),cons((yyvsp[(3) - (7)].exp),(yyvsp[(6) - (7)].exp))); ;}
+#line 371 "parser/faustparser.y"
+    { ;}
     break;
 
   case 34:
-
-/* Line 1455 of yacc.c  */
-#line 362 "parser/faustparser.y"
-    { (yyval.exp) = cons((yyvsp[(1) - (4)].exp),cons(nil,(yyvsp[(3) - (4)].exp))); ;}
+#line 372 "parser/faustparser.y"
+    { ;}
     break;
 
   case 35:
-
-/* Line 1455 of yacc.c  */
-#line 363 "parser/faustparser.y"
-    { (yyval.exp) = nil; yyerr++; ;}
+#line 375 "parser/faustparser.y"
+    { gLstDependenciesSwitch = (yyvsp[(4) - (5)].b); ;}
     break;
 
   case 36:
-
-/* Line 1455 of yacc.c  */
-#line 366 "parser/faustparser.y"
-    { (yyval.exp)=(yyvsp[(1) - (1)].exp); setDefProp((yyvsp[(1) - (1)].exp), yyfilename, yylineno); ;}
+#line 376 "parser/faustparser.y"
+    { gStripDocSwitch = (yyvsp[(4) - (5)].b); gStripDocSwitch==true ? gStripDocSwitch=false : gStripDocSwitch=true; ;}
     break;
 
   case 37:
-
-/* Line 1455 of yacc.c  */
-#line 369 "parser/faustparser.y"
-    { (yyval.exp) = cons((yyvsp[(1) - (1)].exp),nil); ;}
+#line 377 "parser/faustparser.y"
+    { gLstDistributedSwitch = (yyvsp[(4) - (5)].b); ;}
     break;
 
   case 38:
-
-/* Line 1455 of yacc.c  */
-#line 370 "parser/faustparser.y"
-    { (yyval.exp) = cons((yyvsp[(3) - (3)].exp),(yyvsp[(1) - (3)].exp)); ;}
+#line 380 "parser/faustparser.y"
+    { (yyval.b) = true; ;}
     break;
 
   case 39:
-
-/* Line 1455 of yacc.c  */
-#line 373 "parser/faustparser.y"
-    { (yyval.exp) = boxWithLocalDef((yyvsp[(1) - (5)].exp),formatDefinitions((yyvsp[(4) - (5)].exp))); ;}
+#line 381 "parser/faustparser.y"
+    { (yyval.b) = false; ;}
     break;
 
   case 40:
-
-/* Line 1455 of yacc.c  */
-#line 374 "parser/faustparser.y"
-    { (yyval.exp) = boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
+#line 384 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
     break;
 
   case 41:
-
-/* Line 1455 of yacc.c  */
-#line 375 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
+#line 387 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (7)].exp),cons((yyvsp[(3) - (7)].exp),(yyvsp[(6) - (7)].exp))); ;}
     break;
 
   case 42:
-
-/* Line 1455 of yacc.c  */
-#line 376 "parser/faustparser.y"
-    { (yyval.exp) = boxSplit((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
+#line 388 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (4)].exp),cons(nil,(yyvsp[(3) - (4)].exp))); ;}
     break;
 
   case 43:
-
-/* Line 1455 of yacc.c  */
-#line 377 "parser/faustparser.y"
-    { (yyval.exp) = boxMerge((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
+#line 389 "parser/faustparser.y"
+    { (yyval.exp) = nil; yyerr++; ;}
     break;
 
   case 44:
-
-/* Line 1455 of yacc.c  */
-#line 378 "parser/faustparser.y"
-    { (yyval.exp) = boxRec((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
+#line 392 "parser/faustparser.y"
+    { (yyval.exp)=(yyvsp[(1) - (1)].exp); setDefProp((yyvsp[(1) - (1)].exp), yyfilename, yylineno); ;}
     break;
 
   case 45:
-
-/* Line 1455 of yacc.c  */
-#line 379 "parser/faustparser.y"
-    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
+#line 395 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (1)].exp),nil); ;}
     break;
 
   case 46:
-
-/* Line 1455 of yacc.c  */
-#line 382 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigAdd)); ;}
+#line 396 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(3) - (3)].exp),(yyvsp[(1) - (3)].exp)); ;}
     break;
 
   case 47:
-
-/* Line 1455 of yacc.c  */
-#line 383 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigSub)); ;}
+#line 399 "parser/faustparser.y"
+    { (yyval.exp) = boxWithLocalDef((yyvsp[(1) - (5)].exp),formatDefinitions((yyvsp[(4) - (5)].exp))); ;}
     break;
 
   case 48:
-
-/* Line 1455 of yacc.c  */
-#line 384 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigMul)); ;}
+#line 400 "parser/faustparser.y"
+    { (yyval.exp) = boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
   case 49:
-
-/* Line 1455 of yacc.c  */
-#line 385 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigDiv)); ;}
+#line 401 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
   case 50:
-
-/* Line 1455 of yacc.c  */
-#line 386 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigRem)); ;}
+#line 402 "parser/faustparser.y"
+    { (yyval.exp) = boxSplit((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
   case 51:
-
-/* Line 1455 of yacc.c  */
-#line 387 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),gPowPrim->box()); ;}
+#line 403 "parser/faustparser.y"
+    { (yyval.exp) = boxMerge((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
   case 52:
-
-/* Line 1455 of yacc.c  */
-#line 388 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigFixDelay)); ;}
+#line 404 "parser/faustparser.y"
+    { (yyval.exp) = boxRec((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
   case 53:
-
-/* Line 1455 of yacc.c  */
-#line 389 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq((yyvsp[(1) - (2)].exp),boxPrim1(sigDelay1)); ;}
+#line 405 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
   case 54:
-
-/* Line 1455 of yacc.c  */
-#line 390 "parser/faustparser.y"
-    { (yyval.exp) = boxAccess((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
+#line 408 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigAdd)); ;}
     break;
 
   case 55:
-
-/* Line 1455 of yacc.c  */
-#line 392 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigAND)); ;}
+#line 409 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigSub)); ;}
     break;
 
   case 56:
-
-/* Line 1455 of yacc.c  */
-#line 393 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigOR)); ;}
+#line 410 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigMul)); ;}
     break;
 
   case 57:
-
-/* Line 1455 of yacc.c  */
-#line 394 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigXOR)); ;}
+#line 411 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigDiv)); ;}
     break;
 
   case 58:
-
-/* Line 1455 of yacc.c  */
-#line 396 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigLeftShift)); ;}
+#line 412 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigRem)); ;}
     break;
 
   case 59:
-
-/* Line 1455 of yacc.c  */
-#line 397 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigRightShift)); ;}
+#line 413 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),gPowPrim->box()); ;}
     break;
 
   case 60:
-
-/* Line 1455 of yacc.c  */
-#line 399 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigLT)); ;}
+#line 414 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigFixDelay)); ;}
     break;
 
   case 61:
-
-/* Line 1455 of yacc.c  */
-#line 400 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigLE)); ;}
+#line 415 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq((yyvsp[(1) - (2)].exp),boxPrim1(sigDelay1)); ;}
     break;
 
   case 62:
-
-/* Line 1455 of yacc.c  */
-#line 401 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigGT)); ;}
+#line 416 "parser/faustparser.y"
+    { (yyval.exp) = boxAccess((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
   case 63:
-
-/* Line 1455 of yacc.c  */
-#line 402 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigGE)); ;}
+#line 418 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigAND)); ;}
     break;
 
   case 64:
-
-/* Line 1455 of yacc.c  */
-#line 403 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigEQ)); ;}
+#line 419 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigOR)); ;}
     break;
 
   case 65:
-
-/* Line 1455 of yacc.c  */
-#line 404 "parser/faustparser.y"
-    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigNE)); ;}
+#line 420 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigXOR)); ;}
     break;
 
   case 66:
-
-/* Line 1455 of yacc.c  */
-#line 406 "parser/faustparser.y"
-    { (yyval.exp) = buildBoxAppl((yyvsp[(1) - (4)].exp),(yyvsp[(3) - (4)].exp)); ;}
+#line 422 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigLeftShift)); ;}
     break;
 
   case 67:
-
-/* Line 1455 of yacc.c  */
-#line 407 "parser/faustparser.y"
-    { (yyval.exp) = boxModifLocalDef((yyvsp[(1) - (4)].exp),formatDefinitions((yyvsp[(3) - (4)].exp))); ;}
+#line 423 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigRightShift)); ;}
     break;
 
   case 68:
-
-/* Line 1455 of yacc.c  */
-#line 409 "parser/faustparser.y"
-    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
+#line 425 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigLT)); ;}
     break;
 
   case 69:
-
-/* Line 1455 of yacc.c  */
-#line 412 "parser/faustparser.y"
-    { (yyval.exp) = boxInt(atoi(yytext)); ;}
+#line 426 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigLE)); ;}
     break;
 
   case 70:
-
-/* Line 1455 of yacc.c  */
-#line 413 "parser/faustparser.y"
-    { (yyval.exp) = boxReal(atof(yytext)); ;}
+#line 427 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigGT)); ;}
     break;
 
   case 71:
-
-/* Line 1455 of yacc.c  */
-#line 415 "parser/faustparser.y"
-    { (yyval.exp) = boxInt (atoi(yytext)); ;}
+#line 428 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigGE)); ;}
     break;
 
   case 72:
-
-/* Line 1455 of yacc.c  */
-#line 416 "parser/faustparser.y"
-    { (yyval.exp) = boxReal(atof(yytext)); ;}
+#line 429 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigEQ)); ;}
     break;
 
   case 73:
-
-/* Line 1455 of yacc.c  */
-#line 418 "parser/faustparser.y"
-    { (yyval.exp) = boxInt ( -atoi(yytext) ); ;}
+#line 430 "parser/faustparser.y"
+    { (yyval.exp) = boxSeq(boxPar((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)),boxPrim2(sigNE)); ;}
     break;
 
   case 74:
-
-/* Line 1455 of yacc.c  */
-#line 419 "parser/faustparser.y"
-    { (yyval.exp) = boxReal( -atof(yytext) ); ;}
+#line 432 "parser/faustparser.y"
+    { (yyval.exp) = buildBoxAppl((yyvsp[(1) - (4)].exp),(yyvsp[(3) - (4)].exp)); ;}
     break;
 
   case 75:
-
-/* Line 1455 of yacc.c  */
-#line 421 "parser/faustparser.y"
-    { (yyval.exp) = boxWire(); ;}
+#line 433 "parser/faustparser.y"
+    { (yyval.exp) = boxModifLocalDef((yyvsp[(1) - (4)].exp),formatDefinitions((yyvsp[(3) - (4)].exp))); ;}
     break;
 
   case 76:
-
-/* Line 1455 of yacc.c  */
-#line 422 "parser/faustparser.y"
-    { (yyval.exp) = boxCut(); ;}
+#line 435 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
   case 77:
-
-/* Line 1455 of yacc.c  */
-#line 424 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim1(sigDelay1); ;}
+#line 438 "parser/faustparser.y"
+    { (yyval.exp) = boxInt(atoi(yytext)); ;}
     break;
 
   case 78:
-
-/* Line 1455 of yacc.c  */
-#line 425 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigPrefix); ;}
+#line 439 "parser/faustparser.y"
+    { (yyval.exp) = boxReal(atof(yytext)); ;}
     break;
 
   case 79:
-
-/* Line 1455 of yacc.c  */
-#line 427 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim1(sigIntCast); ;}
+#line 441 "parser/faustparser.y"
+    { (yyval.exp) = boxInt (atoi(yytext)); ;}
     break;
 
   case 80:
-
-/* Line 1455 of yacc.c  */
-#line 428 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim1(sigFloatCast); ;}
+#line 442 "parser/faustparser.y"
+    { (yyval.exp) = boxReal(atof(yytext)); ;}
     break;
 
   case 81:
-
-/* Line 1455 of yacc.c  */
-#line 430 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigAdd); ;}
+#line 444 "parser/faustparser.y"
+    { (yyval.exp) = boxInt ( -atoi(yytext) ); ;}
     break;
 
   case 82:
-
-/* Line 1455 of yacc.c  */
-#line 431 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigSub); ;}
+#line 445 "parser/faustparser.y"
+    { (yyval.exp) = boxReal( -atof(yytext) ); ;}
     break;
 
   case 83:
-
-/* Line 1455 of yacc.c  */
-#line 432 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigMul); ;}
+#line 447 "parser/faustparser.y"
+    { (yyval.exp) = boxWire(); ;}
     break;
 
   case 84:
-
-/* Line 1455 of yacc.c  */
-#line 433 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigDiv); ;}
+#line 448 "parser/faustparser.y"
+    { (yyval.exp) = boxCut(); ;}
     break;
 
   case 85:
-
-/* Line 1455 of yacc.c  */
-#line 434 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigRem); ;}
+#line 450 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim1(sigDelay1); ;}
     break;
 
   case 86:
-
-/* Line 1455 of yacc.c  */
-#line 435 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigFixDelay); ;}
+#line 451 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigPrefix); ;}
     break;
 
   case 87:
-
-/* Line 1455 of yacc.c  */
-#line 437 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigAND); ;}
+#line 453 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim1(sigIntCast); ;}
     break;
 
   case 88:
-
-/* Line 1455 of yacc.c  */
-#line 438 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigOR); ;}
+#line 454 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim1(sigFloatCast); ;}
     break;
 
   case 89:
-
-/* Line 1455 of yacc.c  */
-#line 439 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigXOR); ;}
+#line 456 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigAdd); ;}
     break;
 
   case 90:
-
-/* Line 1455 of yacc.c  */
-#line 441 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigLeftShift); ;}
+#line 457 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigSub); ;}
     break;
 
   case 91:
-
-/* Line 1455 of yacc.c  */
-#line 442 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigRightShift); ;}
+#line 458 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigMul); ;}
     break;
 
   case 92:
-
-/* Line 1455 of yacc.c  */
-#line 444 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigLT); ;}
+#line 459 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigDiv); ;}
     break;
 
   case 93:
-
-/* Line 1455 of yacc.c  */
-#line 445 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigLE); ;}
+#line 460 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigRem); ;}
     break;
 
   case 94:
-
-/* Line 1455 of yacc.c  */
-#line 446 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigGT); ;}
+#line 461 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigFixDelay); ;}
     break;
 
   case 95:
-
-/* Line 1455 of yacc.c  */
-#line 447 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigGE); ;}
+#line 463 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigAND); ;}
     break;
 
   case 96:
-
-/* Line 1455 of yacc.c  */
-#line 448 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigEQ); ;}
+#line 464 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigOR); ;}
     break;
 
   case 97:
-
-/* Line 1455 of yacc.c  */
-#line 449 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigNE); ;}
+#line 465 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigXOR); ;}
     break;
 
   case 98:
-
-/* Line 1455 of yacc.c  */
-#line 451 "parser/faustparser.y"
-    { (yyval.exp) = boxPrim2(sigAttach); ;}
+#line 467 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigLeftShift); ;}
     break;
 
   case 99:
-
-/* Line 1455 of yacc.c  */
-#line 453 "parser/faustparser.y"
-    { (yyval.exp) = gAcosPrim->box(); ;}
+#line 468 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigRightShift); ;}
     break;
 
   case 100:
-
-/* Line 1455 of yacc.c  */
-#line 454 "parser/faustparser.y"
-    { (yyval.exp) = gAsinPrim->box(); ;}
+#line 470 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigLT); ;}
     break;
 
   case 101:
-
-/* Line 1455 of yacc.c  */
-#line 455 "parser/faustparser.y"
-    { (yyval.exp) = gAtanPrim->box(); ;}
+#line 471 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigLE); ;}
     break;
 
   case 102:
-
-/* Line 1455 of yacc.c  */
-#line 456 "parser/faustparser.y"
-    { (yyval.exp) = gAtan2Prim->box(); ;}
+#line 472 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigGT); ;}
     break;
 
   case 103:
-
-/* Line 1455 of yacc.c  */
-#line 457 "parser/faustparser.y"
-    { (yyval.exp) = gCosPrim->box(); ;}
+#line 473 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigGE); ;}
     break;
 
   case 104:
-
-/* Line 1455 of yacc.c  */
-#line 458 "parser/faustparser.y"
-    { (yyval.exp) = gSinPrim->box(); ;}
+#line 474 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigEQ); ;}
     break;
 
   case 105:
-
-/* Line 1455 of yacc.c  */
-#line 459 "parser/faustparser.y"
-    { (yyval.exp) = gTanPrim->box(); ;}
+#line 475 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigNE); ;}
     break;
 
   case 106:
-
-/* Line 1455 of yacc.c  */
-#line 461 "parser/faustparser.y"
-    { (yyval.exp) = gExpPrim->box(); ;}
+#line 477 "parser/faustparser.y"
+    { (yyval.exp) = boxPrim2(sigAttach); ;}
     break;
 
   case 107:
-
-/* Line 1455 of yacc.c  */
-#line 462 "parser/faustparser.y"
-    { (yyval.exp) = gLogPrim->box(); ;}
+#line 479 "parser/faustparser.y"
+    { (yyval.exp) = gAcosPrim->box(); ;}
     break;
 
   case 108:
-
-/* Line 1455 of yacc.c  */
-#line 463 "parser/faustparser.y"
-    { (yyval.exp) = gLog10Prim->box(); ;}
+#line 480 "parser/faustparser.y"
+    { (yyval.exp) = gAsinPrim->box(); ;}
     break;
 
   case 109:
-
-/* Line 1455 of yacc.c  */
-#line 464 "parser/faustparser.y"
-    { (yyval.exp) = gPowPrim->box(); ;}
+#line 481 "parser/faustparser.y"
+    { (yyval.exp) = gAtanPrim->box(); ;}
     break;
 
   case 110:
+#line 482 "parser/faustparser.y"
+    { (yyval.exp) = gAtan2Prim->box(); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 465 "parser/faustparser.y"
+  case 111:
+#line 483 "parser/faustparser.y"
+    { (yyval.exp) = gCosPrim->box(); ;}
+    break;
+
+  case 112:
+#line 484 "parser/faustparser.y"
+    { (yyval.exp) = gSinPrim->box(); ;}
+    break;
+
+  case 113:
+#line 485 "parser/faustparser.y"
+    { (yyval.exp) = gTanPrim->box(); ;}
+    break;
+
+  case 114:
+#line 487 "parser/faustparser.y"
+    { (yyval.exp) = gExpPrim->box(); ;}
+    break;
+
+  case 115:
+#line 488 "parser/faustparser.y"
+    { (yyval.exp) = gLogPrim->box(); ;}
+    break;
+
+  case 116:
+#line 489 "parser/faustparser.y"
+    { (yyval.exp) = gLog10Prim->box(); ;}
+    break;
+
+  case 117:
+#line 490 "parser/faustparser.y"
     { (yyval.exp) = gPowPrim->box(); ;}
     break;
 
-  case 111:
+  case 118:
+#line 491 "parser/faustparser.y"
+    { (yyval.exp) = gPowPrim->box(); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 466 "parser/faustparser.y"
+  case 119:
+#line 492 "parser/faustparser.y"
     { (yyval.exp) = gSqrtPrim->box(); ;}
     break;
 
-  case 112:
-
-/* Line 1455 of yacc.c  */
-#line 468 "parser/faustparser.y"
+  case 120:
+#line 494 "parser/faustparser.y"
     { (yyval.exp) = gAbsPrim->box(); ;}
     break;
 
-  case 113:
-
-/* Line 1455 of yacc.c  */
-#line 469 "parser/faustparser.y"
+  case 121:
+#line 495 "parser/faustparser.y"
     { (yyval.exp) = gMinPrim->box(); ;}
     break;
 
-  case 114:
-
-/* Line 1455 of yacc.c  */
-#line 470 "parser/faustparser.y"
+  case 122:
+#line 496 "parser/faustparser.y"
     { (yyval.exp) = gMaxPrim->box(); ;}
     break;
 
-  case 115:
-
-/* Line 1455 of yacc.c  */
-#line 472 "parser/faustparser.y"
+  case 123:
+#line 498 "parser/faustparser.y"
     { (yyval.exp) = gFmodPrim->box(); ;}
     break;
 
-  case 116:
-
-/* Line 1455 of yacc.c  */
-#line 473 "parser/faustparser.y"
+  case 124:
+#line 499 "parser/faustparser.y"
     { (yyval.exp) = gRemainderPrim->box(); ;}
     break;
 
-  case 117:
-
-/* Line 1455 of yacc.c  */
-#line 475 "parser/faustparser.y"
+  case 125:
+#line 501 "parser/faustparser.y"
     { (yyval.exp) = gFloorPrim->box(); ;}
     break;
 
-  case 118:
-
-/* Line 1455 of yacc.c  */
-#line 476 "parser/faustparser.y"
+  case 126:
+#line 502 "parser/faustparser.y"
     { (yyval.exp) = gCeilPrim->box(); ;}
     break;
 
-  case 119:
-
-/* Line 1455 of yacc.c  */
-#line 477 "parser/faustparser.y"
+  case 127:
+#line 503 "parser/faustparser.y"
     { (yyval.exp) = gRintPrim->box(); ;}
     break;
 
-  case 120:
-
-/* Line 1455 of yacc.c  */
-#line 480 "parser/faustparser.y"
+  case 128:
+#line 506 "parser/faustparser.y"
     { (yyval.exp) = boxPrim3(sigReadOnlyTable); ;}
     break;
 
-  case 121:
-
-/* Line 1455 of yacc.c  */
-#line 481 "parser/faustparser.y"
+  case 129:
+#line 507 "parser/faustparser.y"
     { (yyval.exp) = boxPrim5(sigWriteReadTable); ;}
     break;
 
-  case 122:
-
-/* Line 1455 of yacc.c  */
-#line 483 "parser/faustparser.y"
+  case 130:
+#line 509 "parser/faustparser.y"
     { (yyval.exp) = boxPrim3(sigSelect2); ;}
     break;
 
-  case 123:
-
-/* Line 1455 of yacc.c  */
-#line 484 "parser/faustparser.y"
+  case 131:
+#line 510 "parser/faustparser.y"
     { (yyval.exp) = boxPrim4(sigSelect3); ;}
     break;
 
-  case 124:
-
-/* Line 1455 of yacc.c  */
-#line 486 "parser/faustparser.y"
+  case 132:
+#line 512 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 125:
-
-/* Line 1455 of yacc.c  */
-#line 487 "parser/faustparser.y"
+  case 133:
+#line 513 "parser/faustparser.y"
     { (yyval.exp) = boxSeq(boxPar(boxInt(0),(yyvsp[(2) - (2)].exp)),boxPrim2(sigSub)); ;}
     break;
 
-  case 126:
-
-/* Line 1455 of yacc.c  */
-#line 489 "parser/faustparser.y"
+  case 134:
+#line 515 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(2) - (3)].exp); ;}
     break;
 
-  case 127:
-
-/* Line 1455 of yacc.c  */
-#line 491 "parser/faustparser.y"
+  case 135:
+#line 517 "parser/faustparser.y"
     { (yyval.exp) = buildBoxAbstr((yyvsp[(3) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 128:
-
-/* Line 1455 of yacc.c  */
-#line 493 "parser/faustparser.y"
+  case 136:
+#line 519 "parser/faustparser.y"
     { (yyval.exp) = boxCase(checkRulelist((yyvsp[(3) - (4)].exp))); ;}
     break;
 
-  case 129:
-
-/* Line 1455 of yacc.c  */
-#line 495 "parser/faustparser.y"
+  case 137:
+#line 521 "parser/faustparser.y"
     { (yyval.exp) = boxFFun((yyvsp[(1) - (1)].exp)); ;}
     break;
 
-  case 130:
-
-/* Line 1455 of yacc.c  */
-#line 496 "parser/faustparser.y"
+  case 138:
+#line 522 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 131:
-
-/* Line 1455 of yacc.c  */
-#line 497 "parser/faustparser.y"
+  case 139:
+#line 523 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 132:
-
-/* Line 1455 of yacc.c  */
-#line 498 "parser/faustparser.y"
+  case 140:
+#line 524 "parser/faustparser.y"
     { (yyval.exp) = boxComponent((yyvsp[(3) - (4)].exp)); ;}
     break;
 
-  case 133:
-
-/* Line 1455 of yacc.c  */
-#line 499 "parser/faustparser.y"
+  case 141:
+#line 525 "parser/faustparser.y"
     { (yyval.exp) = boxLibrary((yyvsp[(3) - (4)].exp)); ;}
     break;
 
-  case 134:
-
-/* Line 1455 of yacc.c  */
-#line 500 "parser/faustparser.y"
+  case 142:
+#line 526 "parser/faustparser.y"
     { (yyval.exp) = boxWithLocalDef(boxEnvironment(),formatDefinitions((yyvsp[(3) - (4)].exp))); ;}
     break;
 
-  case 135:
+  case 143:
+#line 527 "parser/faustparser.y"
+    { (yyval.exp) = boxWaveform(gWaveForm); gWaveForm.clear(); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 502 "parser/faustparser.y"
+  case 144:
+#line 529 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 136:
-
-/* Line 1455 of yacc.c  */
-#line 503 "parser/faustparser.y"
+  case 145:
+#line 530 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 137:
-
-/* Line 1455 of yacc.c  */
-#line 504 "parser/faustparser.y"
+  case 146:
+#line 531 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 138:
-
-/* Line 1455 of yacc.c  */
-#line 505 "parser/faustparser.y"
+  case 147:
+#line 532 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 139:
-
-/* Line 1455 of yacc.c  */
-#line 506 "parser/faustparser.y"
+  case 148:
+#line 533 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 140:
-
-/* Line 1455 of yacc.c  */
-#line 507 "parser/faustparser.y"
+  case 149:
+#line 534 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 141:
-
-/* Line 1455 of yacc.c  */
-#line 508 "parser/faustparser.y"
+  case 150:
+#line 535 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 142:
-
-/* Line 1455 of yacc.c  */
-#line 509 "parser/faustparser.y"
+  case 151:
+#line 536 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 143:
-
-/* Line 1455 of yacc.c  */
-#line 510 "parser/faustparser.y"
+  case 152:
+#line 537 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 144:
-
-/* Line 1455 of yacc.c  */
-#line 511 "parser/faustparser.y"
+  case 153:
+#line 538 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 145:
-
-/* Line 1455 of yacc.c  */
-#line 513 "parser/faustparser.y"
+  case 154:
+#line 540 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 146:
-
-/* Line 1455 of yacc.c  */
-#line 514 "parser/faustparser.y"
+  case 155:
+#line 541 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 147:
-
-/* Line 1455 of yacc.c  */
-#line 515 "parser/faustparser.y"
+  case 156:
+#line 542 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 148:
+  case 157:
+#line 543 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 516 "parser/faustparser.y"
+  case 158:
+#line 545 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 149:
+  case 159:
+#line 546 "parser/faustparser.y"
+    { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 520 "parser/faustparser.y"
+  case 160:
+#line 551 "parser/faustparser.y"
     { (yyval.exp) = boxIdent(yytext); ;}
     break;
 
-  case 150:
-
-/* Line 1455 of yacc.c  */
-#line 523 "parser/faustparser.y"
+  case 161:
+#line 554 "parser/faustparser.y"
     { (yyval.exp) = tree(yytext); ;}
     break;
 
-  case 151:
-
-/* Line 1455 of yacc.c  */
-#line 528 "parser/faustparser.y"
+  case 162:
+#line 559 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(1) - (1)].exp),nil); ;}
     break;
 
-  case 152:
-
-/* Line 1455 of yacc.c  */
-#line 529 "parser/faustparser.y"
+  case 163:
+#line 560 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(3) - (3)].exp),(yyvsp[(1) - (3)].exp)); ;}
     break;
 
-  case 153:
-
-/* Line 1455 of yacc.c  */
-#line 532 "parser/faustparser.y"
+  case 164:
+#line 563 "parser/faustparser.y"
     { (yyval.exp) = boxSeq((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
-  case 154:
-
-/* Line 1455 of yacc.c  */
-#line 533 "parser/faustparser.y"
+  case 165:
+#line 564 "parser/faustparser.y"
     { (yyval.exp) = boxSplit((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
-  case 155:
-
-/* Line 1455 of yacc.c  */
-#line 534 "parser/faustparser.y"
+  case 166:
+#line 565 "parser/faustparser.y"
     { (yyval.exp) = boxMerge((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
-  case 156:
-
-/* Line 1455 of yacc.c  */
-#line 535 "parser/faustparser.y"
+  case 167:
+#line 566 "parser/faustparser.y"
     { (yyval.exp) = boxRec((yyvsp[(1) - (3)].exp),(yyvsp[(3) - (3)].exp)); ;}
     break;
 
-  case 157:
-
-/* Line 1455 of yacc.c  */
-#line 536 "parser/faustparser.y"
+  case 168:
+#line 567 "parser/faustparser.y"
     { (yyval.exp) = (yyvsp[(1) - (1)].exp); ;}
     break;
 
-  case 158:
-
-/* Line 1455 of yacc.c  */
-#line 539 "parser/faustparser.y"
+  case 169:
+#line 570 "parser/faustparser.y"
     { (yyval.exp) = tree(yytext); ;}
     break;
 
-  case 159:
-
-/* Line 1455 of yacc.c  */
-#line 542 "parser/faustparser.y"
+  case 170:
+#line 573 "parser/faustparser.y"
     { (yyval.exp) = unquote(yytext); ;}
     break;
 
-  case 160:
-
-/* Line 1455 of yacc.c  */
-#line 545 "parser/faustparser.y"
+  case 171:
+#line 576 "parser/faustparser.y"
     { (yyval.exp) = tree(yytext); ;}
     break;
 
-  case 161:
-
-/* Line 1455 of yacc.c  */
-#line 546 "parser/faustparser.y"
+  case 172:
+#line 577 "parser/faustparser.y"
     { (yyval.exp) = tree(yytext); ;}
     break;
 
-  case 162:
-
-/* Line 1455 of yacc.c  */
-#line 552 "parser/faustparser.y"
+  case 173:
+#line 583 "parser/faustparser.y"
     { (yyval.exp) = boxIPar((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 163:
-
-/* Line 1455 of yacc.c  */
-#line 556 "parser/faustparser.y"
+  case 174:
+#line 587 "parser/faustparser.y"
     { (yyval.exp) = boxISeq((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 164:
-
-/* Line 1455 of yacc.c  */
-#line 560 "parser/faustparser.y"
+  case 175:
+#line 591 "parser/faustparser.y"
     { (yyval.exp) = boxISum((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 165:
-
-/* Line 1455 of yacc.c  */
-#line 564 "parser/faustparser.y"
+  case 176:
+#line 595 "parser/faustparser.y"
     { (yyval.exp) = boxIProd((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 166:
+  case 177:
+#line 599 "parser/faustparser.y"
+    { (yyval.exp) = boxInputs((yyvsp[(3) - (4)].exp)); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 571 "parser/faustparser.y"
-    { (yyval.exp) = ffunction((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
+  case 178:
+#line 602 "parser/faustparser.y"
+    { (yyval.exp) = boxOutputs((yyvsp[(3) - (4)].exp)); ;}
     break;
 
-  case 167:
+  case 179:
+#line 610 "parser/faustparser.y"
+    { (yyval.exp) = ffunction((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 575 "parser/faustparser.y"
+  case 180:
+#line 614 "parser/faustparser.y"
     { (yyval.exp) = boxFConst((yyvsp[(3) - (7)].exp),(yyvsp[(4) - (7)].exp),(yyvsp[(6) - (7)].exp)); ;}
     break;
 
-  case 168:
-
-/* Line 1455 of yacc.c  */
-#line 578 "parser/faustparser.y"
+  case 181:
+#line 617 "parser/faustparser.y"
     { (yyval.exp) = boxFVar((yyvsp[(3) - (7)].exp),(yyvsp[(4) - (7)].exp),(yyvsp[(6) - (7)].exp)); ;}
     break;
 
-  case 169:
-
-/* Line 1455 of yacc.c  */
-#line 582 "parser/faustparser.y"
+  case 182:
+#line 621 "parser/faustparser.y"
     { (yyval.exp) = boxButton((yyvsp[(3) - (4)].exp)); ;}
     break;
 
-  case 170:
-
-/* Line 1455 of yacc.c  */
-#line 585 "parser/faustparser.y"
+  case 183:
+#line 624 "parser/faustparser.y"
     { (yyval.exp) = boxCheckbox((yyvsp[(3) - (4)].exp)); ;}
     break;
 
-  case 171:
-
-/* Line 1455 of yacc.c  */
-#line 589 "parser/faustparser.y"
+  case 184:
+#line 628 "parser/faustparser.y"
     { (yyval.exp) = boxVSlider((yyvsp[(3) - (12)].exp),(yyvsp[(5) - (12)].exp),(yyvsp[(7) - (12)].exp),(yyvsp[(9) - (12)].exp),(yyvsp[(11) - (12)].exp)); ;}
     break;
 
-  case 172:
-
-/* Line 1455 of yacc.c  */
-#line 592 "parser/faustparser.y"
+  case 185:
+#line 631 "parser/faustparser.y"
     { (yyval.exp) = boxHSlider((yyvsp[(3) - (12)].exp),(yyvsp[(5) - (12)].exp),(yyvsp[(7) - (12)].exp),(yyvsp[(9) - (12)].exp),(yyvsp[(11) - (12)].exp)); ;}
     break;
 
-  case 173:
-
-/* Line 1455 of yacc.c  */
-#line 595 "parser/faustparser.y"
+  case 186:
+#line 634 "parser/faustparser.y"
     { (yyval.exp) = boxNumEntry((yyvsp[(3) - (12)].exp),(yyvsp[(5) - (12)].exp),(yyvsp[(7) - (12)].exp),(yyvsp[(9) - (12)].exp),(yyvsp[(11) - (12)].exp)); ;}
     break;
 
-  case 174:
-
-/* Line 1455 of yacc.c  */
-#line 598 "parser/faustparser.y"
+  case 187:
+#line 637 "parser/faustparser.y"
     { (yyval.exp) = boxVGroup((yyvsp[(3) - (6)].exp), (yyvsp[(5) - (6)].exp)); ;}
     break;
 
-  case 175:
-
-/* Line 1455 of yacc.c  */
-#line 601 "parser/faustparser.y"
+  case 188:
+#line 640 "parser/faustparser.y"
     { (yyval.exp) = boxHGroup((yyvsp[(3) - (6)].exp), (yyvsp[(5) - (6)].exp)); ;}
     break;
 
-  case 176:
-
-/* Line 1455 of yacc.c  */
-#line 604 "parser/faustparser.y"
+  case 189:
+#line 643 "parser/faustparser.y"
     { (yyval.exp) = boxTGroup((yyvsp[(3) - (6)].exp), (yyvsp[(5) - (6)].exp)); ;}
     break;
 
-  case 177:
-
-/* Line 1455 of yacc.c  */
-#line 608 "parser/faustparser.y"
+  case 190:
+#line 647 "parser/faustparser.y"
     { (yyval.exp) = boxVBargraph((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 178:
-
-/* Line 1455 of yacc.c  */
-#line 611 "parser/faustparser.y"
+  case 191:
+#line 650 "parser/faustparser.y"
     { (yyval.exp) = boxHBargraph((yyvsp[(3) - (8)].exp),(yyvsp[(5) - (8)].exp),(yyvsp[(7) - (8)].exp)); ;}
     break;
 
-  case 179:
+  case 192:
+#line 656 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (5)].exp), cons(cons((yyvsp[(2) - (5)].exp),cons((yyvsp[(2) - (5)].exp),cons((yyvsp[(2) - (5)].exp),nil))), (yyvsp[(4) - (5)].exp))); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 616 "parser/faustparser.y"
-    { (yyval.exp) = cons((yyvsp[(1) - (5)].exp), cons((yyvsp[(2) - (5)].exp), (yyvsp[(4) - (5)].exp))); ;}
+  case 193:
+#line 657 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (7)].exp), cons(cons((yyvsp[(2) - (7)].exp),cons((yyvsp[(4) - (7)].exp),cons((yyvsp[(4) - (7)].exp),nil))), (yyvsp[(6) - (7)].exp))); ;}
     break;
 
-  case 180:
+  case 194:
+#line 658 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (9)].exp), cons(cons((yyvsp[(2) - (9)].exp),cons((yyvsp[(4) - (9)].exp),cons((yyvsp[(6) - (9)].exp),nil))), (yyvsp[(8) - (9)].exp))); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 617 "parser/faustparser.y"
-    { (yyval.exp) = cons((yyvsp[(1) - (4)].exp), cons((yyvsp[(2) - (4)].exp), nil)); ;}
+  case 195:
+#line 660 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (4)].exp), cons(cons((yyvsp[(2) - (4)].exp),cons((yyvsp[(2) - (4)].exp),cons((yyvsp[(2) - (4)].exp),nil))), nil)); ;}
     break;
 
-  case 181:
+  case 196:
+#line 661 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (6)].exp), cons(cons((yyvsp[(2) - (6)].exp),cons((yyvsp[(4) - (6)].exp),cons((yyvsp[(4) - (6)].exp),nil))), nil)); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 620 "parser/faustparser.y"
-    { (yyval.exp) = tree(yytext); ;}
+  case 197:
+#line 662 "parser/faustparser.y"
+    { (yyval.exp) = cons((yyvsp[(1) - (8)].exp), cons(cons((yyvsp[(2) - (8)].exp),cons((yyvsp[(4) - (8)].exp),cons((yyvsp[(6) - (8)].exp),nil))), nil)); ;}
     break;
 
-  case 182:
+  case 198:
+#line 665 "parser/faustparser.y"
+    { (yyval.exp) = tree(yytext); ;}
+    break;
 
-/* Line 1455 of yacc.c  */
-#line 623 "parser/faustparser.y"
+  case 199:
+#line 668 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(1) - (1)].exp),nil); ;}
     break;
 
-  case 183:
-
-/* Line 1455 of yacc.c  */
-#line 624 "parser/faustparser.y"
+  case 200:
+#line 669 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(3) - (3)].exp),(yyvsp[(1) - (3)].exp)); ;}
     break;
 
-  case 184:
-
-/* Line 1455 of yacc.c  */
-#line 627 "parser/faustparser.y"
+  case 201:
+#line 672 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(1) - (1)].exp),nil); ;}
     break;
 
-  case 185:
-
-/* Line 1455 of yacc.c  */
-#line 628 "parser/faustparser.y"
+  case 202:
+#line 673 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(2) - (2)].exp),(yyvsp[(1) - (2)].exp)); ;}
     break;
 
-  case 186:
-
-/* Line 1455 of yacc.c  */
-#line 632 "parser/faustparser.y"
+  case 203:
+#line 677 "parser/faustparser.y"
     { (yyval.exp) = cons((yyvsp[(2) - (6)].exp),(yyvsp[(5) - (6)].exp)); ;}
     break;
 
-  case 187:
-
-/* Line 1455 of yacc.c  */
-#line 635 "parser/faustparser.y"
+  case 204:
+#line 680 "parser/faustparser.y"
     { (yyval.exp) = tree(0); ;}
     break;
 
-  case 188:
-
-/* Line 1455 of yacc.c  */
-#line 636 "parser/faustparser.y"
+  case 205:
+#line 681 "parser/faustparser.y"
     { (yyval.exp) = tree(1); ;}
     break;
 
 
-
-/* Line 1455 of yacc.c  */
-#line 3242 "parser/faustparser.cpp"
+/* Line 1267 of yacc.c.  */
+#line 3106 "parser/faustparser.cpp"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -3249,6 +3113,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
+
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
@@ -3313,7 +3178,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse lookahead token after an
+      /* If just tried and failed to reuse look-ahead token after an
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -3330,7 +3195,7 @@ yyerrlab:
 	}
     }
 
-  /* Else will try to reuse lookahead token after shifting the error
+  /* Else will try to reuse look-ahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -3387,6 +3252,9 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   *++yyvsp = yylval;
 
 
@@ -3411,7 +3279,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -3422,7 +3290,7 @@ yyexhaustedlab:
 #endif
 
 yyreturn:
-  if (yychar != YYEMPTY)
+  if (yychar != YYEOF && yychar != YYEMPTY)
      yydestruct ("Cleanup: discarding lookahead",
 		 yytoken, &yylval);
   /* Do not reclaim the symbols of the rule which action triggered
@@ -3448,9 +3316,7 @@ yyreturn:
 }
 
 
-
-/* Line 1675 of yacc.c  */
-#line 639 "parser/faustparser.y"
+#line 684 "parser/faustparser.y"
 
 
 
diff --git a/compiler/parser/faustparser.hpp b/compiler/parser/faustparser.hpp
index aee0aad..6f77632 100644
--- a/compiler/parser/faustparser.hpp
+++ b/compiler/parser/faustparser.hpp
@@ -1,23 +1,24 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
 /* Skeleton interface for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+
+   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 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -28,11 +29,10 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -126,64 +126,184 @@
      COMPONENT = 342,
      LIBRARY = 343,
      ENVIRONMENT = 344,
-     IPAR = 345,
-     ISEQ = 346,
-     ISUM = 347,
-     IPROD = 348,
-     STRING = 349,
-     FSTRING = 350,
-     IDENT = 351,
-     EXTRA = 352,
-     DECLARE = 353,
-     CASE = 354,
-     ARROW = 355,
-     BDOC = 356,
-     EDOC = 357,
-     BEQN = 358,
-     EEQN = 359,
-     BDGM = 360,
-     EDGM = 361,
-     BLST = 362,
-     ELST = 363,
-     BMETADATA = 364,
-     EMETADATA = 365,
-     DOCCHAR = 366,
-     NOTICE = 367,
-     LISTING = 368,
-     LSTTRUE = 369,
-     LSTFALSE = 370,
-     LSTDEPENDENCIES = 371,
-     LSTMDOCTAGS = 372,
-     LSTDISTRIBUTED = 373,
-     LSTEQ = 374,
-     LSTQ = 375
+     WAVEFORM = 345,
+     IPAR = 346,
+     ISEQ = 347,
+     ISUM = 348,
+     IPROD = 349,
+     INPUTS = 350,
+     OUTPUTS = 351,
+     STRING = 352,
+     FSTRING = 353,
+     IDENT = 354,
+     EXTRA = 355,
+     DECLARE = 356,
+     CASE = 357,
+     ARROW = 358,
+     BDOC = 359,
+     EDOC = 360,
+     BEQN = 361,
+     EEQN = 362,
+     BDGM = 363,
+     EDGM = 364,
+     BLST = 365,
+     ELST = 366,
+     BMETADATA = 367,
+     EMETADATA = 368,
+     DOCCHAR = 369,
+     NOTICE = 370,
+     LISTING = 371,
+     LSTTRUE = 372,
+     LSTFALSE = 373,
+     LSTDEPENDENCIES = 374,
+     LSTMDOCTAGS = 375,
+     LSTDISTRIBUTED = 376,
+     LSTEQ = 377,
+     LSTQ = 378
    };
 #endif
+/* Tokens.  */
+#define WITH 258
+#define MIX 259
+#define SPLIT 260
+#define SEQ 261
+#define PAR 262
+#define REC 263
+#define NE 264
+#define GE 265
+#define GT 266
+#define EQ 267
+#define LE 268
+#define LT 269
+#define OR 270
+#define SUB 271
+#define ADD 272
+#define RSH 273
+#define LSH 274
+#define XOR 275
+#define AND 276
+#define MOD 277
+#define DIV 278
+#define MUL 279
+#define POWOP 280
+#define FDELAY 281
+#define DELAY1 282
+#define DOT 283
+#define APPL 284
+#define MEM 285
+#define PREFIX 286
+#define INTCAST 287
+#define FLOATCAST 288
+#define FFUNCTION 289
+#define FCONSTANT 290
+#define FVARIABLE 291
+#define BUTTON 292
+#define CHECKBOX 293
+#define VSLIDER 294
+#define HSLIDER 295
+#define NENTRY 296
+#define VGROUP 297
+#define HGROUP 298
+#define TGROUP 299
+#define HBARGRAPH 300
+#define VBARGRAPH 301
+#define ATTACH 302
+#define ACOS 303
+#define ASIN 304
+#define ATAN 305
+#define ATAN2 306
+#define COS 307
+#define SIN 308
+#define TAN 309
+#define EXP 310
+#define LOG 311
+#define LOG10 312
+#define POWFUN 313
+#define SQRT 314
+#define ABS 315
+#define MIN 316
+#define MAX 317
+#define FMOD 318
+#define REMAINDER 319
+#define FLOOR 320
+#define CEIL 321
+#define RINT 322
+#define RDTBL 323
+#define RWTBL 324
+#define SELECT2 325
+#define SELECT3 326
+#define INT 327
+#define FLOAT 328
+#define LAMBDA 329
+#define WIRE 330
+#define CUT 331
+#define ENDDEF 332
+#define VIRG 333
+#define LPAR 334
+#define RPAR 335
+#define LBRAQ 336
+#define RBRAQ 337
+#define LCROC 338
+#define RCROC 339
+#define DEF 340
+#define IMPORT 341
+#define COMPONENT 342
+#define LIBRARY 343
+#define ENVIRONMENT 344
+#define WAVEFORM 345
+#define IPAR 346
+#define ISEQ 347
+#define ISUM 348
+#define IPROD 349
+#define INPUTS 350
+#define OUTPUTS 351
+#define STRING 352
+#define FSTRING 353
+#define IDENT 354
+#define EXTRA 355
+#define DECLARE 356
+#define CASE 357
+#define ARROW 358
+#define BDOC 359
+#define EDOC 360
+#define BEQN 361
+#define EEQN 362
+#define BDGM 363
+#define EDGM 364
+#define BLST 365
+#define ELST 366
+#define BMETADATA 367
+#define EMETADATA 368
+#define DOCCHAR 369
+#define NOTICE 370
+#define LISTING 371
+#define LSTTRUE 372
+#define LSTFALSE 373
+#define LSTDEPENDENCIES 374
+#define LSTMDOCTAGS 375
+#define LSTDISTRIBUTED 376
+#define LSTEQ 377
+#define LSTQ 378
+
 
 
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-
-/* Line 1676 of yacc.c  */
 #line 78 "parser/faustparser.y"
-
+{
 	CTree* 	exp;
 	char* str;
 	string* cppstr;
 	bool b;
-
-
-
-/* Line 1676 of yacc.c  */
-#line 181 "parser/faustparser.hpp"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1529 of yacc.c.  */
+#line 302 "parser/faustparser.hpp"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE yylval;
 
-
diff --git a/compiler/parser/faustparser.y b/compiler/parser/faustparser.y
index 16a74b7..9774961 100644
--- a/compiler/parser/faustparser.y
+++ b/compiler/parser/faustparser.y
@@ -34,8 +34,8 @@ extern bool         gLstDistributedSwitch;
 extern bool        	gLstMdocTagsSwitch;
 	
 extern map<Tree, set<Tree> > gMetaDataSet;
-extern vector<Tree> gDocVector;
-
+extern vector<Tree>          gDocVector;
+extern tvec                  gWaveForm; 
 
 int yylex();
 
@@ -186,12 +186,16 @@ Tree unquote(char* str)
 %token COMPONENT
 %token LIBRARY
 %token ENVIRONMENT
+%token WAVEFORM
 
 %token IPAR
 %token ISEQ
 %token ISUM
 %token IPROD
 
+%token INPUTS
+%token OUTPUTS
+
 %token STRING
 %token FSTRING
 %token IDENT
@@ -233,6 +237,7 @@ Tree unquote(char* str)
 %type <exp> statement
 
 %type <exp> deflist
+%type <exp> vallist
 %type <exp> definition
 
 %type <exp> params
@@ -243,6 +248,7 @@ Tree unquote(char* str)
 %type <exp> infixexp
 %type <exp> primitive
 %type <exp> argument
+%type <exp> number
 %type <exp> arglist
 
 %type <exp> ident
@@ -264,6 +270,9 @@ Tree unquote(char* str)
 %type <exp> fsum
 %type <exp> fprod
 
+%type <exp> finputs
+%type <exp> foutputs
+
 %type <exp> button
 %type <exp> checkbox
 %type <exp> vslider
@@ -298,16 +307,33 @@ Tree unquote(char* str)
 
 %% /* grammar rules and actions follow */
 
-program         : stmtlist 						{ $$ = $1; gResult = formatDefinitions($$); }
+program         : stmtlist                              { $$ = $1; gResult = formatDefinitions($$); }
 				;
 
-stmtlist        : /*empty*/                     { $$ = nil; }
-				| stmtlist statement            { $$ = cons ($2,$1); }
+stmtlist        : /*empty*/                             { $$ = nil; }
+				| stmtlist statement                    { $$ = cons ($2,$1); }
 
-deflist         : /*empty*/                     { $$ = nil; }
-				| deflist definition            { $$ = cons ($2,$1); }
+deflist         : /*empty*/                             { $$ = nil; }
+				| deflist definition                    { $$ = cons ($2,$1); }
 				;
 
+// vallist      : argument                              { $$ = cons($1,nil); }
+// 				| argument PAR vallist                  { $$ = cons ($1,$3); }
+// 				;
+// 
+vallist         : number                                { gWaveForm.push_back($1); }
+                | vallist PAR number                    { gWaveForm.push_back($3); }
+                ;
+
+number			: INT   						{ $$ = boxInt(atoi(yytext)); }
+				| FLOAT 						{ $$ = boxReal(atof(yytext)); }
+				| ADD INT   					{ $$ = boxInt (atoi(yytext)); }
+				| ADD FLOAT 					{ $$ = boxReal(atof(yytext)); }
+				| SUB INT   					{ $$ = boxInt ( -atoi(yytext) ); }
+				| SUB FLOAT 					{ $$ = boxReal( -atof(yytext) ); }				
+				;
+				
+				
 statement       : IMPORT LPAR uqstring RPAR ENDDEF	   	{ $$ = importFile($3); }
 				| DECLARE name string  ENDDEF		   	{ declareMetadata($2,$3); $$ = nil; }
 				| definition						   	{ $$ = $1; }
@@ -497,7 +523,8 @@ primitive		: INT   						{ $$ = boxInt(atoi(yytext)); }
                 | fvariable                     { $$ = $1; }
                 | COMPONENT LPAR uqstring RPAR  { $$ = boxComponent($3); }
                 | LIBRARY LPAR uqstring RPAR    { $$ = boxLibrary($3); }
-                | ENVIRONMENT LBRAQ deflist RBRAQ { $$ = boxWithLocalDef(boxEnvironment(),formatDefinitions($3)); }
+                | ENVIRONMENT LBRAQ stmtlist RBRAQ { $$ = boxWithLocalDef(boxEnvironment(),formatDefinitions($3)); }
+                | WAVEFORM LBRAQ vallist RBRAQ  { $$ = boxWaveform(gWaveForm); gWaveForm.clear(); }
 
 				| button						{ $$ = $1; }
 				| checkbox						{ $$ = $1; }
@@ -514,6 +541,10 @@ primitive		: INT   						{ $$ = boxInt(atoi(yytext)); }
 				| fseq							{ $$ = $1; }
 				| fsum							{ $$ = $1; }
 				| fprod							{ $$ = $1; }
+				
+				| finputs						{ $$ = $1; }
+				| foutputs						{ $$ = $1; }
+				
 				;
 
 
@@ -565,6 +596,14 @@ fprod			: IPROD LPAR ident PAR argument PAR expression RPAR
 				;
 
 
+finputs			: INPUTS LPAR expression RPAR { $$ = boxInputs($3); }
+				;
+
+foutputs		: OUTPUTS LPAR expression RPAR { $$ = boxOutputs($3); }
+				;
+
+				
+
 /* description of foreign functions */
 
 ffunction		: FFUNCTION LPAR signature PAR fstring PAR string RPAR
@@ -612,10 +651,16 @@ hbargraph		: HBARGRAPH LPAR uqstring PAR argument PAR argument RPAR
 				;
 
 /* Description of foreign functions */
+/* float sinhf|sinh|sinhl(float) */
 
-signature		: type fun LPAR typelist RPAR	{ $$ = cons($1, cons($2, $4)); }
-				| type fun LPAR RPAR			{ $$ = cons($1, cons($2, nil)); }
-				;
+signature		: type fun LPAR typelist RPAR               { $$ = cons($1, cons(cons($2,cons($2,cons($2,nil))), $4)); }
+                | type fun OR fun LPAR typelist RPAR        { $$ = cons($1, cons(cons($2,cons($4,cons($4,nil))), $6)); }
+                | type fun OR fun OR fun LPAR typelist RPAR	{ $$ = cons($1, cons(cons($2,cons($4,cons($6,nil))), $8)); }
+
+                | type fun LPAR RPAR                        { $$ = cons($1, cons(cons($2,cons($2,cons($2,nil))), nil)); }
+                | type fun OR fun LPAR RPAR                 { $$ = cons($1, cons(cons($2,cons($4,cons($4,nil))), nil)); }
+                | type fun OR fun OR fun LPAR RPAR			{ $$ = cons($1, cons(cons($2,cons($4,cons($6,nil))), nil)); }
+                ;
 
 fun				: IDENT							{ $$ = tree(yytext); }
 				;
diff --git a/compiler/parser/sourcefetcher.cpp b/compiler/parser/sourcefetcher.cpp
new file mode 100644
index 0000000..99ea6b8
--- /dev/null
+++ b/compiler/parser/sourcefetcher.cpp
@@ -0,0 +1,839 @@
+/*
+ * http_fetcher.c - HTTP handling functions
+ * 
+ * HTTP Fetcher Copyright (C) 2001, 2003, 2004 Lyle Hanson
+ * (lhanson at users.sourceforge.net)
+ * 
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Library General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+ * License for more details.
+ * 
+ * See LICENSE file for details
+ * 
+ * --------------------------------- Modified by Yann Orlarey, Grame to be used
+ * within Faust (2013/01/23)
+ * 
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#ifndef WIN32
+#include <strings.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#else
+#include <winsock2.h>
+#define close closesocket
+#define write(s, buf, len) send(s, buf, (int)(len), 0)
+#define read(s, buf, len) recv(s, buf, (int)(len), 0)
+#define rindex strchr
+#define herror perror
+#endif
+#include "compatibility.hh"
+#include "sourcefetcher.hh"
+
+#define VERSION "0"
+
+/* Globals */
+int		timeout = DEFAULT_READ_TIMEOUT;
+char    *userAgent = NULL;
+char    *referer = NULL;
+int		hideUserAgent = 0;
+int		hideReferer = 1;
+static int	followRedirects = DEFAULT_REDIRECTS;	/* # of redirects to
+							 * follow */
+extern const char *http_errlist[];	/* Array of HTTP Fetcher error
+					 * messages */
+extern char	convertedError[128];	/* Buffer to used when errors contain
+					 * %d */
+static int	errorSource = 0;
+static int	http_errno = 0;
+static int	errorInt = 0;	/* When the error message has a %d in it,
+				 * this variable is inserted */
+
+const char     *http_errlist[] =
+{
+	"Success",		/* HF_SUCCESS		 */
+	"Internal Error. What the hell?!",	/* HF_METAERROR		 */
+	"Got NULL url",		/* HF_NULLURL		 */
+	"Timed out, no metadata for %d seconds",	/* HF_HEADTIMEOUT 	 */
+	"Timed out, no data for %d seconds",	/* HF_DATATIMEOUT	 */
+	"Couldn't find return code in HTTP response",	/* HF_FRETURNCODE	 */
+	"Couldn't convert return code in HTTP response",	/* HF_CRETURNCODE	 */
+	"Request returned a status code of %d",	/* HF_STATUSCODE	 */
+	"Couldn't convert Content-Length to integer",	/* HF_CONTENTLEN	 */
+	"Network error (description unavailable)",	/* HF_HERROR		 */
+	"Status code of %d but no Location: field",	/* HF_CANTREDIRECT  */
+	"Followed the maximum number of redirects (%d)"	/* HF_MAXREDIRECTS  */
+};
+
+/*
+ * Used to copy in messages from http_errlist[] and replace %d's with the
+ * value of errorInt.  Then we can pass the pointer to THIS
+ */
+char		convertedError[128];
+
+/*
+ * Actually downloads the page, registering a hit (donation) If the fileBuf
+ * passed in is NULL, the url is downloaded and then freed; otherwise the
+ * necessary space is allocated for fileBuf. Returns size of download on
+ * success, -1 on error is set,
+ */
+int http_fetch(const char *url_tmp, char **fileBuf)
+{
+	fd_set	rfds;
+	struct timeval	tv;
+	char	headerBuf [HEADER_BUF_SIZE];
+	char    *tmp, *url, *pageBuf, *requestBuf = NULL, *host, *charIndex;
+	int		sock, bytesRead = 0, contentLength = -1, bufsize = REQUEST_BUF_SIZE;
+	int		i, ret = -1, tempSize, selectRet, found = 0,	/* For redirects */
+			redirectsFollowed = 0;
+
+
+	if (url_tmp == NULL) {
+		errorSource = FETCHER_ERROR;
+		http_errno = HF_NULLURL;
+		return -1;
+	}
+	/*
+	 * Copy the url passed in into a buffer we can work with, change,
+	 * etc.
+	 */
+	url = (char *)malloc(strlen(url_tmp) + 1);
+	if (url == NULL) {
+		errorSource = ERRNO;
+		return -1;
+	}
+	strncpy(url, url_tmp, strlen(url_tmp) + 1);
+
+	/*
+	 * This loop allows us to follow redirects if need be.  An
+	 * afterthought, added to provide this basic functionality.  Will
+	 * hopefully be designed better in 2.x.x ;)
+	 */
+	/*
+	 * while(!found && (followRedirects < 0 || redirectsFollowed <
+	 * followRedirects) )
+	 */
+	do {
+		/* Seek to the file path portion of the url */
+		charIndex = strstr(url, "://");
+		if (charIndex != NULL) {
+			/* url contains a protocol field */
+			charIndex += strlen("://");
+			host = charIndex;
+			charIndex = strchr(charIndex, '/');
+		} else {
+			host = (char *)url;
+			charIndex = strchr(url, '/');
+		}
+
+		/* Compose a request string */
+		requestBuf = (char *)malloc(bufsize);
+		if (requestBuf == NULL) {
+			free(url);
+			errorSource = ERRNO;
+			return -1;
+		}
+		requestBuf[0] = 0;
+
+		if (charIndex == NULL) {
+			/*
+			 * The url has no '/' in it, assume the user is
+			 * making a root-level request
+			 */
+			tempSize = (int)strlen("GET /") + (int)strlen(HTTP_VERSION) + 2;
+			if (_checkBufSize(&requestBuf, &bufsize, tempSize) ||
+			    snprintf(requestBuf, bufsize, "GET / %s\r\n", HTTP_VERSION) < 0) {
+				free(url);
+				free(requestBuf);
+				errorSource = ERRNO;
+				return -1;
+			}
+		} else {
+			tempSize = (int)strlen("GET ") + (int)strlen(charIndex) +
+				(int)strlen(HTTP_VERSION) + 4;
+			/* + 4 is for ' ', '\r', '\n', and NULL */
+
+			if (_checkBufSize(&requestBuf, &bufsize, tempSize) ||
+			    snprintf(requestBuf, bufsize, "GET %s %s\r\n",
+				     charIndex, HTTP_VERSION) < 0) {
+				free(url);
+				free(requestBuf);
+				errorSource = ERRNO;
+				return -1;
+			}
+		}
+
+		/* Null out the end of the hostname if need be */
+		if (charIndex != NULL)
+			*charIndex = 0;
+
+		/*
+		 * Use Host: even though 1.0 doesn't specify it.  Some
+		 * servers won't play nice if we don't send Host, and it
+		 * shouldn't hurt anything
+		 */
+		ret = (int)bufsize - (int)strlen(requestBuf);	/* Space left in buffer */
+		tempSize = (int)strlen("Host: ") + (int)strlen(host) + 3;
+		/* +3 for "\r\n\0" */
+		if (_checkBufSize(&requestBuf, &bufsize, tempSize + 128)) {
+			free(url);
+			free(requestBuf);
+			errorSource = ERRNO;
+			return -1;
+		}
+		strcat(requestBuf, "Host: ");
+		strcat(requestBuf, host);
+		strcat(requestBuf, "\r\n");
+
+		if (!hideReferer && referer != NULL) {	/* NO default referer */
+			tempSize = (int)strlen("Referer: ") + (int)strlen(referer) + 3;
+			/* + 3 is for '\r', '\n', and NULL */
+			if (_checkBufSize(&requestBuf, &bufsize, tempSize)) {
+				free(url);
+				free(requestBuf);
+				errorSource = ERRNO;
+				return -1;
+			}
+			strcat(requestBuf, "Referer: ");
+			strcat(requestBuf, referer);
+			strcat(requestBuf, "\r\n");
+		}
+		if (!hideUserAgent && userAgent == NULL) {
+			tempSize = (int)strlen("User-Agent: ") +
+				(int)strlen(DEFAULT_USER_AGENT) + (int)strlen(VERSION) + 4;
+			/* + 4 is for '\', '\r', '\n', and NULL */
+			if (_checkBufSize(&requestBuf, &bufsize, tempSize)) {
+				free(url);
+				free(requestBuf);
+				errorSource = ERRNO;
+				return -1;
+			}
+			strcat(requestBuf, "User-Agent: ");
+			strcat(requestBuf, DEFAULT_USER_AGENT);
+			strcat(requestBuf, "/");
+			strcat(requestBuf, VERSION);
+			strcat(requestBuf, "\r\n");
+		} else if (!hideUserAgent) {
+			tempSize = (int)strlen("User-Agent: ") + (int)strlen(userAgent) + 3;
+			/* + 3 is for '\r', '\n', and NULL */
+			if (_checkBufSize(&requestBuf, &bufsize, tempSize)) {
+				free(url);
+				free(requestBuf);
+				errorSource = ERRNO;
+				return -1;
+			}
+			strcat(requestBuf, "User-Agent: ");
+			strcat(requestBuf, userAgent);
+			strcat(requestBuf, "\r\n");
+		}
+		tempSize = (int)strlen("Connection: Close\r\n\r\n");
+		if (_checkBufSize(&requestBuf, &bufsize, tempSize)) {
+			free(url);
+			free(requestBuf);
+			errorSource = ERRNO;
+			return -1;
+		}
+		strcat(requestBuf, "Connection: Close\r\n\r\n");
+
+		/* Now free any excess memory allocated to the buffer */
+		tmp = (char *)realloc(requestBuf, strlen(requestBuf) + 1);
+		if (tmp == NULL) {
+			free(url);
+			free(requestBuf);
+			errorSource = ERRNO;
+			return -1;
+		}
+		requestBuf = tmp;
+
+		sock = makeSocket(host);	/* errorSource set within
+						 * makeSocket */
+		if (sock == -1) {
+			free(url);
+			free(requestBuf);
+			return -1;
+		}
+		free(url);
+		url = NULL;
+
+		if (write(sock, requestBuf, strlen(requestBuf)) == -1) {
+			close(sock);
+			free(requestBuf);
+			errorSource = ERRNO;
+			return -1;
+		}
+		free(requestBuf);
+		requestBuf = NULL;
+
+		/* Grab enough of the response to get the metadata */
+		ret = _http_read_header(sock, headerBuf);	/* errorSource set
+								 * within */
+		if (ret < 0) {
+			close(sock);
+			return -1;
+		}
+		/* Get the return code */
+		charIndex = strstr(headerBuf, "HTTP/");
+		if (charIndex == NULL) {
+			close(sock);
+			errorSource = FETCHER_ERROR;
+			http_errno = HF_FRETURNCODE;
+			return -1;
+		}
+		while (*charIndex != ' ')
+			charIndex++;
+		charIndex++;
+
+		ret = sscanf(charIndex, "%d", &i);
+		if (ret != 1) {
+			close(sock);
+			errorSource = FETCHER_ERROR;
+			http_errno = HF_CRETURNCODE;
+			return -1;
+		}
+		if (i < 200 || i > 307) {
+			close(sock);
+			errorInt = i;	/* Status code, to be inserted in
+					 * error string */
+			errorSource = FETCHER_ERROR;
+			http_errno = HF_STATUSCODE;
+			return -1;
+		}
+		/*
+		 * If a redirect, repeat operation until final URL is found
+		 * or we redirect followRedirects times.  Note the case
+		 * sensitive "Location", should probably be made more robust
+		 * in the future (without relying on the non-standard
+		 * strcasecmp()). This bit mostly by Dean Wilder, tweaked by
+		 * me
+		 */
+		if (i >= 300) {
+			redirectsFollowed++;
+
+			/*
+			 * Pick up redirect URL, allocate new url, and repeat
+			 * process
+			 */
+			charIndex = strstr(headerBuf, "Location:");
+			if (!charIndex) {
+				close(sock);
+				errorInt = i;	/* Status code, to be
+						 * inserted in error string */
+				errorSource = FETCHER_ERROR;
+				http_errno = HF_CANTREDIRECT;
+				return -1;
+			}
+			charIndex += strlen("Location:");
+			/* Skip any whitespace... */
+			while (*charIndex != '\0' && isspace(*charIndex))
+				charIndex++;
+			if (*charIndex == '\0') {
+				close(sock);
+				errorInt = i;	/* Status code, to be
+						 * inserted in error string */
+				errorSource = FETCHER_ERROR;
+				http_errno = HF_CANTREDIRECT;
+				return -1;
+			}
+			i = (int)strcspn(charIndex, " \r\n");
+			if (i > 0) {
+				url = (char *)malloc(i + 1);
+				strncpy(url, charIndex, i);
+				url[i] = '\0';
+			} else
+				/*
+				 * Found 'Location:' but contains no URL!
+				 * We'll handle it as 'found', hopefully the
+				 * resulting document will give the user a
+				 * hint as to what happened.
+				 */
+				found = 1;
+		} else {
+			found = 1;
+		}
+	} while (!found && (followRedirects < 0 || redirectsFollowed <= followRedirects));
+
+	if (url) {		/* Redirection code may malloc this, then
+				 * exceed followRedirects */
+		free(url);
+		url = NULL;
+	}
+	if (redirectsFollowed >= followRedirects && !found) {
+		close(sock);
+		errorInt = followRedirects;	/* To be inserted in error
+						 * string */
+		errorSource = FETCHER_ERROR;
+		http_errno = HF_MAXREDIRECTS;
+		return -1;
+	}
+	/*
+	 * Parse out about how big the data segment is. Note that under
+	 * current HTTP standards (1.1 and prior), the Content-Length field
+	 * is not guaranteed to be accurate or even present. I just use it
+	 * here so I can allocate a ballpark amount of memory.
+	 * 
+	 * Note that some servers use different capitalization
+	 */
+	charIndex = strstr(headerBuf, "Content-Length:");
+	if (charIndex == NULL)
+		charIndex = strstr(headerBuf, "Content-length:");
+
+	if (charIndex != NULL) {
+		ret = sscanf(charIndex + strlen("content-length: "), "%d",
+			     &contentLength);
+		if (ret < 1) {
+			close(sock);
+			errorSource = FETCHER_ERROR;
+			http_errno = HF_CONTENTLEN;
+			return -1;
+		}
+	}
+	/* Allocate enough memory to hold the page */
+	if (contentLength == -1)
+		contentLength = DEFAULT_PAGE_BUF_SIZE;
+
+	pageBuf = (char *)malloc(contentLength);
+	if (pageBuf == NULL) {
+		close(sock);
+		errorSource = ERRNO;
+		return -1;
+	}
+	/* Begin reading the body of the file */
+	while (ret > 0) {
+		FD_ZERO(&rfds);
+		FD_SET(sock, &rfds);
+		tv.tv_sec = timeout;
+		tv.tv_usec = 0;
+
+		if (timeout >= 0)
+			selectRet = select(sock + 1, &rfds, NULL, NULL, &tv);
+		else		/* No timeout, can block indefinately */
+			selectRet = select(sock + 1, &rfds, NULL, NULL, NULL);
+
+		if (selectRet == 0) {
+			errorSource = FETCHER_ERROR;
+			http_errno = HF_DATATIMEOUT;
+			errorInt = timeout;
+			close(sock);
+			free(pageBuf);
+			return -1;
+		} else if (selectRet == -1) {
+			close(sock);
+			free(pageBuf);
+			errorSource = ERRNO;
+			return -1;
+		}
+		ret = read(sock, pageBuf + bytesRead, contentLength);
+		if (ret == -1) {
+			close(sock);
+			free(pageBuf);
+			errorSource = ERRNO;
+			return -1;
+		}
+		bytesRead += ret;
+
+		if (ret > 0) {
+			/*
+			 * To be tolerant of inaccurate Content-Length
+			 * fields, we'll allocate another read-sized chunk to
+			 * make sure we have enough room.
+			 */
+			tmp = (char *)realloc(pageBuf, bytesRead + contentLength);
+			if (tmp == NULL) {
+				close(sock);
+				free(pageBuf);
+				errorSource = ERRNO;
+				return -1;
+			}
+			pageBuf = tmp;
+		}
+	}
+
+	/*
+	 * The download buffer is too large.  Trim off the safety padding.
+	 * Note that we add one NULL byte to the end of the data, as it may
+	 * not already be NULL terminated and we can't be sure what type of
+	 * data it is or what the caller will do with it.
+	 */
+	tmp = (char *)realloc(pageBuf, bytesRead + 1);
+	/*
+	 * tmp shouldn't be null, since we're _shrinking_ the buffer, and if
+	 * it DID fail, we could go on with the too-large buffer, but
+	 * something would DEFINATELY be wrong, so we'll just give an error
+	 * message
+	 */
+	if (tmp == NULL) {
+		close(sock);
+		free(pageBuf);
+		errorSource = ERRNO;
+		return -1;
+	}
+	pageBuf = tmp;
+	pageBuf[bytesRead] = '\0';	/* NULL terminate the data */
+
+	if (fileBuf == NULL)	/* They just wanted us to "hit" the url */
+		free(pageBuf);
+	else
+		*fileBuf = pageBuf;
+
+	close(sock);
+	return bytesRead;
+}
+
+
+
+/*
+ * Changes the User Agent.  Returns 0 on success, -1 on error.
+ */
+int http_setUserAgent(const char *newAgent)
+{
+	static int	freeOldAgent = 0;	/* Indicates previous
+						 * malloc's */
+	char           *tmp;
+
+	if (newAgent == NULL) {
+		if (freeOldAgent)
+			free(userAgent);
+		userAgent = NULL;
+		hideUserAgent = 1;
+	} else {
+		tmp = (char *)malloc(strlen(newAgent));
+		if (tmp == NULL) {
+			errorSource = ERRNO;
+			return -1;
+		}
+		if (freeOldAgent)
+			free(userAgent);
+		userAgent = tmp;
+		strcpy(userAgent, newAgent);
+		freeOldAgent = 1;
+		hideUserAgent = 0;
+	}
+
+	return 0;
+}
+
+
+
+/*
+ * Changes the Referer.  Returns 0 on success, -1 on error
+ */
+int http_setReferer(const char *newReferer)
+{
+	static int	freeOldReferer = 0;	/* Indicated previous
+						 * malloc's */
+	char           *tmp;
+
+	if (newReferer == NULL) {
+		if (freeOldReferer)
+			free(referer);
+		referer = NULL;
+		hideReferer = 1;
+	} else {
+		tmp = (char *)malloc(strlen(newReferer));
+		if (tmp == NULL) {
+			errorSource = ERRNO;
+			return -1;
+		}
+		if (freeOldReferer)
+			free(referer);
+		referer = tmp;
+		strcpy(referer, newReferer);
+		freeOldReferer = 1;
+		hideReferer = 0;
+	}
+
+	return 0;
+}
+
+
+
+/*
+ * Changes the amount of time that HTTP Fetcher will wait for data before
+ * timing out on reads
+ */
+void http_setTimeout(int seconds)
+{
+	timeout = seconds;
+}
+
+
+
+/*
+ * Changes the number of HTTP redirects HTTP Fetcher will automatically
+ * follow.  If a request returns a status code of 3XX and contains a
+ * "Location:" field, the library will transparently follow up to the
+ * specified number of redirects.  With this implementation (which is just a
+ * stopgap, really) the caller won't be aware of any redirection and will
+ * assume the returned document came from the original URL. To disable
+ * redirects, pass a 0.  To follow unlimited redirects (probably unwise),
+ * pass a negative value.  The default is to follow 3 redirects.
+ */
+void http_setRedirects(int redirects)
+{
+	followRedirects = redirects;
+}
+
+
+
+/*
+ * Puts the filename portion of the url into 'filename'. Returns: 0 on
+ * success 1 when url contains no end filename (i.e., 'www.foo.com/'), and
+ * **filename should not be assumed to be valid -1 on error
+ */
+int http_parseFilename(const char *url, char **filename)
+{
+	char           *ptr;
+
+	if (url == NULL) {
+		errorSource = FETCHER_ERROR;
+		http_errno = HF_NULLURL;
+		return -1;
+	}
+	ptr = (char *)rindex(url, '/');
+	if (ptr == NULL)
+		/* Root level request, apparently */
+		return 1;
+
+	ptr++;
+	if (*ptr == '\0')
+		return 1;
+
+	*filename = (char *)malloc(strlen(ptr));
+	if (*filename == NULL) {
+		errorSource = ERRNO;
+		return -1;
+	}
+	strcpy(*filename, ptr);
+
+	return 0;
+}
+
+
+
+/*
+ * Depending on the source of error, calls either perror() or prints an HTTP
+ * Fetcher error message to stdout
+ */
+void http_perror(const char *string)
+{
+	if (errorSource == ERRNO)
+		perror(string);
+	else if (errorSource == H_ERRNO)
+		herror(string);
+	else if (errorSource == FETCHER_ERROR) {
+		const char     *stringIndex;
+
+		if (strstr(http_errlist[http_errno], "%d") == NULL) {
+			fputs(string, stderr);
+			fputs(": ", stderr);
+			fputs(http_errlist[http_errno], stderr);
+			fputs("\n", stderr);
+		} else {
+			/*
+			 * The error string has a %d in it, we need to insert
+			 * errorInt
+			 */
+			stringIndex = http_errlist[http_errno];
+			while (*stringIndex != '%') {	/* Print up to the %d */
+				fputc(*stringIndex, stderr);
+				stringIndex++;
+			}
+			fprintf(stderr, "%d", errorInt);	/* Print the number */
+			stringIndex += 2;	/* Skip past the %d */
+			while (*stringIndex != 0) {	/* Print up to the end
+							 * NULL */
+				fputc(*stringIndex, stderr);
+				stringIndex++;
+			}
+			fputs("\n", stderr);
+		}
+	}
+}
+
+
+
+/*
+ * Returns a pointer to the current error description message. The message
+ * pointed to is only good until the next call to http_strerror(), so if you
+ * need to hold on to the message for a while you should make a copy of it
+ */
+const char* http_strerror()
+{
+	extern int	errno;
+
+	if (errorSource == ERRNO)
+		return strerror(errno);
+	else if (errorSource == H_ERRNO)
+#ifdef HAVE_HSTRERROR
+		return hstrerror(h_errno);
+#else
+		return http_errlist[HF_HERROR];
+#endif
+	else if (errorSource == FETCHER_ERROR) {
+		if (strstr(http_errlist[http_errno], "%d") == NULL)
+			return http_errlist[http_errno];
+		else {
+			/*
+			 * The error string has a %d in it, we need to insert
+			 * errorInt. convertedError[128] has been declared
+			 * for that purpose
+			 */
+			char           *stringIndex, *originalError;
+
+			originalError = (char *)http_errlist[http_errno];
+			convertedError[0] = 0;	/* Start off with NULL */
+			stringIndex = strstr(originalError, "%d");
+			strncat(convertedError, originalError,	/* Copy up to %d */
+                labs(stringIndex - originalError));
+			sprintf(&convertedError[strlen(convertedError)], "%d", errorInt);
+			stringIndex += 2;	/* Skip past the %d */
+			strcat(convertedError, stringIndex);
+
+			return convertedError;
+		}
+	}
+	return http_errlist[HF_METAERROR];	/* Should NEVER happen */
+}
+
+
+/*
+ * Reads the metadata of an HTTP response. Perhaps a little inefficient, as
+ * it reads 1 byte at a time, but I don't think it's that much of a loss
+ * (most headers aren't HUGE). Returns: # of bytes read on success, or -1 on
+ * error
+ */
+int _http_read_header(int sock, char *headerPtr)
+{
+	fd_set		rfds;
+	struct timeval	tv;
+	int		bytesRead = 0, newlines = 0, ret, selectRet;
+
+	while (newlines != 2 && bytesRead != HEADER_BUF_SIZE) {
+		FD_ZERO(&rfds);
+		FD_SET(sock, &rfds);
+		tv.tv_sec = timeout;
+		tv.tv_usec = 0;
+
+		if (timeout >= 0)
+			selectRet = select(sock + 1, &rfds, NULL, NULL, &tv);
+		else		/* No timeout, can block indefinately */
+			selectRet = select(sock + 1, &rfds, NULL, NULL, NULL);
+
+		if (selectRet == 0) {
+			errorSource = FETCHER_ERROR;
+			http_errno = HF_HEADTIMEOUT;
+			errorInt = timeout;
+			return -1;
+		} else if (selectRet == -1) {
+			errorSource = ERRNO;
+			return -1;
+		}
+		ret = read(sock, headerPtr, 1);
+		if (ret == -1) {
+			errorSource = ERRNO;
+			return -1;
+		}
+		bytesRead++;
+
+		if (*headerPtr == '\r') {	/* Ignore CR */
+			/*
+			 * Basically do nothing special, just don't set
+			 * newlines to 0
+			 */
+			headerPtr++;
+			continue;
+		} else if (*headerPtr == '\n')	/* LF is the separator */
+			newlines++;
+		else
+			newlines = 0;
+
+		headerPtr++;
+	}
+
+	headerPtr -= 3;		/* Snip the trailing LF's */
+	*headerPtr = '\0';
+	return bytesRead;
+}
+
+
+
+/*
+ * Opens a TCP socket and returns the descriptor Returns: socket descriptor,
+ * or -1 on error
+ */
+int makeSocket(char *host)
+{
+	int		sock;	/* Socket descriptor */
+	struct sockaddr_in sa;	/* Socket address */
+	struct hostent *hp;	/* Host entity */
+	int		ret;
+	int		port;
+	char           *p;
+
+	/* Check for port number specified in URL */
+	p = strchr(host, ':');
+	if (p) {
+		port = atoi(p + 1);
+		*p = '\0';
+	} else
+		port = PORT_NUMBER;
+
+	hp = gethostbyname(host);
+	if (hp == NULL) {
+		errorSource = H_ERRNO;
+		return -1;
+	}
+	/* Copy host address from hostent to (server) socket address */
+	memcpy((char *)&sa.sin_addr, (char *)hp->h_addr, hp->h_length);
+	sa.sin_family = hp->h_addrtype;	/* Set service sin_family to PF_INET */
+	sa.sin_port = htons(port);	/* Put portnum into sockaddr */
+
+	sock = (int)socket(hp->h_addrtype, SOCK_STREAM, 0);
+	if (sock == -1) {
+		errorSource = ERRNO;
+		return -1;
+	}
+	ret = connect(sock, (struct sockaddr *)&sa, sizeof(sa));
+	if (ret == -1) {
+		errorSource = ERRNO;
+		return -1;
+	}
+	return sock;
+}
+
+
+
+/*
+ * Determines if the given NULL-terminated buffer is large enough to
+ * concatenate the given number of characters.  If not, it attempts to grow
+ * the buffer to fit. Returns: 0 on success, or -1 on error (original buffer
+ * is unchanged).
+ */
+int _checkBufSize(char **buf, int *bufsize, int more)
+{
+	char           *tmp;
+	int		roomLeft = (int)*bufsize - (int)(strlen(*buf) + 1);
+	if (roomLeft > more)
+		return 0;
+	tmp = (char *)realloc(*buf, *bufsize + more + 1);
+	if (tmp == NULL)
+		return -1;
+	*buf = tmp;
+	*bufsize += more + 1;
+	return 0;
+}
diff --git a/compiler/parser/sourcefetcher.hh b/compiler/parser/sourcefetcher.hh
new file mode 100644
index 0000000..3269240
--- /dev/null
+++ b/compiler/parser/sourcefetcher.hh
@@ -0,0 +1,176 @@
+/* http_fetcher.h - HTTP handling functions
+
+	HTTP Fetcher
+	Copyright (C) 2001, 2003, 2004 Lyle Hanson (lhanson at users.sourceforge.net)
+
+	This library is free software; you can redistribute it and/or
+	modify it under the terms of the GNU Library General Public
+	License as published by the Free Software Foundation; either
+	version 2 of the License, or (at your option) any later version.
+
+	This library is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+	Library General Public License for more details.
+
+	See LICENSE file for details
+									
+ */
+
+#ifndef HTTP_FETCHER_H
+#define HTTP_FETCHER_H
+
+/* Error sources */
+#define FETCHER_ERROR	0
+#define ERRNO			1
+#define H_ERRNO			2
+
+/* HTTP Fetcher error codes */
+#define HF_SUCCESS		0
+#define HF_METAERROR	1
+#define HF_NULLURL		2
+#define HF_HEADTIMEOUT	3
+#define HF_DATATIMEOUT	4
+#define HF_FRETURNCODE	5
+#define HF_CRETURNCODE	6
+#define HF_STATUSCODE	7
+#define HF_CONTENTLEN	8
+#define HF_HERROR		9
+#define HF_CANTREDIRECT 10
+#define HF_MAXREDIRECTS 11
+
+#define PORT_NUMBER 			80
+#define HTTP_VERSION 			"HTTP/1.0"
+#define DEFAULT_USER_AGENT		"HTTP Fetcher"
+#define DEFAULT_READ_TIMEOUT	30		/* Seconds to wait before giving up
+										 *	when no data is arriving */
+	 
+#define REQUEST_BUF_SIZE 		1024
+#define HEADER_BUF_SIZE 		1024
+#define DEFAULT_PAGE_BUF_SIZE 	1024 * 200	/* 200K should hold most things */
+#define DEFAULT_REDIRECTS       3       /* Number of HTTP redirects to follow */
+
+
+
+/******************************************************************************/
+/**************** Function declarations and descriptions **********************/
+/******************************************************************************/
+
+/* 
+ * [!!! NOTE !!!]  All HTTP Fetcher functions return -1 on error.  You can
+ *	then either call http_perror to print the error message or call
+ *	http_strerror to get a pointer to it
+ */
+
+
+	/*
+	 * Download the page, registering a hit. If you pass it a NULL for fileBuf,
+	 *	'url' will be requested but will not remain in memory (useful for
+	 *	simply registering a hit).  Otherwise necessary space will be allocated
+	 *	and will be pointed to by fileBuf.  Note that a NULL byte is added to
+     *  the data, so the actual buffer will be the file size + 1.
+	 * Returns:
+	 *	# of bytes downloaded, or
+	 *	-1 on error
+	 */
+int http_fetch(const char *url, char **fileBuf);
+
+	/*
+	 * Changes the User Agent (shown to the web server with each request)
+	 *	Send it NULL to avoid telling the server a User Agent
+	 *	By default, the User Agent is sent (The default one unless changed)
+	 * Returns:
+	 *	0 on success, or
+	 *	-1 on error (previous value for agent remains unchanged)
+	 */
+int http_setUserAgent(const char *newAgent);
+
+	/*
+	 * Changes the Referer (shown to the web server with each request)
+	 *	Send it NULL to avoid thelling the server a Referer
+	 *	By default, no Referer is sent
+	 * Returns:
+	 *	0 on success, or
+	 *	-1 on error
+	 */
+int http_setReferer(const char *newReferer);
+
+	/*
+	 * Changes the maximum amount of time that HTTP Fetcher will wait on
+	 *	data.  If this many seconds elapses without more data from the
+	 *	server, http_fetch will return with an error.
+	 * If you pass a value less than 0, reads will not time out, potentially
+	 *	waiting forever (or until data shows up, whichever comes first)
+	 */
+void http_setTimeout(int seconds);
+
+	/*
+	 * Changes the number of HTTP redirects HTTP Fetcher will automatically
+	 *	follow.  If a request returns a status code of 3XX and contains
+	 *	a "Location:" field, the library will transparently follow up to
+	 *	the specified number of redirects.  With this implementation
+	 *	(which is just a stopgap, really) the caller won't be aware of any
+	 *	redirection and will assume the returned document came from the original
+	 *	URL.
+	 * To disable redirects, pass a 0.  To follow unlimited redirects (probably
+	 *  unwise), pass a negative value.  The default is to follow 3 redirects.
+	 */
+void http_setRedirects(int redirects);
+
+	/*
+	 * Takes a url and puts the filename portion of it into 'filename'.
+	 * Returns:
+	 *	0 on success, or
+	 *	1 when url contains no end filename (i.e., "www.foo.com/")
+	 *		and **filename should not be assumed to point to anything), or
+	 *	-1 on error
+	 */
+int http_parseFilename(const char *url, char **filename);
+
+	/*
+	 * Works like perror.  If an HTTP Fetcher function ever returns an
+	 *	error (-1), this will print a descriptive message to standard output
+	 */
+void http_perror(const char *string);
+
+	/*
+	 * Returns a pointer to the current error description message.  The
+	 *	message pointed to is only good until the next call to http_strerror(),
+	 *	so if you need to hold on to the message for a while you should make
+	 *	a copy of it.
+	 */
+const char *http_strerror();
+
+
+
+/******************************************************************************/
+/**** The following functions are used INTERNALLY by http_fetcher *************/
+/******************************************************************************/
+
+	/*
+	 * Reads the metadata of an HTTP response.  On success returns the number
+	 * Returns:
+	 *	# of bytes read on success, or
+	 *	-1 on error
+	 */
+int _http_read_header(int sock, char *headerPtr);
+
+	/*
+	 * Opens a TCP socket and returns the descriptor
+	 * Returns:
+	 *	socket descriptor, or
+	 *	-1 on error
+	 */
+int makeSocket(char *host);
+
+	/*
+	 * Determines if the given NULL-terminated buffer is large enough to
+	 *	concatenate the given number of characters.  If not, it attempts to
+	 *	grow the buffer to fit.
+	 * Returns:
+	 *	0 on success, or
+	 *	-1 on error (original buffer is unchanged).
+	 */
+int _checkBufSize(char **buf, int *bufsize, int more);
+
+#endif
diff --git a/compiler/parser/sourcereader.cpp b/compiler/parser/sourcereader.cpp
index 66b6f22..10b091a 100644
--- a/compiler/parser/sourcereader.cpp
+++ b/compiler/parser/sourcereader.cpp
@@ -12,6 +12,7 @@
 
 
 #include "sourcereader.hh"
+#include "sourcefetcher.hh"
 #include "enrobage.hh"
 #include "ppbox.hh"
 
@@ -28,6 +29,8 @@ extern bool gLatexDocSwitch;
 
 
 int yyparse();
+void yyrestart( FILE *new_file );
+struct yy_buffer_state* yy_scan_string (const char *yy_str  ); // In principle YY_BUFFER_STATE
 
 extern int 		yyerr;
 extern int 		yydebug;
@@ -186,29 +189,62 @@ Tree formatDefinitions(Tree rldef)
 Tree SourceReader::parse(string fname)
 {
 	string	fullpath;
+    char*   fileBuf = 0;
 	
 	yyerr = 0;
 	
 	yyfilename = fname.c_str();
-	yyin = fopensearch(yyfilename, fullpath);
-	if (yyin == NULL) {
-		fprintf(stderr, "ERROR : Unable to open file  %s \n", yyfilename); 
-		exit(1);
-	}
-	
-	yylineno = 1;
-	int r = yyparse();
-	if (r) { 
-		fprintf(stderr, "Parse error : code = %d \n", r); 
-	}
-	if (yyerr > 0) {
-		//fprintf(stderr, "Erreur de parsing 2, count = %d \n", yyerr); 
-		exit(1);
-	}
+    if (strstr(yyfilename,"http://") != 0) {
+        // We are requested to parse an URL file
+        int ret = http_fetch(yyfilename, &fileBuf);
+        if (ret == -1) {
+            http_perror("http fetch");
+            exit(1);
+        }
+        yy_scan_string(fileBuf);
+        yylineno = 1;
+        int r = yyparse();
+        if (r) {
+            fprintf(stderr, "Parse error : code = %d \n", r);
+        }
+        if (yyerr > 0) {
+            //fprintf(stderr, "Erreur de parsing 2, count = %d \n", yyerr);
+            exit(1);
+        }
+        
+        // we have parsed a valid file
+        fFilePathnames.push_back(fullpath);
+        free(fileBuf);
+        return gResult;
 
-	// we have parsed a valid file
-	fFilePathnames.push_back(fullpath);
-	return gResult;
+    } else {
+		// test for local url
+		if (strstr(yyfilename,"file://") != 0) {
+			yyfilename  = &yyfilename[7]; // skip 'file://'
+		}
+		
+        // We are requested to parse a regular file
+        FILE* tmp_file = yyin = fopensearch(yyfilename, fullpath);
+        if (yyin == NULL) {
+            fprintf(stderr, "ERROR : Unable to open file  %s \n", yyfilename); 
+            exit(1);
+        }
+        yyrestart(yyin);	// make sure we scan from file again (in case we scanned a string just before)
+        yylineno = 1;
+        int r = yyparse();
+        if (r) { 
+            fprintf(stderr, "Parse error : code = %d \n", r); 
+        }
+        if (yyerr > 0) {
+            //fprintf(stderr, "Erreur de parsing 2, count = %d \n", yyerr); 
+            exit(1);
+        }
+
+        // we have parsed a valid file
+        fFilePathnames.push_back(fullpath);
+        fclose(tmp_file);
+        return gResult;
+    }
 }
 
 
diff --git a/compiler/parser/sourcereader.hh b/compiler/parser/sourcereader.hh
index aecfba6..1e286ff 100644
--- a/compiler/parser/sourcereader.hh
+++ b/compiler/parser/sourcereader.hh
@@ -19,9 +19,9 @@ class SourceReader
 	vector<string>		fFilePathnames;
 	Tree parse(string fname);
 	Tree expandrec(Tree ldef, set<string>& visited, Tree lresult);
+	bool cached(string fname);
 	
 public:
-	bool cached(string fname);
 	Tree getlist(string fname);
 	Tree expandlist(Tree ldef);
 	vector<string>	listSrcFiles();
diff --git a/compiler/patternmatcher/patternmatcher.cpp b/compiler/patternmatcher/patternmatcher.cpp
index d1ff39c..4711246 100644
--- a/compiler/patternmatcher/patternmatcher.cpp
+++ b/compiler/patternmatcher/patternmatcher.cpp
@@ -61,7 +61,7 @@ typedef vector<int> Path;
 
 static Tree subtree(Tree X, int i, const Path& p)
 {
-  int n = p.size();
+  int n = (int)p.size();
   Node op(0);
   Tree x0, x1;
   if (i < n && isBoxPatternOp(X, op, x0, x1))
@@ -191,7 +191,7 @@ struct Automaton {
   Automaton() : state(vector<State*>()), rhs(vector<Tree>()), s(0) {}
 
   // number of rules
-  int n_rules() { return rhs.size(); }
+  int n_rules() { return (int)rhs.size(); }
   // markers of rules still active in state s
   const list<Rule>& rules(int s) { return state[s]->rules; }
   // transitions in state s
@@ -527,7 +527,7 @@ Automaton *make_pattern_matcher(Tree R)
      it is *not* enough to just check the rule lists of final states and
      determine whether they have multiple matched rules. */
   for (r = 0; r < n; r++) {
-    int s = 0, m = testpats[r].size();
+    int s = 0, m = (int)testpats[r].size();
     Tree C;
     vector<Tree> E(n, nil);
     /* try to match the lhs of rule #r */
diff --git a/compiler/propagate/propagate.cpp b/compiler/propagate/propagate.cpp
index 0856444..d1c835e 100644
--- a/compiler/propagate/propagate.cpp
+++ b/compiler/propagate/propagate.cpp
@@ -48,7 +48,7 @@
 //! mix une liste de signaux sur n bus				
 siglist mix(const siglist& lsig, int nbus)
 {
-	int nlines	= lsig.size();
+	int nlines	= (int)lsig.size();
 	
 	siglist dst(nbus);
 	
@@ -65,7 +65,7 @@ siglist mix(const siglist& lsig, int nbus)
 //! split une liste de signaux sur n bus				
 siglist split(const siglist& inputs, int nbus)
 {
-	int nlines	= inputs.size();
+	int nlines	= (int)inputs.size();
 	
 	siglist outputs(nbus);
 	
@@ -116,8 +116,8 @@ siglist listRange(const siglist& l, int i, int j)
 
 siglist listConcat(const siglist& a, const siglist& b)
 {
-	int n1 = a.size();
-	int n2 = b.size();
+	int n1 = (int)a.size();
+	int n2 = (int)b.size();
 	siglist r(n1+n2);
 	
 	for (int x=0; x<n1; x++) r[x] = a[x];
@@ -130,22 +130,24 @@ siglist listConcat(const siglist& a, const siglist& b)
  */
 Tree listConvert(const siglist& a)
 {
-	int 	n = a.size();
+	int 	n = (int)a.size();
 	Tree 	t=nil;
 	while (n--) t = cons(a[n],t);
 	return t;
 }
 
-// siglist listConvertBack(Tree l)
-// {
-// 	siglist r;
-// 	while (!isNil(l)) { r.push_back(hd(l)); l = tl(l); }
-// 	return r;
-// }
+/**
+ * Convert a tree list of signals into an stl list of signals
+ */
+ void treelist2siglist(Tree l, siglist& r)
+ {
+    r.clear();
+    while (!isNil(l)) { r.push_back(hd(l)); l = tl(l); }
+ }
 
 siglist listLift(const siglist& l)
 {
-	int 		n = l.size();
+	int 		n = (int)l.size();
 	siglist		r(n);
 	
 	for(int i = 0; i<n; i++) r[i] = lift(l[i]);
@@ -163,41 +165,91 @@ static int	gDummyInput = 10000;
  *\param lsig list of signals to be propagated into box
  *\return list of resulting signals
  */
-/*
-// for debugging purposes
 
-siglist realpropagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig);
 
-siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
+
+/**
+ * Node used for memoization purposes
+ */
+
+static Node PROPAGATEPROPERTY(symbol("PropagateProperty"));
+
+/**
+ * Store the propagation result as a property of the arguments tuplet
+ * @param args propagation arguments
+ * @param value propagation result
+ */
+void setPropagateProperty(Tree args, const siglist&  lsig)
 {
-	cerr << "propagate in " << boxpp(box) << endl; 
-	for (int i=0; i<lsig.size(); i++) { cerr << " -> signal " << i << " : " << *(lsig[i]) << endl; }
-	cerr << endl;
-	return realpropagate (slotenv, path, box, lsig);
+    setProperty(args, tree(PROPAGATEPROPERTY), listConvert(lsig));
 }
-*/
+
 
 /**
- * Old try for names propagation.
+ * Retreive the propagation result as a property of the arguments tuplet
+ * @param args propagation arguments
+ * @param lsig the propagation result if any
+ * @return true if a propagation result was stored
  */
-//siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
-//{
-//	siglist S = realPropagate(slotenv, path, box, lsig);
-//
-//	if (gPrintDocSwitch) {
-//		Tree	id;
-//		if (lsig.size()==0 && getDefNameProperty(box, id)) {
-//			string nickname = defName2NickName(tree2str(id));
-//			//setSigListNickName(S, nickname);
-//		}
-//	}
-//
-//	return S;
-//}
-
-//siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
+bool getPropagateProperty(Tree args, siglist&  lsig)
+{
+    Tree value;
+    if (getProperty(args, tree(PROPAGATEPROPERTY), value)) {
+        treelist2siglist(value, lsig);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
+/**
+ * Propagate a list of signals into a block diagram.
+ * @param slotenv environment associating slots and signals
+ * @param path user interface group path
+ * @param box the block diagram
+ * @param lsig the list of input signals to propagate
+ * @return the resulting list of output signals
+ */
+
+siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig);
+
+
+/**
+ * Propagate a list of signals into a block diagram. Do memoization.
+ * @param slotenv environment associating slots and signals
+ * @param path user interface group path
+ * @param box the block diagram
+ * @param lsig the list of input signals to propagate
+ * @return the resulting list of output signals
+ */
+
 siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 {
+    Tree args =tree(PROPAGATEPROPERTY,slotenv,path,box,listConvert(lsig));
+    siglist result;
+    if (! getPropagateProperty(args, result)) {
+        result = realPropagate (slotenv, path, box, lsig);
+        setPropagateProperty(args, result);
+    }
+    //cerr << "propagate in " << boxpp(box) << endl;
+    //for (int i=0; i<lsig.size(); i++) { cerr << " -> signal " << i << " : " << *(lsig[i]) << endl; }
+    //cerr << endl;
+    return result;
+}
+
+
+/**
+ * Propagate a list of signals into a block diagram. Actual function.
+ * @param slotenv environment associating slots and signals
+ * @param path user interface group path
+ * @param box the block diagram
+ * @param lsig the list of input signals to propagate
+ * @return the resulting list of output signals
+ */
+
+siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
+{
 	int		i;
 	double	r;
 	prim0	p0;
@@ -207,7 +259,8 @@ siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 	prim4	p4;
 	prim5	p5;
 	
-	Tree	t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;
+    Tree	t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;
+    tvec    wf;
 	
 	
 	xtended* xt = (xtended*)getUserData(box);
@@ -229,7 +282,15 @@ siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 		assert(lsig.size()==0); 
 		return makeList(sigReal(r)); 
 	}
-    
+
+    // A Waveform has two outputs it size and a period signal representing its content
+
+    else if (isBoxWaveform(box)) 	{
+        assert(lsig.size()==0);
+        const tvec br = box->branches();
+        return listConcat(makeList(sigInt(br.size())), makeList(sigWaveform(br)));
+    }
+
     else if (isBoxFConst(box, type, name, file))    { 
         assert(lsig.size()==0); 
         return makeList(sigFConst(type, name, file)); 
@@ -268,7 +329,7 @@ siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 	
 	else if (isBoxSymbolic(box, slot, body)) 				{ 
 		assert(lsig.size()>0); 
-		return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, lsig.size()));
+		return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, (int)lsig.size()));
 	}
 	
 	// Primitives
@@ -331,7 +392,7 @@ siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 		assert(lsig.size()==0); 
 		return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step)); 
 	}
-	
+
 	else if (isBoxNumEntry(box, label, cur, min, max, step)) 	{ 
 		assert(lsig.size()==0); 
 		return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step)); 
@@ -408,19 +469,7 @@ siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 		siglist l2 = mix(l1, in2);
 		return propagate(slotenv, path, t2, l2);
 	}
-/*	
-	else if (isBoxRec(box, t1, t2)) 	{ 
-		int in1, out1, in2, out2;
-		getBoxType(t1, &in1, &out1);
-		getBoxType(t2, &in2, &out2);
-		
-		siglist l0 = makeSigProjList(ref(1), in2);
-		siglist l1 = propagate(slotenv, path, t2, l0);
-		siglist l2 = propagate(slotenv, path, t1, listConcat(l1,listLift(lsig)));
-		Tree g = rec(listConvert(l2));
-		return makeSigProjList(g, out1);
-	}
-*/	
+
     else if (isBoxRec(box, t1, t2)) 	{
         // Bug Corrected
         int in1, out1, in2, out2;
@@ -441,7 +490,14 @@ siglist propagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
 	return siglist();
 }
 
-	
+/**
+ * Top level propagate a list of signals into a block diagram. Do memoization.
+ * @param path user interface group path
+ * @param box the block diagram
+ * @param lsig the list of input signals to propagate
+ * @return the resulting list of output signals
+ */
+
 Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig)
 {
 	return listConvert(propagate(nil, path, box, lsig));
diff --git a/compiler/propagate/propagate.hh b/compiler/propagate/propagate.hh
index d3bbb07..bf7d043 100644
--- a/compiler/propagate/propagate.hh
+++ b/compiler/propagate/propagate.hh
@@ -32,30 +32,18 @@
 /**
  * boxPropagateSig : box listOfSignal-> listOfSignal'
  *
- * Propage une liste de signaux de l'entrÈe vers la sortie d'une boite
- * La boite ‡ ÈtÈ annotÈe aec son type
+ * Propagate a list of signals into a block-diagram. Fo example to
+ * compute the list of outputs of a block-diagram with n inputs, do :
+ * Tree lsig =  boxPropagateSig(box, makeSigInputList(n));
  */
 ///////////////////////////////////////////////////////////////////////
+
 using namespace std;
 
 typedef vector<Tree> siglist;
 
 siglist makeSigInputList (int n);
-Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig);
-
-//bool getSigListNickName (Tree t, Tree& id);
-//void setSigListNickName (const siglist&  lsig, const string& nickname);
-
-
-//siglist makeSigProjList (Tree t, int n);
-//siglist lrepeat(int n, const siglist& l);
-//siglist lmerge(int nbelems, int nblignes, Tree src);
 
+Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig);
 
-/*
-	exemple :
-	Pour calculer 'lsig' la liste des signaux de sortie d'une boite 'box' 
-	‡ n entrÈes on utilisera :
-		lsig =  boxPropagateSig(box, makeSigInputList(n));
-*/
 #endif
diff --git a/compiler/signals/binop.cpp b/compiler/signals/binop.cpp
index 7a3063d..e332472 100644
--- a/compiler/signals/binop.cpp
+++ b/compiler/signals/binop.cpp
@@ -30,7 +30,7 @@ BinOp* gBinOpTable[] = {
 	new BinOp("+","add_vec","add_scal", &addNode, &isZero, &isZero, 6),
     new BinOp("-","sub_vec","sub_scal", &subNode, &noNtrl, &isZero, 7),
     new BinOp("*","mul_vec","mul_scal", &mulNode, &isOne, &isOne, 8),
-    new BinOp("/","div_vec","div_scal", &divNode, &noNtrl, &isOne, 10),
+    new BinOp("/","div_vec","div_scal", &divExtendedNode, &noNtrl, &isOne, 10),
     new BinOp("%","mod_vec","mod_scal", &remNode, &noNtrl, &noNtrl, 9),
 
     new BinOp("<<","shift_left_vec","shift_left_scal", &lshNode, &noNtrl, &isZero, 8),
@@ -54,7 +54,7 @@ BinOp* gBinOpLateqTable[] = {
 	new BinOp("+","add_vec","add_scal", &addNode, &isZero, &isZero, 6),
     new BinOp("-","sub_vec","sub_scal", &subNode, &noNtrl, &isZero, 7),
     new BinOp("*","mul_vec","mul_scal", &mulNode, &isOne, &isOne, 8), // \DeclareMathSymbol{*}{\mathbin}{symbols}{"01}
-    new BinOp("/","div_vec","div_scal", &divNode, &noNtrl, &isOne, 10), // \frac{}{} used in generateBinOp
+    new BinOp("/","div_vec","div_scal", &divExtendedNode, &noNtrl, &isOne, 10), // \frac{}{} used in generateBinOp
     new BinOp("\\bmod","mod_vec","mod_scal", &remNode, &noNtrl, &noNtrl, 9),
 	
     new BinOp("\\hiderel{\\ll}","shift_left_vec","shift_left_scal", &lshNode, &noNtrl, &isZero, 8),
diff --git a/compiler/signals/interval.hh b/compiler/signals/interval.hh
index eb599f8..477b8d7 100644
--- a/compiler/signals/interval.hh
+++ b/compiler/signals/interval.hh
@@ -44,7 +44,9 @@ struct interval
 	interval (double n, double m) 	: valid(true), lo(min(n,m)), hi(max(n,m)) {}
     interval (const interval& r)	: valid(r.valid), lo(r.lo), hi(r.hi) {}
 	
-	bool isconst() { return valid & (lo == hi); }
+    bool isvalid()  { return valid; }
+    bool isconst()  { return valid && (lo == hi); }
+    bool haszero()  { return (lo <= 0) && (0 <= hi); }
 };
 
 inline ostream& operator<<(ostream& dst, const interval& i) 	
@@ -209,7 +211,32 @@ inline interval max(const interval& x, const interval& y)
 {
 	return interval(max(x.lo,y.lo), max(x.hi,y.hi));
 }
-		
+
+inline interval pow(const interval& x, const interval& y)
+{
+    if (x.lo > 0.0) {
+        double a = pow(x.lo,y.lo);
+        double b = pow(x.lo,y.hi);
+        double c = pow(x.hi,y.lo);
+        double d = pow(x.hi,y.hi);
+        return interval(min4(a,b,c,d), max4(a,b,c,d));
+    } else {
+        //std::cerr << "interval not computed for : pow(" << x <<"," << y << ")" << std::endl;
+        return interval();
+    }
+}
+
+inline interval iint(const interval& x)
+{
+    return interval(double(int(x.lo)), double(int(x.hi)));
+}
+
+inline interval fmod(const interval& x, const interval& y)
+{
+    interval n = iint(x/y);
+    return x - n*y;
+}
+
 inline interval abs(const interval& x)
 {
 	if (x.valid) {
diff --git a/compiler/signals/ppsig.cpp b/compiler/signals/ppsig.cpp
index 562e275..caccc9e 100644
--- a/compiler/signals/ppsig.cpp
+++ b/compiler/signals/ppsig.cpp
@@ -21,6 +21,7 @@
 
 
 
+#include "Text.hh"
 #include "ppsig.hh"
 #include "binop.hh"
 #include "prim2.hh"
@@ -191,8 +192,9 @@ ostream& ppsig::print (ostream& fout) const
 	
 	else if ( getUserData(sig) ) 					{ printextended(fout, sig); }
 	else if ( isSigInt(sig, &i) ) 					{ fout << i; }
-	else if ( isSigReal(sig, &r) ) 					{ fout << r; }
-	else if ( isSigInput(sig, &i) ) 				{ fout << "IN[" << i << "]"; }
+    else if ( isSigReal(sig, &r) ) 					{ fout << T(r); }
+    else if ( isSigWaveform(sig) )                  { fout << "waveform{...}"; }
+    else if ( isSigInput(sig, &i) ) 				{ fout << "IN[" << i << "]"; }
 	else if ( isSigOutput(sig, &i, x) ) 			{ printout(fout, i, x) ; }
 	
 	else if ( isSigDelay1(sig, x) ) 				{ fout << ppsig(x, fEnv, 9) << "'"; }
diff --git a/compiler/signals/prim2.cpp b/compiler/signals/prim2.cpp
index f85d7c2..1abe705 100644
--- a/compiler/signals/prim2.cpp
+++ b/compiler/signals/prim2.cpp
@@ -19,7 +19,8 @@
  ************************************************************************
  ************************************************************************/
  
- 
+extern int gFloatSize;
+
  
 #include "prim2.hh"
 #include "stdlib.h"
@@ -58,7 +59,9 @@ int ffrestype(Tree t)
 
 const char* ffname(Tree t)
 {
-	return tree2str(nth(ffsignature(t),1));
+    Tree namelist = nth(ffsignature(t),1);
+    //cerr << "ffname " << tree2str(nth(namelist,gFloatSize-1)) << endl;
+    return tree2str(nth(namelist,gFloatSize-1));
 }
 
 int ffarity(Tree t)
diff --git a/compiler/signals/signals.cpp b/compiler/signals/signals.cpp
index 0bd4411..75e9b76 100644
--- a/compiler/signals/signals.cpp
+++ b/compiler/signals/signals.cpp
@@ -201,9 +201,14 @@ bool isSigButton (Tree s, Tree& lbl)		{ return isTree(s, SIGBUTTON, lbl);				}
 
 
 Sym SIGCHECKBOX = symbol ("SigCheckbox");
-Tree sigCheckbox   (Tree lbl)				{ return tree(SIGCHECKBOX, lbl); 					}
+Tree sigCheckbox   (Tree lbl)				{ return tree(SIGCHECKBOX, lbl); 				}
 bool isSigCheckbox (Tree s)					{ Tree lbl; return isTree(s, SIGCHECKBOX, lbl);	}
-bool isSigCheckbox (Tree s, Tree& lbl)		{ return isTree(s, SIGCHECKBOX, lbl);				}
+bool isSigCheckbox (Tree s, Tree& lbl)		{ return isTree(s, SIGCHECKBOX, lbl);           }
+
+
+Sym SIGWAVEFORM = symbol("SigWaveform");
+Tree sigWaveform (const tvec& wf)           { return tree(SIGWAVEFORM, wf);                 }
+bool isSigWaveform(Tree s)                  { return isTree(s, SIGWAVEFORM);   }
 
 
 Sym SIGHSLIDER = symbol ("SigHSlider");
@@ -308,12 +313,12 @@ Tree mulNums(Tree a, Tree b)
 	return r;
 }
 
-Tree divNums(Tree a, Tree b)
-{
-	Tree r = tree(divNode(a->node(),b->node()));
-	//cerr.flags(ios::showpoint); cerr << "divNums " << *a << "/" << *b << " -> " << *r << endl;
-	return r;
-}
+//Tree divNums(Tree a, Tree b)
+//{
+//	Tree r = tree(divNode(a->node(),b->node()));
+//	//cerr.flags(ios::showpoint); cerr << "divNums " << *a << "/" << *b << " -> " << *r << endl;
+//	return r;
+//}
 
 Tree divExtendedNums(Tree a, Tree b)
 {
diff --git a/compiler/signals/signals.hh b/compiler/signals/signals.hh
index ab27ecb..bff9a9e 100644
--- a/compiler/signals/signals.hh
+++ b/compiler/signals/signals.hh
@@ -47,6 +47,10 @@ Tree sigReal(double n);
 bool  isSigInt(Tree t, int* i);
 bool  isSigReal(Tree t, double* r);
 
+// waveforms
+
+Tree sigWaveform (const tvec& wf);
+bool isSigWaveform(Tree s);
 
 // Inputs and outputs
 Tree sigInput(int i);
@@ -175,7 +179,6 @@ bool isSigDiv	(Tree a, Tree&x, Tree&y);
 Tree addNums 	(Tree a, Tree b);
 Tree subNums 	(Tree a, Tree b);
 Tree mulNums 	(Tree a, Tree b);
-Tree divNums 	(Tree a, Tree b);
 Tree divExtendedNums 	(Tree a, Tree b);
 Tree minusNum	(Tree a);
 Tree inverseNum	(Tree a);
diff --git a/compiler/signals/sigorderrules.cpp b/compiler/signals/sigorderrules.cpp
index dafed51..0930dce 100644
--- a/compiler/signals/sigorderrules.cpp
+++ b/compiler/signals/sigorderrules.cpp
@@ -100,8 +100,10 @@ static int infereSigOrder(Tree sig)
 	
 	else if (isSigInt(sig, &i))					return 0;
 		
-	else if (isSigReal(sig, &r)) 				return 0;
-		
+    else if (isSigReal(sig, &r)) 				return 0;
+
+    else if (isSigWaveform(sig))                return 3;
+
 	else if (isSigInput(sig, &i))				return 3;
 		
 	else if (isSigOutput(sig, &i, s1)) 			return 3;
diff --git a/compiler/signals/sigtype.hh b/compiler/signals/sigtype.hh
index 8ea7c5c..1c6e409 100644
--- a/compiler/signals/sigtype.hh
+++ b/compiler/signals/sigtype.hh
@@ -269,7 +269,7 @@ class SimpleType : public AudioType
 inline Type intCast (Type t)	{ return makeSimpleType(kInt, t->variability(), t->computability(), t->vectorability(), t->boolean(), t->getInterval()); }
 inline Type floatCast (Type t)	{ return makeSimpleType(kReal, t->variability(), t->computability(), t->vectorability(), t->boolean(), t->getInterval()); }
 inline Type sampCast (Type t)	{ return makeSimpleType(t->nature(), kSamp, t->computability(), t->vectorability(), t->boolean(), t->getInterval()); }
-inline Type boolCast (Type t)   { return makeSimpleType(t->nature(), t->variability(), t->computability(), t->vectorability(), kBool, t->getInterval()); }
+inline Type boolCast (Type t)   { return makeSimpleType(kInt, t->variability(), t->computability(), t->vectorability(), kBool, t->getInterval()); }
 inline Type numCast (Type t)    { return makeSimpleType(t->nature(), t->variability(), t->computability(), t->vectorability(), kNum, t->getInterval()); }
 inline Type vecCast (Type t)    { return makeSimpleType(t->nature(), t->variability(), t->computability(), kVect, t->boolean(), t->getInterval()); }
 inline Type scalCast (Type t)   { return makeSimpleType(t->nature(), t->variability(), t->computability(), kScal, t->boolean(), t->getInterval()); }
@@ -355,7 +355,7 @@ class TupletType : public AudioType
 		  AudioType(n|mergenature(vt), v|mergevariability(vt), c|mergecomputability(vt), vec|mergevectorability(vt), b|mergeboolean(vt), i),
 		  fComponents(vt) {}
 
-	int arity()	const						{ return fComponents.size(); }
+	int arity()	const						{ return (int)fComponents.size(); }
 	Type operator[](unsigned int i) const	{ return fComponents[i]; }
 	virtual ostream& print(ostream& dst) const;
 	
diff --git a/compiler/signals/sigtyperules.cpp b/compiler/signals/sigtyperules.cpp
index ffd431c..60a2be3 100644
--- a/compiler/signals/sigtyperules.cpp
+++ b/compiler/signals/sigtyperules.cpp
@@ -60,13 +60,15 @@ static Type infereXType(Tree sig, Tree env);
 static Type infereDocConstantTblType(Type size, Type init);
 static Type infereDocWriteTblType(Type size, Type init, Type widx, Type wsig);
 static Type infereDocAccessTblType(Type tbl, Type ridx);
+static Type infereWaveformType (Tree lv, Tree env);
+
 static interval arithmetic (int opcode, const interval& x, const interval& y);
 
 
 
 // Uncomment to activate type inferrence tracing
 //#define TRACE(x) x
-#define TRACE(x) 0;
+#define TRACE(x) ;
 
 
 /**
@@ -95,7 +97,10 @@ void typeAnnotation(Tree sig)
     //cerr << "Symlist " << *sl << endl;
     for (Tree l=sl; isList(l); l=tl(l)) {
         Tree    id, body;
-        assert(isRec(hd(l), id, body));
+		assert(isRec(hd(l), id, body));
+		if (!isRec(hd(l), id, body)) {
+			continue;
+		}
 
         vrec.push_back(hd(l));
         vdef.push_back(body);
@@ -258,6 +263,9 @@ static Type infereSigType(Tree sig, Tree env)
     else if (isSigReal(sig, &r)) 			{   Type t = makeSimpleType(kReal, kKonst, kComp, kVect, kNum, interval(r));
                                                 /*sig->setType(t);*/ return t; }
 
+    else if (isSigWaveform(sig))            {   return infereWaveformType(sig, env); }
+
+
     else if (isSigInput(sig, &i))			{   /*sig->setType(TINPUT);*/ return TINPUT; }
 
     else if (isSigOutput(sig, &i, s1))      return sampCast(T(s1,env));
@@ -303,8 +311,14 @@ static Type infereSigType(Tree sig, Tree env)
 		Type t2 = T(s2,env);
 		Type t3 = castInterval(t1 | t2, arithmetic(i, t1->getInterval(), t2->getInterval()));
 		//cerr <<"type rule for : " << ppsig(sig) << " -> " << *t3 << endl;
-	  	//return (!gVectorSwitch && (i>=kGT) && (i<=kNE)) ?  intCast(t3) : t3; // for comparaison operation the result is int
-	  	return ((i>=kGT) && (i<=kNE)) ?  intCast(t3) : t3; // for comparaison operation the result is int
+
+        if (i == kDiv) {
+            return floatCast(t3);            // division always result in a float even with int arguments
+        } else if ((i>=kGT) && (i<=kNE)) {
+            return boolCast(t3);             // comparison always result in a boolean int
+        } else {
+            return t3;                       //  otherwise most general of t1 and t2
+        }
 	}
 
     else if (isSigIntCast(sig, s1))             return intCast(T(s1,env));
@@ -572,6 +586,47 @@ static Type infereFVarType (Tree type)
 
 
 /**
+ *  Infere the type of a waveform:
+ *  - the nature is int if all values are int, otherwise it is float
+ *  - the variability is by samples
+ *  - the waveform is known at compile time
+ *  - it can be vectorized because all values are known
+ *  - knum ???
+ *  - the interval is min and max of values
+ */
+static Type infereWaveformType (Tree wfsig, Tree env)
+{
+    bool    iflag = true;
+    int     n = wfsig->arity();
+    double  lo, hi;
+
+    if (n == 0) {
+        std::cerr << "ERROR, empty waveform" << std::endl;
+        exit(1);
+    }
+
+    lo = hi = tree2float(wfsig->branch(0));
+    iflag = isInt(wfsig->branch(0)->node());
+    T(wfsig->branch(0), env);
+
+    for (int i = 1; i < n; i++)  {
+        Tree v = wfsig->branch(i);
+        T(v,env);
+        // compute range
+        double f = tree2float(v);
+        if (f < lo) {
+            lo = f;
+        } else if (f > hi) {
+            hi = f;
+        }
+        iflag &= isInt(v->node());
+    }
+
+    return makeSimpleType((iflag)?kInt:kReal, kSamp, kComp, kScal, kNum, interval(lo,hi));
+}
+
+
+/**
  *	Infere the type of an extended (primitive) block
  */
 static Type infereXType(Tree sig, Tree env)
diff --git a/compiler/signals/subsignals.cpp b/compiler/signals/subsignals.cpp
index 1f2a80c..6ee6bb6 100644
--- a/compiler/signals/subsignals.cpp
+++ b/compiler/signals/subsignals.cpp
@@ -21,6 +21,10 @@ int	getSubSignals (Tree sig, vector<Tree>& vsigs, bool visitgen)
 													  return sig->arity(); }
 	else if ( isSigInt(sig, &i) ) 					{ return 0; }
 	else if ( isSigReal(sig, &r) ) 					{ return 0; }
+    else if ( isSigWaveform(sig))                   { vsigs = sig->branches(); return vsigs.size(); }
+
+    //else if ( isSigWaveform(sig) )                  { return 0; }
+
 	else if ( isSigInput(sig, &i) ) 				{ return 0; 			}
 	else if ( isSigOutput(sig, &i, x) ) 			{ vsigs.push_back(x); return 1;	}
 
@@ -59,7 +63,7 @@ int	getSubSignals (Tree sig, vector<Tree>& vsigs, bool visitgen)
 	else if ( isSigCheckbox(sig, label) ) 			{ return 0; }
 	else if ( isSigVSlider(sig, label,c,x,y,z) )	{ return 0; }
 	else if ( isSigHSlider(sig, label,c,x,y,z) )	{ return 0; }
-	else if ( isSigNumEntry(sig, label,c,x,y,z) )	{ return 0; }
+    else if ( isSigNumEntry(sig, label,c,x,y,z) )	{ return 0; }
 
 	else if ( isSigVBargraph(sig, label,x,y,z) )	{ vsigs.push_back(z); return 1;	}
 	else if ( isSigHBargraph(sig, label,x,y,z) )	{ vsigs.push_back(z); return 1;	}
@@ -68,7 +72,7 @@ int	getSubSignals (Tree sig, vector<Tree>& vsigs, bool visitgen)
     else if ( isNil(sig) )                          { return 0; }
 
 	else {
-		cerr << "ERROR, unrecognized signal : " << *sig << endl;
+        cerr << "ERROR, getSubSignals unrecognized signal : " << *sig << endl;
 		exit(1);
 	}
 	return 0;
diff --git a/compiler/tlib/compatibility.cpp b/compiler/tlib/compatibility.cpp
index e3190f6..bf300da 100644
--- a/compiler/tlib/compatibility.cpp
+++ b/compiler/tlib/compatibility.cpp
@@ -19,15 +19,64 @@
  ************************************************************************
  ************************************************************************/
  
+#include "compatibility.hh"
+#include "math.h"
 
-#if defined( __MINGW32__) || defined (WIN32)
+#if defined(__MINGW32__) || defined (WIN32)
 	// Simulate some Unix fonctions on Windows
 
-	#include <windows.h>
-	#include "math.h"
+	#ifndef __MINGW32__
+	/* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */
+	double rint(double nr)
+	{
+		double f = floor(nr);
+		double c = ceil(nr);
+		return (((c -nr) >= (nr - f)) ? f : c);
+	}
+	#endif
+
+	#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+	  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+	#else
+	  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+	#endif
+
+	int gettimeofday(struct timeval *tv, struct timezone *tz)
+	{
+	  FILETIME ft;
+	  unsigned __int64 tmpres = 0;
+	  static int tzflag;
+
+	  if (NULL != tv)
+	  {
+		GetSystemTimeAsFileTime(&ft);
+
+		tmpres |= ft.dwHighDateTime;
+		tmpres <<= 32;
+		tmpres |= ft.dwLowDateTime;
+
+		/*converting file time to unix epoch*/
+		tmpres -= DELTA_EPOCH_IN_MICROSECS; 
+		tmpres /= 10;  /*convert into microseconds*/
+		tv->tv_sec = (long)(tmpres / 1000000UL);
+		tv->tv_usec = (long)(tmpres % 1000000UL);
+	  }
+
+	  if (NULL != tz)
+	  {
+		if (!tzflag)
+		{
+		  _tzset();
+		  tzflag++;
+		}
+		tz->tz_minuteswest = _timezone / 60;
+		tz->tz_dsttime = _daylight;
+	  }
+	  return 0;
+	}
 
 #if defined(_MBCS) || __MINGW32__
-	bool chdir(const char* path)
+	int chdir(const char* path)
 	{
 		return !SetCurrentDirectory(path);
 	}
@@ -37,7 +86,7 @@
 		return CreateDirectory(path,NULL);
 	}
 
-	char* getcwd(char* str, unsigned int size)
+	char* getcwd(char* str, int size)
 	{
 		GetCurrentDirectory(size, str);
 		return str;
@@ -78,11 +127,6 @@
 
 #endif
 
-	int isatty(int file)
-	{
-		return 0;
-	}
-
 #if !defined(__MINGW32__)
 
 	typedef union
diff --git a/compiler/tlib/compatibility.hh b/compiler/tlib/compatibility.hh
index 3e977cc..7a4accc 100644
--- a/compiler/tlib/compatibility.hh
+++ b/compiler/tlib/compatibility.hh
@@ -24,23 +24,37 @@
 #define     __COMPATIBILITY__
 
 
-#if defined (WIN32)
-
+#ifdef WIN32
 #include <windows.h>
+#include <time.h>
+#include <assert.h>
 
-#ifdef WIN32
-	#undef min
-	#undef max
-#endif
+#undef min
+#undef max
 
-bool	chdir(const char* path);
+//#define int64_t __int64
+#define YY_NO_UNISTD_H 1
+
+struct timezone 
+{
+	int  tz_minuteswest; /* minutes W of Greenwich */
+	int  tz_dsttime;     /* type of dst correction */
+};
+
+#define alarm(x)
+#define strdup _strdup
+#define snprintf _snprintf
+extern "C" {
+double  rint(double nr);
+int		gettimeofday(struct timeval *tv, struct timezone *tz);
+int chdir(const char *path);
 int		mkdir(const char* path, unsigned int attribute);
-char*	getcwd(char* str, unsigned int size);
+char*	getcwd(char* str, int size);
 int		isatty(int file);
+}
 void	getFaustPathname(char* str, unsigned int size);
 void	getFaustPathname(char* str, unsigned int size);
 
-#include <assert.h>
 #ifdef  NDEBUG
 #undef assert
 #define assert(_Expression) do { bool bTest = (_Expression) != 0; } while (0)
diff --git a/compiler/tlib/list.cpp b/compiler/tlib/list.cpp
index 7ddc499..67549b2 100644
--- a/compiler/tlib/list.cpp
+++ b/compiler/tlib/list.cpp
@@ -365,7 +365,7 @@ bool searchEnv (Tree key, Tree& v, Tree env)
 	return false;
 }
 
-
+#if 0
 //------------------------------------------------------------------------------
 // Property list
 //------------------------------------------------------------------------------
@@ -390,7 +390,7 @@ static Tree removeKey (Tree pl, Tree key)
 	if (left(hd(pl)) == key) 	return tl(pl);
 	/*  left(hd(pl)) != key	*/	return cons (hd(pl), removeKey(tl(pl), key));
 }
-
+#endif
 
 #if 0
 void setProperty (Tree t, Tree key, Tree val)
@@ -452,28 +452,15 @@ Tree tmap (Tree key, tfun f, Tree t)
 		return (isNil(p)) ? t : p;	// truc pour eviter les boucles
 		
 	} else {
-		
-		Tree r1=nil;
-		switch (t->arity()) {
-			
-			case 0 : 
-				r1 = t; 
-				break;
-			case 1 : 
-				r1 = tree(t->node(), tmap(key,f,t->branch(0))); 
-				break;
-			case 2 : 
-				r1 = tree(t->node(), tmap(key,f,t->branch(0)), tmap(key,f,t->branch(1))); 
-				break;
-			case 3 : 
-				r1 = tree(t->node(), tmap(key,f,t->branch(0)), tmap(key,f,t->branch(1)),
-										   tmap(key,f,t->branch(2))); 
-				break;
-			case 4 : 
-				r1 = tree(t->node(), tmap(key,f,t->branch(0)), tmap(key,f,t->branch(1)),
-										   tmap(key,f,t->branch(2)), tmap(key,f,t->branch(3))); 
-				break;
-		}
+
+        tvec br;
+        int n = t->arity();
+        for (int i = 0; i < n; i++) {
+            br.push_back( tmap(key, f, t->branch(i)) );
+        }
+
+        Tree r1 = tree(t->node(), br);
+
 		Tree r2 = f(r1);
 		if (r2 == t) {
 			setProperty(t, key, nil);
@@ -500,8 +487,8 @@ static Tree substkey(Tree t, Tree id, Tree val)
 	return tree(unique(name));
 }	
 
-// realise la substitution proprement dite tout en mettant � jour la propriete
-// pour ne pas avoir � la calculer deux fois
+// realise la substitution proprement dite tout en mettant a jour la propriete
+// pour ne pas avoir a la calculer deux fois
 
 static Tree subst (Tree t, Tree propkey, Tree id, Tree val)
 {
@@ -515,36 +502,15 @@ static Tree subst (Tree t, Tree propkey, Tree id, Tree val)
 	} else if (getProperty(t, propkey, p)) {
 		return (isNil(p)) ?  t : p;
 	} else {
-		Tree r=nil;
-		switch (t->arity()) {
-			
-			case 1 : 
-				r = tree(t->node(), 
-							subst(t->branch(0), propkey, id, val)); 
-				break;
-				
-			case 2 : 
-				r = tree(t->node(), 
-							subst(t->branch(0), propkey, id, val), 
-							subst(t->branch(1), propkey, id, val)); 
-				break;
-				
-			case 3 : 
-				r = tree(t->node(), 
-							subst(t->branch(0), propkey, id, val), 
-							subst(t->branch(1), propkey, id, val), 
-							subst(t->branch(2), propkey, id, val)); 
-				break;
-				
-			case 4 : 
-				r = tree(t->node(), 
-							subst(t->branch(0), propkey, id, val), 
-							subst(t->branch(1), propkey, id, val), 
-							subst(t->branch(2), propkey, id, val), 
-							subst(t->branch(3), propkey, id, val)); 
-				break;
-			
-		}
+
+        tvec br;
+        int n = t->arity();
+        for (int i = 0; i < n; i++) {
+            br.push_back( subst(t->branch(i), propkey, id, val) );
+        }
+
+        Tree r = tree(t->node(), br);
+
 		if (r == t) {
 			setProperty(t, propkey, nil);
 		} else {
diff --git a/compiler/tlib/node.hh b/compiler/tlib/node.hh
index 55fb30b..6490a11 100644
--- a/compiler/tlib/node.hh
+++ b/compiler/tlib/node.hh
@@ -53,8 +53,13 @@
 #ifndef     __NODE__
 #define     __NODE__
 
+#if defined(WIN32) && !defined(__MINGW32__)
+#define int64_t __int64
+#endif
+
 #include <iostream>
 #include "symbol.hh"
+#include <sys/types.h>
 
 using namespace std;
 
@@ -75,6 +80,7 @@ class Node
 		double 	f;
 		Sym 	s;
 		void* 	p;
+        int64_t v;
 	} fData;
 
  public:
@@ -89,8 +95,8 @@ class Node
     Node (const Node& n)        : fType(n.fType)        { fData = n.fData; }
 
 	// predicats
-	bool operator == (const Node& n) const { return fType == n.fType && fData.f == n.fData.f; }
-	bool operator != (const Node& n) const { return fType != n.fType || fData.f != n.fData.f; }
+	bool operator == (const Node& n) const { return fType == n.fType && fData.v == n.fData.v; }
+	bool operator != (const Node& n) const { return fType != n.fType || fData.v != n.fData.v; }
 
 	// accessors
 	int		type() 		const 	{ return fType; }
@@ -241,9 +247,6 @@ inline const Node subNode (const Node& x, const Node& y)
 inline const Node mulNode (const Node& x, const Node& y)
 	{ return (isDouble(x)||isDouble(y)) ? Node(double(x)*double(y)) : Node(int(x)*int(y)); }
 
-inline const Node divNode (const Node& x, const Node& y)
-	{ return (isDouble(x)||isDouble(y)) ? Node(double(x)/double(y)) : Node(int(x)/int(y)); }
-
 inline const Node divExtendedNode (const Node& x, const Node& y)
 	{ return  (isDouble(x)||isDouble(y)) ? Node(double(x)/double(y))
 			: (double(int(x)/int(y))==double(x)/double(y)) ? Node(int(x)/int(y))
@@ -258,7 +261,7 @@ inline const Node minusNode (const Node& x)
 	{ return subNode(0, x); }
 
 inline const Node inverseNode (const Node& x)
-	{ return divNode(1.0f, x); }
+    { return divExtendedNode(1.0f, x); }
 
 
 // bit shifting operations
diff --git a/compiler/tlib/symbol.cpp b/compiler/tlib/symbol.cpp
index 1e2390c..02917c9 100644
--- a/compiler/tlib/symbol.cpp
+++ b/compiler/tlib/symbol.cpp
@@ -45,33 +45,31 @@ Symbol*	Symbol::gSymbolTable[kHashTableSize];
   
 Symbol* Symbol::get(const string& str)
 {
-	char 	buf[1024];
-	int		i;
-	int		n = str.length();
-	
-	if (n>1023) n = 1023;
-	for (i = 0; i < n; i++) { buf[i] = str[i]; }
-	buf[i] = 0;
-	
-	return Symbol::get(buf);
+    return Symbol::get(str.c_str());
 }
 
-
-
 /**
  * Search the hash table for the symbol of name \p str or returns a new one.
  * \param str the name of the symbol
  * \return a symbol of name str
  */ 
 
-Symbol* Symbol::get(const char* str)
+Symbol* Symbol::get(const char* rawstr)
 {
-    unsigned int 			hsh  = calcHashKey(str);
+    // ---replaces control characters with white spaces---
+    char* str = strdup(rawstr);
+    for (size_t i = 0; i < strlen(rawstr); i++) {
+        char c = rawstr[i];
+        str[i] = (c >= 0 && c < 32) ? 32 : c;
+    }
+ 
+    unsigned int 	hsh  = calcHashKey(str);
     int 			bckt = hsh % kHashTableSize;
 	Symbol*			item = gSymbolTable[bckt];
-
+  
     while ( item && !item->equiv(hsh,str) ) item = item->fNext;
 	Symbol* r = item ? item : gSymbolTable[bckt] = new Symbol(str, hsh, gSymbolTable[bckt]);
+     
 	return r;
 }
 
@@ -84,7 +82,7 @@ Symbol* Symbol::get(const char* str)
 
 bool Symbol::isnew(const char* str)
 {
-    unsigned int 			hsh  = calcHashKey(str);
+    unsigned int    hsh  = calcHashKey(str);
     int 			bckt = hsh % kHashTableSize;
 	Symbol*			item = gSymbolTable[bckt];
 	
@@ -149,18 +147,15 @@ unsigned int Symbol::calcHashKey (const char* str)
 
 /**
  * Constructs a symbol ready to be placed in the hash table. 
- * It makes a private copy of its name.
+ * Gets a string to be kept.
  * \param str the name of the symbol
  * \param hsh the hash key of the symbol
  * \param nxt a pointer to the next symbol in the hash table entry
  */
 
-Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt)
+Symbol::Symbol(char* str, unsigned int hsh, Symbol* nxt)
 {
-	int len = strlen(str);
-	
-    fName = new char [len+1];
-    memcpy(fName, str, len+1);
+    fName = str;
     fHash = hsh;
     fNext = nxt;
 	fData = 0;
@@ -168,7 +163,7 @@ Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt)
 
 Symbol::~Symbol ()
 {
-	delete [] fName;
+	free(fName);
 }
 
 ostream& Symbol::print (ostream& fout) const 					///< print a symbol on a stream
diff --git a/compiler/tlib/symbol.hh b/compiler/tlib/symbol.hh
index 5a24a74..5ce8de0 100644
--- a/compiler/tlib/symbol.hh
+++ b/compiler/tlib/symbol.hh
@@ -66,7 +66,7 @@ class Symbol
 	void*			fData;										///< Field to user disposal to store additional data
 	
  // Constructors & destructors
-    Symbol (const char* str, unsigned int hsh, Symbol* nxt); 	///< Constructs a new symbol ready to be placed in the hash table
+    Symbol (char* str, unsigned int hsh, Symbol* nxt);          ///< Constructs a new symbol ready to be placed in the hash table
    ~Symbol ();													///< The Destructor is never used
 	
  // Others
diff --git a/compiler/tlib/tree.cpp b/compiler/tlib/tree.cpp
index 7f115a3..24f9226 100644
--- a/compiler/tlib/tree.cpp
+++ b/compiler/tlib/tree.cpp
@@ -284,6 +284,11 @@ const char* tree2str (Tree t)
 	return name(s);
 }	
 
+string tree2quotedstr (Tree t)
+{
+    return "\"" + string(tree2str(t)) + "\"";
+}
+
 // if t has a node of type ptr, return it otherwise error			
 void* tree2ptr (Tree t)
 {
@@ -307,14 +312,14 @@ bool isTree (const Tree& t, const Node& n)
 	return (t->node() == n);
 }
 
-bool isTree (const Tree& t, const Node& n, Tree& a) 
-{ 
-	if ((t->node() == n) && (t->arity() == 1)) { 
-		a=t->branch(0); 
-		return true; 
-	} else {
-		return false;
-	}
+bool isTree (const Tree& t, const Node& n, Tree& a)
+{
+    if ((t->node() == n) && (t->arity() == 1)) {
+        a=t->branch(0);
+        return true;
+    } else {
+        return false;
+    }
 }
 
 bool isTree (const Tree& t, const Node& n, Tree& a, Tree& b)
diff --git a/compiler/tlib/tree.hh b/compiler/tlib/tree.hh
index 9ab6170..e4b994c 100644
--- a/compiler/tlib/tree.hh
+++ b/compiler/tlib/tree.hh
@@ -141,9 +141,10 @@ class CTree
 
  	// Accessors
  	const Node& node() const		{ return fNode; 		}	///< return the content of the tree
- 	int 		arity() const		{ return fBranch.size();}	///< return the number of branches (subtrees) of a tree
-	Tree 		branch(int i) const	{ return fBranch[i];	}	///< return the ith branch (subtree) of a tree
- 	unsigned int 		hashkey() const		{ return fHashKey; 		}	///< return the hashkey of the tree
+ 	int 		arity() const		{ return (int)fBranch.size();}	///< return the number of branches (subtrees) of a tree
+    Tree 		branch(int i) const	{ return fBranch[i];	}	///< return the ith branch (subtree) of a tree
+    const tvec& branches() const	{ return fBranch;	}       ///< return all branches (subtrees) of a tree
+    unsigned int 		hashkey() const		{ return fHashKey; 		}	///< return the hashkey of the tree
  	int 		aperture() const	{ return fAperture; 	}	///< return how "open" is a tree in terms of free variables
  	void 		setAperture(int a) 	{ fAperture=a; 			}	///< modify the aperture of a tree
 
@@ -189,14 +190,16 @@ inline Tree tree (const Node& n, const Tree& a, const Tree& b, const Tree& c) {
 inline Tree tree (const Node& n, const Tree& a, const Tree& b, const Tree& c, const Tree& d) { Tree br[]= {a,b,c,d}; return CTree::make(n, 4, br); }
 
 inline Tree tree (const Node& n, const Tree& a, const Tree& b, const Tree& c, const Tree& d, const Tree& e) { Tree br[]= {a,b,c,d,e}; return CTree::make(n, 5, br); }
+inline Tree tree (const Node& n, const tvec& br) { return CTree::make(n, br); }
 
 // useful conversions
 int 		tree2int (Tree t);		///< if t has a node of type int, return it otherwise error
 double      tree2float (Tree t);    ///< if t has a node of type float, return it otherwise error
 double      tree2double (Tree t);    ///< if t has a node of type float, return it otherwise error
 const char* tree2str (Tree t);		///< if t has a node of type symbol, return its name otherwise error
-void* 		tree2ptr (Tree t);		///< if t has a node of type ptr, return it otherwise error
-void*		getUserData(Tree t);	///< if t has a node of type symbol, return the associated user data
+string      tree2quotedstr (Tree t);
+void*       tree2ptr (Tree t);		///< if t has a node of type ptr, return it otherwise error
+void*       getUserData(Tree t);	///< if t has a node of type symbol, return the associated user data
 
 // pattern matching
 bool isTree (const Tree& t, const Node& n);
diff --git a/compiler/utils/files.cpp b/compiler/utils/files.cpp
new file mode 100644
index 0000000..2935452
--- /dev/null
+++ b/compiler/utils/files.cpp
@@ -0,0 +1,91 @@
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+	Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+ 
+#include "files.hh"
+#include "compatibility.hh"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+using namespace std;
+
+static string gCurrentDir;			///< Room to save current directory name.
+
+/**
+ *Switch back to the previously stored current directory
+ */
+ 
+int	cholddir()
+{
+    if (chdir(gCurrentDir.c_str()) == 0) {
+		return 0;
+	} else {
+		perror("cholddir");
+		exit(errno);
+	}
+}
+
+/**
+ * Create a new directory in the current one to store the diagrams.
+ * The current directory is saved to be later restored.
+ */
+ 
+int mkchdir(string dirname)
+{
+    getCurrentDir();
+    if (gCurrentDir != "") {
+		int status = mkdir(dirname.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+		if (status == 0 || errno == EEXIST) {
+			if (chdir(dirname.c_str()) == 0) {
+				return 0;
+			}
+		}
+	}
+	perror("mkchdir");
+	exit(errno);
+}
+
+int	makedir(string dirname)
+{
+    getCurrentDir();
+    if (gCurrentDir != "") {
+		int status = mkdir(dirname.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+		if (status == 0 || errno == EEXIST) {
+			return 0;
+		}
+	}
+	perror("makedir");
+	exit(errno);
+}
+
+void getCurrentDir()
+{
+    char buffer[FAUST_PATH_MAX];
+    char* current_dir = getcwd(buffer, FAUST_PATH_MAX);
+    gCurrentDir = (current_dir) ? current_dir : "";
+}
+
diff --git a/compiler/utils/files.hh b/compiler/utils/files.hh
new file mode 100644
index 0000000..e641264
--- /dev/null
+++ b/compiler/utils/files.hh
@@ -0,0 +1,32 @@
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+	Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+ 
+#ifndef __FILES__
+#define __FILES__
+
+#include <string>
+
+int	cholddir();
+int mkchdir(std::string dirname);
+int	makedir(std::string dirname);
+void getCurrentDir();
+
+#endif
diff --git a/compiler/utils/names.cpp b/compiler/utils/names.cpp
index 479b1ce..a30dff3 100644
--- a/compiler/utils/names.cpp
+++ b/compiler/utils/names.cpp
@@ -60,7 +60,7 @@ void setDefNameProperty(Tree t, Tree id)
 void setDefNameProperty(Tree t, const string& name)
 {
 	//cerr << "setDefNameProperty : " << name << " FOR " << t << "#" << boxpp(t) << endl;
-	int		n = name.size();
+	int		n = (int)name.size();
 	int 	m = (gMaxNameSize>1023) ? 1023 : gMaxNameSize;
 	if (n > m) {
 		// the name is too long we reduce it to 2/3 of maxsize
diff --git a/documentation/faust-quick-reference-src/chapters/acknowledgments.tex b/documentation/faust-quick-reference-src/chapters/acknowledgments.tex
index a71d5ac..5ac0cfc 100644
--- a/documentation/faust-quick-reference-src/chapters/acknowledgments.tex
+++ b/documentation/faust-quick-reference-src/chapters/acknowledgments.tex
@@ -1,39 +1,52 @@
 \chapter{Acknowledgments}
-Many persons are contributing to the \faust project, by providing code for the compiler, architecture files, libraries, examples, documentation, scripts, bug reports, ideas, etc. I would like in particular to thank:
+Many persons are contributing to the \faust project, by providing code for the compiler, architecture files, libraries, examples, documentation, scripts, bug reports, ideas, etc. We would like in particular to thank:
 
 \begin{itemize}
-
 \item[-]Fons Adriaensen	
+\item[-]Karim Barkati
+\item[-]J\'er\^ome Barth\'elemy
+\item[-]Tim Blechmann
 \item[-]Tiziano Bole	
+\item[-]Alain Bonardi
 \item[-]Thomas Charbonnel
+\item[-]Raffaele Ciavarella
+\item[-]Julien Colafrancesco
 \item[-]Damien Cramet
 \item[-]\'Etienne Gaudrin
+\item[-]Pierre Guillot
 \item[-]Albert Gr\"af
+\item[-]Pierre Jouvelot
 \item[-]Stefan Kersten
 \item[-]Victor Lazzarini
 \item[-]Matthieu Leberre
 \item[-]Mathieu Leroi
+\item[-]Fernando Lopez-Lezcano
 \item[-]Kjetil Matheussen
+\item[-]Hermann Meyer
+\item[-]Romain Michon
 \item[-]R\'emy Muller
+\item[-]Eliott Paris
+\item[-]Reza Payami
+\item[-]Laurent Pottier
+\item[-]Sampo Savolainen
 \item[-]Nicolas Scaringella
+\item[-]Anne Sedes
+\item[-]Priyanka Shekar
 \item[-]Stephen Sinclair
 \item[-]Travis Skare
 \item[-]Julius Smith
+\item[-]Michael Wilson
 \end{itemize}
-
-
-Many developments of the \faust project are now made within the \astree project (ANR 2008 CORD 003 02). I would like to thank my \astree's partners:
+as well as our colleagues at GRAME:
 \begin{itemize}
-\item[-]J\'er\^ome Barth\'elemy (\ircam)
-\item[-]Alain Bonardi (\ircam)
-\item[-]Raffaele Ciavarella (\ircam)
-\item[-]Pierre Jouvelot (\'Ecole des Mines/ParisTech)
-\item[-]Laurent Pottier (U. Saint-Etienne)
+\item[-]	Sarah Denoux
+\item[-]	Olivier Guillerminet
+\item[-]	Christophe Lebreton
+\item[-]	Mike Solomon
 \end{itemize}
-as well as my colleagues at \textsc{Grame}, in particular : Dominique Fober, St\'ephane Letz and Karim Barkati.
 
 
-I would like also to thank for their financial support:
+We would like also to thank for their financial support:
 \begin{itemize}
 \item[-]the French Ministry of Culture
 \item[-]the Rh\^one-Alpes Region
diff --git a/documentation/faust-quick-reference-src/chapters/architectures.tex b/documentation/faust-quick-reference-src/chapters/architectures.tex
index 9483571..f5a7d08 100644
--- a/documentation/faust-quick-reference-src/chapters/architectures.tex
+++ b/documentation/faust-quick-reference-src/chapters/architectures.tex
@@ -37,6 +37,7 @@ The architecture to be used is specified at compile time with the \lstinline'-a'
 \texttt{vst.cpp} 			& VST plugin  \\
 \texttt{vst2p4.cpp} 		& VST 2.4 plugin  \\
 \texttt{vsti-mono.cpp} 		& VSTi mono instrument  \\
+\texttt{vsti-poly.cpp} 		& VSTi polyphonic instrument  \\
 \texttt{ladspa.cpp} 		& LADSPA plugin  \\
 \texttt{q.cpp} 				& Q language plugin  \\
 \texttt{supercollider.cpp} 	& SuperCollider Unit Generator  \\
@@ -247,163 +248,3 @@ OSC  & OSC control (see \ref{sec:oscgui}) \\
 \label{tab:uiarch}
 \end{table}%
 
-
-%---------------------------------------------------
-\section{OSC architecture modules} \label{sec:osc}
-%---------------------------------------------------
-
-The OSC \cite{OSC} support opens \faust application's control to any OSC capable application or programming language.
-It also transforms a full range of devices embedding sensors (wiimote, smart phones, ...) into physical interfaces for \faust application's control, allowing a direct use like musical instruments.
-
-The \faust OSC architecture is twofold: it is declined as a UI architecture and also as an audio architecture, proposing a new and original way to make digital signal computation.
-
-%---------------------------------------------------
-\subsection{OSC GUI architecture module}
-\label{sec:oscgui}
-
-The OSC UI architecture transforms each UI active widget addition into an \code{addnode} call, ignores the passive widgets and transforms container calls (\code{openXxxBox, closeBox}) into \code{opengroup} and \code{closegroup} calls.
-
-\subsubsection{OSC address space and messages} 
-The OSC address space adheres strictly to the hierarchy defined by the \code{addnode} and \code{opengroup, closegroup} calls. It supports the OSC pattern matching mechanism as described in \cite{OSC}.
-
-A node expects to receive OSC messages with a single float value as parameter. This policy is strict for the parameters count, but relaxed for the parameter type: OSC int values are accepted and casted to float.
-
-\begin{table}[htdp]
-\begin{center}
-\begin{tabular}{|c|c|c|}
-\hline
-\bf{Audio system} 	& \bf{Environment} & \bf{OSC support}	\\
-\hline
-\OSTab{Linux} \\
-%\multicolumn{3}{|l|}{Linux} \\
-\hline
-Alsa  			& GTK, Qt				& yes\\
-Jack 			& GTK, Qt, Console		& yes\\
-PortAudio 		& GTK, Qt				& yes\\
-\hline
-\OSTab{Mac OS X} \\
-\hline
-CoreAudio 		& Qt 			& yes\\
-Jack 			& Qt, Console & yes\\
-PortAudio 		& Qt 			& yes\\
-\hline
-\OSTab{Windows} \\
-\hline
-Jack 			& Qt, Console & yes\\
-PortAudio 		& Qt 			& yes\\
-\hline
-\OSTab{iOS (iPhone)} \\
-\hline
-CoreAudio		& Cocoa 		& not yet\\
-\hline
-\end{tabular}
-\end{center}
-\caption{OSC support in \faust application's architectures.}
-\label{tab:oscarch}
-\end{table}
-
-
-Two additional messages are defined to provide \faust applications discovery and address space discoveries:
-\begin{itemize}
-\item the \code{hello} message: accepted by any module root address. The module responds with its root address, followed by its IP address and the UDP port numbers (listening port, output port, error port).
-See the network management section below for ports numbering scheme.
-\item the \code{get} message: accepted by any valid OSC address. The \code{get} message is propagated to every terminal node that responds with its OSC address and current values (value, min and max).
-\end{itemize}
-
-\textbf{Example:} \\
-Consider the \emph{noise} module provided with the \faust examples:
-\begin{itemize}
-\item it sends \code{/noise 192.168.0.1 5510 5511 5512} \\in answer to a \code{hello} message,
-\item it sends \code{/noise/Volume 0.8 0. 1.} \\in answer to a \code{get} message.
-\end{itemize}
-
- 
-\subsubsection{Network management.}
-The OSC module makes use of three different UDP port numbers:
-\begin{itemize}
-\item 5510 is the listening port number: control messages should be addressed to this port.
-\item 5511 is the output port number: answers to query messages are sent to this port.
-\item 5512 is the error port number: used for asynchronous error notifications.
-\end{itemize}
-
-When the UDP listening port number is busy (for instance in case of multiple \faust programs running), the system automatically looks for the next available port number. Unless otherwise specified by the command line, the UDP output port numbers are unchanged. 
-
-A program sends its name (actually its root address) and allocated port numbers on the OSC output port on startup.
-
-Port numbers can be changed on the command line with the following options: \\
-\hspace*{6mm}\lstinline'[-port | -outport | -errport] number'
-
-The default UDP output streams destination is \code{localhost}. It can also be changed with the command line option \\
-\hspace*{6mm}\code{-dest address} where address is a host name or an IP number.
-
-%---------------------------------------------------
-\subsection{OSC message aliases}
-\label{sec:oscaudio}
-Alias is a metadata-based mechanism allowing to map arbitrary incoming OSC messages to program parameters. 
-%%This is  convenient when one has no control on the OSC messages emitted. 
-Some remote controllers, like TouchOSC on Android, can only transmit predefined messages, for example \lstinline'/1/push1 1.000000' when push button 1 is pressed, \lstinline'/accxyz -0.421380 0.268151 9.232041' for the x, y and z accelerometers, \lstinline'/1/fader1 0.563994' when fader 1 is moved, etc. 
-
-Such messages can be used to control a specific program parameter by inserting an OSC metadata \lstinline'[osc:/path/name]' in its label. For example \lstinline'vslider("Volume", 0, 0, 1, 0.1)' can be controlled by TouchOSC fader 1 by indicating its OSC address : \lstinline'vslider("Volume[osc:/1/fader1]", 0, 0, 1, 0.1)' (see table \ref{tab:oscalias} for a more complete list of aliases).  
-
-By default the incoming value range is assumed to be between 0 and 1. But it is possible to indicate a different range : \lstinline'[osc:/path/name min max]'. When incoming messages provide more than one value it is possible to select the right one with an additional suffix (numbered starting form 0) to the pathname.  For instance \lstinline'vslider("Volume[osc:/accxyz/1 -10 10]", 0, 0, 1, 0.1)' would allow to control the volume using the $y$ accelerometer. Moreover the accelerometer's values are mapped from range $[-10..10]$ to range $[0..1]$.
-
-
-\begin{table}[htdp]
-\begin{center}
-\begin{tabular}{|l|l|}
-\hline
-\bf{alias} 	& \bf{description}	\\
-\hline
-\lstinline'[osc:/1/rotary1]' & top left rotary knob\\
-\lstinline'[osc:/1/rotary2]' & middle left rotary knob\\
-\lstinline'[osc:/1/rotary3]' & bottom left rotary knob\\
-\lstinline'[osc:/1/push1]' & bottom left push button\\
-\lstinline'[osc:/1/push2]' & bottom center left push button\\
-\hline
-\lstinline'[osc:/1/toggle1]' & top center left toggle button\\
-\lstinline'[osc:/1/toggle2]' & middle center left toggle button\\
-\lstinline'[osc:/1/fader1]' & center left vertical fader\\
-\hline
-\lstinline'[osc:/1/toggle3]' & top center right toggle button\\
-\lstinline'[osc:/1/toggle4]' & middle center right toggle button\\
-\lstinline'[osc:/1/fader2]' & center right vertical toggle button\\
-\hline
-\lstinline'[osc:/1/rotary4]' & top right rotary knob\\
-\lstinline'[osc:/1/rotary5]' & middle right rotary knob\\
-\lstinline'[osc:/1/rotary6]' & bottom right rotary knob\\
-\lstinline'[osc:/1/push3]' & bottom center right push button\\
-\lstinline'[osc:/1/push4]' & bottom right push button\\
-\hline
-\lstinline'[osc:/1/fader3]' & bottom horizontal fader\\
-\hline
-\lstinline'[osc:/accxyz/0 -10 10]' &  $x$ accelerometer\\
-\lstinline'[osc:/accxyz/1 -10 10]' &  $y$ accelerometer\\
-\lstinline'[osc:/accxyz/2 -10 10]' &  $z$ accelerometer\\
-\hline
-\end{tabular}
-\end{center}
-\caption{Examples of OSC message aliases for TouchOSC (layout Mix2). Since most of these messages produce values in the default range $[0..1]$ , there is no need to indicate this range. Accelerometers producing values in a different range, this range $[-10..10]$ has to be indicated. }
-\label{tab:oscalias}
-\end{table}
-
-
-%---------------------------------------------------
-\subsection{OSC audio architecture}
-\label{sec:oscaudio}
-
-The OSC audio architecture implements an audio architecture where audio inputs and outputs are replaced by OSC messages. Using this architecture, a \faust module accepts arbitrary data streams on its root OSC address, and handles this input stream as interleaved signals. Thus, each incoming OSC packet addressed to a module root triggers a computation loop, where as many values as the number of incoming frames are computed.
-
-The output of the signal computation is sent to the OSC output port as non-interleaved data to the OSC addresses \code{/root/n} where \code{root} is the module root address and \code{n} is the output number (indexed from 0).
-
-For example: \\
-consider a \faust program named \emph{split} and defined by:\\
-\hspace*{6mm} \lstinline'process = _ <: _,_' \\
-the message \\
-\hspace*{6mm} \code{/split 0.3}
-\\ will produce the 2 following messages as output: \\
-\hspace*{6mm}\code{/split/0 0.3}\\
-\hspace*{6mm}\code{/split/1 0.3}
-
-
-The OSC audio architecture provides a very convenient way to execute a signal processing at an arbitrary rate, even allowing to make step by step computation. Connecting the output OSC signals to Max/MSP or to a system like INScore\footnote{\url{http://inscore.sf.net}}\cite{Fober:10c}, provides a close examination of the computation results.
-
diff --git a/documentation/faust-quick-reference-src/chapters/http.tex b/documentation/faust-quick-reference-src/chapters/http.tex
new file mode 100644
index 0000000..bc834a0
--- /dev/null
+++ b/documentation/faust-quick-reference-src/chapters/http.tex
@@ -0,0 +1,232 @@
+%---------------------------------------------------
+\chapter{HTTP support} \label{sec:http}
+%---------------------------------------------------
+
+Similarly to OSC, several \faust architectures provide also HTTP support. This allows \faust applications to be remotely controlled from any web browser using specific URLs. Moreover OSC and HTTPD can be freely combined.
+
+While OSC support is installed by default when \faust is build, this is not the case for HTTP. That's because it depends on GNU \emph{libmicrohttpd} library which is usually not installed by default on the system. An additional \lstinline'make httpd' step is therefore required when compiling and installing \faust:
+\begin{lstlisting}
+make httpd
+make
+sudo make install
+\end{lstlisting}
+Note that \lstinline'make httpd' will fail if \emph{libmicrohttpd} is not available on the system.
+
+The HTTP support can be activated using the \code{-httpd} option when building the audio application with the appropriate \code{faust2xxx} command. The following table (table \ref{tab:httparch}) lists \faust's architectures which provide HTTP support. 
+
+\begin{table}[htdp]
+\begin{center}
+\begin{tabular}{rcc}
+\hline
+\bf{Audio system} 	& \bf{Environment} & \bf{HTTP support}	\\
+\hline
+%\OSTab{Linux} \\
+%\multicolumn{3}{|l|}{Linux} \\
+%\hline
+\\
+\emph{Linux}\\
+Alsa  			& GTK, Qt, Console		& yes\\
+Jack 			& GTK, Qt, Console		& yes\\
+Netjack 			& GTK, Qt, Console & yes\\
+PortAudio 		& GTK, Qt				& yes\\
+%\hline
+\\
+\emph{Mac OS X} \\
+%\hline
+CoreAudio 		& Qt 			& yes\\
+Jack 			& Qt, Console & yes\\
+Netjack 			& Qt, Console & yes\\
+PortAudio 		& Qt 			& yes\\
+%\hline
+\\
+\emph{Windows} \\
+%\hline
+Jack 			& Qt, Console & yes\\
+PortAudio 		& Qt 			& yes\\
+%\hline
+\hline
+\end{tabular}
+\end{center}
+\caption{\faust architectures with HTTP support.}
+\label{tab:httparch}
+\end{table}
+
+
+\section{A simple example}
+
+To illustrate how HTTP support works let's reuse our previous \code{mix4.dsp} example, a very simplified monophonic audio mixer with 4 inputs and one output. For each input we have a mute button and a level slider:
+\begin{lstlisting}
+input(v) = vgroup("input %v", *(1-checkbox("mute")) 
+         : *(vslider("level", 0, 0, 1, 0.01)));
+process  = hgroup("mixer", par(i, 4, input(i)) :> _);
+\end{lstlisting}
+
+We are going to compile this example as a standalone Jack QT application with HTTP support using the command:
+\begin{lstlisting}
+faust2jaqt -httpd mix4.dsp
+\end{lstlisting}
+Th effect of the \code{-httpd} is to embed a small web server into the application. The purpose of this web server is to serve an HTML page representing the user interface for the application. This page makes use of javascript and SVG and is quite similar to the native QT interface.
+
+When we start the application from the command line:
+\begin{lstlisting}
+./mix4 
+\end{lstlisting}
+we get various information on the standard output, including:
+\begin{lstlisting}
+Faust httpd server version 0.72 is running on TCP port 5510
+\end{lstlisting}
+As we can see the embedded WEB server is running by default on TCP port 5510. The entry point is \url{http://localhost:5510}. It can be open from any recent browser and it produces the page reproduced figure \ref{fig:mix4-http}.
+
+
+\begin{figure}[h!]
+  \centering
+  \includegraphics[scale=0.275]{images/mix4-http.png}
+  \caption{User interface of mix4.dsp in a web browser}   
+  \label{fig:mix4-http}
+\end{figure}
+
+\section{JSON description of the user interface}
+The communication between the application and the web browser is based on several underlying URLs. The first one is \url{http://localhost:5510/JSON} that return a json description of the user interface of the application. This json description is used internally by the Javascript code to build the graphical user interface. Here is (part of) the json returned by \code{mix4}:
+\begin{lstlisting}
+{
+  "name": "mix4",
+  "address": "YannAir.local",
+  "port": "5511",
+  "ui": [
+    {
+      "type": "hgroup",
+      "label": "mixer",
+      "items": [
+        {
+          "type": "vgroup",
+          "label": "input_0",
+          "items": [
+            {
+              "type": "vslider",
+              "label": "level",
+              "address": "/mixer/input_0/level",
+              "init": "0", "min": "0", "max": "1", 
+              "step": "0.01"
+            },
+            {
+              "type": "checkbox",
+              "label": "mute",
+              "address": "/mixer/input_0/mute",
+              "init": "0", "min": "0", "max": "0", 
+              "step": "0"
+            }
+          ]
+        },
+        
+        ...
+        
+      ]
+    }
+  ]
+}
+\end{lstlisting}
+
+\section{Quering the state of the application}
+
+Each widget has a unique "address" field that can be used to query its value. In our example here the level of the input 0 has the address \lstinline'/mixer/input_0/level'. The address can be used to forge an URL to get the value of the widget: \url{http://localhost:5510/mixer/input_0/level}, resulting in:
+\begin{lstlisting}
+/mixer/input_0/level 0.00000  
+\end{lstlisting}
+
+Multiple widgets can be query at once by using an address higher in the hierarchy. For example to get the values of the level and the mute state of input 0 we use \url{http://localhost:5510/mixer/input_0}, resulting in:
+\begin{lstlisting}
+/mixer/input_0/level 0.00000 
+/mixer/input_0/mute  0.00000 
+\end{lstlisting}
+
+To get the all the values at once we simply use \url{http://localhost:5510/mixer}, resulting in:
+\begin{lstlisting}
+/mixer/input_0/level 0.00000 
+/mixer/input_0/mute  0.00000 
+/mixer/input_1/level 0.00000 
+/mixer/input_1/mute  0.00000 
+/mixer/input_2/level 0.00000 
+/mixer/input_2/mute  0.00000 
+/mixer/input_3/level 0.00000 
+/mixer/input_3/mute  0.00000 
+\end{lstlisting}
+
+
+\section{Changing the value of a widget}
+
+\begin{figure}[h!]
+  \centering
+  \includegraphics[scale=0.35]{images/mix4-http-mute.png}
+  \caption{Muting input 1 by forging the appropriate URL}   
+  \label{fig:mix4-http-mute}
+\end{figure}
+
+Let's say that we want to mute input 1 of our mixer. We can use for that purpose the URL \url{http://localhost:5510/mixer/input_1/mute?value=1} obtained by concatenating \url{?value=1} at the end of the widget URL. 
+
+All widgets can be controlled similarly. For example \url{http://localhost:5510/mixer/input_3/level?value=0.7} will sets the input 3 level to 0.7.
+
+
+\section{HTTP cheat sheet}
+Here is a summary of the various URLs used to interact with the application's web server.
+\subsection*{Default ports}
+
+\begin{tabular}{ll}
+\lstinline'5510' & default TCP port used by the application's web server\\
+\lstinline'5511...' & alternative TCP ports
+\end{tabular}
+
+\subsection*{Command line options}
+
+\begin{tabular}{rl}
+\lstinline'-port' $n$ & set the TCP port number used by the application's web server\\
+\end{tabular}
+
+\subsection*{URLs}
+
+\begin{tabular}{ll}
+\code{http://}\emph{host}\code{:}\emph{port}\code{/JSON} & get a json description of the user interface \\
+\code{http://}\emph{host}\code{:}\emph{port}\code{/}\emph{address} & get the value of a widget or a group of widgets \\
+\code{http://}\emph{host}\code{:}\emph{port}\code{/}\emph{address}\code{?value=}\emph{v} & set the value of a widget to $v$
+\end{tabular}
+
+\subsection*{JSON}
+\subsubsection*{Top level}
+The json describes the name, host and port of the application and a hierarchy of user interface items:
+\begin{lstlisting}
+{
+  "name": <name>,
+  "address": <host>,
+  "port": <port>,
+  "ui": [ <item> ]
+}
+\end{lstlisting}
+An \code{<item>} is either a group (of items) or a widget.
+
+\subsubsection*{Groups}
+A group is essentially a list of items with a specific layout: 
+\begin{lstlisting}
+{
+	"type": <type>,
+	"label": <label>,
+	"items": [ <item>, <item>,...]
+}
+\end{lstlisting}
+The \code{<type>} defines the layout. It can be either \code{"vgroup"}, \code{"hgroup"} or \code{"tgroup"}
+
+\subsubsection*{Widgets}
+\begin{lstlisting}
+{
+	"type": <type>,
+	"label": <label>,
+	"address": <address>,
+	"meta": [ { "key": "value"},... ],
+	"init": <num>,
+	"min": <num>,
+	"max": <num>,
+	"step": <num>
+},
+\end{lstlisting}
+Widgets are the basic items of the user interface. They can be of different \code{<type>} : \code{"button"},  \code{"checkbox"}, \code{"nentry"}, \code{"vslider"}, \code{"hslider"}, \code{"vbargraph"} or \code{"hbargraph"}.
+
+
+
diff --git a/documentation/faust-quick-reference-src/chapters/osc.tex b/documentation/faust-quick-reference-src/chapters/osc.tex
new file mode 100644
index 0000000..590d5fd
--- /dev/null
+++ b/documentation/faust-quick-reference-src/chapters/osc.tex
@@ -0,0 +1,568 @@
+%---------------------------------------------------
+\chapter{OSC support} \label{sec:osc}
+%---------------------------------------------------
+
+Most \faust architectures provide Open Sound Control (OSC) support \footnote{The implementation is based internally on the \emph{oscpack} library by Ross Bencina}. This allows \faust applications to be remotely controlled from any OSC capable application, programming language, or hardware device. OSC support can be activated using the 
+\code{-osc} option when building the application with the appropriate \code{faust2xxx} command. The following table (table \ref{tab:oscarch}) lists \faust's architectures which provide OSC support. 
+
+\begin{table}[htdp]
+\begin{center}
+\begin{tabular}{rcc}
+\hline
+\bf{Audio system} 	& \bf{Environment} & \bf{OSC support}	\\
+\hline
+%\OSTab{Linux} \\
+%\multicolumn{3}{|l|}{Linux} \\
+%\hline
+\\
+\emph{Linux}\\
+Alsa  			& GTK, Qt, Console		& yes\\
+Jack 			& GTK, Qt, Console		& yes\\
+Netjack 			& GTK, Qt, Console & yes\\
+PortAudio 		& GTK, Qt				& yes\\
+%\hline
+\\
+\emph{Mac OS X} \\
+%\hline
+CoreAudio 		& Qt 			& yes\\
+Jack 			& Qt, Console & yes\\
+Netjack 			& Qt, Console & yes\\
+PortAudio 		& Qt 			& yes\\
+%\hline
+\\
+\emph{Windows} \\
+%\hline
+Jack 			& Qt, Console & yes\\
+PortAudio 		& Qt 			& yes\\
+%\hline
+\hline
+\end{tabular}
+\end{center}
+\caption{\faust architectures with OSC support.}
+\label{tab:oscarch}
+\end{table}
+
+
+\section{A simple example}
+
+%Let's use a very simple 'noise.dsp' example, a white noise generator with a level control, to illustrate how OSC support works:
+To illustrate how OSC support works let's define a very simple noise generator with a level control: \lstinline'noise.dsp'
+\begin{lstlisting}
+	process = library("music.lib").noise 
+	        * hslider("level", 0, 0, 1, 0.01);
+\end{lstlisting}
+	
+We are going to compile this example as a standalone Jack QT application with OSC support using the command:
+\begin{lstlisting}
+	faust2jaqt -osc noise.dsp
+\end{lstlisting}
+
+When we start the application from the command line:
+\begin{lstlisting}
+	./noise 
+\end{lstlisting}
+we get various information on the standard output, including:
+\begin{lstlisting}
+	Faust OSC version 0.93 application 'noise' is running on UDP ports 5510, 5511, 5512
+\end{lstlisting}
+As we can see the OSC module makes use of three different UDP ports:
+\begin{itemize}
+\item \lstinline'5510' is the listening port number: control messages should be addressed to this port.
+\item \lstinline'5511' is the output port number: control messages sent by the application and answers to query messages are sent to this port.
+\item \lstinline'5512' is the error port number: used for asynchronous error notifications.
+\end{itemize}
+
+
+These OSC parameters can be changed from the command line using one of the following options:
+%\begin{lstlisting}
+%	-port number
+%	-outport number
+%	-errport number
+%	-desthost host
+%	-xmit	0|1 
+%\end{lstlisting}
+\begin{itemize}
+\item \lstinline'-port number' set the port number used by the application to receive messages.
+\item \lstinline'-outport number' set the port number used by the application to transmit messages.
+\item \lstinline'-errport number' set the port number used by the application to transmit error messages.
+\item \lstinline'-desthost host' set the destination host for the messages sent by the application.
+\item \lstinline'-xmit 1|0' turn transmission ON or OFF (default OFF). When transmission is ON user's actions are transmitted as OSC messages.
+\item \lstinline'-xmitfilter path' allows to filter output messages. Note that 'path' can be a regular expression (like "/freeverb/Reverb1/*").
+\end{itemize}
+
+For example:
+\begin{lstlisting}
+	./noise -xmit 1 -desthost 192.168.1.104 -outport 6000
+\end{lstlisting}
+will run noise with transmission mode ON, using 192.168.1.104 on port 6000 as destination.
+
+\section{Automatic port allocation}
+In order to address each application individually, only one application can be listening on a single port at one time. Therefore when the default incoming port 5510 is already opened by some other application, an application will automatically try increasing port numbers until it finds an available port. Let's say that we start two applications \code{noise} and \code{mixer} on the same machine, here is what we get:
+\begin{lstlisting}
+	$ ./noise &
+	...
+	Faust OSC version 0.93 application 'noise' is running on UDP ports 5510, 5511, 5512
+	$ ./mixer
+	...
+	Faust OSC version 0.93 application 'mixer' is running on UDP ports 5513, 5511, 5512
+\end{lstlisting}
+The \code{mixer} application fails to open the default incoming port 5510 because it is already opened by \code{noise}. Therefore it tries to find an available port starting from 5513 and open it. Please note that the two outcoming ports 5511 and 5512 are shared by all running applications.
+
+\section{Discovering OSC applications}
+
+The commands \code{oscsend}\marginpar{\code{oscsend} \emph{hostname} \emph{port} \emph{address} \emph{types} \emph{values}: send OpenSound Control message via UDP. \emph{types} is a string, the letters indicates the type of the following values: i=integer, f=float, s=string,...}
+Send OpenSound Control message via UDP. and \code{oscdump}\marginpar{\code{oscdump} \emph{port} : receive OpenSound Control messages via UDP and dump to standard output} from the liblo package provide a convenient mean to experiment with OSC control. For the experiment let's use two additional terminals. The first one will be used to send OSC messages to the noise application using \code{oscsend}. The second terminal will be used to monitor the messages sent by the application using \code{oscdump}. We will indicate by \lstinline'T1$' the command types on terminal T1 and by \lstinline'T2:' the messages received on terminal T2. To monitor on terminal T2 the OSC messages received on UDP port 5511 we will use \code{oscdump}:
+\begin{lstlisting}
+	T2$ oscdump 5511
+\end{lstlisting}
+
+
+Once set we can use the \code{hello} message  to scan UDP ports for FAUST applications. For example:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 "/*" s hello
+\end{lstlisting}
+
+gives us the root message address, the network and the UDP ports used by the noise application :
+\begin{lstlisting}
+	T2: /noise siii "192.168.1.102" 5510 5511 5512
+\end{lstlisting}
+
+
+\section{Discovering the OSC interface of an application}
+
+Once we have an application we can discover its OSC interface (the set of OSC messages we can use to control it) by sending the \code{get} message to the root:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /noise s get 
+\end{lstlisting}
+
+As an answer of the osc messages  understood by the application, a full description is available on terminal T2:
+\begin{lstlisting}
+	T2: /noise sF "xmit" #F
+	T2: /noise ss "desthost" "127.0.0.1"
+	T2: /noise si "outport" 5511
+	T2: /noise si "errport" 5512
+	T2: /noise/level fff 0.000000 0.000000 1.000000
+\end{lstlisting}
+
+The root of the osc interface is \code{/noise}. Transmission is OFF, \code{xmit} is set to false. The destination host for sending messages is \code{"127.0.0.1"}, the output port is \code{5511} and the error port is \code{5512}. The application has only one user interface element: \code{/noise/level} with current value \code{0.0}, minimal value \code{0.0} and maximal value \code{1.0}.
+
+
+
+\section{Widget's OSC address}
+
+Each widget of an application has a unique OSC address obtained by concatenating the labels of it's surrounding groups with its own label. 
+\marginpar{ There are potential conflicts between widget's labels and the OSC address space. An OSC symbolic name is an ASCII string consisting of a restricted set of printable characters. Therefore to ensure compatibility spaces are replaced by underscores and some other characters (asterisk, comma, forward, question mark, open bracket, close bracket, open curly brace, close curly brace) are replaced by hyphens.}
+Here is as an example \code{mix4.dsp}, a very simplified monophonic audio mixer with 4 inputs and one output. For each input we have a mute button and a level slider:
+\begin{lstlisting}
+	input(v) = vgroup("input %v", *(1-checkbox("mute")) : *(vslider("level", 0, 0, 1, 0.01)));
+	process = hgroup("mixer", par(i, 4, input(i)) :> _);
+\end{lstlisting}
+If we query this application:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 "/*" s get 
+\end{lstlisting}
+
+We get a full description of its OSC interface on terminal T2:
+\begin{lstlisting}
+	T2: /mixer sF "xmit" #F
+	T2: /mixer ss "desthost" "127.0.0.1"
+	T2: /mixer si "outport" 5511
+	T2: /mixer si "errport" 5512
+	T2: /mixer/input_0/level fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_0/mute  fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_1/level fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_1/mute  fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_2/level fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_2/mute  fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_3/level fff 0.0000 0.0000 1.0000
+	T2: /mixer/input_3/mute  fff 0.0000 0.0000 1.0000
+\end{lstlisting}
+
+As we can see each widget has a unique OSC address obtained by concatenating the top level group label "mixer", with the "input" group label and the widget label. Please note that in this operation whites spaces are replaced by underscores and metadata are removed. 
+
+All addresses must have a common root. This is the case in our example because there is a unique horizontal group "mixer" containing all widgets. If a common root is missing as in the following code:
+\begin{lstlisting}
+	input(v) = vgroup("input %v", *(1-checkbox("mute")) : *(vslider("level", 0, 0, 1, 0.01)));
+	process = par(i, 4, input(i)) :> _;
+\end{lstlisting}
+then a default vertical group is automatically create by the \faust compiler using the name of the file \code{mix4} as label:
+\begin{lstlisting}
+	T2: /mix4 sF "xmit" #F
+	T2: /mix4 ss "desthost" "127.0.0.1"
+	T2: /mix4 si "outport" 5511
+	T2: /mix4 si "errport" 5512
+	T2: /mix4/input_0/level fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_0/mute  fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_1/level fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_1/mute  fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_2/level fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_2/mute  fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_3/level fff 0.0000 0.0000 1.0000
+	T2: /mix4/input_3/mute  fff 0.0000 0.0000 1.0000
+\end{lstlisting}
+
+ 
+\section{Controlling the application via OSC}
+
+We can control any user interface element of the application by sending one of the previously discovered messages. For example to set the noise level of the application to \code{0.2} we send:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /noise/level f 0.2
+\end{lstlisting}
+	
+If we now query \code{/noise/level} we get, as expected, the value \code{0.2}:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /noise/level s get
+	T2: /noise/level fff 0.2000 0.0000 1.0000
+\end{lstlisting}
+
+
+\section{Turning transmission ON}
+The xmit message at the root level is used to control the realtime transmission of OSC messages corresponding to user interface's actions. For examples:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /noise si xmit 1
+\end{lstlisting}
+
+turns transmission on. Now if we move the level slider we get a bunch of messages:
+
+\begin{lstlisting}
+	T2: /noise/level f 0.024000
+	T2: /noise/level f 0.032000
+	T2: /noise/level f 0.105000
+	T2: /noise/level f 0.250000
+	T2: /noise/level f 0.258000
+	T2: /noise/level f 0.185000
+	T2: /noise/level f 0.145000
+	T2: /noise/level f 0.121000
+	T2: /noise/level f 0.105000
+	T2: /noise/level f 0.008000
+	T2: /noise/level f 0.000000
+\end{lstlisting}
+
+This feature can be typically used for automation to record and replay actions on the user interface, or to remote control from one application to another. It can be turned OFF any time using:
+
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /noise si xmit 0
+\end{lstlisting}
+
+\section{Filtering OSC messages}
+
+When the transmission of OSC messages is ON, all the user interface elements are sent through the OSC connection.  
+
+\begin{lstlisting}
+	T2: /harpe/level f 0.024000
+	T2: /harpe/hand f 0.1
+	T2: /harpe/level f 0.024000
+	T2: /harpe/hand f 0.25
+	T2: /harpe/level f 0.024000
+	T2: /harpe/hand f 0.44
+	T2: /noise/level f 0.145000
+	T2: /harpe/hand f 0.78
+	T2: /noise/level f 0.145000
+	T2: /harpe/hand f 0.99
+\end{lstlisting}
+
+We can choose to filter the unwanted parameters (or group of parameters).  For example:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /harpe si xmit 1 xmitfilter /harpe/level
+\end{lstlisting}
+
+As a result, we will receive:
+\begin{lstlisting}
+	T2: /harpe/hand f 0.1
+	T2: /harpe/hand f 0.25
+	T2: /harpe/hand f 0.44
+	T2: /harpe/hand f 0.78
+\end{lstlisting}
+
+To reset the filter, send:
+\begin{lstlisting}
+	T1$ oscsend localhost 5510 /harpe si xmit 1 xmitfilter
+\end{lstlisting}
+
+\section{Using OSC aliases}
+
+Aliases are a convenient mechanism to control a \faust application from a preexisting set of OSC messages. 
+
+Let's say we want to control our noise example with touchOSC on Android. The first step is to configure TouchOSC host to 192.168.1.102 (the host running our noise application) and outgoing port to 5510. 
+
+Then we can use oscdump 5510 (after quitting the noise application in order to free port 5510) to visualize the OSC messages sent by TouchOSC. Let's use for that the left slider of simple layout. Here is what we get:
+
+\begin{lstlisting}
+	T2: /1/fader1 f 0.000000
+	T2: /1/fader1 f 0.004975
+	T2: /1/fader1 f 0.004975
+	T2: /1/fader1 f 0.008125
+	T2: /1/fader1 f 0.017473
+	T2: /1/fader1 f 0.032499
+	T2: /1/fader1 f 0.051032
+	T2: ...
+	T2: /1/fader1 f 0.993289
+	T2: /1/fader1 f 1.000000
+\end{lstlisting}
+
+We can associate this OSC message to the noise level slider by inserting the metadata [osc:/1/fader1 0 1] into the slider's label:
+\marginpar{
+Several osc aliases can be inserted into a single label allowing the same widget to be controlled by several OSC messages.
+}
+
+\begin{lstlisting}
+	process = library("music.lib").noise * hslider("level[osc:/1/fader1 0 1]",0,0,1,0.01);
+\end{lstlisting}
+	
+Because here the range of /1/fader1 is 0 to 1 like the level slider we can remove the range mapping information and write simply :
+
+\begin{lstlisting}
+	process = library("music.lib").noise * hslider("level[osc:/1/fader1]", 0, 0, 1, 0.01);
+\end{lstlisting}
+	
+TouchOSC can also send accelerometer data by enabling Settings/Options/Accelerometer. Using again oscdump 5510 we can visualize the messages send by TouchOSC:
+
+\begin{lstlisting}
+	T2: ...
+	T2: /accxyz fff -0.147842 0.019752 9.694721
+	T2: /accxyz fff -0.157419 0.016161 9.686341
+	T2: /accxyz fff -0.167594 0.012570 9.683948
+	T2: ...
+\end{lstlisting}
+
+As we can see TouchOSC send the x, y and z accelerometers in a single message, as a triplet of values ranging approximatively from $-9.81$ to $9.81$. In order to select the appropriate accelerometer we need to concatenate to /accxyz a suffix /0, /1 or /2. For example /accxyz/0 will correspond to x, /accxyz/1 to y, etc. We also need to define a mapping because the ranges are different:
+
+\begin{lstlisting}
+ process = library("music.lib").noise * hslider("level[osc:/accxyz/0 0 9.81]",0,0,1,0.01);
+\end{lstlisting}
+
+\begin{table}[htdp]
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline
+\bf{alias} 	& \bf{description}	\\
+\hline
+\lstinline'[osc:/1/rotary1 0 1]' & top left rotary knob\\
+\lstinline'[osc:/1/rotary2 0 1]' & middle left rotary knob\\
+\lstinline'[osc:/1/rotary3 0 1]' & bottom left rotary knob\\
+\lstinline'[osc:/1/push1 0 1]' & bottom left push button\\
+\lstinline'[osc:/1/push2 0 1]' & bottom center left push button\\
+\hline
+\lstinline'[osc:/1/toggle1 0 1]' & top center left toggle button\\
+\lstinline'[osc:/1/toggle2 0 1]' & middle center left toggle button\\
+\lstinline'[osc:/1/fader1 0 1]' & center left vertical fader\\
+\hline
+\lstinline'[osc:/1/toggle3 0 1]' & top center right toggle button\\
+\lstinline'[osc:/1/toggle4 0 1]' & middle center right toggle button\\
+\lstinline'[osc:/1/fader2 0 1]' & center right vertical toggle button\\
+\hline
+\lstinline'[osc:/1/rotary4 0 1]' & top right rotary knob\\
+\lstinline'[osc:/1/rotary5 0 1]' & middle right rotary knob\\
+\lstinline'[osc:/1/rotary6 0 1]' & bottom right rotary knob\\
+\lstinline'[osc:/1/push3 0 1]' & bottom center right push button\\
+\lstinline'[osc:/1/push4 0 1]' & bottom right push button\\
+\hline
+\lstinline'[osc:/1/fader3 0 1]' & bottom horizontal fader\\
+\hline
+\lstinline'[osc:/accxyz/0 -10 10]' &  $x$ accelerometer\\
+\lstinline'[osc:/accxyz/1 -10 10]' &  $y$ accelerometer\\
+\lstinline'[osc:/accxyz/2 -10 10]' &  $z$ accelerometer\\
+\hline
+\end{tabular}
+\end{center}
+\caption{Examples of OSC message aliases for TouchOSC (layout Mix2).}
+\label{tab:oscalias}
+\end{table}
+
+\section{OSC cheat sheet}
+
+\subsection*{Default ports}
+
+\begin{tabular}{ll}
+\lstinline'5510' & default listening port\\
+\lstinline'5511' & default transmission port\\
+\lstinline'5512' & default error port\\
+\lstinline'5513...' & alternative listening ports
+\end{tabular}
+
+\subsection*{Command line options}
+
+\begin{tabular}{rl}
+\lstinline'-port' $n$ & set the port number used by the application to receive messages\\
+\lstinline'-outport' $n$ & set the port number used by the application to transmit messages\\
+\lstinline'-errport' $n$ & set the port number used by the application to transmit error messages\\
+\lstinline'-desthost' $h$ & set the destination host for the messages sent by the application\\
+\lstinline'-xmit 1|0' & turn transmission ON or OFF (default OFF) \\
+\lstinline'-xmitfilter' $s$ & filter the \faust paths at emission time
+\end{tabular}
+
+\subsection*{Discovery messages}
+
+\begin{tabular}{ll}
+\lstinline'oscsend' \emph{host} \emph{port} \lstinline'"/*" s hello' & discover if any OSC application is listening on port $p$ \\
+\lstinline'oscsend' \emph{host} \emph{port} \lstinline'"/*" s get' & query OSC interface of application listening on port $p$
+\end{tabular}
+
+\subsection*{Control messages}
+
+\begin{tabular}{ll}
+\lstinline'oscsend' \emph{host} \emph{port} \lstinline'"/*"' \lstinline'si xmit 0|1' & set transmission mode \\
+\lstinline'oscsend' \emph{host} \emph{port} \emph{widget} \lstinline's get' & get widget's value \\
+\lstinline'oscsend' \emph{host} \emph{port} \emph{widget} \lstinline'f' $v$ & set widget's value
+\end{tabular}
+
+\subsection*{Alias}
+
+\begin{tabular}{ll}
+\lstinline'"...[osc:' \emph{address}  \emph{lo}  \emph{hi} \lstinline']..."' & alias with \emph{lo}$\rightarrow$\emph{min}, \emph{hi}$\rightarrow$\emph{max} mapping\\
+\lstinline'"...[osc:' \emph{address}\lstinline']..."' & alias with \emph{min}, \emph{max} clipping
+\end{tabular}
+
+%
+%\section{OLD}
+%
+%%---------------------------------------------------
+%\subsection{OSC GUI architecture module}
+%\label{sec:oscgui}
+%
+%The OSC UI architecture transforms each UI active widget addition into an \code{addnode} call, ignores the passive widgets and transforms container calls (\code{openXxxBox, closeBox}) into \code{opengroup} and \code{closegroup} calls.
+%
+%\subsubsection{OSC address space and messages} 
+%The OSC address space adheres strictly to the hierarchy defined by the \code{addnode} and \code{opengroup, closegroup} calls. It supports the OSC pattern matching mechanism as described in \cite{OSC}.
+%
+%A node expects to receive OSC messages with a single float value as parameter. This policy is strict for the parameters count, but relaxed for the parameter type: OSC int values are accepted and casted to float.
+%
+%\begin{table}[htdp]
+%\begin{center}
+%\begin{tabular}{|c|c|c|}
+%\hline
+%\bf{Audio system} 	& \bf{Environment} & \bf{OSC support}	\\
+%\hline
+%\OSTab{Linux} \\
+%%\multicolumn{3}{|l|}{Linux} \\
+%\hline
+%Alsa  			& GTK, Qt				& yes\\
+%Jack 			& GTK, Qt, Console		& yes\\
+%PortAudio 		& GTK, Qt				& yes\\
+%\hline
+%\OSTab{Mac OS X} \\
+%\hline
+%CoreAudio 		& Qt 			& yes\\
+%Jack 			& Qt, Console & yes\\
+%PortAudio 		& Qt 			& yes\\
+%\hline
+%\OSTab{Windows} \\
+%\hline
+%Jack 			& Qt, Console & yes\\
+%PortAudio 		& Qt 			& yes\\
+%\hline
+%\OSTab{iOS (iPhone)} \\
+%\hline
+%CoreAudio		& Cocoa 		& not yet\\
+%\hline
+%\end{tabular}
+%\end{center}
+%\caption{OSC support in \faust application's architectures.}
+%\label{tab:oscarch2}
+%\end{table}
+%
+%
+%Two additional messages are defined to provide \faust applications discovery and address space discoveries:
+%\begin{itemize}
+%\item the \code{hello} message: accepted by any module root address. The module responds with its root address, followed by its IP address and the UDP port numbers (listening port, output port, error port).
+%See the network management section below for ports numbering scheme.
+%\item the \code{get} message: accepted by any valid OSC address. The \code{get} message is propagated to every terminal node that responds with its OSC address and current values (value, min and max).
+%\end{itemize}
+%
+%\textbf{Example:} \\
+%Consider the \emph{noise} module provided with the \faust examples:
+%\begin{itemize}
+%\item it sends \code{/noise 192.168.0.1 5510 5511 5512} \\in answer to a \code{hello} message,
+%\item it sends \code{/noise/Volume 0.8 0. 1.} \\in answer to a \code{get} message.
+%\end{itemize}
+%
+% 
+%\subsubsection{Network management.}
+%The OSC module makes use of three different UDP port numbers:
+%\begin{itemize}
+%\item 5510 is the listening port number: control messages should be addressed to this port.
+%\item 5511 is the output port number: answers to query messages are sent to this port.
+%\item 5512 is the error port number: used for asynchronous error notifications.
+%\end{itemize}
+%
+%When the UDP listening port number is busy (for instance in case of multiple \faust programs running), the system automatically looks for the next available port number. Unless otherwise specified by the command line, the UDP output port numbers are unchanged. 
+%
+%A program sends its name (actually its root address) and allocated port numbers on the OSC output port on startup.
+%
+%Port numbers can be changed on the command line with the following options: \\
+%\hspace*{6mm}\lstinline'[-port | -outport | -errport] number'
+%
+%The default UDP output streams destination is \code{localhost}. It can also be changed with the command line option \\
+%\hspace*{6mm}\code{-dest address} where address is a host name or an IP number.
+%
+%%---------------------------------------------------
+%\subsection{OSC message aliases}
+%\label{sec:oscaudio}
+%Alias is a metadata-based mechanism allowing to map arbitrary incoming OSC messages to program parameters. 
+%%%This is  convenient when one has no control on the OSC messages emitted. 
+%Some remote controllers, like TouchOSC on Android, can only transmit predefined messages, for example \lstinline'/1/push1 1.000000' when push button 1 is pressed, \lstinline'/accxyz -0.421380 0.268151 9.232041' for the x, y and z accelerometers, \lstinline'/1/fader1 0.563994' when fader 1 is moved, etc. 
+%
+%Such messages can be used to control a specific program parameter by inserting an OSC metadata \lstinline'[osc:/path/name]' in its label. For example \lstinline'vslider("Volume", 0, 0, 1, 0.1)' can be controlled by TouchOSC fader 1 by indicating its OSC address : \lstinline'vslider("Volume[osc:/1/fader1]", 0, 0, 1, 0.1)' (see table \ref{tab:oscalias} for a more complete list of aliases).  
+%
+%By default the incoming value range is assumed to be between 0 and 1. But it is possible to indicate a different range : \lstinline'[osc:/path/name min max]'. When incoming messages provide more than one value it is possible to select the right one with an additional suffix (numbered starting form 0) to the pathname.  For instance \lstinline'vslider("Volume[osc:/accxyz/1 -10 10]", 0, 0, 1, 0.1)' would allow to control the volume using the $y$ accelerometer. Moreover the accelerometer's values are mapped from range $[-10..10]$ to range $[0..1]$.
+%
+%
+%\begin{table}[htdp]
+%\begin{center}
+%\begin{tabular}{|l|l|}
+%\hline
+%\bf{alias} 	& \bf{description}	\\
+%\hline
+%\lstinline'[osc:/1/rotary1]' & top left rotary knob\\
+%\lstinline'[osc:/1/rotary2]' & middle left rotary knob\\
+%\lstinline'[osc:/1/rotary3]' & bottom left rotary knob\\
+%\lstinline'[osc:/1/push1]' & bottom left push button\\
+%\lstinline'[osc:/1/push2]' & bottom center left push button\\
+%\hline
+%\lstinline'[osc:/1/toggle1]' & top center left toggle button\\
+%\lstinline'[osc:/1/toggle2]' & middle center left toggle button\\
+%\lstinline'[osc:/1/fader1]' & center left vertical fader\\
+%\hline
+%\lstinline'[osc:/1/toggle3]' & top center right toggle button\\
+%\lstinline'[osc:/1/toggle4]' & middle center right toggle button\\
+%\lstinline'[osc:/1/fader2]' & center right vertical toggle button\\
+%\hline
+%\lstinline'[osc:/1/rotary4]' & top right rotary knob\\
+%\lstinline'[osc:/1/rotary5]' & middle right rotary knob\\
+%\lstinline'[osc:/1/rotary6]' & bottom right rotary knob\\
+%\lstinline'[osc:/1/push3]' & bottom center right push button\\
+%\lstinline'[osc:/1/push4]' & bottom right push button\\
+%\hline
+%\lstinline'[osc:/1/fader3]' & bottom horizontal fader\\
+%\hline
+%\lstinline'[osc:/accxyz/0 -10 10]' &  $x$ accelerometer\\
+%\lstinline'[osc:/accxyz/1 -10 10]' &  $y$ accelerometer\\
+%\lstinline'[osc:/accxyz/2 -10 10]' &  $z$ accelerometer\\
+%\hline
+%\end{tabular}
+%\end{center}
+%\caption{Examples of OSC message aliases for TouchOSC (layout Mix2). Since most of these messages produce values in the default range $[0..1]$ , there is no need to indicate this range. Accelerometers producing values in a different range, this range $[-10..10]$ has to be indicated. }
+%\label{tab:oscalias}
+%\end{table}
+%
+%
+%%---------------------------------------------------
+%\subsection{OSC audio architecture}
+%\label{sec:oscaudio}
+%
+%The OSC audio architecture implements an audio architecture where audio inputs and outputs are replaced by OSC messages. Using this architecture, a \faust module accepts arbitrary data streams on its root OSC address, and handles this input stream as interleaved signals. Thus, each incoming OSC packet addressed to a module root triggers a computation loop, where as many values as the number of incoming frames are computed.
+%
+%The output of the signal computation is sent to the OSC output port as non-interleaved data to the OSC addresses \code{/root/n} where \code{root} is the module root address and \code{n} is the output number (indexed from 0).
+%
+%For example: \\
+%consider a \faust program named \emph{split} and defined by:\\
+%\hspace*{6mm} \lstinline'process = _ <: _,_' \\
+%the message \\
+%\hspace*{6mm} \code{/split 0.3}
+%\\ will produce the 2 following messages as output: \\
+%\hspace*{6mm}\code{/split/0 0.3}\\
+%\hspace*{6mm}\code{/split/1 0.3}
+%
+%
+%The OSC audio architecture provides a very convenient way to execute a signal processing at an arbitrary rate, even allowing to make step by step computation. Connecting the output OSC signals to Max/MSP or to a system like INScore\footnote{\url{http://inscore.sf.net}}\cite{Fober:10c}, provides a close examination of the computation results.
+%
diff --git a/documentation/faust-quick-reference-src/chapters/syntax.tex b/documentation/faust-quick-reference-src/chapters/syntax.tex
index 6dd0e6f..7b68940 100644
--- a/documentation/faust-quick-reference-src/chapters/syntax.tex
+++ b/documentation/faust-quick-reference-src/chapters/syntax.tex
@@ -1,7 +1,7 @@
 \chapter{\faust syntax}
 
 This section describes the syntax of \faust. Figure \ref{fig:syntax} gives an overview of the various concepts and where they are defined in this section. 
-%% suggestion Carlos : la figure crée une confusion entre la syructure de la syntaxe et la structure de la section. Faire un autre schema!
+%% suggestion Carlos : la figure crée une confusion entre la structure de la syntaxe et la structure de la section. Faire un autre schema!
 \begin{figure}[ht!]
 \centering
 \includegraphics[scale=0.45]{illustrations/syntax-chart}
@@ -315,7 +315,7 @@ the first rule will always match and the second rule will never be called.
 Despite its textual syntax, \faust is conceptually a block-diagram language. \faust expressions represent DSP block-diagrams and are assembled from primitive ones using various \textit{composition} operations. More traditional \textit{numerical} expressions in infix notation are also possible. Additionally \faust provides time based expressions, like delays, expressions related to lexical environments, expressions to interface with foreign function and lambda expressions.
 
 \begin{rail}
-expression : diagram | numerical | time | lexical | foreign | lambda;
+expression : diagram | insouts | numerical | time | lexical | foreign | lambda;
 \end{rail}
   
 \subsection{Diagram Expressions}
@@ -450,6 +450,29 @@ The inputs of the resulting block diagram are the remaining unconnected inputs o
 \label{figure:rec1}
 \end{figure}
 
+\subsubsection{Inputs and outputs of an expression}
+These two constructions can be used to know at compile time the number of inputs and outputs of any Faust expression. 
+
+\begin{rail}
+insouts: "inputs" '(' expression ')'
+       | "outputs" '(' expression ')';
+\end{rail}
+
+They are useful to define high order functions and build algorithmically complex block-diagrams. Here is an example to automatically reverse the order of the outputs of an expression.
+
+\begin{lstlisting}
+Xo(expr) = expr <: par(i,n,selector(n-i-1,n)) 
+		 with { n=outputs(expr); };
+\end{lstlisting}
+
+And the inputs of an expression :
+
+\begin{lstlisting}
+Xi(expr) = bus(n) <: par(i,n,selector(n-i-1,n)) : expr 
+		 with { n=inputs(expr); };
+\end{lstlisting}
+
+For example \lstinline'Xi(-)' will reverse the order of the two inputs of the substraction.
 
 
 
@@ -511,6 +534,10 @@ numiter : expression;
 The number of iterations must be a constant expression. 
 
 
+
+
+
+
 \subsection{Numerical Expressions}
 
 Numerical expressions are essentially syntactic sugar allowing to use a familiar infix notation to express mathematical expressions, bitwise operations and to compare signals. Please note that is this section only built-in primitives with an infix syntax are presented. A complete description of all the build-ins is available in the primitive section (see \ref{primitives}). 
@@ -774,7 +801,7 @@ An external C function is declared by indicating its name and signature as well
 The file \lstinline'"math.lib"' of the \faust distribution contains several foreign function definitions, for example the inverse hyperbolic sine function \lstinline'asinh':
 
 \begin{lstlisting}
-asinh = ffunction(float asinhf (float), <math.h>, "");
+asinh = ffunction(float asinh (float), <math.h>, "");
 \end{lstlisting}
 
 Foreign functions with input parameters are considered pure math functions. They are therefore considered free of side effects and called only when their parameters change (that is at the rate of the fastest parameter). 
@@ -783,12 +810,15 @@ Exceptions are functions with no input parameters. A typical example is the C \l
 
 
 \subsubsection{signature} 
-The signature part (\lstinline'float asinhf (float)' in our previous example) describes the prototype of the C function : return type, function name and list of parameter types. 
+The signature part (\lstinline'float asinh (float)' in our previous example) describes the prototype of the C function : return type, function name and list of parameter types. Because the name of the foreign function can possibly depend on the floating point precision in use (float, double and quad), it is possible to give a different function name for each floating point precision using a signature with up to three function names. 
 
 \begin{rail}
-signature : type identifier '(' (type + ',') ')';
+signature : type funnames '(' (type + ',') ')';
+funnames : identifier (| '|' identifier) (| '|' identifier);
 \end{rail}
 
+For example in the declaration \lstinline'asinh = ffunction(float asinhf|asinh|asinhl (float), <math.h>, "");', the signature  \lstinline'float asinhf|asinh|asinhl (float)' indicates to use the function name \lstinline'asinhf' in single precision, \lstinline'asinh' in double precision and \lstinline'asinhl' in long double (quad) precision.
+
 
 \subsubsection{types}
 Note that currently only numerical functions involving simple int and float parameters are allowed. No vectors, tables or data structures can be passed as parameters or returned.
@@ -981,6 +1011,17 @@ Please note that patterns are evaluated before the pattern matching operation. T
 \label{primitives}
 The primitive signal processing operations represent the built-in functionalities of \faust, that is the atomic operations on signals provided by the language. All these primitives denote \emph{signal processors}, functions transforming \emph{input signals} into \emph{output signals}.
 
+  \begin{rail}
+  primitive : number
+  			| waveform
+			| cprimitive
+			| mathprimitive
+			| delayandtables
+			| uielements
+			;
+  \end{rail}
+
+
 %--------------------------------------------------------------------------------------------------------------
 \subsection{Numbers}
 %--------------------------------------------------------------------------------------------------------------
@@ -1009,6 +1050,29 @@ Like any other \faust expression, numbers are signal processors. For example the
 
 %\end{tabular}
 
+
+%--------------------------------------------------------------------------------------------------------------
+\subsection{Waveforms}
+%--------------------------------------------------------------------------------------------------------------
+
+A waveform is a fixed periodic signal defined by a list of samples. A waveform has two outputs. The first output is constant and indicates the size (number of samples) of the period. The second output is the periodic signal itself. 
+
+
+  \begin{rail}
+  waveform : "waveform" lbrace (number + ',') rbrace;
+  \end{rail}
+
+For example \lstinline'waveform {0,1,2,3}' produces two outputs, the constant signal 4 and the periodic signal \lstinline'0,1,2,3,0,1,2,3,0,1'\ldots. 
+
+Please note that \lstinline'waveform' works nicely with \lstinline'rdtable'. Its first output, known at compile time, gives the size of the table, while the second signal gives the content of the table. Here is an example:
+\begin{lstlisting}
+process = waveform {10,20,30,40,50,60,70}, %(7)~+(3) : rdtable;
+\end{lstlisting}
+
+
+\bigskip
+
+
 %--------------------------------------------------------------------------------------------------------------
 \subsection{C-equivalent primitives}
 %--------------------------------------------------------------------------------------------------------------
@@ -1322,6 +1386,6 @@ a convenient means to control the alphabetical order of the widgets.
 \subsubsection{Attach}
 The \lstinline'attach' primitive takes two input signals and produce one output signal which is a copy of the first input. The role of \lstinline'attach' is to force its second input signal to be compiled with the first one. From a mathematical point of view \lstinline'attach(x,y)' is equivalent to \lstinline'1*x+0*y', which is in turn equivalent to \lstinline'x', but it tells the compiler not to optimize-out \lstinline'y'.
 
-To illustrate this role let say that we want to develop a mixer application with a vumeter for each input signals. Such vumeters can be easily coded in \faust using an envelop detector connected to a bargraph. The problem is that these envelop signals have no role in the output signals. Using \lstinline'attach(x,vumeter(x))' one can tel the compiler that when \lstinline'x' is compiled \lstinline'vumeter(x)' should also be compiled. 
+To illustrate this role let say that we want to develop a mixer application with a vumeter for each input signals. Such vumeters can be easily coded in \faust using an envelop detector connected to a bargraph. The problem is that these envelop signals have no role in the output signals. Using \lstinline'attach(x,vumeter(x))' one can tell the compiler that when \lstinline'x' is compiled \lstinline'vumeter(x)' should also be compiled. 
 
 
diff --git a/documentation/faust-quick-reference-src/faust-quick-reference.tex b/documentation/faust-quick-reference-src/faust-quick-reference.tex
index 9847ea2..6dca85b 100644
--- a/documentation/faust-quick-reference-src/faust-quick-reference.tex
+++ b/documentation/faust-quick-reference-src/faust-quick-reference.tex
@@ -137,9 +137,9 @@
 % \titlepic{
 %   \includegraphics[width=15cm]{images/bandeau-faust}
 % }
-\title{\Huge\color{yoheader}FAUST Quick Reference\\\Large(version 0.9.46)}
+\title{\Huge\color{yoheader}FAUST Quick Reference\\\Large(version 0.9.65)}
 \author{\textsc{Grame}\\Centre National de Cr\'eation Musicale}
-\date{January 2012} 
+\date{January 2014} 
 
 
 \railalias{recur}{$\sim$}
@@ -183,7 +183,7 @@
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                            		CHAPTERS                                         %
+%                            		CHAPTERS                                        %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -192,6 +192,8 @@
 \input{chapters/syntax}
 \input{chapters/compiler}
 \input{chapters/architectures}
+\input{chapters/osc}
+\input{chapters/http}
 \input{chapters/codegeneration} 
 \input{chapters/mathdoc} 
 \input{chapters/acknowledgments} 
diff --git a/documentation/faust-quick-reference-src/images/mix4-http-mute.png b/documentation/faust-quick-reference-src/images/mix4-http-mute.png
new file mode 100644
index 0000000..9e963b4
Binary files /dev/null and b/documentation/faust-quick-reference-src/images/mix4-http-mute.png differ
diff --git a/documentation/faust-quick-reference-src/images/mix4-http.png b/documentation/faust-quick-reference-src/images/mix4-http.png
new file mode 100644
index 0000000..f5304b6
Binary files /dev/null and b/documentation/faust-quick-reference-src/images/mix4-http.png differ
diff --git a/documentation/faust-quick-reference-src/images/noise-http-control.png b/documentation/faust-quick-reference-src/images/noise-http-control.png
new file mode 100644
index 0000000..15b9c08
Binary files /dev/null and b/documentation/faust-quick-reference-src/images/noise-http-control.png differ
diff --git a/documentation/faust-quick-reference-src/images/noise-http.png b/documentation/faust-quick-reference-src/images/noise-http.png
new file mode 100644
index 0000000..48c7437
Binary files /dev/null and b/documentation/faust-quick-reference-src/images/noise-http.png differ
diff --git a/documentation/faust-quick-reference.pdf b/documentation/faust-quick-reference.pdf
index 8695d77..5657326 100644
Binary files a/documentation/faust-quick-reference.pdf and b/documentation/faust-quick-reference.pdf differ
diff --git a/documentation/touchOSC.txt b/documentation/touchOSC.txt
index e8f7a9b..0761d94 100644
--- a/documentation/touchOSC.txt
+++ b/documentation/touchOSC.txt
@@ -7,7 +7,7 @@ expressed as Faust metadata ready to be inserted in widget labels.
 
 [osc:/accxyz/0 -10 10]  	x-accelerometer
 [osc:/accxyz/1 -10 10]  	y-accelerometer
-[osc:/accxyz/Z -10 10]  	z-accelerometer
+[osc:/accxyz/2 -10 10]  	z-accelerometer
 
 
 
diff --git a/documentation/using-faust-with-ros-src/Makefile b/documentation/using-faust-with-ros-src/Makefile
new file mode 100644
index 0000000..16f50b7
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/Makefile
@@ -0,0 +1,9 @@
+UsingFaustWithROS.pdf : UsingFaustWithROS.tex chapters/*.tex
+	pdflatex UsingFaustWithROS.tex
+	rail UsingFaustWithROS
+	pdflatex UsingFaustWithROS.tex
+	
+clean :
+	rm -f *.out *.toc *.pdf *.aux *.dvi *.rai *.rao *.log *~
+	
+	
diff --git a/documentation/using-faust-with-ros-src/chapters/cheatsheet.tex b/documentation/using-faust-with-ros-src/chapters/cheatsheet.tex
new file mode 100644
index 0000000..633dcc4
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/cheatsheet.tex
@@ -0,0 +1,27 @@
+\chapter{Cheat Sheet}
+\label{cheatsheet}
+
+\section*{Compilation}
+\begin{tabular}{p{2cm} p{7cm}}
+\lstinline'faust2ros' & compile a .dsp file\\
+\lstinline'faust2rosgtk' & compile a .dsp file with a GTK graphic interface\\
+\end{tabular}
+
+\paragraph{Options}~\\
+\begin{tabular}{p{2cm} p{7cm}}
+\lstinline'-install' & installation in a specified workspace\\
+\lstinline'-o' & rename the executable\\
+\end{tabular}
+
+\paragraph{Example}~\\
+\lstinline'faust2ros -install ~/catkin_ws -o harpe4ros ~/dsp/harpe.dsp'
+
+
+\section*{Run}
+\begin{tabular}{p{5cm} p{7cm}}
+\lstinline'rosrun harpe4ros harpe4ros' & run the executable \textit{harpe4ros}\\
+\end{tabular}
+\section*{Metadata}
+
+\lstinline'[ros:/my/topic msg_type msg_name msg_field]'\newline
+\lstinline'[ros:/my/topic msg_type msg_name msg_field min_value max_value]'
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/compilation.tex b/documentation/using-faust-with-ros-src/chapters/compilation.tex
new file mode 100644
index 0000000..2e333f5
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/compilation.tex
@@ -0,0 +1,143 @@
+\chapter{Compiling a FAUST Program for ROS Use}
+\label{chap:compilation}
+
+To compile a \faust program for a \ros use, you can use either the \lstinline'faust2ros' command, or the \lstinline'faust2rosgtk' one, which adds a gtk graphic user interface to the simple \lstinline'faust2ros' command.
+Note that all the \faust compilation options remain.
+\paragraph{Comment :}The compilation can last between 10 and 20 seconds. This is completely normal ! The bash script includes some \ros compilation with \lstinline'catkin_make'.
+
+\paragraph{\color{yoheader}BE CAREFUL !}To run these commands, you need to have \ros installed on your machine. They are indeed using \lstinline'catkin_make' and \lstinline'rosrun', which are \ros commands.
+
+\section{How does it work ?}
+\lstinline'faust2ros' (or \lstinline'faust2rosgtk') is a small command, which hides a lot of things. This section aims for a clarification.
+\subsection{Different steps}
+\label{subsec:steps}
+\newcounter{descriptcount}
+\begin{description}[%
+  before={\setcounter{descriptcount}{0}},%
+  ,font=\bfseries\stepcounter{descriptcount}Step \arabic{descriptcount}.~]
+\item [Workspace Creation :] if asked, a workspace can be created if it does not already exist. A workspace is considered as a \ros workspace if it contains a non-writable CMakeLists.txt in its \lstinline'src' folder. If the user wants to get a .zip file, a temporary workspace is created.
+\item [First compilation :] the .dsp file is compiled a first time thanks to the \faust compiler and the ros-callbacks.cpp architecture file. This step is dedicated to the \ros metadata. The C$++$ file is then compiled into an executable thanks to \lstinline'catkin', which uses CMake.
+\item [Second compilation :]the .dsp file is compiled again, thanks to the \faust compiler and the jack-ros.cpp architecture file (respectively jack-gtk-ros.cpp). This step creates the \ros code, with a missing class. This class is then included with the execution of the previous executable, and the C$++$ file can be compiled with \lstinline'catkin'.
+\item[Cleaning :] the package is compressed into a .zip archive and the temporary folder deleted.
+\end{description}
+
+\subsection{With an example}
+Let's imagine that I want to compile the harpe.dsp file. There are three parameters that can be 
+changed : attenuation, hand and level. I want \textit{hand} to be controlled through a topic 
+called \texttt{/my/robot/topic}. This topic is going to deliver messages of type 
+std\_msgs/Int64. \\
+My metadata declaration line will look like 
+\lstinline'[ros:/my/robot/topic std_msgs Int64 data]'.
+The second compilation (step 3 below in subsection \ref{subsec:steps}) will add a class called RosCallbacks in which are :
+\begin{itemize}
+\item a ranging function, that re-scales values from the topic to fit with the \faust sliders scale.
+\item a specific callback, called callback0, which sets the audio parameter value to the message value : \begin{lstlisting}
+void callback0(const std_msgs::Int64ConstPtr& msg, FAUSTFLOAT* zone)
+\end{lstlisting}
+\item a subscribing function, which calls callback0 in the \ros way : 
+\begin{lstlisting}
+void Subscribe(std::vector<FAUSTFLOAT*> zones)
+{
+ros::Subscriber* my_sub0 = new ros::Subscriber();
+*my_sub0 = nh_.subscribe<std_msgs::Int64>("my/robot/topic", 1, boost::bind(&RosCallbacks::callback0, this, _1, zones[0]));
+}
+\end{lstlisting}
+\end{itemize}
+
+\newpage
+\section{Compiling in a FAUST Archive}
+In order to compile a DSP file into a \faust archive, just type the command followed by your file : 
+\begin{lstlisting}
+faust2ros file.dsp
+\end{lstlisting}
+It should output :
+\begin{lstlisting}
+file.zip;
+\end{lstlisting}
+and the resulting  \lstinline'file.zip' folder should contain a package called \lstinline'file', which contains a .cpp file corresponding to the DSP file.\\
+
+If the DSP file is not in the current directory, make sure to type the right path. For instance :
+\begin{lstlisting}
+faust2ros ~/faust/examples/myfile.dsp
+\end{lstlisting}
+
+
+\paragraph{Comments:}
+\begin{itemize}
+	\item If you want to use the \lstinline'faust2rosgtk' command, the output will have a \lstinline'_gtk' extension. For instance :
+		\begin{lstlisting}
+faust2rosgtk file.dsp
+		\end{lstlisting}
+		should output :
+		\begin{lstlisting}
+file_gtk.zip;
+		\end{lstlisting}
+	\item The zip file is located in the current directory.
+	
+\end{itemize} 
+
+\newpage
+\section{Compiling in a Workspace}
+Thanks to the option \lstinline'-install', you have the possibility to create a package from your DSP file directly in a workspace you choose.
+Just type :
+\begin{lstlisting}
+faust2ros -install faust_ws file.dsp
+\end{lstlisting}
+
+It should output : 
+\begin{lstlisting}
+file.cpp; 
+\end{lstlisting}
+and you should have a faust\_ws repository looking like this :\\
+
+\dirtree{%
+.1 faust\_ws. 
+	.2 build. 
+	.2 devel. 
+	.2 src. 
+		.3 file :  \begin{minipage}[t]{10cm}
+						File Package{}
+				\end{minipage}. 
+			.4 include. 
+			.4 src. 
+				.5 \textcolor{margincolor}{file.cpp} : 
+						\begin{minipage}[t]{10cm}
+						File generated with the \faust compiler{}
+					   \end{minipage}. 
+			.4 CMakeLists.txt. 
+			.4 package.xml. 
+}
+
+%\section{Renaming DSP file}
+%If the dsp file name does not fit you, you can change it using the \lstinline'-o' command.
+%For instance, if you want the package generated from DSP file to have a different name that your DSP file name, you can type :
+%\begin{lstlisting}
+%	faust2ros -o foobar file.dsp
+%\end{lstlisting}
+%The output is going to be : \\
+%
+%\dirtree{%
+%.1 foobar.zip. 
+%	.2 faust\_msgs. 
+%	.2 foobar. 
+%}
+
+\section{Example}
+Here is an example of a three files compilation.\\
+
+Input :
+\begin{lstlisting}
+faust2rosgtk -install foo_ws -o foo1 file1.dsp 
+			 -install foo_ws -o foo2 file2.dsp 
+			 -install bar_ws -o bar file3.dsp
+\end{lstlisting}
+
+Output :\\
+\dirtree{%
+.1 \~{ }. 	
+	.2 foo\_ws. 
+		.3 foo1. 
+		.3 foo2. 
+	.2 bar\_ws. 
+		.3 bar. 
+}
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/errors.tex b/documentation/using-faust-with-ros-src/chapters/errors.tex
new file mode 100644
index 0000000..82e63b4
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/errors.tex
@@ -0,0 +1,57 @@
+\chapter{Common Error Messages}
+\label{chap:errors}
+Compiling can fail. Here are some common mistakes and how to solve them.
+\section{The command does not output anything}
+If, after typing your command followed by a file name, your terminal does not output anything like \lstinline'myfile.zip;' or \lstinline'myfile.cpp;' and returns only a blank line, make sure \textbf{you are in the correct directory or you entered the correct path to reach the DSP file.} 
+
+\section{No such file or directory}
+If you used the \lstinline'-install' option, make sure you typed the complete workspace path.
+For instance, instead of typing this :
+\begin{lstlisting}
+faust2ros -install myworkspace ~/path/to/myfile.dsp
+\end{lstlisting}
+you should type :
+\begin{lstlisting}
+faust2ros -install path/to/myworkspace ~/path/to/myfile.dsp
+\end{lstlisting}
+
+%\section{Fatal error during \lstinline'catkin_make' operation}
+%Once your DSP file compiled into a cpp file, if you try to compile it into a \ros executable, the terminal might output :
+%\begin{lstlisting}
+%fatal error: faust_msgs/faust_param.h: No such file or directory
+%\end{lstlisting}
+%\newpage
+%You have two possibilities :
+%
+%\begin{itemize}[leftmargin=*]
+%	\item If your workspace is only a test workspace, then type :
+%	\begin{lstlisting}
+%source path/to/myworkspace/devel/setup.bash
+%	\end{lstlisting}
+%	in your terminal.
+%	\item If your workspace is going to be your current \ros workspace, you can add it to the source directories :
+%	\begin{lstlisting}
+%echo "source path/to/myworkspace/devel/setup.bash" >> ~/.bashrc 
+%	\end{lstlisting}
+%\end{itemize}
+
+\section{[rosrun] error}
+\label{sec:rosrun error}
+If, while trying to run a \faust node (called \textit{myname}), an error message showed up saying :
+
+\begin{lstlisting}
+[rosrun] Couldn't find executable named myname below /path/to/myworkspace/src/myname
+\end{lstlisting}
+
+Then you have to source your workspace :
+\begin{itemize}[leftmargin=*]
+	\item If your workspace is only a test workspace, then type :
+	\begin{lstlisting}
+source path/to/myworkspace/devel/setup.bash
+	\end{lstlisting}
+	in your terminal.
+	\item If your workspace is going to be your current \ros workspace, you can add it to the source directories :
+	\begin{lstlisting}
+echo "source path/to/myworkspace/devel/setup.bash" >> ~/.bashrc 
+	\end{lstlisting}
+\end{itemize}
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/introduction.tex b/documentation/using-faust-with-ros-src/chapters/introduction.tex
new file mode 100644
index 0000000..d8aea71
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/introduction.tex
@@ -0,0 +1,235 @@
+\chapter{Introduction}
+\label{chap:intro}
+If you wanted to add some sound to your robot, or if you wanted to use your sound applications 
+on a robot, it is now possible with \faust and the \lstinline'faust2ros' and
+\lstinline'faust2rosgtk' commands. \\
+\faust (\textit{Functional Audio Stream}) is a functional programming language specifically 
+designed for real-time signal processing and synthesis.  \faust targets high-performance signal 
+processing applications and audio plug-ins for a variety of platforms and standards.\newline
+\ros (\textit{Robot Operating System}) is a flexible framework for robot software writing. It 
+is a collection of tools, libraries, and conventions that aim to simplify the task of creating 
+complex and robust robot behavior across a wide variety of robotic platforms.
+
+
+\section{FAUST} 
+\subsection{Design Principles}
+
+Various principles have guided the design of \faust :
+
+\begin{itemize}
+
+\item \faust is a \textit{specification language}. It aims at providing an adequate notation to describe \textit{signal processors} from a mathematical point of view. \faust is, as much as possible, free from implementation details. 
+
+\item \faust programs are fully compiled, not interpreted. The compiler translates \faust programs into equivalent C++ programs taking care of generating the most efficient code. The result can generally compete with, and sometimes even outperform, C++ code written by seasoned programmers. 
+
+\item The generated code works at the sample level. It is therefore suited to implement low-level DSP functions like recursive filters. Moreover the code can be easily embedded. It is self-contained and doesn't depend of any DSP library or runtime system. It has a very deterministic behavior and a constant memory footprint. 
+
+\item The semantic of \faust is simple and well defined. This is not just of academic interest. It allows the \faust compiler to be \emph{semantically driven}. Instead of compiling a program literally, it compiles the mathematical function it denotes. This feature is useful for example to promote components reuse while preserving optimal performance.  
+
+\item \faust is a textual language but nevertheless block-diagram oriented. It actually combines two approaches: \textit{functional programming} and \textit{algebraic block-diagrams}. The key idea is to view block-diagram construction as function composition. For that purpose, \faust relies on a \emph{block-diagram algebra} of five composition operations (\lstinline': , ~ <: :>').
+
+\item Thanks to the notion of \textit{architecture}, \faust programs can be easily deployed on a large variety of audio platforms and plugin formats without any change to the \faust code.
+
+\end{itemize}
+
+\subsection{Signal Processor Semantic}
+A \faust program describes a \emph{signal processor}. 
+The role of a \textit{signal processor} is to transform a group  of (possibly empty) \emph{input signals} in order to produce a group of (possibly empty) \emph{output signals}. 
+Most audio equipments can be modeled as \emph{signal processors}. 
+They have audio inputs, audio outputs as well as control signals interfaced with sliders, knobs, vu-meters, etc... \\
+
+For more informations about \faust, please see \textit{faust-quick-reference.pdf} and the tutorials in \faust documentation.
+
+\section{ROS}
+\subsection{What is it ?}
+\marginpar {This section's content (1.2 \ros) is taken from \ros documentation. It can be found on \href{http://www.ros.org}{\ros official website} and \href{http://www.wiki.ros.org }{\ros wiki}.} Creating truly robust, general-purpose robot software is \textit {hard}. From the robot's perspective, problems that seem trivial to humans often vary wildly between instances of tasks and environments. Dealing with these variations is so hard that no single individual, laboratory, or institution can hope to do it on their own. \newline
+
+\ros is an open-source, meta-operating system for your robot. It provides the services you would expect from an operating system, including hardware abstraction, low-level device control, implementation of commonly-used functionality, message-passing between processes, and package management. It also provides tools and libraries for obtaining, building, writing, and running code across multiple computers. \newline
+
+As a result, \ros was built from the ground up to encourage \textit{collaborative} robotics software development. For example, one laboratory might have experts in mapping indoor environments, and could contribute a world-class system for producing maps. Another group might have experts at using maps to navigate, and yet another group might have discovered a computer vision approach that works well for recognizing small objects in clutter. \ros was designed specifically for groups like these to collaborate and build upon each other's work, as is described throughout this site.\\
+
+\subsection{Concepts}
+\subsubsection{Filesystem level}
+The filesystem level concepts mainly cover \ros resources that you encounter on disk, such as:
+
+\begin{itemize}
+
+\item \textbf{Packages} are the main unit for organizing software in \ros. 
+	A package may contain \ros runtime processes (nodes), a \ros-dependent library, datasets, configuration files, or anything else that is usefully organized together. 
+	Packages are the most atomic build item and release item in \ros. Meaning that the most granular thing you can build and release is a package.
+
+\item \textbf{Metapackages} are specialized Packages which only serve to represent a group of related other packages. 
+
+
+\item \textbf{Services : }
+Service descriptions, stored in my\_package/srv/MyServiceType.srv, define the request and response data structures for  \href{http://wiki.ros.org/Services}{services} in \ros.
+
+\item \textbf{Messages : }  
+Message descriptions, stored in my\_package/msg/MyMessageType.msg, define the data structures for  \href{http://wiki.ros.org/Messages}{messages} sent in \ros.
+
+
+\end{itemize}
+
+
+\subsubsection{Computation Graph level}
+The Computation Graph is the peer-to-peer network of \ros processes that are processing data together. The basic Computation Graph concepts of \ros are nodes, Master, Parameter Server, messages, services, topics, and bags, all of which provide data to the Graph in different ways.
+
+\begin{itemize}
+\item \textbf{Master : }
+The \ros Master provides name registration and lookup to the rest of the Computation Graph. Without the Master, nodes would not be able to find each other, exchange messages, or invoke services.
+
+\item \textbf{Nodes : } 
+Nodes are processes that perform computation. \ros is designed to be modular at a fine-grained scale; a robot control system usually comprises many nodes. For example, one node controls a laser range-finder, one node controls the wheel motors, one node performs localization, one node performs path planning, one Node provides a graphical view of the system, and so on. A \ros node is written with the use of a \ros client \href{http://wiki.ros.org/Client\%20Libraries}{library}, such as \href{http://wiki.ros.org/roscpp}{roscpp} or \href{http://wiki.ros.org/rospy}{rospy}.
+
+\item \textbf{Topics : } Messages are routed via a transport system with publish / subscribe semantics. A node sends out a message by publishing it to a given \href{http://wiki.ros.org/Topics}{topic}. The topic is a name that is used to identify the content of the message. A node that is interested in a certain kind of data will subscribe to the appropriate topic. There may be multiple concurrent publishers and subscribers for a single topic, and a single node may publish and/or subscribe to multiple topics. In general, publishers and subscribers are not aware of each others' existence. The idea is to decouple the production of information from its consumption. Logically, one can think of a topic as a strongly typed message bus. Each bus has a name, and anyone can connect to the bus to send or receive messages as long as they are the right type.
+
+\item \textbf{The Parameter Server : }The Parameter Server allows data to be stored by key in a central location. It is currently part of the Master.
+
+\item \textbf{Messages : }Nodes communicate with each other by passing \href{http://wiki.ros.org/Messages}{messages}. A message is simply a data structure, comprising typed fields. Standard primitive types (integer, floating point, boolean, etc.) are supported, as are arrays of primitive types. Messages can include arbitrarily nested structures and arrays (much like C structures).
+
+\end{itemize}
+
+\begin{figure}[ht!]
+\centering
+
+ \begin{tikzpicture} [remember picture]
+ \node[draw=roscolor, label={[roscolor] above left:{MASTER}}, ] (master) {
+ 	\begin{tikzpicture}[node distance=2.5cm]
+	  \node[fill=roscolor, text=white, ellipse, text width=1.5cm, align=center](n1){Node 1};	  
+	  \node[fill=roscolor, text=white, ellipse, text width=1.5cm, below=of n1, align=center](n2){Node 2};
+	  \node[draw=roscolor, text=roscolor, rounded corners=3pt, text width=1.5cm, right=of n1, align=center](t1){Topic 1};
+	  \node[draw=roscolor, text=roscolor, rounded corners=3pt, text width=1.5cm, right=of n2, align=center](t2){Topic 2};
+	  \node[fill=roscolor, text=white, ellipse, text width=1.5cm, right=of t1, align=center](n3){Node 3};
+	  \node[fill=roscolor, text=white, ellipse, text width=1.5cm, below=of n3, align=center](n4){Node 4};
+	  
+ 
+	  \draw[margincolor,->, very thick] (n1) to node [sloped, midway, above] {publication} (t1);
+	  \draw[margincolor,->, very thick] (n2) to node [sloped, midway, above] {publication} (t1.south west);
+ 	  \draw[margincolor,->, very thick] (n3) to node [sloped, midway, above] {publication} (t2.north east);
+	  \draw[yoheader,->, very thick] (t1) to node [sloped, midway, above] {subscription} (n3);
+ 	  \draw[yoheader,->, very thick] (t2) to node [sloped, midway, above, text width=1.9cm, align=center] {subscription} (n2);
+  	  \draw[yoheader,->, very thick] (t2) to node [sloped, midway, above, text width=1.9cm, align=center] {subscription} (n4);
+	\end{tikzpicture}
+ };
+  
+ \end{tikzpicture}
+
+\caption{\ros Concepts in a Diagram }
+\label{fig:ROS Concepts}
+\end{figure}
+
+\subsubsection{Names}
+Names are really important in \ros. Valid names have these characteristics :
+\begin{itemize}
+	\item first chararacter is an alpha character : [a-z][A-Z]
+	\item subsequent characters can be alphanumeric : [a-z][A-Z][0-9], underscores : \_ or forward slash : /
+	\item there is at most one forward slash : /
+
+\end{itemize}
+
+For more informations on \ros and tutorials, please have a look to the website :
+\myurl{www.wiki.ros.org}.\\
+\newpage
+\section{Using FAUST with ROS}
+The idea of using \faust modules with \ros could be summed up in the following diagrams.
+
+\begin{figure}[ht!]
+\centering
+
+\begin{tikzpicture} [remember picture, node distance=0.5cm]
+ \node[draw, dashed, label=above:{\faust part}] (faust) { 
+ 	\begin{tikzpicture}
+	 \node[draw, solid, text=yoheader, fill=lightgray] (dsp) {.dsp file};
+	 \node[draw=yoheader, solid, ellipse, text=black, right=of dsp, text width=1.5cm, align=center](compiler) {\faust compiler};
+	 \node[draw, solid, text=yoheader, fill=lightgray, above=of compiler](archfile){architecture file};
+	 \draw[->, very thick, solid] (dsp)--(compiler);
+	 \draw[->, very thick, solid] (archfile)--(compiler);
+	 \end{tikzpicture}
+ };
+ \node[draw, solid, text=yoheader, fill=lightgray, right=of compiler] (cpp) {.cpp file};
+ \node[draw, dashed, right=of cpp, label=above:{\ros part}] (ROS) {
+	 \begin{tikzpicture}
+	 
+	 \node[draw=yoheader, solid, ellipse, text=black, right=of cpp] (CMake) {catkin};
+	 \node[draw, solid, text=yoheader, fill=lightgray, right=of CMake, text width=2cm, align=center] (exec) {\ros executable};
+	 
+	 \draw[->, very thick, solid] (CMake)--(exec);
+	 \end{tikzpicture}
+ };
+ \draw[->,very thick] (cpp.east) -- (CMake.west);
+ \draw[->,very thick] (compiler.east) -- (cpp.west);
+ 
+\end{tikzpicture}
+\caption{Compilation process }
+\label{fig:Compilation principle}
+\end{figure}
+
+As shown on figure~\ref{fig:Compilation principle}, the dsp file is compiled into a C++ file thanks to the \faust compiler. Then, the C++ file can be compiled with \textit{catkin} in a \ros package to create a \ros executable, that you can run with \lstinline'rosrun'.
+
+\begin{figure}[ht!]
+\centering
+
+ \begin{tikzpicture} [remember picture]
+ 
+%  \node[fill=faustcolor, text=white, rounded corners=3pt, text width=1.5cm, align=center](sensor topic){Robot sensors topic};
+  \node[fill=roscolor, text=white, ellipse, text width=3.5cm,  align=center](process node){\large Robot Node\\ (sends sensor data)};
+  \node[draw=roscolor, text=roscolor, rounded corners=3pt, text width=3cm, align=center,  right=4cm of process node](faust topic){\large A Topic};
+  \node[draw=roscolor, text=roscolor, rounded corners=3pt, text width=3cm, align=center,  below=1.5cm of process node](faust topic2){\large An other Topic};
+  \node[fill=faustcolor, text=white, ellipse, text width=3.5cm, below=0.9cm of faust topic, align=center, minimum height=\heightof{process node}](faust node){\large \faust Node \\(sets audio\\ parameters with messages contents)};
+% \node[fill=roscolor, text=white, ellipse, text width=1.8cm, right=of faust topic2, align=center](faust node2){\faust node : signal processing};
+ 
+% \draw[yoheader,->, very thick] (sensor topic) to node [sloped, midway, above] {subscribing} (process node);
+ \draw[margincolor,->, very thick] (process node) to node [midway, above, text width=3cm, align=center] {publishes messages} (faust topic);
+ \draw[margincolor,->, thick] (process node) to node [midway, left,  text width=2.5cm, align=center] {publishes \\ other messages} (faust topic2);
+ \draw[yoheader,->, very thick] (faust topic) to node [ midway, right,  text width=2.5cm] {is subscribed} (faust node);
+ \draw[yoheader,->, very thick] (faust topic2) to node [ midway, above,  text width=2cm] {is subscribed} (faust node);
+ 
+ \end{tikzpicture}
+
+\caption{Robot using \faust}
+\label{fig:Use Diagram}
+\end{figure}
+
+Once the executables coming from DSP files compiled, you can run and combine them with robotic applications (figure~\ref{fig:Use Diagram}).
+\newpage
+\section{Audio Server}
+\faust applications use the jack audio server. Make sure it is installed on your machine.
+\begin{figure}[ht!]
+	\centering
+	\begin{tikzpicture}[remember picture, node distance=3.5cm]
+	
+		\node[node distance=0, label=\color{teal}{Node 1}](node1)
+		{
+			\begin{tikzpicture}
+				\node[draw=black,text=white, fill=indigodye, text width=4cm, align=center](processing1){\ros : processing \\ and interface};
+				\node[draw=black, fill=darkpastelblue, below=of processing1, text width=4cm, align=center](audio1){jack : audio server};
+			\end{tikzpicture}
+		};
+		\node[right=of node1, node distance=0, label=\color{teal}{Node 2}](node2){
+			\begin{tikzpicture}
+				\node[draw=black,text=white, fill=indigodye, text width=4cm, align=center](processing2){\ros : processing \\ and interface};
+				\node[draw=black, fill=darkpastelblue, below=of processing2, text width=4cm, align=center](audio2){jack : audio server};
+			\end{tikzpicture}		
+		};	
+		 \draw[indigodye, <->, very thick, text width=3cm, align=center] (processing1.east) to node [sloped, midway, above] {nodes parameters \\ through topics} (processing2.west);
+		  \draw[darkpastelblue, <->, very thick] (audio1.east) to node [sloped, midway, below, darkcerulean] {audio datas} (audio2.west);
+
+	\end{tikzpicture}
+	
+	\caption{APIs used by \faust nodes}
+	\label{fig: Audio server}
+\end{figure}
+
+\section{Installation}
+\subsection{FAUST}
+You can get \faust on the \faust website : \href{http://faust.grame.fr/index.php/downloads}
+{faust.grame.fr}. Either get it on the
+ \href{https://sourceforge.net/projects/faudiostream/files/}{Source Forge Project}, or browse
+  the \href{https://sourceforge.net/p/faudiostream/_list/git}{\faust's git repository}.
+ You also can download the ubuntu package directly by typing : 
+ \lstinline'sudo apt-get install faust' (probably an outdated version).
+ \subsection{ROS}
+ A \ros installation guide can be found on the
+  \href{http://wiki.ros.org/indigo/Installation/Ubuntu}{\ros website}.
+ \subsection{Jack}
+ A Jack installation layout can be found on \href{https://github.com/jackaudio/jackaudio.github.com/wiki/InstallationLayout}{Jack's github's page}. You can download it as an Ubuntu package by typing : \lstinline'sudo apt-get install jackd2'.
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/messages.tex b/documentation/using-faust-with-ros-src/chapters/messages.tex
new file mode 100644
index 0000000..1bf2a65
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/messages.tex
@@ -0,0 +1,33 @@
+\chapter{\faust Messages}
+\label{chap:msgs}
+
+In order to share data, \ros nodes publish in and subscribe to topics. Topics can handle only one type of messages (a float, a string and an integer, etc \dots).\\
+A \faust node is configured to read a single type of messages : faust\_param.msg.
+
+\section{faust\_param.msg}
+When you compile a DSP file, a faust\_msgs package is automatically created next to your file package. As describe above in chapter~\ref{chap:compilation}, the faust\_msgs package contains a msg folder, in which is the faust\_param.msg file. 
+When you make the workspace with \lstinline'catkin_make', a faust\_param.h file is created in the devel/include/faust\_msgs directory. For more informations and details about messages in \ros, refer to \href{http://wiki.ros.org/msg}{\ros documentation}.\\
+The faust\_param messages definition is very simple :
+\begin{lstlisting}
+float32 value
+\end{lstlisting}
+It means this message only constituted by a float, which is named value.
+\newpage
+\section{How to Use these Messages ?}
+Let's put it in diagram :\\
+\begin{figure}[ht!]
+\centering
+\begin{tikzpicture}[node distance=1.5cm]
+	\node[draw, fill=orange, rounded corners=3pt, text width=1.5cm, align=center](sensor topic){sensor data get published into that topic};
+	\node[draw, fill=cyan, ellipse, text width=1.4cm, right=of sensor topic, align=center](processing){data are processed to fit to faust\_param type};
+	\node[draw, fill=orange, rounded corners=3pt, text width=1.5cm, right=of processing, align=center](faust topic){processed data get published into that topic};
+	\node[draw, fill=cyan, ellipse, text width=1.3cm, right=of faust topic, align=center](faust node){parameters are set};
+	
+	\draw[yoheader,->, very thick] (sensor topic) to node [sloped, midway, above, text width=1.5cm, align=center] {Sensor messages} (processing);
+	\draw[yoheader,->, very thick] (processing) to node [sloped, midway, above, text width=1.4cm, align=center] {\faust messages: \\ a float} (faust topic);
+	\draw[yoheader,->, very thick] (faust topic) to node [sloped, midway, above, text width=1.4cm, align=center] {\faust messages: \\ a float} (faust node);
+\end{tikzpicture}
+\caption{Diagram explaining messages dynamic between a sensor topic and a \faust node}
+\label{fig:msgs diagram}
+\end{figure}\\
+Data coming from a sensor need to get processed to be used by a \faust node. For example, if the data is an image message, coming from a camera, you cannot use it directly : you need to perform some processing on the picture, in order t get the value you're interested in. Once this value is processed, you can send it to a \faust topic, on which a \faust node has subscribed. The \faust node is now able to change its parameter value.
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/running.tex b/documentation/using-faust-with-ros-src/chapters/running.tex
new file mode 100644
index 0000000..54ee3f2
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/running.tex
@@ -0,0 +1,108 @@
+\chapter{Using FAUST Nodes}
+\label{chap:run}
+Once your DSP files are compiled into \ros executables, you can run them into a \ros master.
+
+\section{Run the Master}
+A \faust node needs a master to run. You can check if a master is already running by typing :
+\begin{lstlisting}
+rostopic list
+\end{lstlisting}
+Then, there are two possibilities :
+\begin{itemize}
+	\item either you get the following message :
+	\begin{lstlisting}
+ERROR: Unable to communicate with master!
+	\end{lstlisting}
+	which means there is no master running
+	\item or you get :
+	\begin{lstlisting}
+/rosout
+/rosout_agg
+	\end{lstlisting}
+	which means a master is already running.
+\end{itemize}
+To run a master, you have to type the following command :
+\begin{lstlisting}
+roscore
+\end{lstlisting}
+
+\newpage
+\section{Run a FAUST Node}
+Now that your master is running, you can run your \faust node. It is quite simple. Type :
+\begin{lstlisting}
+rosrun mynodepackage mynode
+\end{lstlisting}
+For instance, if your node name is \textit{foo}, then type :
+\begin{lstlisting}
+rosrun foo foo
+\end{lstlisting}
+If you get an error message looking like this :
+\begin{lstlisting}
+[rosrun] Couldn't find executable named foo below /path/to/myworkspace/src/foo
+\end{lstlisting}
+then refer to section~\ref{sec:rosrun error}
+
+\section{To Which Topics is a FAUST Node Subscribing ?}
+Once your \faust node is running, it automatically subscribes to topics corresponding to the parameters you can modify, and to the widgets the gtk graphic interface has. For instance, if you use a \faust node generated from the noise.dsp file (in the examples directory), the noise\_gtk node will subscribe to the topic \lstinline'noise_gtk/Volume' and the graphic interface will look like this :
+\begin{figure}[ht!]
+\centering
+\begin{adjustbox}{minipage=5cm,margin=0pt 10pt,bgcolor=roscolor}
+\centering
+\includegraphics[scale=0.5]{images/noise_gtk.png}
+\end{adjustbox}
+\caption{noise\_gtk graphic interface}
+\label{fig:noise_gtk}
+
+\end{figure}
+\newpage
+A more complex example like the harpe.dsp file, which contains three widgets, can generate several topics to subscribe to :
+\\
+\begin{center}
+
+\begin{tabular}{l}
+	\lstinline'/harpe_gtk/attenuation' \\
+	\lstinline'/harpe_gtk/hand' \\
+	\lstinline'/harpe_gtk/level' \\
+\end{tabular}\\
+\end{center}
+and the graphic interface can look like this :
+\begin{figure}[ht!]
+\centering
+\begin{adjustbox}{minipage=5cm,margin=0pt 10pt,bgcolor=roscolor}
+\centering
+\includegraphics[scale=0.5]{images/harpe_gtk.png}
+\end{adjustbox}
+\caption{harpe\_gtk graphic interface}
+\label{fig:harpe_gtk}
+\end{figure}
+
+If you want to change the topic name, just remap them while running your node :
+\begin{lstlisting}
+rosrun myfaustpackage myfaustnode /topicname:=/newtopicname
+\end{lstlisting}
+For instance, to remap the /harpe/hand topic to /play, then run the harpe node like this :
+\begin{lstlisting}
+rosrun harpe harpe /harpe/hand:=/play
+\end{lstlisting}
+
+\paragraph{Comment:}The \faust nodes subscribe to topics using std\_msgs message types. Depending on the widgets you use, you can subscribe to default topics using either Float32 or Bool messages.\\
+
+\begin{center}
+	\begin{tabular}{ | c | c | }
+		\hline
+		\rowcolor{yobg} Widget & Message type \\ \hline
+		Button & std\_msgs/Bool \\ \hline
+		Check Button & std\_msgs/Bool \\ \hline
+		Slider & std\_msgs/Float32 \\ \hline
+		Num. Entry & std\_msgs/Float32 \\ \hline
+	\end{tabular}
+\end{center}
+
+\newpage
+
+\section{How to Escape from a Running Node ?}
+To close a node running in \ros, you have two possibilities, depending on the graphic interface :
+\begin{itemize}
+	\item If your node has a graphic interface, then quit by clicking on the red cross in the corner of the window.
+	\item If your node does not have any graphic interface, then quit by typing Ctrl+C in the node's terminal window.
+\end{itemize}
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/spec.tex b/documentation/using-faust-with-ros-src/chapters/spec.tex
new file mode 100644
index 0000000..7aa0fc6
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/spec.tex
@@ -0,0 +1,39 @@
+\chapter{Metadata}
+\label{chap:spec}
+You might not want to use the float or bool standard messages for your topic, and compile the dsp file directly with the right topic name. In order to accomplish this, you can use \ros metadata.
+\section{DSP writing}
+It all starts in the widgets definition. Until now, maybe that you only wrote :
+\begin{lstlisting}
+param = hslider("level", etc);
+\end{lstlisting}
+To use \ros metadata, you simply have to add square brackets with your topic parameters :
+\begin{lstlisting}
+param = hslider("level [ros:/my/topic/name msg_type msg_name field_name]", etc);
+\end{lstlisting}
+~\\
+As an example, if you intend to use integers in a foo/bar/baz topic, you can type :
+\begin{lstlisting}
+param = hslider("level [foo/bar/baz std_msgs Int32 data]", etc);
+\end{lstlisting}
+And if you intend to use the y field of a Point32 geometry\_msg, then type :
+\begin{lstlisting}
+param = hslider("level [foo/bar/baz geometry_msgs Point32 y]", etc);
+\end{lstlisting}
+You can also add the minimal and maximal values of the signal (4.1 and 9.3 for instance) by adding in the metadata declaration :
+\begin{lstlisting}
+param = hslider("level [foo/bar/baz std_msgs Int32 data 4.1 9.3]", etc);
+\end{lstlisting}
+\paragraph{\color{yoheader}BE CAREFUL !}The minimal and maximal values must be floats ! Otherwise, compilation fails.
+\newpage
+\section{Compilation}
+To compile your dsp file, just do like you used to do before to find out this wonderful chapter about metadata : \lstinline'faust2ros' or \lstinline'faust2rosgtk'. It will add a RosCallbacks class in your C++ file, containing specific callbacks.
+\paragraph{Comment : }Even without any declared \ros metadata, a rosCallbacks class is created, but it does not contain any callback implementation. It is just an empty class.\\
+
+You can then build your executable using \lstinline'catkin_make'.
+
+\section{Run}
+To run your node, just do as usual, using \lstinline'rosrun' or a launch file you wrote. The \faust node creates two kinds of topics :
+\begin{itemize}
+	\item Default topics, using Float32 and Bool standard messages
+	\item Customized topics, created from \ros metadata.
+\end{itemize}
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/chapters/tuto.tex b/documentation/using-faust-with-ros-src/chapters/tuto.tex
new file mode 100644
index 0000000..f2a95c3
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/chapters/tuto.tex
@@ -0,0 +1,125 @@
+\chapter{Tutorials}
+\label{chap:tuto}
+This tutorial will teach you how to use \faust with \ros through the turtlesim package.
+
+\section{DSP File}
+Copy the following code into a text file and save it as \lstinline'roscillator.dsp'.
+
+\begin{lstlisting}
+declare name 		"roscillator";
+declare version 	"1.0";
+declare author 		"Grame";
+declare license 	"BSD";
+declare copyright 	"(c)GRAME 2009";
+
+//-----------------------------------------------
+// 			Sinusoidal Oscillator
+//-----------------------------------------------
+
+import("music.lib");
+
+smooth(c) = *(1-c) : +~*(c);
+vol = hslider("volume [unit:dB][ros:/turtle1/pose turtlesim Pose x 0.0 11.0]", 0, -96, -96, 0.1) : db2linear : smooth(0.999) ;
+freq = hslider("freq [unit:Hz][ros:/turtle1/pose turtlesim Pose y 0.0 11.0]", 1000, 20, 24000, 1);
+
+
+process = vgroup("Oscillator", osc(freq) * vol);
+
+\end{lstlisting}
+
+\newpage
+
+\section{Compilation}
+\subsection{If you installed FAUST on your machine}
+In a terminal, type :
+\begin{lstlisting}
+faust2rosgtk -install ~/catkin_ws ~/path/to/roscillator.dsp
+\end{lstlisting}
+The compilation can take between 10 and 15 seconds.
+Then, go in your workspace's root and source the setup file (see section \ref{sec:rostips})
+
+\subsection{With FaustLive}
+FaustLive is available on \href{https://sourceforge.net/projects/faudiostream/files/}
+{Source Forge}. Once FaustLive installed, launch it.\\
+Choose \texttt{Open your File.dsp} and select \texttt{roscillator.dsp}. The file 
+will be compiled and executed. 
+To export it, clic on \texttt{Window/Export As...} or press \texttt{Ctrl+P}. The Export 
+Manager window should be opened.
+
+\begin{figure}[ht!]
+\centering
+\includegraphics[scale=0.5]{images/faustlive-export.png}
+\caption{FaustLive Export Manager}
+\label{fig:welcomefaustlive}
+\end{figure}
+
+Select \texttt{ros} as platform, \texttt{ros-jack-gtk} as architecture, and \texttt{binary.zip} 
+as binary. Then click on \texttt{Export}, and \texttt{Save}. \\
+Unzip your package in your current \ros workspace, and make your workspace with 
+\texttt{catkin\_make}, and source it (see the \ros tips in section \ref{sec:rostips}).
+
+%\begin{figure}[ht!]
+%\centering
+%\includegraphics[scale=0.2]{images/faustlive-welcome.png}
+%\caption{FaustLive interface}
+%\label{fig:welcomefaustlive}
+%\end{figure}
+
+\subsection{With the online compiler}
+The online compiler is available on \href{http://faust.grame.fr/index.php/online-examples}{the 
+\faust Website}. In \texttt{Faust Code} tab, drop your roscillator.dsp file.  In the 
+\texttt{Exec File} tab, choose \texttt{Ros ros-jack-gtk} as architecture, and click on 
+\texttt{Download the executable file}.\\
+Unzip your package in your current \ros workspace, make your workspace with 
+\texttt{catkin\_make}, and source it (see the \ros tips in section \ref{sec:rostips}).
+
+\newpage
+
+\section{Run}
+In a terminal, run the master : 
+\begin{lstlisting}
+roscore
+\end{lstlisting}
+In two new terminals, run the turtlesim node and the teleop\_key node :
+\begin{lstlisting}
+rosrun turtlesim turtlesim_node
+\end{lstlisting}
+\begin{lstlisting}
+rosrun turtlesim turtle_teleop_key
+\end{lstlisting}
+In a fourth (and last) terminal, run your \faust node :
+\begin{lstlisting}
+rosrun roscillator_gtk roscillator_gtk
+\end{lstlisting}
+You should have four open terminals, a turtle window, and a \faust window.
+
+\begin{figure}[ht!]
+\centering
+\includegraphics[scale=0.2]{images/tutocommandline.png}
+\caption{Screenshot with the four open terminals}
+\label{fig:screenshot}
+\end{figure}
+
+\subsection{Use}
+To move your turtle, go back on the teleop\_key terminal and use your arrow keys.
+
+\newpage
+
+\section{ROS tips}
+\label{sec:rostips}
+\subsection{How to create a ROS workspace ?} 
+\begin{lstlisting}
+mkdir -p ~/catkin_ws/src
+cd ~/catkin_ws/src
+catkin_init_workspace
+\end{lstlisting}
+\subsection{How to make your workspace ?}
+\begin{lstlisting}
+cd ~/catkin_ws
+catkin_make
+\end{lstlisting}
+\subsection{How to source a workspace ?}
+\begin{lstlisting}
+cd ~/catkin_ws
+source devel/setup.bash
+\end{lstlisting}
\ No newline at end of file
diff --git a/documentation/using-faust-with-ros-src/images/faustlive-export.png b/documentation/using-faust-with-ros-src/images/faustlive-export.png
new file mode 100644
index 0000000..ac03835
Binary files /dev/null and b/documentation/using-faust-with-ros-src/images/faustlive-export.png differ
diff --git a/documentation/using-faust-with-ros-src/images/harpe_gtk.png b/documentation/using-faust-with-ros-src/images/harpe_gtk.png
new file mode 100644
index 0000000..76f15c9
Binary files /dev/null and b/documentation/using-faust-with-ros-src/images/harpe_gtk.png differ
diff --git a/documentation/using-faust-with-ros-src/images/noise_gtk.png b/documentation/using-faust-with-ros-src/images/noise_gtk.png
new file mode 100644
index 0000000..b2c05cf
Binary files /dev/null and b/documentation/using-faust-with-ros-src/images/noise_gtk.png differ
diff --git a/documentation/using-faust-with-ros-src/images/tutocommandline.png b/documentation/using-faust-with-ros-src/images/tutocommandline.png
new file mode 100644
index 0000000..ece6985
Binary files /dev/null and b/documentation/using-faust-with-ros-src/images/tutocommandline.png differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.05.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.05.pdf
new file mode 100644
index 0000000..235a3b1
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.05.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.06.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.06.pdf
new file mode 100644
index 0000000..312ec05
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.06.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.07.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.07.pdf
new file mode 100644
index 0000000..312ec05
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.07.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.08.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.08.pdf
new file mode 100644
index 0000000..9e4d411
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.08.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.09.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.09.pdf
new file mode 100644
index 0000000..44e489e
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros-0.0.09.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.01.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.01.pdf
new file mode 100644
index 0000000..1b4cf6e
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.01.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.02.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.02.pdf
new file mode 100644
index 0000000..cdb25b1
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.02.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.03.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.03.pdf
new file mode 100644
index 0000000..8ad1a14
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.03.pdf differ
diff --git a/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.04.pdf b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.04.pdf
new file mode 100644
index 0000000..88d5467
Binary files /dev/null and b/documentation/using-faust-with-ros-src/pdf_versions/using-faust-with-ros_0.0.04.pdf differ
diff --git a/documentation/faust-quick-reference-src/rail.sty b/documentation/using-faust-with-ros-src/rail.sty
similarity index 100%
copy from documentation/faust-quick-reference-src/rail.sty
copy to documentation/using-faust-with-ros-src/rail.sty
diff --git a/documentation/using-faust-with-ros-src/using-faust-with-ros-0.0.09.tex b/documentation/using-faust-with-ros-src/using-faust-with-ros-0.0.09.tex
new file mode 100644
index 0000000..5338c20
--- /dev/null
+++ b/documentation/using-faust-with-ros-src/using-faust-with-ros-0.0.09.tex
@@ -0,0 +1,189 @@
+\documentclass[a4paper,10pt]{book}
+
+\usepackage{latexsym}
+\usepackage{graphicx}
+\usepackage{supertabular}
+\usepackage{xspace}
+\usepackage{pdfpages}
+\usepackage{hyperref} 
+\usepackage{listings}
+\usepackage{color} 
+\usepackage{colortbl}
+\usepackage{ctable}
+\usepackage{enumitem}
+
+\usepackage[cc]{titlepic}
+\usepackage{sectsty}
+\usepackage[T1]{fontenc}
+\usepackage[urw-garamond]{mathdesign}
+\usepackage{fncychap}
+\usepackage{fancyhdr}
+\usepackage{lscape}
+
+\usepackage{dirtree}
+\usepackage{tikz}
+\usetikzlibrary{arrows, shapes, positioning}
+\usepackage{adjustbox}
+
+\usepackage{rail}
+\railoptions{-t -h}
+
+\fancyhead{} % clear all header fields
+\fancyheadoffset[LE,RO]{\marginparsep+\marginparwidth}
+\fancyhead[RO,LE]{\thepage}
+\fancyhead[LO]{\rightmark}
+\fancyhead[RE]{\leftmark}
+\renewcommand{\headrulewidth}{0.1pt}
+
+\fancyfoot{}
+
+
+\hypersetup{%
+            colorlinks = true, %true, false
+            linkcolor = black,
+            citecolor = blue,
+            urlcolor = blue,
+}
+\urlstyle{sf} %rm
+\newcommand{\myurl}[1]{\textcolor{blue}{\underbar{\url{#1}}}}
+
+
+%%%%%%%%%%%%%%%%%%%command imported from lac paper
+\newcommand{\code}[1]	{\lstinline'#1'}
+\newcommand{\OSTab}[1]	{\multicolumn{3}{|l|}{\hspace{14mm}\emph{#1}}}
+\newcommand{\htab}		{\hspace*{3mm}}
+
+\newcommand{\ros}		{\textsc{ROS}\xspace}
+
+\newcommand{\faust}		{\textsc{Faust}\xspace}
+\newcommand{\grame}		{\textsc{Grame}\xspace}
+\newcommand{\cierec}	{\textsc{Cierec}\xspace}
+\newcommand{\ccrma}		{\textsc{Ccrma}\xspace}
+\newcommand{\cnmat}		{\textsc{Cnmat}\xspace}
+\newcommand{\create}	{\textsc{Create}\xspace}
+\newcommand{\mines}		{\textsc{Mines} ParisTech\xspace}
+\newcommand{\pdf}		{\textsc{Pdf}\xspace}
+\newcommand{\ie}		{i.e.\ }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%% MY COLORS
+\definecolor{yoheader}{rgb}{0.71,0.01,0.0}
+
+\definecolor{darkcerulean}{rgb}{0.03, 0.27, 0.49}
+\definecolor{darkpastelblue}{rgb}{0.47, 0.62, 0.8}
+\definecolor{indigodye}{rgb}{0.0, 0.25, 0.42}
+
+\definecolor{roscolor}{HTML}{1F2A44}
+\definecolor{faustcolor}{HTML}{E76E18}
+
+
+%%%% margin par
+\definecolor{margincolor}{rgb}{0.52,0.02,0.02} % grey red.
+\definecolor{yobg}{rgb}{0.9,0.9,1}
+\definecolor{yotxt}{rgb}{0.01,0.01,0.52}
+\definecolor{mylstcmt}{rgb}{0.01,0.52,0.01} % a dark green..
+\definecolor{mylstdoc}{rgb}{0.80,0.30,0.80} % a medium pink.
+\definecolor{mylstkey}{rgb}{0.52,0.01,0.01} % a dark red.
+
+\setlength{\marginparwidth}{1.2in}
+\let\oldmarginpar\marginpar
+\renewcommand\marginpar[1]{\-\oldmarginpar[\raggedleft\color{margincolor}\footnotesize #1]%
+{\raggedright\color{margincolor}\footnotesize #1}}
+
+
+
+% \relax
+
+\begin{document} 
+
+\ChRuleWidth{1pt}
+\ChNumVar{\raggedleft\Huge\color{yoheader}}
+\ChTitleVar{\raggedleft\sffamily\fontsize{30}{32}\bf\color{yoheader}}
+
+\chapterfont{\color{yoheader}}
+\sectionfont{\color{yoheader}}
+\subsectionfont{\color{yoheader}}
+\subsubsectionfont{\color{yoheader}}
+
+% parameters for listings
+\lstset{
+  tabsize=4,
+  showspaces=false,
+  showstringspaces=false,
+  language=C++, 
+  basicstyle=\ttfamily\color{yotxt},
+  numbers=none,
+  stepnumber=2,
+  commentstyle=\slshape\color{mylstcmt},
+  breaklines=true, 
+  emph={component, declare, environment, import, library, process},
+  emph={[2]ffunction, fconstant, fvariable},
+  emph={[3]button, checkbox, vslider, hslider, nentry, vgroup, hgroup, tgroup, vbargraph, hbargraph, attach},
+  emphstyle=\color{mylstkey},
+  morecomment=[s][\color{mylstdoc}]{<mdoc>}{</mdoc>},
+  backgroundcolor=\color{yobg},
+  captionpos=b
+}
+
+\lstloadlanguages{C++,[LaTeX]TeX}
+
+\title{\Huge\color{yoheader}Using FAUST with ROS\\\Large(version 0.0.09)}
+\author{\textsc{Grame}\\Centre National de Cr\'eation Musicale}
+\date{December 2014} 
+
+
+\railalias{recur}{$\sim$}
+\railalias{lbrace}{\{}
+\railalias{rbrace}{\}}
+\railalias{dollar}{\$}
+\railalias{mod}{\%}
+\railalias{arobase}{@}
+\railalias{ampersand}{\&}
+\railalias{hat}{$\land$}
+\railalias{kot}{'}
+\railalias{pipe}{$|$}
+\railalias{fdelay}{}
+\railalias{backslash}{\char"5C}
+\railterm{recur,lbrace,rbrace,dollar,mod,kot,arobase,ampersand,backslash,fdelay, pipe, hat}
+
+\newcommand{\farg}[1]{\textrm{\textit{#1}}}
+\newcommand{\ldbrack}{[\![ \,}
+\newcommand{\rdbrack}{\, ]\!] }
+\newcommand{\rdbrackC}{\rdbrack_{\mathrm{C}}\,}
+\newcommand{\dbrack}[1]{\ldbrack #1 \rdbrack}
+\newcommand{\semantic}[1]{\ldbrack #1 \rdbrack}
+\newcommand{\dbrackC}[1]{\ldbrack #1 \rdbrackC}
+
+\newcommand{\latex}{\LaTeX\xspace}
+\newcommand{\ircam}{\textsc{Ircam}\xspace}
+\newcommand{\astree}{\textsc{Astree}\xspace}
+\newcommand{\svg}{\textsc{Svg}\xspace}
+ 
+
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}
+
+\maketitle
+
+\tableofcontents
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                            		CHAPTERS                                        %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\input{chapters/introduction}
+\input{chapters/compilation}
+\input{chapters/running}
+\input{chapters/spec}
+%\input{chapters/messages}
+\input{chapters/errors}
+\input{chapters/cheatsheet}
+\input{chapters/tuto}
+
+\end{document}
diff --git a/documentation/using-faust-with-ros.pdf b/documentation/using-faust-with-ros.pdf
new file mode 100644
index 0000000..44e489e
Binary files /dev/null and b/documentation/using-faust-with-ros.pdf differ
diff --git a/examples/FourSourcesToOcto.dsp b/examples/FourSourcesToOcto.dsp
new file mode 100644
index 0000000..8fcce8b
--- /dev/null
+++ b/examples/FourSourcesToOcto.dsp
@@ -0,0 +1,22 @@
+declare name 		"FourSourcesToOcto";
+declare version 	"1.0";
+declare author 	"CICM";
+declare license 	"BSD";
+declare copyright 	"(c)CICM 2013";
+
+import("hoa.lib") ;
+import("filter.lib") ;
+import("oscillator.lib");
+
+r1 = hslider("Radius1", 1.0, 0, 5, 0.001) : smooth(tau2pole(0.02));
+a1 = hslider("Angle1", 62831, -6.28318530717959, 6.28318530717959, 0.001) : smooth(tau2pole(0.02));
+r2 = hslider("Radius2", 1.0, 0, 5, 0.001) : smooth(tau2pole(0.02));
+a2 = hslider("Angle2", 62831, -6.28318530717959, 6.28318530717959, 0.001) : smooth(tau2pole(0.02));
+r3 = hslider("Radius3", 1.0, 0, 5, 0.001) : smooth(tau2pole(0.02));
+a3 = hslider("Angle3", 62831, -6.28318530717959, 6.28318530717959, 0.001) : smooth(tau2pole(0.02));
+r4 = hslider("Radius4", 1.0, 0, 5, 0.001) : smooth(tau2pole(0.02));
+a4 = hslider("Angle4", 62831, -6.28318530717959, 6.28318530717959, 0.001) : smooth(tau2pole(0.02));
+
+process(sig1, sig2, sig3, sig4) = map(3, sig1, r1, a1), map(3, sig2, r2, a2), map(3, sig3, r3, a3), map(3, sig4, r4, a4) :> optimInPhase(3) : decoder(3, 8);
+
+
diff --git a/examples/Makefile b/examples/Makefile
index 814ec74..686b6c3 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -6,18 +6,34 @@ LIB := $(if $(wildcard $(ck1)),/opt/local/lib,"")
 LIB := $(if $(wildcard $(ck2)),/usr/local/lib,$(LIB))
 LIB := $(if $(wildcard $(ck3)),$(FAUST_LIB_PATH),$(LIB))
 
+# Directory containing Faust include files:
+ck11 := /opt/local/include/faust/misc.h
+ck12 := /usr/local/include/faust/misc.h
+ck13 := /usr/include/faust/misc.h
+ck14 := $(FAUST_INC_PATH)/faust/misc.h
+FAUSTINC := $(if $(wildcard $(ck11)),/opt/local/include/faust,"")
+FAUSTINC := $(if $(wildcard $(ck12)),/usr/local/include/faust,$(FAUSTINC))
+FAUSTINC := $(if $(wildcard $(ck13)),/usr/include/faust,$(FAUSTINC))
+FAUSTINC := $(if $(wildcard $(ck14)),$(FAUST_INC_PATH),$(FAUSTINC))
+
 ifeq ($(OSC),1)
- OSCCTRL := -DOSCCTRL -I$(LIB)/faust/osclib
- QTDEFS  := "DEFINES += OSCCTRL"
- OSCLIB  := -L$(LIB)/faust/osclib -lOSCFaust -loscpack
+ OSCCTRL := -DOSCCTRL -I$(FAUSTINC)/gui/
+ QTDEFS  := OSCCTRL
+ OSCLIB  := -L$(LIB)/faust/ -lOSCFaust -loscpack
+endif
+
+ifeq ($(HTTPD),1)
+ HTTPDCTRL := -DHTTPCTRL -I$(FAUSTINC)/gui
+ HTTPDDEFS := HTTPCTRL
+ HTTPDLIB  := -L$(LIB)/faust/ -lHTTPDFaust -lmicrohttpd
 endif
 
-MYICCFLAGS := '-O3 -xHost -ftz -fno-alias -fp-model fast=2 $(OSCCTRL)' 
+MYICCFLAGS := '-O3 -xHost -ftz -fno-alias -fp-model fast=2 $(OSCCTRL) $(HTTPDCTRL)' 
 
 ifeq ($(system), Darwin)
-MYGCCFLAGS := '-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math $(OSCCTRL)'
+MYGCCFLAGS := '-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math $(OSCCTRL) $(HTTPDCTRL)'
 else
-MYGCCFLAGS := '-O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math $(OSCCTRL)'
+MYGCCFLAGS := '-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math $(OSCCTRL) $(HTTPDCTRL)'
 endif
 
 VSIZE := 256
@@ -26,95 +42,209 @@ SC_SOURCE_DIR = ../../supercollider
 
 all : jackgtk
 
-test: ijackgtk ijackvec ijackomp gjackgtk gjackvec gjackomp
+testlin: alsagtk alsaqt jackgtk jackconsole jackqt netjackqt puredata ladspa dssi csound csounddouble w32vst
+
+testmac: caqt puredata maxmsp maxmsp64 csound csounddouble supercollider
+
+
+json :
+	install -d jsondir
+	$(MAKE) DEST='jsondir/' ARCH='gen-json.cpp' CXXFLAGS=$(MYGCCFLAGS) LIB='-L$(LIB)/faust/ -lHTTPDFaust' -f Makefile.compile
+
+alsagtk :
+	install -d alsagtkdir
+	$(MAKE) DEST='alsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0` $(OSCLIB) $(HTTPDLIB)'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+alsaqt :
+	install -d alsaqtdir
+	$(MAKE) DEST='alsaqtdir/' ARCH='alsa-qt.cpp' LIB='-lpthread -lasound $(OSCLIB) $(HTTPDLIB)' DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)" CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+
+caqt :
+	install -d caqtdir
+	$(MAKE) DEST='caqtdir/' ARCH='ca-qt.cpp' LIB='-framework CoreAudio -framework AudioUnit -framework CoreServices $(OSCLIB) $(HTTPDLIB)' CXXFLAGS=$(MYGCCFLAGS)  DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)"  -f Makefile.qtcompile
+
+
+jackgtk :
+	install -d jackgtkdir
+	$(MAKE) DEST='jackgtkdir/' ARCH='jack-gtk.cpp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB) $(HTTPDLIB)' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+jackconsole :
+	install -d jackconsoledir
+	$(MAKE) DEST='jackconsoledir/' ARCH='jack-console.cpp' VEC='-vec -vs $(VSIZE)' LIB='-lpthread `pkg-config --cflags --libs jack ` $(OSCLIB) $(HTTPDLIB)' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+jackqt :
+	install -d jackqtdir
+	$(MAKE) DEST='jackqtdir/' ARCH='jack-qt.cpp' LIB='-ljack $(OSCLIB) $(HTTPDLIB)' DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)" CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+
+netjackqt :
+	install -d netjackqtdir
+	$(MAKE) DEST='netjackqtdir/' ARCH='netjack-qt.cpp' LIB='-ljacknet $(OSCLIB) $(HTTPDLIB)' DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)" CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+
+svg:
+	$(MAKE) -f Makefile.svgcompile
+
+
+puredata :
+	install -d puredatadir
+	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.pdcompile
+
+
+ladspa :
+	install -d ladspadir
+	$(MAKE) DEST='ladspadir/' ARCH='ladspa.cpp' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
+
+
+dssi :
+	install -d dssidir
+	$(MAKE) DEST='dssidir/' ARCH='dssi.cpp' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.dssicompile
+
+
+csound :
+	install -d csounddir
+	$(MAKE) DEST='csounddir/'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.csound
+
+
+csounddouble :
+	install -d csounddoubledir
+	$(MAKE) DEST='csounddoubledir/' VEC='-double'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.csound
+
+
+module :
+	install -d moduledir
+	$(MAKE) DEST='moduledir/' ARCH='module.cpp' LIB='-fPIC -shared' EXT='.so'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+bundle :
+	install -d bundledir
+	$(MAKE) DEST='bundledir/' ARCH='module.cpp' LIB='-fPIC -bundle' EXT='.so'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+maxmsp msp :
+	install -d mspdir
+	$(MAKE) DEST='mspdir/' VEC='-g -vs 256' ARCH='max-msp.cpp' LIB=''  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.mspcompile
+
+maxmsp64 msp64 :
+	install -d msp64dir
+	$(MAKE) DEST='msp64dir/' VEC='-double -g -vs 256' ARCH='max-msp64.cpp' LIB=''  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.mspcompile
+
+
+w32vstdir :
+	mkdir w32vstdir
+
+w32vst : w32vstdir
+	$(MAKE) DEST='w32vstdir/' ARCH='vst2p4.cpp' LIB=''  -f Makefile.w32vstcompile
+
+vst :
+	install -d vstdir
+	$(MAKE) DEST='vstdir/' ARCH='vst2p4.cpp' LIB=''  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.vstcompile
+
+vsti:
+	install -d vstidir
+	$(MAKE) DEST='vstidir/' ARCH='vsti-poly.cpp' LIB='' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.vsticompile
+
+sndfile :
+	install -d sndfiledir
+	$(MAKE) DEST='sndfiledir/' ARCH='sndfile.cpp' LIB='-lsndfile'   CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+plot :
+	install -d plotdir
+	$(MAKE) DEST='plotdir/' ARCH='plot.cpp'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+matlabplot :
+	install -d matlabplotdir
+	$(MAKE) DEST='matlabplotdir/' ARCH='matlabplot.cpp'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+bench :
+	install -d benchdir
+	$(MAKE) DEST='benchdir/' ARCH='bench.cpp'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+gvecbench :
+	install -d gvecbenchdir
+	$(MAKE) DEST='gvecbenchdir/' ARCH='bench.cpp'  VEC='-vec -vs 256' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+ibench :
+	install -d ibenchdir
+	$(MAKE) DEST='ibenchdir/' ARCH='bench.cpp' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+
+
+supercollider sc:
+	install -d supercolliderdir
+	$(MAKE) DEST='supercolliderdir/' -f Makefile.sccompile
+
+mathdoc :
+	$(MAKE) -f Makefile.mathdoc
+
+
+
+
 
 ijackgtk :
 	install -d ijackgtkdir
-	$(MAKE) DEST='ijackgtkdir/' ARCH='jack-gtk.cpp' LIB='-I$(LIB)/faust/  `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ijackgtkdir/' ARCH='jack-gtk.cpp' LIB=' `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	###$(MAKE) DEST='ijackgtkdir/' ARCH='jack-gtk.cpp' LIB='-I$(LIB)/faust/  `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
 ijackvec :
 	install -d ijackvecdir
-	$(MAKE) DEST='ijackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ijackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
 ijackomp :
 	install -d ijackompdir
-	$(MAKE) DEST='ijackompdir/' ARCH='jack-gtk.cpp' VEC='-vs $(VSIZE) -omp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ijackompdir/' ARCH='jack-gtk.cpp' VEC='-vs $(VSIZE) -omp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
 
 ijacksch :
 	install -d ijackschdir
-	$(MAKE) DEST='ijackschdir/' ARCH='jack-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ijackschdir/' ARCH='jack-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
 gjackgtk :
 	install -d gjackgtkdir
-	$(MAKE) DEST='gjackgtkdir/' ARCH='jack-gtk.cpp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='gjackgtkdir/' ARCH='jack-gtk.cpp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
 
 gjackvec :
 	install -d gjackvecdir
-	$(MAKE) DEST='gjackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='gjackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
 
 gjackomp :
 	install -d gjackompdir
-	$(MAKE) DEST='gjackompdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS='-fopenmp '$(MYGCCFLAGS) -f Makefile.compile
-
-svg:
-	$(MAKE) -f Makefile.svgcompile
-
-puredata :
-	install -d puredatadir
-	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' LIB='-I$(LIB)/faust/' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.pdcompile
-
-alsagtk :
-	install -d alsagtkdir
-	$(MAKE) DEST='alsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-I$(LIB)/faust/ -lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0` $(OSCLIB)'  CXXFLAGS=$(OSCCTRL) -f Makefile.compile
+	$(MAKE) DEST='gjackompdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS='-fopenmp '$(MYGCCFLAGS) -f Makefile.compile
 
 ialsagtk :
 	install -d ialsagtkdir
-	$(MAKE) DEST='ialsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-I$(LIB)/faust/ -lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ialsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
 ialsavec :
 	install -d ialsavecdir
-	$(MAKE) DEST='ialsavecdir/' ARCH='alsa-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='-I$(LIB)/faust/ -lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ialsavecdir/' ARCH='alsa-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
 ialsaomp :
 	install -d ialsaompdir
-	$(MAKE) DEST='ialsaompdir/' ARCH='alsa-gtk.cpp' VEC='-omp -vs $(VSIZE)' LIB='-I$(LIB)/faust/ -lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ialsaompdir/' ARCH='alsa-gtk.cpp' VEC='-omp -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
 
 ialsasch :
 	install -d ialsaschdir
-	$(MAKE) DEST='ialsaschdir/' ARCH='alsa-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='-I$(LIB)/faust/ -lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-jackgtk :
-	install -d jackgtkdir
-	$(MAKE) DEST='jackgtkdir/' ARCH='jack-gtk.cpp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB)' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+	$(MAKE) DEST='ialsaschdir/' ARCH='alsa-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
 
 msjackgtk :
 	install -d msjackgtkdir
-	$(MAKE) DEST='msjackgtkdir/' ARCH='ms-jack-gtk.cpp' LIB='-I$(LIB)/faust/ -lMidiShare `pkg-config --cflags --libs jack gtk+-2.0`' -f Makefile.compile
-
-jackqt :
-	install -d jackqtdir
-	$(MAKE) DEST='jackqtdir/' ARCH='jack-qt.cpp' LIB='-ljack $(OSCLIB)' DEFS=$(QTDEFS) CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+	$(MAKE) DEST='msjackgtkdir/' ARCH='ms-jack-gtk.cpp' LIB='-lMidiShare `pkg-config --cflags --libs jack gtk+-2.0`' -f Makefile.compile
 
 jackqtsch :
 	install -d jackqtschdir
 	$(MAKE) DEST='jackqtschdir/' ARCH='jack-qt.cpp' VEC='-sch -vs $(VSIZE)' LIB='-ljack' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
 
-netjackqt :
-	install -d netjackqtdir
-	$(MAKE) DEST='netjackqtdir/' ARCH='netjack-qt.cpp' LIB='-ljacknet $(OSCLIB)' DEFS=$(QTDEFS) CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
-
 jackwt :
 	install -d jackwtdir
-	$(MAKE) DEST='jackwtdir/' ARCH='jack-wt.cpp' LIB='-I$(LIB)/faust/ -ljack -lwt -lwthttp -lboost_signals-mt $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.compile
+	$(MAKE) DEST='jackwtdir/' ARCH='jack-wt.cpp' LIB='-ljack -lwt -lwthttp -lboost_signals-mt $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.compile
 
 paqt :
 	install -d paqtdir
 	$(MAKE) DEST='paqtdir/' ARCH='pa-qt.cpp' LIB='-lportaudio $(OSCLIB)'  DEFS=$(QTDEFS) -f Makefile.qtcompile
 
-caqt :
-	install -d caqtdir
-	$(MAKE) DEST='caqtdir/' ARCH='ca-qt.cpp' LIB='-framework CoreAudio -framework AudioUnit -framework CoreServices $(OSCLIB)' CXXFLAGS=$(MYGCCFLAGS)  DEFS=$(QTDEFS)  -f Makefile.qtcompile
-
 oscioqt :  OSCLIB = -L$(LIB)/faust/osclib -lOSCFaust -loscpack
 oscioqt :
 	install -d oscioqtdir
@@ -123,31 +253,11 @@ oscioqt :
 osciogtk :  OSCLIB = -L$(LIB)/faust/osclib -lOSCFaust -loscpack
 osciogtk :
 	install -d osciogtkdir
-	$(MAKE) DEST='osciogtkdir/' ARCH='oscio-gtk.cpp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB)' CXXFLAGS=-I$(LIB)/faust/osclib -f Makefile.compile
-
-alsaqt :
-	install -d alsaqtdir
-	$(MAKE) DEST='alsaqtdir/' ARCH='alsa-qt.cpp' LIB='-lpthread -lasound $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.qtcompile
-
-ladspa :
-	install -d ladspadir
-	$(MAKE) DEST='ladspadir/' ARCH='ladspa.cpp' LIB='-I$(LIB)/faust/' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
+	$(MAKE) DEST='osciogtkdir/' ARCH='oscio-gtk.cpp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB)' CXXFLAGS=-I$(LIB)/faust/osclib -f Makefile.compile
 
 ladspasch :
 	install -d ladspaschdir
-	$(MAKE) DEST='ladspaschdir/' ARCH='ladspa.cpp' VEC='-sch -vs $(VSIZE)' LIB='-I$(LIB)/faust/' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
-
-dssi :
-	install -d dssidir
-	$(MAKE) DEST='dssidir/' ARCH='dssi.cpp' LIB='-I$(LIB)/faust/' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.dssicompile
-
-csound :
-	install -d csounddir
-	$(MAKE) DEST='csounddir/' -f Makefile.csound
-
-csounddouble :
-	install -d csounddoubledir
-	$(MAKE) DEST='csounddoubledir/' VEC='-double' -f Makefile.csound
+	$(MAKE) DEST='ladspaschdir/' ARCH='ladspa.cpp' VEC='-sch -vs $(VSIZE)' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
 
 jackwx :
 	install -d jackwxdir
@@ -163,34 +273,12 @@ osswx :
 
 pagtk :
 	install -d pagtkdir
-	$(MAKE) DEST='pagtkdir/' ARCH='pa-gtk.cpp' LIB='-I$(LIB)/faust/ -lpthread  -lportaudio `pkg-config gtk+-2.0  --cflags --libs` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
+	$(MAKE) DEST='pagtkdir/' ARCH='pa-gtk.cpp' LIB='-lpthread  -lportaudio `pkg-config gtk+-2.0  --cflags --libs` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
 
 pawx :
 	install -d pawxdir
 	$(MAKE) DEST='pawxdir/' ARCH='pa-wx.cpp' LIB='-lpthread  -lportaudio `wx-config --cflags --libs`' -f Makefile.compile
 
-module :
-	install -d moduledir
-	$(MAKE) DEST='moduledir/' ARCH='module.cpp' LIB='-I$(LIB)/faust/ -fPIC -shared' EXT='.so' -f Makefile.compile
-
-bundle :
-	install -d bundledir
-	$(MAKE) DEST='bundledir/' ARCH='module.cpp' LIB='-I$(LIB)/faust/ -fPIC -bundle' EXT='.so' -f Makefile.compile
-
-maxmsp msp :
-	install -d mspdir
-	$(MAKE) DEST='mspdir/' ARCH='max-msp.cpp' LIB='' -f Makefile.mspcompile
-
-w32vstdir :
-	mkdir w32vstdir
-
-w32vst : w32vstdir
-	$(MAKE) DEST='w32vstdir/' ARCH='vst2p4.cpp' LIB='' -f Makefile.w32vstcompile
-
-vst :
-	install -d vstdir
-	$(MAKE) DEST='vstdir/' ARCH='vst.cpp' LIB='' -f Makefile.vstcompile
-
 iphone :
 	install -d iphonedir
 	$(MAKE) DEST='iphonedir/' ARCH='iphone-cocoa.cpp' LIB='' -f Makefile.iphonecompile
@@ -199,72 +287,45 @@ iphonenet :
 	install -d iphonenetdir
 	$(MAKE) DEST='iphonenetdir/' ARCH='iphone-cocoa-net.cpp' LIB='' -f Makefile.iphonenetcompile
 
-bench :
-	install -d benchdir
-	$(MAKE) DEST='benchdir/' ARCH='bench.cpp' LIB='-I$(LIB)/faust/' -f Makefile.compile
-
-ibench :
-	install -d ibenchdir
-	$(MAKE) DEST='ibenchdir/' ARCH='bench.cpp' LIB='-I$(LIB)/faust/' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+ios :
+	install -d iosdir
+	$(MAKE) DEST='iosdir/' ARCH='ios-coreaudio.cpp'  LIB='' -f Makefile.ioscompile
 
 ivecbench :
 	install -d ivecbenchdir
-	$(MAKE) DEST='ivecbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE)' LIB='-I$(LIB)/faust/' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+	$(MAKE) DEST='ivecbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE)' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
 
 ivecjack :
 	install -d ivecjackdir
-	$(MAKE) DEST='ivecjackdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0`' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+	$(MAKE) DEST='ivecjackdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0`' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
 
 iparbench :
 	install -d iparbenchdir
-	$(MAKE) DEST='iparbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='-I$(LIB)/faust/' CXX='icc' CXXFLAGS='-O3 -openmp -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+	$(MAKE) DEST='iparbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE) -omp' CXX='icc' CXXFLAGS='-O3 -openmp -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
 
 gparbench :
 	install -d gparbenchdir
-	$(MAKE) DEST='gparbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='-I$(LIB)/faust/' CXX='g++' CXXFLAGS='-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math' -f Makefile.compile
-
-sndfile :
-	install -d sndfiledir
-	$(MAKE) DEST='sndfiledir/' ARCH='sndfile.cpp' LIB='-I$(LIB)/faust/ -lsndfile'  -f Makefile.compile
-CXXFLAGS=$(OSCCTRL)
-plot :
-	install -d plotdir
-	$(MAKE) DEST='plotdir/' ARCH='plot.cpp' LIB='-I$(LIB)/faust/' -f Makefile.compile
-
-matlabplot :
-	install -d matlabplotdir
-	$(MAKE) DEST='matlabplotdir/' ARCH='matlabplot.cpp' LIB='-I$(LIB)/faust/' -f Makefile.compile
+	$(MAKE) DEST='gparbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE) -omp' CXX='g++' CXXFLAGS='-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math' -f Makefile.compile
 
 q :
 	install -d qdir
-	$(MAKE) DEST='qdir/' ARCH='q.cpp' LIB='-I$(LIB)/faust/' -f Makefile.qcompile
-
-supercollider sc:
-	install -d supercolliderdir
-	$(MAKE) DEST='supercolliderdir/' -f Makefile.sccompile
-
-jackconsole :
-	install -d jackconsoledir
-	$(MAKE) DEST='jackconsoledir/' ARCH='jack-console.cpp' VEC='-vec -vs $(VSIZE)' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack ` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
-
-mathdoc :
-	$(MAKE) -f Makefile.mathdoc
+	$(MAKE) DEST='qdir/' ARCH='q.cpp' -f Makefile.qcompile
 
 help:
-	@echo "make alsagtk     [OSC=1] : compile examples as ALSA applications with a GTK Graphical User Interface"
-	@echo "make alsaqt      [OSC=1] : compile examples as ALSA applications with a QT4 Graphical User Interface"
-	@echo "make sndfile             : compile examples as sound file processors with a Command line User Interface"
-	@echo "make jackconsole [OSC=1] : compile examples as JACK applications with a Command line User Interface"
-	@echo "make jackgtk     [OSC=1] : compile examples as JACK applications with a GTK Graphical User Interface"
-	@echo "make jackqt      [OSC=1] : compile examples as JACK applications with a QT4 Graphical User Interface"
-	@echo "make jackwx              : compile examples as JACK applications with a wxWindows Graphical User Interface"
-	@echo "make ossgtk              : compile examples as OSS applications with a GTK Graphical User Interface"
-	@echo "make osswx               : compile examples as OSS applications with a wxWindows Graphical User Interface"
-	@echo "make pagtk       [OSC=1] : compile examples as PortAudio applications with a GTK Graphical User Interface"
-	@echo "make paqt        [OSC=1] : compile examples as PortAudio applications with a QT4 Graphical User Interface"
-	@echo "make pawx                : compile examples as PortAudio applications with a wxWindows Graphical User Interface"
-	@echo "make caqt        [OSC=1] : compile examples as CoreAudio applications with a QT4 Graphical User Interface"
-	@echo "make oscioqt             : compile examples as OSC driven applications with a QT4 Graphical User Interface"
+	@echo "make alsagtk     [OSC=1] [HTTPD=1] : compile examples as ALSA applications with a GTK Graphical User Interface"
+	@echo "make alsaqt      [OSC=1] [HTTPD=1] : compile examples as ALSA applications with a QT4 Graphical User Interface"
+	@echo "make sndfile             	  : compile examples as sound file processors with a Command line User Interface"
+	@echo "make jackconsole [OSC=1] [HTTPD=1] : compile examples as JACK applications with a Command line User Interface"
+	@echo "make jackgtk     [OSC=1] [HTTPD=1] : compile examples as JACK applications with a GTK Graphical User Interface"
+	@echo "make jackqt      [OSC=1] [HTTPD=1] : compile examples as JACK applications with a QT4 Graphical User Interface"
+	@echo "make jackwx              	  : compile examples as JACK applications with a wxWindows Graphical User Interface"
+	@echo "make ossgtk              	  : compile examples as OSS applications with a GTK Graphical User Interface"
+	@echo "make osswx               	  : compile examples as OSS applications with a wxWindows Graphical User Interface"
+	@echo "make pagtk       [OSC=1] [HTTPD=1] : compile examples as PortAudio applications with a GTK Graphical User Interface"
+	@echo "make paqt        [OSC=1] [HTTPD=1] : compile examples as PortAudio applications with a QT4 Graphical User Interface"
+	@echo "make pawx                	  : compile examples as PortAudio applications with a wxWindows Graphical User Interface"
+	@echo "make caqt        [OSC=1] [HTTPD=1] : compile examples as CoreAudio applications with a QT4 Graphical User Interface"
+	@echo "make oscioqt             	  : compile examples as OSC driven applications with a QT4 Graphical User Interface"
 	@echo "--------------------------------------------"
 	@echo "make ladspa        : compile examples as LADSPA plugins"
 	@echo "make dssi          : compile examples as DSSI plugins"
diff --git a/examples/Makefile.csound b/examples/Makefile.csound
index c6e9456..f5c2962 100644
--- a/examples/Makefile.csound
+++ b/examples/Makefile.csound
@@ -5,8 +5,10 @@
 
 system			:= $(shell uname -s)
 
+
 ifeq ($(system), Darwin)
-LIB := -I/Library/Frameworks/CsoundLib.framework/Headers -I/usr/local/include -framework CsoundLib -L/usr/local/lib -dynamiclib -arch i386
+LIB := -I/Library/Frameworks/CsoundLib.framework/Headers -I/usr/local/include -framework CsoundLib -L/usr/local/lib -dynamiclib
+#LIB := -F/Library/Frameworks -framework CsoundLib -dynamiclib -arch i386
 else
 #LIB := -I/usr/local/include -lsndfile -lcsound -shared
 LIB := -I/usr/include/csound -shared -fPIC
@@ -30,9 +32,11 @@ all :  $(opcodes)
 
 
 $(DEST)%.dylib : %.dsp
-	faust $(VEC) -uim -a csound.cpp $< -o $@.cpp
-	$(CXX) -O3 $(CXXFLAGS) $(LIB) -DOPCODE_NAME=$(notdir $(@:.dylib=)) $@.cpp -o $@
+	faust $(VEC) -i -uim -double -a csound.cpp $< -o $@.cpp
+	g++ $(CXXFLAGS) $(LIB) $(FAUSTINC) -DOPCODE_NAME=$(notdir $(@:.dylib=)) $@.cpp -o $@
 	
 
+
+
 clean :
 	rm -f $(DEST)
diff --git a/examples/Makefile.ioscompile b/examples/Makefile.ioscompile
new file mode 100644
index 0000000..690491d
--- /dev/null
+++ b/examples/Makefile.ioscompile
@@ -0,0 +1,17 @@
+## yann nina version 
+
+dspsrc  := $(wildcard *.dsp)
+cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
+appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=$(EXT)))
+
+all :  $(appl)
+
+$(DEST)% : %.dsp
+	install -d $@
+	cp -r /usr/local/lib/faust/iOS/* $@
+	faust $(VEC) -a $(ARCH) $< -o $@/ios-faust.h
+	xcodebuild -project $@/iOS.xcodeproj PRODUCT_NAME=$(<:.dsp=)
+	cp -r $@/build/Release-iphoneos/$(<:.dsp=.app) $@/../
+
+clean :
+	rm -f $(DEST)
\ No newline at end of file
diff --git a/examples/Makefile.mspcompile b/examples/Makefile.mspcompile
index fa5f1d5..10351d0 100644
--- a/examples/Makefile.mspcompile
+++ b/examples/Makefile.mspcompile
@@ -1,35 +1,37 @@
+#-------------------------------------------------------------------------------#
+# 				Makefile to produce Max MSP externals on MacOSX
+#
+#-------------------------------------------------------------------------------
+
+# Lists dsp file we have to compile
 dspsrc  := $(wildcard *.dsp)
 cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
 appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=~.mxo))
 processor := $(shell uname -p)
 
+# Path to Max/MSP SDK
+SDK		:=/usr/local/include/c74support/
+MAXINC	:=$(SDK)/max-includes
+MSPINC	:=$(SDK)/msp-includes
+
+# MacOSX Frameworks we are going to use
+FRAMEWORKS	:= -framework Carbon -I$(MAXINC) -I$(MSPINC) -F$(MAXINC) -F$(MSPINC) -framework MaxAPI -framework MaxAudioAPI
+
+# Compilation and optimisation options
+OPTIONS		:= -arch i386 -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -Wl,-Y,1455 -bundle
+
+# Which compiler we use
 CC=g++
 #CC=/Developer/usr/bin/llvm-g++
 
-INC	:= -I/usr/local/include/c74support/max-includes -I/usr/local/include/c74support/msp-includes -I $(PWD) -I/usr/local/lib/faust
 
 all :  $(appl)
 
 $(DEST)%~.mxo : %.dsp Info.plist.template
 	install -d $@/Contents/MacOS
-	faust $(VEC) -g -vs 2048 -a $(ARCH) $< -o $@/$(<:.dsp=.cpp)
-	#faust -sch -g -vs 2048 $(VEC) -a $(ARCH) $< -o $@/$(<:.dsp=.cpp)
-ifeq ($(processor), i386)
-	$(CC) -arch i386 -fpascal-strings -fasm-blocks -g -O3 $(INC)  -c $@/$(<:.dsp=.cpp) -o $@/$(<:.dsp=.i386.o)
-	$(CC) -framework MaxAPI -framework Carbon -framework MaxAudioAPI -arch i386 -Wl,-Y,1455 -bundle $@/$(<:.dsp=.i386.o) -o $@/$(<:.dsp=.i386~) 
-#	$(CC) -arch ppc -fpascal-strings -fasm-blocks -g -O3 $(INC)  -c $@/$(<:.dsp=.cpp) -o $@/$(<:.dsp=.ppc.o)
-#	$(CC) -framework Carbon -framework MaxAPI -framework MaxAudioAPI -arch ppc -Wl,-Y,1455 -bundle $@/$(<:.dsp=.ppc.o) -o $@/$(<:.dsp=.ppc~)
-	sed s/FOO/$(<:.dsp=~)/ <Info.plist.template >$@/Contents/Info.plist
-#	lipo -create $@/$(<:.dsp=.i386~) $@/$(<:.dsp=.ppc~) -output $@/Contents/MacOS/$(<:.dsp=~)
-	lipo -create $@/$(<:.dsp=.i386~) -output $@/Contents/MacOS/$(<:.dsp=~)
-	rm -f $@/$(<:.dsp=.ppc~) $@/$(<:.dsp=.ppc.o) $@/$(<:.dsp=.i386.o) $@/$(<:.dsp=.i386~)
-else
-	g++ -arch ppc -fpascal-strings -fasm-blocks -g -O3 $(INC)  -c $@/$(<:.dsp=.cpp) -o $@/$(<:.dsp=.ppc.o)
-	g++ -framework Carbon -framework MaxAPI -framework MaxAudioAPI -arch ppc -Wl,-Y,1455 -bundle $@/$(<:.dsp=.ppc.o) -o $@/$(<:.dsp=.ppc~)
+	faust $(VEC) -a $(ARCH) $< -o $@/$(<:.dsp=.cpp)
+	$(CC) $(FRAMEWORKS) $(OPTIONS) $@/$(<:.dsp=.cpp) -o $@/Contents/MacOS/$(<:.dsp=~)
 	sed s/FOO/$(<:.dsp=~)/ <Info.plist.template >$@/Contents/Info.plist
-	lipo -create $@/$(<:.dsp=.ppc~) -output $@/Contents/MacOS/$(<:.dsp=~)
-	rm -f $@/$(<:.dsp=.ppc~) $@/$(<:.dsp=.ppc.o)
-endif
 
 Info.plist.template :
 	echo '<?xml version="1.0" encoding="UTF-8"?>' > Info.plist.template
diff --git a/examples/Makefile.qtcompile b/examples/Makefile.qtcompile
index a4a7e3f..c4ffb5f 100644
--- a/examples/Makefile.qtcompile
+++ b/examples/Makefile.qtcompile
@@ -10,7 +10,7 @@ cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
 ### check what type of applications to build (MacOSX Darwin or Linux)
 ifeq ($(system), Darwin)
 appls	:= $(addprefix $(DEST),  $(dspsrc:.dsp=.app))
-SPEC	:= -spec macx-g++
+SPEC	:= -spec macx-clang
 else
 appls	:= $(addprefix $(DEST),  $(dspsrc:.dsp=))
 SPEC	:= 
@@ -30,8 +30,8 @@ all : $(appls)
 ### Darwin 
 $(DEST)%.app : %.dsp
 	install -d $(TMP)
-	faust -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
-	cd $(TMP); qmake -project "$(DEFS)" "INCLUDEPATH+=/usr/local/lib/faust/" "INCLUDEPATH+=/usr/local/lib/faust/osclib" "LIBS+=$(LIB)" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" 
+	faust -i -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
+	cd $(TMP); qmake -project "QT+=widgets printsupport network"  "$(DEFS)" "CONFIG+=warn_off" "CONFIG+=c++11" "INCLUDEPATH+=/usr/local/include/" "HEADERS+=/usr/local/include/faust/gui/faustqt.h" "LIBS+=$(LIB)" "QMAKE_CXXFLAGS= -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize -Wno-unused-parameter"
 	cd $(TMP); qmake $(SPEC)
 	make -C $(TMP)
 	rm -rf $@
@@ -40,9 +40,9 @@ $(DEST)%.app : %.dsp
 
 
 ### Linux
-hdir1 := $(wildcard /usr/local/lib/faust/gui/faustqt.h)
+hdir1 := $(wildcard /usr/local/include/faust/gui/faustqt.h)
 hdir2 := $(wildcard /usr/share/faust/faustqt.h)
-hdir3 := $(wildcard /usr/local/lib/faust/faustqt.h)
+hdir3 := $(wildcard /usr/local/include/faust/faustqt.h)
 hdir23 := $(if $(hdir2),$(dir $(hdir2)),$(dir $(hdir3)))
 hdir := $(if $(hdir1),$(dir $(hdir1)),$(hdir23))
 qm4 := $(shell which qmake-qt4)
@@ -52,7 +52,7 @@ $(DEST)% : %.dsp
 	rm -rf $(TMP)
 	install -d $(TMP)
 	faust -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
-	cd $(TMP); $(qm) -project "$(DEFS)" "INCLUDEPATH+=/usr/local/lib/faust/" "INCLUDEPATH+=/usr/local/lib/faust/osclib" "LIBS+=$(LIB)" "HEADERS+=$(hdir)faustqt.h" 
+	cd $(TMP); $(qm) -project "QT += widgets printsupport" "$(DEFS)" "INCLUDEPATH+=/usr/local/include/faust/" "INCLUDEPATH+=/usr/local/include/faust/osclib" "LIBS+=$(LIB)" "HEADERS+=$(hdir)faustqt.h" 
 	cd $(TMP); $(qm) $(SPEC)
 	make -C $(TMP)
 	mv $(TMP)/$(<:.dsp=) $@
diff --git a/examples/Makefile.vstcompile b/examples/Makefile.vstcompile
index 658a69b..70bdc7f 100644
--- a/examples/Makefile.vstcompile
+++ b/examples/Makefile.vstcompile
@@ -1,30 +1,13 @@
 dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=$(EXT)))
-
-# Setup this variable to access the VST SDK files
-vst_sdk := "/Volumes/Document1/Developpement/ProjectsCVS/JackCVS/JackOSX/jackosx/jackplugins/JACK-ASinsert/VST/VSTSDK"
-
-# Setup this variable with the location for the compiled VST plug-ins
-install_plug_ins := "/Library/Audio/Plug-Ins/VST"
+appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=.vst))
 
 all :  $(appl)
 
 	
-$(DEST)% : %.dsp
-	install -d $@
-	cp -r $(vst_sdk) $@
-	cp -r /usr/local/lib/faust/VST/* $@
-	faust $(VEC) -a $(ARCH) $< -o $@/vst-output.cpp
-	mv  $@/vst-output.cpp  $@/$(<:.dsp=.cpp)
-	sed -e 's/vst-output.cpp/$(<:.dsp=.cpp)/'  $@/VST.xcode/project.pbxproj > $@/VST.xcode/new_project.pbxproj &&  mv $@/VST.xcode/new_project.pbxproj $@/VST.xcode/project.pbxproj
-	sed -e 's/XXXX/$(<:.dsp=)/'  $@/Info.plist  >  $@/new_Info.plist  &&  mv $@/new_Info.plist $@/Info.plist
-	xcodebuild -project $@/VST.xcode clean
-	xcodebuild -project $@/VST.xcode
-	mv $@/build/FaustVST.vst $@/build/$(<:.dsp=.vst)
-	rm -r $@/build/VST.build
-	install -d $(install_plug_ins)
-	cp -r $@/build/$(<:.dsp=.vst) $(install_plug_ins)
+$(DEST)%.vst : %.dsp
+	faust2vst $<
+	rm -rf $@
+	mv $(<:.dsp=.vst) $(DEST)
 	
 
 clean :
diff --git a/examples/Makefile.vsticompile b/examples/Makefile.vsticompile
new file mode 100644
index 0000000..c97d8b3
--- /dev/null
+++ b/examples/Makefile.vsticompile
@@ -0,0 +1,14 @@
+dspsrc  := $(wildcard *.dsp)
+appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=.vst))
+
+all :  $(appl)
+
+	
+$(DEST)%.vst : %.dsp
+	faust2vsti $<
+	rm -rf $@
+	mv $(<:.dsp=.vst) $(DEST)
+	
+
+clean :
+	rm -f $(DEST)
diff --git a/examples/Makefile.w32vstcompile b/examples/Makefile.w32vstcompile
index a987147..672313c 100644
--- a/examples/Makefile.w32vstcompile
+++ b/examples/Makefile.w32vstcompile
@@ -14,7 +14,7 @@ VST=/usr/local/lib/vstsdk2.4
 #CROSS=i386-mingw32-
 CROSS=i586-mingw32msvc-
 CXX=$(CROSS)g++
-CXXFLAGS=-I$(VST) -I$(VST)/public.sdk/source/vst2.x -DBUILDING_DLL -mno-cygwin
+CXXFLAGS=-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -I$(VST) -I$(VST)/public.sdk/source/vst2.x -DBUILDING_DLL -mno-cygwin
 LDFLAGS=
 DLLWRAP=$(CROSS)dllwrap --target=i386-mingw32 -mno-cygwin
 STRIP=$(CROSS)strip
diff --git a/examples/OneSourceToStereo.dsp b/examples/OneSourceToStereo.dsp
new file mode 100644
index 0000000..8f90666
--- /dev/null
+++ b/examples/OneSourceToStereo.dsp
@@ -0,0 +1,14 @@
+declare name 		"OneSourceToStereo";
+declare version 	"1.0";
+declare author 		"CICM";
+declare license 	"BSD";
+declare copyright 	"(c)CICM 2013";
+
+import("hoa.lib") ;
+import("filter.lib") ;
+import("oscillator.lib");
+
+r1 = hslider("Radius", 1.0, 0, 5, 0.001) : smooth(tau2pole(0.02));
+a1 = hslider("Angle", 62831, -6.28318530717959, 6.28318530717959, 0.001) : smooth(tau2pole(0.02));
+
+process(sig) = map(7, sig, r1, a1) : optimInPhase(7) : decoderStereo(7);
diff --git a/examples/UITester.dsp b/examples/UITester.dsp
new file mode 100644
index 0000000..d0bb949
--- /dev/null
+++ b/examples/UITester.dsp
@@ -0,0 +1,72 @@
+declare name "UI Tester";
+declare version "1.0";
+declare author "O. Guillerminet";
+declare license "BSD";
+declare copyright "(c) O. Guillerminet 2012";
+
+vbox =			vgroup(		"vbox", 
+					checkbox("check1"),
+					checkbox("check2"),
+					nentry("knob0[style:knob]", 60, 0, 127, 0.1));
+
+sliders = 		hgroup(		"sliders",
+					vslider("vslider1", 60, 0, 127, 0.1),
+					vslider("vslider2", 60, 0, 127, 0.1),
+					vslider("vslider3", 60, 0, 127, 0.1));
+
+knobs = 		hgroup(		"knobs",
+					vslider("knob1[style:knob]", 60, 0, 127, 0.1),
+					vslider("knob2[style:knob]", 60, 0, 127, 0.1), 
+					vslider("knob3[style:knob]", 60, 0, 127, 0.1));
+
+smallhbox1 =		hgroup(		"small box 1",
+					vslider("vslider5 [unit:Hz]", 60, 0, 127, 0.1),
+					vslider("vslider6 [unit:Hz]", 60, 0, 127, 0.1),
+					vslider("knob4[style:knob]", 60, 0, 127, 0.1),
+					nentry("num1 [unit:f]", 60, 0, 127, 0.1),
+					vbargraph("vbar1", 0, 127));
+
+smallhbox2 =		hgroup(		"small box 2",
+					vslider("vslider7 [unit:Hz]", 60, 0, 127, 0.1),
+					vslider("vslider8 [unit:Hz]", 60, 0, 127, 0.1),
+					vslider("knob5[style:knob]", 60, 0, 127, 0.1),
+					nentry("num2 [unit:f]", 60, 0, 127, 0.1),
+					vbargraph("vbar2", 0, 127));
+
+smallhbox3 =		hgroup(		"small box 3",
+					vslider("vslider9 [unit:Hz]", 60, 0, 127, 0.1),
+					vslider("vslider10 [unit:m]", 60, 0, 127, 0.1),
+					vslider("knob6[style:knob]", 60, 0, 127, 0.1),
+					nentry("num3 [unit:f]", 60, 0, 127, 0.1),
+					vbargraph("vbar3", 0, 127));
+
+subhbox1 =		hgroup(		"sub box 1",
+					smallhbox2,
+					smallhbox3);
+
+vmisc = 		vgroup(		"vmisc",
+					vslider("vslider4 [unit:Hz]", 60, 0, 127, 0.1),
+					button("button"),
+					hslider("hslider [unit:Hz]", 60, 0, 127, 0.1),
+					smallhbox1,
+					subhbox1,
+					hbargraph("hbar", 0, 127));
+
+hmisc = 		hgroup(		"hmisc",
+					vslider("vslider4 [unit:f]", 60, 0, 127, 0.1),
+					button("button"),
+					hslider("hslider", 60, 0, 127, 0.1),
+					nentry("num [unit:f]", 60, 0, 127, 0.1),
+					vbargraph("vbar", 0, 127),
+					hbargraph("hbar", 0, 127));
+
+
+//------------------------- Process --------------------------------
+
+process = 		tgroup(		"grp 1",
+					vbox,
+					sliders,
+					knobs,
+					vmisc,
+					hmisc);
+
diff --git a/examples/cubic_distortion.dsp b/examples/cubic_distortion.dsp
index c8b562e..c2b0fcf 100644
--- a/examples/cubic_distortion.dsp
+++ b/examples/cubic_distortion.dsp
@@ -1,6 +1,9 @@
+declare name 		"cubic_distortion";
+
 ol = library("oscillator.lib");
 fl = library("filter.lib");
 el = library("effect.lib");
+
 process = 
 // ol.oscr_demo : el.cubicnl_demo : fl.spectral_level_demo <: _,_;
    vgroup("[1]",ol.oscr_demo) : 
diff --git a/examples/envelop.dsp b/examples/envelop.dsp
deleted file mode 100644
index 9dfc2c1..0000000
--- a/examples/envelop.dsp
+++ /dev/null
@@ -1,35 +0,0 @@
-declare name 		"envelop";
-declare version 	"1.0";
-declare author 		"Grame";
-declare license 	"BSD";
-declare copyright 	"(c)GRAME 2006";
-
-import("music.lib");
-
-//-------------------------------------------------
-// 		ADSR Envelop Generator
-//		The 'state' of the envelop generator is
-//		defined by a phase signal p2 allowing to
-//		distinguish the attack and the decay-sustain
-//		phases, and the envelop signal y itself.
-//-------------------------------------------------
-
-envelop(a,d,s,r,t) = adsr ~ (_,_) : (!,_)	 					// The 2 'state' signal are feedback
-    with {
-		adsr (p2,y) = (t>0) & (p2|(y>=1)),					// p2 = decay-sustain phase
-					  y + p1*a - (p2&(y>s))*d*y - p3*r*y	// y  = envelop signal
-		with {
-			p1 = (p2==0) & (t>0) & (y<1);					// p1 = attack phase
-			p3 = (t<=0) & (y>0);							// p3 = release phase
-		};
-    };
-
-
-attack 	= 1.0/(SR*nentry("[1:]attack [unit:ms][style:knob]", 20, 1, 1000, 1)/1000);
-decay  	= nentry("[2:]decay[style:knob]", 2, 1, 100, 0.1)/100000;
-sustain	= nentry("[3:]sustain [unit:pc][style:knob]", 10, 1, 100, 0.1)/100;
-release	= nentry("[4:]release[style:knob]", 10, 1, 100, 0.1)/100000;
-
-
-process =  button("play"): hgroup("", envelop(attack, decay, sustain, release) : *(noise));
-
diff --git a/examples/faust-stk/Makefile b/examples/faust-stk/Makefile
deleted file mode 100644
index 9dc1e94..0000000
--- a/examples/faust-stk/Makefile
+++ /dev/null
@@ -1,318 +0,0 @@
-# Directory containing Faust .lib and .cpp architecture files:
-ck1 := /opt/local/lib/faust/music.lib
-ck2 := /usr/local/lib/faust/music.lib
-ck3 := $(FAUST_LIB_PATH)/faust/music.lib
-LIB := $(if $(wildcard $(ck1)),/opt/local/lib,"")
-LIB := $(if $(wildcard $(ck2)),/usr/local/lib,$(LIB))
-LIB := $(if $(wildcard $(ck3)),$(FAUST_LIB_PATH),$(LIB))
-
-ifeq ($(OSC),1)
- OSCCTRL := "-DOSCCTRL -I$(LIB)/faust/osclib"
- QTDEFS  := "DEFINES += OSCCTRL"
- OSCLIB  := -L$(LIB)/faust/osclib -lOSCFaust -loscpack
-endif
-
-MYICCFLAGS := '-O3 -xT -ftz -fno-alias -fp-model fast=2 $(OSCCTRL)' 
-
-ifeq ($(system), Darwin)
-MYGCCFLAGS := '-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math $(OSCCTRL)'
-else
-MYGCCFLAGS := '-O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math $(OSCCTRL)'
-endif
-
-VSIZE := 256
-
-SC_SOURCE_DIR = ../../supercollider
-
-ifdef POLY
-  PDPOLY=$(POLY)
-else
-  PDPOLY=2
-endif
-
-ifdef RADIO
-  PDRADIO=-r $(RADIO)
-endif
-
-MYF2PDFLAGS='-s -n $(PDPOLY) $(PDRADIO)'
-
-all puredata:
-	install -d puredatadir
-	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' LIB='-L$(LIB)' F2PDFLAGS=$(MYF2PDFLAGS) CXXFLAGS=$(MYGCCFLAGS) -f Makefile.pdcompile
-
-pdpoly2 :
-	install -d puredatadir
-	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' LIB='-L$(LIB)' F2PDFLAGS='-n 2 -s' -f Makefile.pdcompile
-
-pdpoly4 :
-	install -d puredatadir
-	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' LIB='-L$(LIB)' F2PDFLAGS='-n 4 -s' -f Makefile.pdcompile
-
-pdpoly6 :
-	install -d puredatadir
-	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' LIB='-L$(LIB)' F2PDFLAGS='-n 6 -s' -f Makefile.pdcompile
-
-pdpoly8 :
-	install -d puredatadir
-	$(MAKE) DEST='puredatadir/' ARCH='puredata.cpp' LIB='-L$(LIB)' F2PDFLAGS='-n 8 -s' -f Makefile.pdcompile
-
-test: ijackgtk ijackvec ijackomp gjackgtk gjackvec gjackomp
-
-ijackgtk :
-	install -d ijackgtkdir
-	$(MAKE) DEST='ijackgtkdir/' ARCH='jack-gtk.cpp' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-ijackvec :
-	install -d ijackvecdir
-	$(MAKE) DEST='ijackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-ijackomp :
-	install -d ijackompdir
-	$(MAKE) DEST='ijackompdir/' ARCH='jack-gtk.cpp' VEC='-vs $(VSIZE) -omp' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
-
-ijacksch :
-	install -d ijackschdir
-	$(MAKE) DEST='ijackschdir/' ARCH='jack-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-gjackgtk :
-	install -d gjackgtkdir
-	$(MAKE) DEST='gjackgtkdir/' ARCH='jack-gtk.cpp' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
-
-gjackvec :
-	install -d gjackvecdir
-	$(MAKE) DEST='gjackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
-
-gjackomp :
-	install -d gjackompdir
-	$(MAKE) DEST='gjackompdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='-L$(LIB) `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS='-fopenmp '$(MYGCCFLAGS) -f Makefile.compile
-
-svg:
-	$(MAKE) -f Makefile.svgcompile
-
-alsagtk :
-	install -d alsagtkdir
-	$(MAKE) DEST='alsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-I$(LIB)/faust/ -lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0` $(OSCLIB)'  CXXFLAGS=$(OSCCTRL) -f Makefile.compile
-
-ialsagtk :
-	install -d ialsagtkdir
-	$(MAKE) DEST='ialsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-ialsavec :
-	install -d ialsavecdir
-	$(MAKE) DEST='ialsavecdir/' ARCH='alsa-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-ialsaomp :
-	install -d ialsaompdir
-	$(MAKE) DEST='ialsaompdir/' ARCH='alsa-gtk.cpp' VEC='-omp -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
-
-ialsasch :
-	install -d ialsaschdir
-	$(MAKE) DEST='ialsaschdir/' ARCH='alsa-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
-
-jackgtk :
-	install -d jackgtkdir
-	$(MAKE) DEST='jackgtkdir/' ARCH='jack-gtk.cpp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
-
-msjackgtk :
-	install -d msjackgtkdir
-	$(MAKE) DEST='msjackgtkdir/' ARCH='ms-jack-gtk.cpp' LIB='-lMidiShare `pkg-config --cflags --libs jack gtk+-2.0`' -f Makefile.compile
-
-jackqt :
-	install -d jackqtdir
-	$(MAKE) DEST='jackqtdir/' ARCH='jack-qt.cpp' LIB='-ljack $(OSCLIB)' DEFS=$(QTDEFS) CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
-
-jackqtsch :
-	install -d jackqtschdir
-	$(MAKE) DEST='jackqtschdir/' ARCH='jack-qt.cpp' VEC='-sch -vs $(VSIZE)' LIB='-ljack' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
-
-netjackqt :
-	install -d netjackqtdir
-	$(MAKE) DEST='netjackqtdir/' ARCH='netjack-qt.cpp' LIB='-ljacknet $(OSCLIB)' DEFS=$(QTDEFS) CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
-
-jackwt :
-	install -d jackwtdir
-	$(MAKE) DEST='jackwtdir/' ARCH='jack-wt.cpp' LIB='-I$(LIB)/faust/ -ljack -lwt -lwthttp -lboost_signals-mt $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.compile
-
-paqt :
-	install -d paqtdir
-	$(MAKE) DEST='paqtdir/' ARCH='pa-qt.cpp' LIB='-lportaudio $(OSCLIB)'  DEFS=$(QTDEFS) -f Makefile.qtcompile
-
-caqt :
-	install -d caqtdir
-	$(MAKE) DEST='caqtdir/' ARCH='ca-qt.cpp' LIB='-framework CoreAudio -framework AudioUnit -framework CoreServices $(OSCLIB)' CXXFLAGS=$(MYGCCFLAGS)  DEFS=$(QTDEFS)  -f Makefile.qtcompile
-
-oscioqt :  OSCLIB = -L$(LIB)/faust/osclib -lOSCFaust -loscpack
-oscioqt :
-	install -d oscioqtdir
-	$(MAKE) DEST='oscioqtdir/' ARCH='oscio-qt.cpp' LIB='-ljack $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.qtcompile
-
-osciogtk :  OSCLIB = -L$(LIB)/faust/osclib -lOSCFaust -loscpack
-osciogtk :
-	install -d osciogtkdir
-	$(MAKE) DEST='osciogtkdir/' ARCH='oscio-gtk.cpp' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB)' CXXFLAGS=-I$(LIB)/faust/osclib -f Makefile.compile
-
-alsaqt :
-	install -d alsaqtdir
-	$(MAKE) DEST='alsaqtdir/' ARCH='alsa-qt.cpp' LIB='-lpthread -lasound $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.qtcompile
-
-ladspa :
-	install -d ladspadir
-	$(MAKE) DEST='ladspadir/' ARCH='ladspa.cpp' LIB='-I$(LIB)/faust/' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
-
-ladspasch :
-	install -d ladspaschdir
-	$(MAKE) DEST='ladspaschdir/' ARCH='ladspa.cpp' VEC='-sch -vs $(VSIZE)' LIB='-I$(LIB)/faust/' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
-
-dssi :
-	install -d dssidir
-	$(MAKE) DEST='dssidir/' ARCH='dssi.cpp' LIB='-I$(LIB)/faust/' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.dssicompile
-
-csound :
-	install -d csounddir
-	$(MAKE) DEST='csounddir/' -f Makefile.csound
-
-csounddouble :
-	install -d csounddoubledir
-	$(MAKE) DEST='csounddoubledir/' VEC='-double' -f Makefile.csound
-
-jackwx :
-	install -d jackwxdir
-	$(MAKE) DEST='jackwxdir/' ARCH='jack-wx.cpp' LIB='`pkg-config jack  --cflags --libs` `wx-config --cflags --libs`' -f Makefile.compile
-
-ossgtk :
-	install -d ossgtkdir
-	$(MAKE) DEST='ossgtkdir/' ARCH='oss-gtk.cpp' LIB='-lpthread  `pkg-config gtk+-2.0  --cflags --libs`' -f Makefile.compile
-
-osswx :
-	install -d osswxdir
-	$(MAKE) DEST='osswxdir/' ARCH='oss-wx.cpp' LIB='-lpthread  `wx-config --cflags --libs`' -f Makefile.compile
-
-pagtk :
-	install -d pagtkdir
-	$(MAKE) DEST='pagtkdir/' ARCH='pa-gtk.cpp' LIB='-I$(LIB)/faust/ -lpthread  -lportaudio `pkg-config gtk+-2.0  --cflags --libs` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
-
-pawx :
-	install -d pawxdir
-	$(MAKE) DEST='pawxdir/' ARCH='pa-wx.cpp' LIB='-lpthread  -lportaudio `wx-config --cflags --libs`' -f Makefile.compile
-
-module :
-	install -d moduledir
-	$(MAKE) DEST='moduledir/' ARCH='module.cpp' LIB='-fPIC -shared' EXT='.so' -f Makefile.compile
-
-bundle :
-	install -d bundledir
-	$(MAKE) DEST='bundledir/' ARCH='module.cpp' LIB='-I$(LIB)/faust/ -fPIC -bundle' EXT='.so' -f Makefile.compile
-
-maxmsp msp :
-	install -d mspdir
-	$(MAKE) DEST='mspdir/' ARCH='max-msp.cpp' LIB='' -f Makefile.mspcompile
-
-w32vstdir :
-	mkdir w32vstdir
-
-w32vst : w32vstdir
-	$(MAKE) DEST='w32vstdir/' ARCH='vst2p4.cpp' LIB='' -f Makefile.w32vstcompile
-
-vst :
-	install -d vstdir
-	$(MAKE) DEST='vstdir/' ARCH='vst.cpp' LIB='' -f Makefile.vstcompile
-
-iphone :
-	install -d iphonedir
-	$(MAKE) DEST='iphonedir/' ARCH='iphone-cocoa.cpp' LIB='' -f Makefile.iphonecompile
-
-iphonenet :
-	install -d iphonenetdir
-	$(MAKE) DEST='iphonenetdir/' ARCH='iphone-cocoa-net.cpp' LIB='' -f Makefile.iphonenetcompile
-
-bench :
-	install -d benchdir
-	$(MAKE) DEST='benchdir/' ARCH='bench.cpp' LIB='' -f Makefile.compile
-
-ibench :
-	install -d ibenchdir
-	$(MAKE) DEST='ibenchdir/' ARCH='parbench.cpp' LIB='' CXX='icc' CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
-
-ivecbench :
-	install -d ivecbenchdir
-	$(MAKE) DEST='ivecbenchdir/' ARCH='parbench.cpp' VEC='-vec -vs $(VSIZE)' LIB='' CXX='icc' CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
-
-ivecjack :
-	install -d ivecjackdir
-	$(MAKE) DEST='ivecjackdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0`' CXX='icc' CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
-
-iparbench :
-	install -d iparbenchdir
-	$(MAKE) DEST='iparbenchdir/' ARCH='parbench.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='' CXX='icc' CXXFLAGS='-O3 -openmp -xT -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
-
-gparbench :
-	install -d gparbenchdir
-	$(MAKE) DEST='gparbenchdir/' ARCH='parbench.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='' CXX='g++' CXXFLAGS='-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math' -f Makefile.compile
-
-sndfile :
-	install -d sndfiledir
-	$(MAKE) DEST='sndfiledir/' ARCH='sndfile.cpp' LIB='-I$(LIB)/faust/ -lsndfile'  -f Makefile.compile
-CXXFLAGS=$(OSCCTRL)
-plot :
-	install -d plotdir
-	$(MAKE) DEST='plotdir/' ARCH='plot.cpp' LIB='' -f Makefile.compile
-
-matlabplot :
-	install -d matlabplotdir
-	$(MAKE) DEST='matlabplotdir/' ARCH='matlabplot.cpp' LIB='' -f Makefile.compile
-
-q :
-	install -d qdir
-	$(MAKE) DEST='qdir/' ARCH='q.cpp' LIB='' -f Makefile.qcompile
-
-supercollider sc:
-	install -d supercolliderdir
-	$(MAKE) DEST='supercolliderdir/' -f Makefile.sccompile
-
-jackconsole :
-	install -d jackconsoledir
-	$(MAKE) DEST='jackconsoledir/' ARCH='jack-console.cpp' VEC='-vec -vs $(VSIZE)' LIB='-I$(LIB)/faust/ `pkg-config --cflags --libs jack ` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
-
-mathdoc :
-	$(MAKE) -f Makefile.mathdoc
-
-help:
-	@echo "make alsagtk     [OSC=1] : compile examples as ALSA applications with a GTK Graphical User Interface"
-	@echo "make alsaqt      [OSC=1] : compile examples as ALSA applications with a QT4 Graphical User Interface"
-	@echo "make sndfile             : compile examples as sound file processors with a Command line User Interface"
-	@echo "make jackconsole [OSC=1] : compile examples as JACK applications with a Command line User Interface"
-	@echo "make jackgtk     [OSC=1] : compile examples as JACK applications with a GTK Graphical User Interface"
-	@echo "make jackqt      [OSC=1] : compile examples as JACK applications with a QT4 Graphical User Interface"
-	@echo "make jackwx              : compile examples as JACK applications with a wxWindows Graphical User Interface"
-	@echo "make ossgtk              : compile examples as OSS applications with a GTK Graphical User Interface"
-	@echo "make osswx               : compile examples as OSS applications with a wxWindows Graphical User Interface"
-	@echo "make pagtk       [OSC=1] : compile examples as PortAudio applications with a GTK Graphical User Interface"
-	@echo "make paqt        [OSC=1] : compile examples as PortAudio applications with a QT4 Graphical User Interface"
-	@echo "make pawx                : compile examples as PortAudio applications with a wxWindows Graphical User Interface"
-	@echo "make caqt        [OSC=1] : compile examples as CoreAudio applications with a QT4 Graphical User Interface"
-	@echo "make oscioqt             : compile examples as OSC driven applications with a QT4 Graphical User Interface"
-	@echo "--------------------------------------------"
-	@echo "make ladspa        : compile examples as LADSPA plugins"
-	@echo "make dssi          : compile examples as DSSI plugins"
-	@echo "make csound        : compile examples as CSOUND opcodes"
-	@echo "make csounddouble  : compile examples as double precision CSOUND opcodes"
-	@echo "make maxmsp        : compile examples as Max/MSP externals"
-	@echo "make vst           : compile examples as native VST plugins"
-	@echo "make w32vst        : crosscompile examples as windows VST plugins"
-	@echo "make iphone        : compile examples for Apple iPhone/iPod"
-	@echo "make supercollider : compile examples as Supercollider plugins"
-	@echo "make puredata      : compile examples as Puredata externals"
-	@echo "make q             : compile examples as Q plugins"
-	@echo "--------------------------------------------"
-	@echo "make svg           : generate the examples block-diagrams in SVG format "
-	@echo "make mathdoc       : generate the examples math documentation in TEX and PDF formats "
-	@echo "make bench         : compile examples as command line benchmarks "
-	@echo "make plot          : compile examples as command line programs that print samples for plotting  with, e.g., gnuplot"
-	@echo "make matlabplot    : compile examples as command line programs that print samples in matlab input format"
-	@echo "--------------------------------------------"
-	@echo "make clean         : remove all object files"
-
-clean :
-	rm -rf *dir
-	rm -rf *-svg
-	$(MAKE) -f Makefile.mathdoc clean
diff --git a/examples/faust-stk/Makefile.compile b/examples/faust-stk/Makefile.compile
deleted file mode 100644
index 7f7b44b..0000000
--- a/examples/faust-stk/Makefile.compile
+++ /dev/null
@@ -1,15 +0,0 @@
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=$(EXT)))
-
-
-all :  $(appl)
-
-
-$(DEST)%$(EXT) : %.dsp 
-	faust $(VEC) -a $(ARCH) $< -o $@.cpp
-	$(CXX) -O3 $(CXXFLAGS) -I $(PWD) $(LIB) $@.cpp -o $@
-	
-
-clean :
-	rm -f $(DEST)
diff --git a/examples/faust-stk/Makefile.csound b/examples/faust-stk/Makefile.csound
deleted file mode 100644
index c6e9456..0000000
--- a/examples/faust-stk/Makefile.csound
+++ /dev/null
@@ -1,38 +0,0 @@
-
-###--------------------------------------------
-### adjust flags to the system
-###
-
-system			:= $(shell uname -s)
-
-ifeq ($(system), Darwin)
-LIB := -I/Library/Frameworks/CsoundLib.framework/Headers -I/usr/local/include -framework CsoundLib -L/usr/local/lib -dynamiclib -arch i386
-else
-#LIB := -I/usr/local/include -lsndfile -lcsound -shared
-LIB := -I/usr/include/csound -shared -fPIC
-endif
-
-###For Windows with gcc/mingw:(if headers in /usr/local/include and libs in /usr/local/lib)
-###g++ -O2  -shared -o myopcode.dylib myopcode.cpp -DOPCODE_NAME=myopcode -I/usr/local/include -lsndfile -lcsound32
-
-
-###--------------------------------------------
-### Build csound opcodes on Darwin or Linux (fx.dsp -> fx.cpp -> fx.dylib)
-###
-
-dspsrc  := $(wildcard *.dsp)
-##cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-opcodes := $(addprefix $(DEST), $(dspsrc:.dsp=.dylib))
-
-
-
-all :  $(opcodes)
-
-
-$(DEST)%.dylib : %.dsp
-	faust $(VEC) -uim -a csound.cpp $< -o $@.cpp
-	$(CXX) -O3 $(CXXFLAGS) $(LIB) -DOPCODE_NAME=$(notdir $(@:.dylib=)) $@.cpp -o $@
-	
-
-clean :
-	rm -f $(DEST)
diff --git a/examples/faust-stk/Makefile.dssicompile b/examples/faust-stk/Makefile.dssicompile
deleted file mode 100644
index 1e75c0a..0000000
--- a/examples/faust-stk/Makefile.dssicompile
+++ /dev/null
@@ -1,24 +0,0 @@
-ARCH    := dssi.cpp
-DEST	:= dssidir/
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-modules	:= $(addprefix $(DEST),  $(dspsrc:%.dsp=%.so))
-
-###allcpp: $(cppsrc)
-
-allmodules: $(modules)
-
-ifeq ($(system), Darwin)
-SHAREDFLAG := -bundle
-else
-SHAREDFLAG := -shared
-endif
-
-$(DEST)%.so: $(DEST)%.cpp
-	$(CXX) -I. -Wall $(LIB) -fPIC -DPIC $(SHAREDFLAG) $(CXXFLAGS) -Dmydsp=$(patsubst %.so,%,$(notdir $@)) $< -o $@
-
-$(DEST)%.cpp: %.dsp 
-	faust $(VEC) -a $(ARCH) $< -o $@
-
-clean:
-	rm -rf $(DEST)
diff --git a/examples/faust-stk/Makefile.iphonecompile b/examples/faust-stk/Makefile.iphonecompile
deleted file mode 100644
index 7a2822e..0000000
--- a/examples/faust-stk/Makefile.iphonecompile
+++ /dev/null
@@ -1,16 +0,0 @@
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=$(EXT)))
-
-all :  $(appl)
-
-$(DEST)% : %.dsp
-	install -d $@
-	cp -r /usr/local/lib/faust/iPhone/* $@
-	faust $(VEC) -a $(ARCH) $< -o $@/iphone-faust.h
-	xcodebuild -project $@/iPhone.xcodeproj PRODUCT_NAME=$(<:.dsp=)
-	cp -r $@/build/Release-iphoneos/$(<:.dsp=.app) $@/../
-	rm -r $@
-
-clean :
-	rm -f $(DEST)
diff --git a/examples/faust-stk/Makefile.mathdoc b/examples/faust-stk/Makefile.mathdoc
deleted file mode 100644
index 45ffa5d..0000000
--- a/examples/faust-stk/Makefile.mathdoc
+++ /dev/null
@@ -1,47 +0,0 @@
-DSP = $(wildcard *.dsp)
-TEX = $(wildcard *-mdoc/tex/*.tex)
-PDF = $(wildcard *-mdoc/pdf/*.pdf)
-
-all : mathdoc copypdfs
-
-
-.PHONY: all clean compile copypdfs copyall install mathdoc help
-
-
-compile :
-	$(MAKE) -C ..
-
-install :
-	sudo $(MAKE) -C .. install
-	sudo $(MAKE) -C ../tools/faust2appls install
-
-mathdoc :
-	faust2mathdoc *.dsp
-
-copypdfs :
-	mkdir -p allmathpdfs
-	cp $(wildcard *-mdoc/pdf/*.pdf) allmathpdfs/
-
-copyall :
-	mkdir -p allmathdsps
-	mkdir -p allmathtexs
-	mkdir -p allmathpdfs
-	cp $(wildcard *.dsp) allmathdsps/
-	cp $(wildcard *-mdoc/tex/*.tex) allmathtexs/
-	cp $(wildcard *-mdoc/pdf/*.pdf) allmathpdfs/
-
-help :
-	@echo "make or make all : compile math documentation of all examples, then copy resulting pdf files into \"allmathpdfs\" directory."
-	@echo "make clean    : remove \"*-mdoc\" and \"allmath*\" directories."
-	@echo "make compile  : compile the faust compiler."
-	@echo "make install  : install the faust compiler and faust2appls scripts."
-	@echo "make mathdoc  : generate math documentation of all examples (with faust2mathdoc)."
-	@echo "make copypdfs : copy pdf files into \"allmathpdfs\" directory."
-	@echo "make copyall  : copy dsp, pdf, and tex files into \"allmathdsps\", \"allmathpdfs\", and \"allmathtexs\" directories."
-	@echo "make total    : clean, compile faust, install faust and faust2appls, compile math docs, and copy files."
-
-clean :
-	rm -rf allmath*
-	rm -rf *-mdoc
-
-total : clean compile install mathdoc copyall
diff --git a/examples/faust-stk/Makefile.mspcompile b/examples/faust-stk/Makefile.mspcompile
deleted file mode 100644
index 0d14eb4..0000000
--- a/examples/faust-stk/Makefile.mspcompile
+++ /dev/null
@@ -1,48 +0,0 @@
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=~.mxo))
-processor := $(shell uname -p)
-
-CC=g++
-#CC=/Developer/usr/bin/llvm-g++
-
-INC	:= -I/usr/local/include/c74support/max-includes -I/usr/local/include/c74support/msp-includes -I $(PWD) -I/usr/local/lib/faust
-
-all :  $(appl)
-
-$(DEST)%~.mxo : %.dsp Info.plist.template
-	install -d $@/Contents/MacOS
-	faust $(VEC) -g -vs 2048 -a $(ARCH) $< -o $@/$(<:.dsp=.cpp)
-	#faust -sch -g -vs 2048 $(VEC) -a $(ARCH) $< -o $@/$(<:.dsp=.cpp)
-ifeq ($(processor), i386)
-	$(CC) -arch i386 -fpascal-strings -fasm-blocks -g -O3 $(INC)  -c $@/$(<:.dsp=.cpp) -o $@/$(<:.dsp=.i386.o)
-	$(CC) -framework MaxAPI -framework Carbon -framework MaxAudioAPI -arch i386 -Wl,-Y,1455 -bundle $@/$(<:.dsp=.i386.o) -o $@/$(<:.dsp=.i386~) 
-	$(CC) -arch ppc -fpascal-strings -fasm-blocks -g -O3 $(INC)  -c $@/$(<:.dsp=.cpp) -o $@/$(<:.dsp=.ppc.o)
-	$(CC) -framework Carbon -framework MaxAPI -framework MaxAudioAPI -arch ppc -Wl,-Y,1455 -bundle $@/$(<:.dsp=.ppc.o) -o $@/$(<:.dsp=.ppc~)
-	sed s/FOO/$(<:.dsp=~)/ <Info.plist.template >$@/Contents/Info.plist
-	lipo -create $@/$(<:.dsp=.i386~) $@/$(<:.dsp=.ppc~) -output $@/Contents/MacOS/$(<:.dsp=~)
-	rm -f $@/$(<:.dsp=.ppc~) $@/$(<:.dsp=.ppc.o) $@/$(<:.dsp=.i386.o) $@/$(<:.dsp=.i386~)
-else
-	g++ -arch ppc -fpascal-strings -fasm-blocks -g -O3 $(INC)  -c $@/$(<:.dsp=.cpp) -o $@/$(<:.dsp=.ppc.o)
-	g++ -framework Carbon -framework MaxAPI -framework MaxAudioAPI -arch ppc -Wl,-Y,1455 -bundle $@/$(<:.dsp=.ppc.o) -o $@/$(<:.dsp=.ppc~)
-	sed s/FOO/$(<:.dsp=~)/ <Info.plist.template >$@/Contents/Info.plist
-	lipo -create $@/$(<:.dsp=.ppc~) -output $@/Contents/MacOS/$(<:.dsp=~)
-	rm -f $@/$(<:.dsp=.ppc~) $@/$(<:.dsp=.ppc.o)
-endif
-
-Info.plist.template :
-	echo '<?xml version="1.0" encoding="UTF-8"?>' > Info.plist.template
-	echo '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'  >> Info.plist.template
-	echo '<plist version="1.0">'  		>> Info.plist.template
-	echo '<dict>'  				>> Info.plist.template
-	echo '	<key>CFBundleExecutable</key>'  >> Info.plist.template
-	echo '	<string>FOO</string>'  		>> Info.plist.template
-	echo '	<key>CFBundleName</key>'  	>> Info.plist.template
-	echo '	<string>FOO</string>'  		>> Info.plist.template
-	echo '	<key>CFBundlePackageType</key>'  >> Info.plist.template
-	echo '	<string>iLaX</string>'  	>> Info.plist.template
-	echo '</dict>'  			>> Info.plist.template
-	echo '</plist>'  			>> Info.plist.template
-
-clean :
-	rm -f $(DEST)
diff --git a/examples/faust-stk/Makefile.pdcompile b/examples/faust-stk/Makefile.pdcompile
deleted file mode 100644
index cf12a71..0000000
--- a/examples/faust-stk/Makefile.pdcompile
+++ /dev/null
@@ -1,79 +0,0 @@
-
-###--------------------------------------------
-### Build puredata externals on Darwin or Linux
-###
-
-system			:= $(shell uname -s)
-DEST			:= pddir/
-dspsrc  		:= $(wildcard *.dsp)
-cppsrc  		:= $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-patches			:= $(addprefix $(DEST),  $(dspsrc:.dsp=.pd))
-FAUST2PD 		:= faust2pd
-OPTIONAL 		:= -I ./
-FREEVERB 		:= freeverb.dsp.xml
-
-###--------------------------------------------
-### compilation flags for Linux
-### include dir must contain m_pd.h
-###
-LINUXCFLAGS 	:= -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \
-                   -Wall $(CXXFLAGS)
-LINUXINCLUDE 	:= -I/usr/include/pdextended
-
-###--------------------------------------------
-### compilation flags for Darwin
-###
-DARWINCFLAGS 	:= -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC -Wall -msse
-DYNLOAD_FLAGS	:= -bundle -undefined suppress -flat_namespace
-DARWININCLUDE 	:= -I/Applications/Pd-extended.app/Contents/Resources/include/  -I/opt/local/include
-
-###--------------------------------------------
-### check what type of modules to build (MacOSX Darwin or Linux)
-###
-ifeq ($(system), Darwin)
-modules 		:= $(addprefix $(DEST),  $(dspsrc:.dsp=~.pd_darwin))
-else
-modules			:= $(addprefix $(DEST),  $(dspsrc:.dsp=~.pd_linux))
-endif
-
-
-###--------------------------------------------
-### Will use faust2pd to create the GUI patches
-### only if it is installed
-
-helper:=$(shell which faust2pd)
-hasfaust2pd := $(findstring /faust2pd, $(helper))
-
-ifeq ($(hasfaust2pd),)
-	todo:=$(modules)
-	message:="*** Install <faust>/tools/faust2pd if you want the example Pd patches to work ***"
-else
-	todo:=$(modules) $(patches)
-	message:="Compiled: $(todo)"
-endif
-
-###--------------------------------------------
-
-
-allmodules: $(todo) print_message
-
-$(DEST)%.cpp: %.dsp
-	faust -a $(ARCH) $< -o $@
-	
-$(DEST)%.pd: %.dsp
-	faust -xml $< -o /dev/null
-	$(FAUST2PD) $(F2PDFLAGS) $<.xml
-	mv $(<:.dsp=.pd) $(DEST)
-	rm -f $<.xml
-
-$(DEST)%~.pd_linux: $(DEST)%.cpp
-	$(CXX) $(LINUXCFLAGS) $(LINUXINCLUDE) $(OPTIONAL) -shared -Dmydsp=$(patsubst %~.pd_linux,%,$(notdir $@)) $< -o $@
-
-$(DEST)%~.pd_darwin: $(DEST)%.cpp
-	$(CXX) $(DARWINCFLAGS) $(DARWININCLUDE) $(DYNLOAD_FLAGS) $(OPTIONAL) -Dmydsp=$(patsubst %~.pd_darwin,%,$(notdir $@)) $< -o $@
-
-print_message:
-	echo $(message)
-
-clean:
-	rm -rf $(DEST)
diff --git a/examples/faust-stk/Makefile.qcompile b/examples/faust-stk/Makefile.qcompile
deleted file mode 100644
index 9a12af2..0000000
--- a/examples/faust-stk/Makefile.qcompile
+++ /dev/null
@@ -1,17 +0,0 @@
-DEST	:= qdir/
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-modules	:= $(addprefix $(DEST),  $(dspsrc:%.dsp=%.so))
-
-###allcpp: $(cppsrc)
-
-allmodules: $(modules)
-
-$(DEST)%.so: $(DEST)%.cpp
-	$(CXX) -shared -O3 $(CXXFLAGS) -Dmydsp=$(patsubst %.so,%,$(notdir $@)) $< -o $@
-
-$(DEST)%.cpp: %.dsp 
-	faust $(VEC) -a q.cpp $< -o $@
-
-clean:
-	rm -rf $(DEST)
diff --git a/examples/faust-stk/Makefile.qtcompile b/examples/faust-stk/Makefile.qtcompile
deleted file mode 100644
index 39abac2..0000000
--- a/examples/faust-stk/Makefile.qtcompile
+++ /dev/null
@@ -1,62 +0,0 @@
-###--------------------------------------------
-### DEST : directory where to put binaries
-### ARCH : faust architecture file
-
-system	:= $(shell uname -s)
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-
-
-### check what type of applications to build (MacOSX Darwin or Linux)
-ifeq ($(system), Darwin)
-appls	:= $(addprefix $(DEST),  $(dspsrc:.dsp=.app))
-SPEC	:= -spec macx-g++
-else
-appls	:= $(addprefix $(DEST),  $(dspsrc:.dsp=))
-SPEC	:= 
-endif
-### --------------------------------------------
-
-
-### allocate a unique directory
-TDR := $(shell mktemp -d -t FAUST.XXXXXX)
-TMP = $(TDR)/$(<:.dsp=)
-### --------------------------------------------
-
-
-all : $(appls)
-
-
-### Darwin 
-$(DEST)%.app : %.dsp
-	install -d $(TMP)
-	faust -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
-	cd $(TMP); qmake -project "$(DEFS)" "INCLUDEPATH+=/usr/local/lib/faust/" "INCLUDEPATH+=$(PWD)" "INCLUDEPATH+=/usr/local/lib/faust/osclib" "LIBS+=$(LIB)" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" 
-	cd $(TMP); qmake $(SPEC)
-	make -C $(TMP)
-	rm -rf $@
-	mv $(TMP)/$(<:.dsp=.app) $(DEST)
-	rm -rf $(TDR)
-
-
-### Linux
-hdir1 := $(wildcard /usr/local/lib/faust/gui/faustqt.h)
-hdir2 := $(wildcard /usr/share/faust/faustqt.h)
-hdir3 := $(wildcard /usr/local/lib/faust/faustqt.h)
-hdir23 := $(if $(hdir2),$(dir $(hdir2)),$(dir $(hdir3)))
-hdir := $(if $(hdir1),$(dir $(hdir1)),$(hdir23))
-qm4 := $(shell which qmake-qt4)
-qm := $(if $(qm4),$(qm4),qmake)
-
-$(DEST)% : %.dsp
-	rm -rf $(TMP)
-	install -d $(TMP)
-	faust -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
-	cd $(TMP); $(qm) -project "$(DEFS)" "INCLUDEPATH+=/usr/local/lib/faust/" "INCLUDEPATH+=$(PWD)" "INCLUDEPATH+=/usr/local/lib/faust/osclib" "LIBS+=$(LIB)" "HEADERS+=$(hdir)faustqt.h" 
-	cd $(TMP); $(qm) $(SPEC)
-	make -C $(TMP)
-	mv $(TMP)/$(<:.dsp=) $@
-	rm -rf $(TMP)
-
-clean:
-	rm -rf $(DEST)
diff --git a/examples/faust-stk/Makefile.sccompile b/examples/faust-stk/Makefile.sccompile
deleted file mode 100644
index 8decba2..0000000
--- a/examples/faust-stk/Makefile.sccompile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile to produce supercollider plugins with Faust:
-#  'foo.dsp' -> 'foo.so|scx' and 'foo.sc'
-# These two files (scsynth plugin and sclang extension), can be copied to
-#  $HOME/share/SuperCollider/Extensions (Linux) or 
-#  $HOME/Library/Application Support/SuperCollider/Extensions (Mac OS X)
-#
-# The shell script <faust>/tools/faust2appls/faust2supercollider 
-#  needs to be installed somewhere in the user's search path.
-
-system	:= $(shell uname -s)
-ifeq ($(system), Darwin)
-EXT	:= scx
-else
-EXT	:= so
-endif
-
-dspsrc := $(wildcard *.dsp)
-libsrc := $(wildcard *.lib)
-incsrc := $(wildcard *.h)
-allsrc := $(dspsrc) $(libsrc) $(incsrc)
-
-ifeq ($(DEST),)
-	DEST := ./supercolliderdir
-endif 
-
-F2SC = faust2supercollider -sd
-
-### allocate a unique directory for staging
-TMP := $(shell mktemp -d -t F2SC.XXXXXX)
-### --------------------------------------------
-
-# NOTE: Some source files need others, so best to copy all together:
-all : $(allsrc) $(DEST) $(TMP)
-	cp -i $(allsrc) $(TMP) || echo "Cannot copy temp source to $(TMP)"
-	(cd $(TMP); for i in $(dspsrc); do $(F2SC) $$i; done)
-	mv $(TMP)/*.sc $(TMP)/*.$(EXT) $(DEST)
-	rm -rf $(TMP)
-
-$(DEST):
-	mkdir -p $(DEST)
-
-$(TMP):
-	mkdir -p $(TMP)
diff --git a/examples/faust-stk/Makefile.vstcompile b/examples/faust-stk/Makefile.vstcompile
deleted file mode 100644
index 658a69b..0000000
--- a/examples/faust-stk/Makefile.vstcompile
+++ /dev/null
@@ -1,31 +0,0 @@
-dspsrc  := $(wildcard *.dsp)
-cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
-appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=$(EXT)))
-
-# Setup this variable to access the VST SDK files
-vst_sdk := "/Volumes/Document1/Developpement/ProjectsCVS/JackCVS/JackOSX/jackosx/jackplugins/JACK-ASinsert/VST/VSTSDK"
-
-# Setup this variable with the location for the compiled VST plug-ins
-install_plug_ins := "/Library/Audio/Plug-Ins/VST"
-
-all :  $(appl)
-
-	
-$(DEST)% : %.dsp
-	install -d $@
-	cp -r $(vst_sdk) $@
-	cp -r /usr/local/lib/faust/VST/* $@
-	faust $(VEC) -a $(ARCH) $< -o $@/vst-output.cpp
-	mv  $@/vst-output.cpp  $@/$(<:.dsp=.cpp)
-	sed -e 's/vst-output.cpp/$(<:.dsp=.cpp)/'  $@/VST.xcode/project.pbxproj > $@/VST.xcode/new_project.pbxproj &&  mv $@/VST.xcode/new_project.pbxproj $@/VST.xcode/project.pbxproj
-	sed -e 's/XXXX/$(<:.dsp=)/'  $@/Info.plist  >  $@/new_Info.plist  &&  mv $@/new_Info.plist $@/Info.plist
-	xcodebuild -project $@/VST.xcode clean
-	xcodebuild -project $@/VST.xcode
-	mv $@/build/FaustVST.vst $@/build/$(<:.dsp=.vst)
-	rm -r $@/build/VST.build
-	install -d $(install_plug_ins)
-	cp -r $@/build/$(<:.dsp=.vst) $(install_plug_ins)
-	
-
-clean :
-	rm -f $(DEST)
diff --git a/examples/faust-stk/Makefile.w32vstcompile b/examples/faust-stk/Makefile.w32vstcompile
deleted file mode 100644
index 486a5e1..0000000
--- a/examples/faust-stk/Makefile.w32vstcompile
+++ /dev/null
@@ -1,58 +0,0 @@
-################################################################################
-#
-#              CROSSCOMPILATION FROM LINUX OF VST PLUGINS FOR WINDOWS
-#              Faust Project, Y. Orlarey - Grame
-#
-################################################################################
-
-#------------------------------------------------------------------------------
-# 1/ VST SDK Should be installed somewhere
-VST=../vstsdk2.4
-
-#------------------------------------------------------------------------------
-# 2/ mingw crosscompiler should be installed ('mingw32' package on Ubuntu)
-#CROSS=i386-mingw32-
-CROSS=i586-mingw32msvc-
-CXX=$(CROSS)g++
-CXXFLAGS=-I$(VST) -I$(VST)/public.sdk/source/vst2.x -DBUILDING_DLL -mno-cygwin
-LDFLAGS=
-DLLWRAP=$(CROSS)dllwrap --target=i386-mingw32 -mno-cygwin
-STRIP=$(CROSS)strip
-
-
-#------------------------------------------------------------------------------
-# 3/ we transform all .dsp Faust codes into the corresponding dll
-DSP= $(wildcard *.dsp)
-DLL= $(addprefix $(DEST), $(DSP:.dsp=.dll))
-
-##PLUGIN= $(SRC:.dsp=)
-##DLL=$(PLUGIN).dll
-#
-
-all : $(DLL)
-
-# how to generate the cpp file from the faust source
-$(DEST)%.cpp : %.dsp
-	faust -a vst2p4.cpp $< -o $@
-
-# we need to create the .def file needed to generate the .dll
-$(DEST)%.def :
-	@echo LIBRARY     $(@:.def=) 						 > $@
-	@echo DESCRIPTION \'Faust generated VST plugin\' 	>> $@
-	@echo EXPORTS     main=VSTPluginMain 				>> $@
-
-
-$(DEST)%.dll: $(DEST)%.o  $(DEST)%.def $(DEST)audioeffect.o $(DEST)audioeffectx.o $(DEST)vstplugmain.o
-	$(DLLWRAP) --driver-name $(CXX) --def $(@:.dll=.def) $^ -o $@
-	$(STRIP) $@
-
-$(DEST)audioeffect.o: $(VST)/public.sdk/source/vst2.x/audioeffect.cpp
-	$(CXX) $(CXXFLAGS) -c $< -o $@
-
-$(DEST)audioeffectx.o: $(VST)/public.sdk/source/vst2.x/audioeffectx.cpp
-	$(CXX) $(CXXFLAGS) -c $< -o $@
-
-$(DEST)vstplugmain.o: $(VST)/public.sdk/source/vst2.x/vstplugmain.cpp
-	$(CXX) $(CXXFLAGS) -c $< -o $@
- 
-
diff --git a/examples/faust-stk/README b/examples/faust-stk/README
index a43dca7..0798b40 100644
--- a/examples/faust-stk/README
+++ b/examples/faust-stk/README
@@ -92,11 +92,14 @@ of the architecture files (jackqt, jackgtk, etc.).
 3/ How to compile?
 ------------------
 
-In order to compile the instruments, the latest FAUST repository must be installed on your computer 
-(03/21/2011) as well as all the required dependencies for the FAUST architecture you wish to use. 
+In order to compile the instruments, the latest FAUST repository must be installed on your computer as well 
+as all the required dependencies for the FAUST architecture you wish to use. 
 
-Type "make help" in a terminal to print the list of available architectures and to know how to compile
-the examples.
+Run any of the faust compilation script with one of the .dsp file contained in this directory. For example:
+
+faust2caqt *
+
+will compile all the objects as Core Audio Qt applications...
 
 4/ Acknowledgments
 ------------------
@@ -119,4 +122,4 @@ About FAUST: https://lists.sourceforge.net/lists/listinfo/faudiostream-users
 
 
 
-Romain Michon
\ No newline at end of file
+Romain Michon
diff --git a/examples/faust-stk/instrument.lib b/examples/faust-stk/instrument.lib
deleted file mode 100644
index dffdbeb..0000000
--- a/examples/faust-stk/instrument.lib
+++ /dev/null
@@ -1,298 +0,0 @@
-//instrument.lib - Faust function of various types usefull for building physical model instruments 
-
-declare name "Faust-STK Tools Library";
-declare author "Romain Michon (rmichon at ccrma.stanford.edu)";
-declare copyright "Romain Michon";
-declare version "1.0";
-declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
-
-import("math.lib");
-import("filter.lib");
-import("effect.lib");
-
-//========================= ENVELOPE GENERATORS ===============================
-
-//----------------------- VIBRATO ENVELOPE ----------------------------
-// 4 phases envelope to control vibrato gain
-//
-// USAGE: 
-//   _ : *(envVibrato(b,a,s,r,t)) : _
-// where
-//   b = beginning duration (silence) in seconds
-//   a = attack duration in seconds
-//   s = sustain as a percentage of the amplitude to be modified
-//   r = release duration in seconds
-//   t = trigger signal 
-
-envVibrato(b,a,s,r,t) = env ~ (_,_,_) : (!,!,_) // the 3 'state' signals are fed back
-with {
-    env (p2,cnt,y) =
-        (t>0) & (p2|(y>=1)),
-		(cnt + 1)*(t>0), // counter for the first step "b" 
-        (y + p1*p3*u*(s/100) - p4*w*y)*((p4==0)|(y>=eps))	// y  = envelop signal
-		//*(y>=eps) // cut off tails to prevent denormals
-    with {
-	p1 = (p2==0) & (t>0) & (y<1) & (cnt>(b*SR)); // p1 = attack phase
-	p3 = 1-(cnt<(nb)); // p3 = beginning phase
-	p4 = (t<=0) & (y>0);  // p4 = release phase
-	// #samples in attack, release, must be >0
-	nb = SR*b+(b==0.0) ; na = SR*a+(a==0.0); nr = SR*r+(r==0.0);
-	// attack and (-60dB) release rates
-	z = s+(s==0.0)*db2linear(-60);
-	u = 1/na; w = 1-1/pow(z*db2linear(60), 1/nr);
-	// values below this threshold are considered zero in the release phase
-	eps = db2linear(-120);
-    };
-};
-
-//----------------------- ATTACK - SUSTAIN - RELEASE ----------------------------
-// Attack - Sustain - Release envelope
-//
-// USAGE: 
-//   _ : *(asr(a,s,r,t)) : _
-// where
-//   a = attack duration in seconds
-//   s = sustain as a percentage of the amplitude to be modified
-//   r = release duration in seconds
-//   t = trigger signal 
-
-asr(a,s,r,t) = env ~ (_,_) : (!,_) // the 2 'state' signals are fed back
-with {
-    env (p2,y) =
-        (t>0) & (p2|(y>=1)),
-        (y + p1*u*(s/100) - p3*w*y)	// y  = envelop signal
-	*((p3==0)|(y>=eps)) // cut off tails to prevent denormals
-    with {
-	p1 = (p2==0) & (t>0) & (y<1); // p1 = attack phase
-	p3 = (t<=0) & (y>0); // p3 = release phase
-	// #samples in attack, release, must be >0
-	na = SR*a+(a==0.0); nr = SR*r+(r==0.0);
-	// correct zero sustain level
-	z = s+(s==0.0)*db2linear(-60);
-	// attack and (-60dB) release rates
-	u = 1/na; w = 1-1/pow(z*db2linear(60), 1/nr);
-	// values below this threshold are considered zero in the release phase
-	eps = db2linear(-120);
-    };
-};
-
-//----------------------- ASYMPT60 ----------------------------
-// Envelope generator which asymptotically approaches a target value.
-//
-// USAGE: 
-//   asympT60(value,trgt,T60,trig) : _
-// where
-//   value = starting value
-//   trgt = target value
-//   T60 = ramping time
-//   trig = trigger signal 
-
-asympT60(value,trgt,T60,trig) = (_*factor + constant)~_
-	with{
-		cntSample = *(trig) + 1~_ : -(1);
-		attDur = float(2);
-		cndFirst = ((cntSample < attDur) & (trig > 0));
-		target = value*cndFirst + trgt*(cndFirst < 1);
-		factorAtt = exp(-7/attDur);
-		factorT60 = exp(-7/(T60*float(SR)));
-		factor = factorAtt*((cntSample < attDur) & (trig > 0)) + 
-		       ((cntSample >= attDur) | (trig < 1))*factorT60;
-		constant = (1 - factor)*target;	
-	};
-
-//========================= TABLES ===============================
-
-//----------------------- CLIPPING FUNCTION ----------------------------
-// Positive and negative clipping functions.
-//
-// USAGE: 
-//   _ : saturationPos : _
-//   _ : saturationNeg : _
-//   _ : saturationPos : saturationNeg : _
-
-saturationPos(x) = x <: (_>1),(_<=1 : *(x)) :> +;
-saturationNeg(x) = x <: (_<-1),(_>=-1 : *(x)) :> *(-1) + _;
-
-//----------------------- BOW TABLE ----------------------------
-// Simple bow table.
-//
-// USAGE: 
-//   index : bow(offset,slope) : _
-// where
-//   0 <= index <= 1 
-
-bow(offset,slope) = pow(abs(sample) + 0.75, -4) : saturationPos
-	with{
-	sample(y) = (y + offset)*slope;
-	};
-
-//----------------------- REED TABLE ----------------------------
-// Simple reed table to be used with waveguide models of clanrinet, saxophone, etc.
-//
-// USAGE:
-//   _ : reed(offset,slope) : _
-// where
-//   offset = offset between 0 and 1
-//   slope = slope between 0 and 1
-// REFERENCE:
-//   https://ccrma.stanford.edu/~jos/pasp/View_Single_Reed_Oscillation.html
-
-reed(offset,slope) = reedTable : saturationPos : saturationNeg
-	with{
-	reedTable = offset + (slope*_);
-	};
-
-//========================= FILTERS ===============================
-
-//----------------------- ONE POLE ----------------------------
-
-onePole(b0,a1,x) = (b0*x - a1*_)~_;
-
-//----------------------- ONE POLE SWEPT ----------------------------
-
-onePoleSwep(a1,x) = (1 + a1)*x - a1*x';
-
-//----------------------- POLE ZERO ----------------------------
-
-poleZero(b0,b1,a1,x) = (b0*x + b1*x' - a1*_)~_;
-
-//----------------------- ONE ZEROS ----------------------------
-// Simple One zero and One zero recursive filters
-//
-// USAGE:
-//   _ : oneZero0(b0,b1) : _
-//   _ : oneZero1(b0,b1) : _
-// REFERENCE:
-//   https://ccrma.stanford.edu/~jos/fp2/One_Zero.html
-
-oneZero0(b0,b1,x) = (*(b1) + x*b0)~_;
-oneZero1(b0,b1,x) = (x'*b1 + x*b0);
-
-//----------------------- BANDPASS FILTER WITH CONSTANT UNITY PEAK GAIN BASED ON A BIQUAD ----------------------------
-
-bandPass(resonance,radius) = TF2(b0,b1,b2,a1,a2)
-	with{
-		a2 = radius*radius;
-		a1 = -2*radius*cos(PI*2*resonance/SR);
-		b0 = 0.5-0.5*a2;
-		b1 = 0;
-		b2 = -b0;
-	};
-
-//----------------------- BANDPASS FILTER BASED ON A BIQUAD ----------------------------
-// Band pass filter using a biquad (TF2 is declared in filter.lib)
-//
-// USAGE:
-//   _ : bandPassH(resonance,radius) : _
-// where
-//   resonance = center frequency
-//   radius = radius
-
-bandPassH(resonance,radius) = TF2(b0,b1,b2,a1,a2)
-	with{
-		a2 = radius*radius;
-		a1 = -2*radius*cos(PI*2*resonance/SR);
-		b0 = 1;
-		b1 = 0;
-		b2 = 0;
-	};
-
-//----------------------- FLUE JET NON-LINEAR FUNCTION ----------------------------	
-// Jet Table: flue jet non-linear function, computed by a polynomial calculation
-	
-jetTable(x) = x <: _*(_*_-1) : saturationPos : saturationNeg;
-
-//----------------------- NON LINEAR MODULATOR ----------------------------
-// nonLinearModulator adapts the function allpassnn from filter.lib for using it with waveguide instruments
-//
-// USAGE:
-//   _ : nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) : _
-// where
-//   nonlinearity = nonlinearity coefficient between 0 and 1 
-//   env = input to connect any kind of envelope
-//   freq = current tone frequency
-//   typeMod = if 0: theta is modulated by the incoming signal;
-//	       if 1: theta is modulated by the averaged incoming signal;
-//	       if 2: theta is modulated by the squared incoming signal;
-//	       if 3: theta is modulated by a sine wave of frequency freqMod;
-//	       if 4: theta is modulated by a sine wave of frequency freq;
-//   freqMod = frequency of the sine wave modulation
-//   order = order of the filter
- 
-nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) = 
-	//theta is modulated by a sine wave
-	_ <: nonLinearFilterOsc*(typeMod >= 3),
-	//theta is modulated by the incoming signal
-	     (_ <: nonLinearFilterSig*nonlinearity,_*(1 - nonlinearity) :> +)*(typeMod < 3)
-	:> +
-	with{
-		//which frequency to use for the sine wave oscillator?
-		freqOscMod = (typeMod == 4)*freq + (typeMod != 4)*freqMod;
-
-		//the incoming signal is scaled and the envelope is applied
-		tsignorm(x) = nonlinearity*PI*x*env;
-		tsigsquared(x) = nonlinearity*PI*x*x*env; //incoming signal is squared
-		tsigav(x) = nonlinearity*PI*((x + x')/2)*env; //incoming signal is averaged with its previous sample
-		
-		//select which version of the incoming signal of theta to use
-		tsig(x) = tsignorm(x)*(typeMod == 0) + tsigav(x)*(typeMod == 1) 
-			  + tsigsquared(x)*(typeMod == 2);
-
-		//theta is modulated by a sine wave generator
-		tosc = nonlinearity*PI*osc(freqOscMod)*env; 
-
-		//incoming signal is sent to the nonlinear passive allpass ladder filter
-		nonLinearFilterSig(x) = x <: allpassnn(order,(par(i,order,tsig(x))));
-		nonLinearFilterOsc = _ <: allpassnn(order,(par(i,order,tosc)));
-	};
-	
-//========================= WAVE TABLES ===============================
-
-//----------------------- STICK IMPACT ----------------------------
-// Stick impact table.
-//
-// USAGE:
-//   index : readMarmstk1 : _
-
-readMarmstk1 = ffunction(float readMarmstk1 (int), <instrument.h>,"");
-marmstk1TableSize = 246;
-
-//========================= TOOLS ===============================
-
-//----------------------- STEREOIZER ----------------------------
-// This function takes a mono input signal and spacialize it in stereo 
-// in function of the period duration of the tone being played.
-//
-// USAGE:
-//   _ : stereo(periodDuration) : _,_
-// where
-//   periodDuration = period duration of the tone being played in number of samples 
-// ACKNOWLEDGMENT
-//   Formulation initiated by Julius O. Smith in https://ccrma.stanford.edu/realsimple/faust_strings/  	
-
-stereoizer(periodDuration) = _ <: _,widthdelay : stereopanner
-	   with{
-		W = hslider("v:Spat/spatial width", 0.5, 0, 1, 0.01);
-		A = hslider("v:Spat/pan angle", 0.6, 0, 1, 0.01);
-		widthdelay = delay(4096,W*periodDuration/2);
-		stereopanner = _,_ : *(1.0-A), *(A);
-	   };
-
-//----------------------- INSTRREVERB ----------------------------
-// GUI for zita_rev1_stereo from effect.lib
-//
-// USAGE:
-//  _,_ : instrRerveb
-
-instrReverb = _,_ <: *(reverbGain),*(reverbGain),*(1 - reverbGain),*(1 - reverbGain) : 
-zita_rev1_stereo(rdel,f1,f2,t60dc,t60m,fsmax),_,_ <: _,!,_,!,!,_,!,_ : +,+
-       with{
-       reverbGain = hslider("v:Reverb/reverbGain",0.137,0,1,0.01) : smooth(0.999);
-       roomSize = hslider("v:Reverb/roomSize",0.72,0.01,2,0.01);
-       rdel = 20;
-       f1 = 200;
-       f2 = 6000;
-       t60dc = roomSize*3;
-       t60m = roomSize*2;
-       fsmax = 48000;
-       };
diff --git a/examples/faust-stk/modalBar.dsp b/examples/faust-stk/modalBar.dsp
index 04eb859..72ad4ea 100644
--- a/examples/faust-stk/modalBar.dsp
+++ b/examples/faust-stk/modalBar.dsp
@@ -4,16 +4,29 @@ declare author "Romain Michon (rmichon at ccrma.stanford.edu)";
 declare copyright "Romain Michon";
 declare version "1.0";
 declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
-declare description "A number of different struck bar instruments. Presets numbers: 0->Marimba, 1->Vibraphone, 2->Agogo, 3->Wood1, 4->Reso, 5->Wood2, 6->Beats, 7->2Fix; 8->Clump"; 
+declare description "A number of different struck bar instruments. Presets numbers: 0->Marimba, 1->Vibraphone, 2->Agogo, 3->Wood1, 4->Reso, 5->Wood2, 6->Beats, 7->2Fix; 8->Clump";
 
 import("music.lib");
 import("instrument.lib");
 
+
+//========================= WAVE TABLES ===============================
+
+//----------------------- STICK IMPACT ----------------------------
+// Stick impact table.
+//
+// USAGE:
+//   index : readMarmstk1 : _
+
+readMarmstk1 = ffunction(float readMarmstk1 (int), <instrument.h>,"");
+marmstk1TableSize = 246;
+
+
 //==================== GUI SPECIFICATION ================
 
 freq = nentry("h:Basic_Parameters/freq [1][unit:Hz] [tooltip:Tone frequency]",440,20,20000,1);
-gain = nentry("h:Basic_Parameters/gain [1][tooltip:Gain (value between 0 and 1)]",0.8,0,1,0.01); 
-gate = button("h:Basic_Parameters/gate [1][tooltip:noteOn = 1, noteOff = 0]"); 
+gain = nentry("h:Basic_Parameters/gain [1][tooltip:Gain (value between 0 and 1)]",0.8,0,1,0.01);
+gate = button("h:Basic_Parameters/gate [1][tooltip:noteOn = 1, noteOff = 0]");
 
 stickHardness = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Stick_Hardness
 [2][tooltip:A value between 0 and 1]",0.25,0,1,0.01);
@@ -22,18 +35,18 @@ reson = nentry("h:Physical_and_Nonlinearity/v:Physical_Parameters/Resonance
 presetNumber = nentry("h:Physical_and_Nonlinearity/v:Physical_Parameters/Preset
 [2][tooltip:0->Marimba, 1->Vibraphone, 2->Agogo, 3->Wood1, 4->Reso, 5->Wood2, 6->Beats, 7->2Fix; 8->Clump]",1,0,8,1);
 
-typeModulation = nentry("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Type 
+typeModulation = nentry("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Type
 [3][tooltip: 0=theta is modulated by the incoming signal; 1=theta is modulated by the averaged incoming signal;
 2=theta is modulated by the squared incoming signal; 3=theta is modulated by a sine wave of frequency freqMod;
 4=theta is modulated by a sine wave of frequency freq;]",0,0,4,1);
-nonLinearity = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity 
+nonLinearity = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity
 [3][tooltip:Nonlinearity factor (value between 0 and 1)]",0,0,1,0.01);
-frequencyMod = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Frequency 
+frequencyMod = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Frequency
 [3][unit:Hz][tooltip:Frequency of the sine wave for the modulation of theta (works if Modulation Type=3)]",220,20,1000,0.1);
 nonLinAttack = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity_Attack
 [3][unit:s][Attack duration of the nonlinearity]",0.1,0,2,0.01);
 
-vibratoFreq = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Freq 
+vibratoFreq = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Freq
 [4][unit:Hz]",6,1,15,0.1);
 vibratoGain = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Gain
 [4][tooltip:A value between 0 and 1]",0.1,0,1,0.01);
@@ -44,44 +57,44 @@ vibratoGain = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Gain
 //nonlinearities are created by the nonlinear passive allpass ladder filter declared in filter.lib
 
 //nonlinear filter order
-nlfOrder = 6; 
+nlfOrder = 6;
 
-//nonLinearModultor is declared in instrument.lib, it adapts allpassnn from filter.lib 
+//nonLinearModultor is declared in instrument.lib, it adapts allpassnn from filter.lib
 //for using it with waveguide instruments
 NLFM =  nonLinearModulator((nonLinearity : smooth(0.999)),1,freq,
      typeModulation,(frequencyMod : smooth(0.999)),nlfOrder);
 
 //----------------------- Synthesis parameters computing and functions declaration ----------------------------
 
-//stereoizer is declared in instrument.lib and implement a stereo spacialisation in function of 
-//the frequency period in number of samples 
+//stereoizer is declared in instrument.lib and implement a stereo spacialisation in function of
+//the frequency period in number of samples
 stereo = stereoizer(SR/freq);
 
 //check if the vibraphone is used
 vibratoOn = presetNumber == 1;
 
 //vibrato
-vibrato = 1 + osc(vibratoFreq)*vibratoGain*vibratoOn; 
+vibrato = 1 + osc(vibratoFreq)*vibratoGain*vibratoOn;
 
 //filter bank output gain
 directGain = loadPreset(presetNumber,3,2);
 
-//modal values for the filter bank 
+//modal values for the filter bank
 loadPreset = ffunction(float loadPreset (int,int,int), <modalBar.h>,"");
- 
+
 //filter bank using biquad filters
 biquadBank = _ <: sum(i, 4, oneFilter(i))
 	with{
 		condition(x) = x<0 <: *(-x),((-(1))*-1)*x*freq :> +;
 		dampCondition = (gate < 1) & (reson != 1);
-		
+
 		//the filter coefficients are interpolated when changing of preset
-		oneFilter(j,y) = (loadPreset(presetNumber,0,j : smooth(0.999)) : condition), 
-						loadPreset(presetNumber,1,j : smooth(0.999))*(1-(gain*0.03*dampCondition)), 
+		oneFilter(j,y) = (loadPreset(presetNumber,0,j : smooth(0.999)) : condition),
+						loadPreset(presetNumber,1,j : smooth(0.999))*(1-(gain*0.03*dampCondition)),
 						y*(loadPreset(presetNumber,2,j) : smooth(0.999)) : bandPassH;
 	};
 
-//one pole filter with pole set at 0.9 for pre-filtering, onePole is declared in instrument.lib 
+//one pole filter with pole set at 0.9 for pre-filtering, onePole is declared in instrument.lib
 sourceFilter = onePole(b0,a1)
 	with{
 		b0 = 1 - 0.9;
@@ -93,17 +106,17 @@ excitation = counterSamples < (marmstk1TableSize*rate) : *(marmstk1Wave*gate)
 	   with{
 		//readMarmstk1 and marmstk1TableSize are both declared in instrument.lib
 		marmstk1 = time%marmstk1TableSize : int : readMarmstk1;
-		
+
 		dataRate(readRate) = readRate : (+ : decimal) ~ _ : *(float(marmstk1TableSize));
-		
+
 		//the reading rate of the stick table is defined in function of the stickHardness
 		rate = 0.25*pow(4,stickHardness);
-		
+
 		counterSamples = (*(gate)+1)~_ : -(1);
 		marmstk1Wave = rdtable(marmstk1TableSize,marmstk1,int(dataRate(rate)*gate));
 	   };
 
-process = excitation : sourceFilter : *(gain) <: 
+process = excitation : sourceFilter : *(gain) <:
 	//resonance
 	(biquadBank <: -(*(directGain))) + (directGain*_) :
 	//vibrato for the vibraphone
diff --git a/examples/faust-tubes/Makefile b/examples/faust-tubes/Makefile
new file mode 100644
index 0000000..fad84e7
--- /dev/null
+++ b/examples/faust-tubes/Makefile
@@ -0,0 +1,350 @@
+# Directory containing Faust .lib and .cpp architecture files:
+ck1 := /opt/local/lib/faust/music.lib
+ck2 := /usr/local/lib/faust/music.lib
+ck3 := $(FAUST_LIB_PATH)/faust/music.lib
+LIB := $(if $(wildcard $(ck1)),/opt/local/lib,"")
+LIB := $(if $(wildcard $(ck2)),/usr/local/lib,$(LIB))
+LIB := $(if $(wildcard $(ck3)),$(FAUST_LIB_PATH),$(LIB))
+
+# Directory containing Faust include files:
+ck11 := /opt/local/include/faust/misc.h
+ck12 := /usr/local/include/faust/misc.h
+ck13 := /usr/include/faust/misc.h
+ck14 := $(FAUST_INC_PATH)/faust/misc.h
+FAUSTINC := $(if $(wildcard $(ck11)),/opt/local/include/faust,"")
+FAUSTINC := $(if $(wildcard $(ck12)),/usr/local/include/faust,$(FAUSTINC))
+FAUSTINC := $(if $(wildcard $(ck13)),/usr/include/faust,$(FAUSTINC))
+FAUSTINC := $(if $(wildcard $(ck14)),$(FAUST_INC_PATH),$(FAUSTINC))
+
+ifeq ($(OSC),1)
+ OSCCTRL := -DOSCCTRL -I$(FAUSTINC)/gui/
+ QTDEFS  := OSCCTRL
+ OSCLIB  := -L$(LIB)/faust/ -lOSCFaust -loscpack
+endif
+
+ifeq ($(HTTPD),1)
+ HTTPDCTRL := -DHTTPCTRL -I$(FAUSTINC)/gui
+ HTTPDDEFS := HTTPCTRL
+ HTTPDLIB  := -L$(LIB)/faust/ -lHTTPDFaust -lmicrohttpd
+endif
+
+MYICCFLAGS := '-O3 -xHost -ftz -fno-alias -fp-model fast=2 $(OSCCTRL) $(HTTPDCTRL) -I$(PWD)/valve/' 
+
+ifeq ($(system), Darwin)
+MYGCCFLAGS := '-O3 -march=native -mfpmath=sse -msse -msse2 -ffast-math $(OSCCTRL) $(HTTPDCTRL) -I$(PWD)/valve/'
+else
+MYGCCFLAGS := '-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -ffast-math $(OSCCTRL) $(HTTPDCTRL) -I$(PWD)/valve/'
+endif
+
+VSIZE := 256
+
+SC_SOURCE_DIR = ../../supercollider
+
+all : jackgtk
+
+testlin: alsagtk alsaqt jackgtk jackconsole jackqt netjackqt puredata ladspa dssi csound csounddouble w32vst
+
+testmac: caqt puredata maxmsp maxmsp64 csound csounddouble supercollider
+
+
+json :
+	install -d jsondir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jsondir/' ARCH='gen-json.cpp' CXXFLAGS=$(MYGCCFLAGS) LIB='-L$(LIB)/faust/ -lHTTPDFaust' -f Makefile.compile
+
+alsagtk :
+	install -d alsagtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='alsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0` $(OSCLIB) $(HTTPDLIB)'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+alsaqt :
+	install -d alsaqtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='alsaqtdir/' ARCH='alsa-qt.cpp' LIB='-lpthread -lasound $(OSCLIB) $(HTTPDLIB)' DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)" CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+
+caqt :
+	install -d caqtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='caqtdir/' ARCH='ca-qt.cpp' LIB='-framework CoreAudio -framework AudioUnit -framework CoreServices $(OSCLIB) $(HTTPDLIB)' CXXFLAGS=$(MYGCCFLAGS)  DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)"  -f Makefile.qtcompile
+
+
+jackgtk :
+	install -d jackgtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jackgtkdir/' ARCH='jack-gtk.cpp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB) $(HTTPDLIB)' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+jackconsole :
+	install -d jackconsoledir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jackconsoledir/' ARCH='jack-console.cpp' VEC='-vec -vs $(VSIZE)' LIB='-lpthread `pkg-config --cflags --libs jack ` $(OSCLIB) $(HTTPDLIB)' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+jackqt :
+	install -d jackqtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jackqtdir/' ARCH='jack-qt.cpp' LIB='-ljack $(OSCLIB) $(HTTPDLIB)' DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)" CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+
+netjackqt :
+	install -d netjackqtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='netjackqtdir/' ARCH='netjack-qt.cpp' LIB='-ljacknet $(OSCLIB) $(HTTPDLIB)' DEFS="DEFINES +=$(QTDEFS) $(HTTPDDEFS)" CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+
+svg:
+	$(MAKE) -f Makefile.svgcompile
+
+
+puredata :
+	install -d puredatadir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='puredatadir/' ARCH='puredata.cpp' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.pdcompile
+
+
+ladspa :
+	install -d ladspadir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ladspadir/' ARCH='ladspa.cpp' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
+
+
+dssi :
+	install -d dssidir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='dssidir/' ARCH='dssi.cpp' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.dssicompile
+
+
+csound :
+	install -d csounddir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='csounddir/'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.csound
+
+
+csounddouble :
+	install -d csounddoubledir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='csounddoubledir/' VEC='-double'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.csound
+
+
+module :
+	install -d moduledir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='moduledir/' ARCH='module.cpp' LIB='-fPIC -shared' EXT='.so'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+bundle :
+	install -d bundledir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='bundledir/' ARCH='module.cpp' LIB='-fPIC -bundle' EXT='.so'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+maxmsp msp :
+	install -d mspdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='mspdir/' VEC='-g -vs 256' ARCH='max-msp.cpp' LIB=''  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.mspcompile
+
+maxmsp64 msp64 :
+	install -d msp64dir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='msp64dir/' VEC='-double -g -vs 256' ARCH='max-msp64.cpp' LIB=''  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.mspcompile
+
+
+w32vstdir :
+	mkdir w32vstdir
+
+w32vst : w32vstdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='w32vstdir/' ARCH='vst2p4.cpp' LIB=''  -f Makefile.w32vstcompile
+
+vst :
+	install -d vstdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='vstdir/' ARCH='vst.cpp' LIB=''  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.vstcompile
+
+
+sndfile :
+	install -d sndfiledir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='sndfiledir/' ARCH='sndfile.cpp' LIB='-lsndfile'   CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+plot :
+	install -d plotdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='plotdir/' ARCH='plot.cpp'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+matlabplot :
+	install -d matlabplotdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='matlabplotdir/' ARCH='matlabplot.cpp'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+
+bench :
+	install -d benchdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='benchdir/' ARCH='bench.cpp'  CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+gvecbench :
+	install -d gvecbenchdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='gvecbenchdir/' ARCH='bench.cpp'  VEC='-vec -vs 256' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+ibench :
+	install -d ibenchdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ibenchdir/' ARCH='bench.cpp' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+
+
+supercollider sc:
+	install -d supercolliderdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='supercolliderdir/' -f Makefile.sccompile
+
+mathdoc :
+	$(MAKE) -f Makefile.mathdoc
+
+
+
+
+
+ijackgtk :
+	install -d ijackgtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ijackgtkdir/' ARCH='jack-gtk.cpp' LIB=' `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+	###$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ijackgtkdir/' ARCH='jack-gtk.cpp' LIB='-I$(LIB)/faust/  `pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
+ijackvec :
+	install -d ijackvecdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ijackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
+ijackomp :
+	install -d ijackompdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ijackompdir/' ARCH='jack-gtk.cpp' VEC='-vs $(VSIZE) -omp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
+
+ijacksch :
+	install -d ijackschdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ijackschdir/' ARCH='jack-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
+gjackgtk :
+	install -d gjackgtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='gjackgtkdir/' ARCH='jack-gtk.cpp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+gjackvec :
+	install -d gjackvecdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='gjackvecdir/' ARCH='jack-gtk.cpp' VEC='-vec -lv 1 -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.compile
+
+gjackomp :
+	install -d gjackompdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='gjackompdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE) -omp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` -I/usr/local/include' CXX='g++' CXXFLAGS='-fopenmp '$(MYGCCFLAGS) -f Makefile.compile
+
+ialsagtk :
+	install -d ialsagtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ialsagtkdir/' ARCH='alsa-gtk.cpp' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
+ialsavec :
+	install -d ialsavecdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ialsavecdir/' ARCH='alsa-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
+ialsaomp :
+	install -d ialsaompdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ialsaompdir/' ARCH='alsa-gtk.cpp' VEC='-omp -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS='-openmp '$(MYICCFLAGS) -f Makefile.compile
+
+ialsasch :
+	install -d ialsaschdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ialsaschdir/' ARCH='alsa-gtk.cpp' VEC='-sch -vs $(VSIZE)' LIB='-lpthread -lasound  `pkg-config --cflags --libs gtk+-2.0`' CXX='icc' CXXFLAGS=$(MYICCFLAGS) -f Makefile.compile
+
+msjackgtk :
+	install -d msjackgtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='msjackgtkdir/' ARCH='ms-jack-gtk.cpp' LIB='-lMidiShare `pkg-config --cflags --libs jack gtk+-2.0`' -f Makefile.compile
+
+jackqtsch :
+	install -d jackqtschdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jackqtschdir/' ARCH='jack-qt.cpp' VEC='-sch -vs $(VSIZE)' LIB='-ljack' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.qtcompile
+
+jackwt :
+	install -d jackwtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jackwtdir/' ARCH='jack-wt.cpp' LIB='-ljack -lwt -lwthttp -lboost_signals-mt $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.compile
+
+paqt :
+	install -d paqtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='paqtdir/' ARCH='pa-qt.cpp' LIB='-lportaudio $(OSCLIB)'  DEFS=$(QTDEFS) -f Makefile.qtcompile
+
+oscioqt :  OSCLIB = -L$(LIB)/faust/osclib -lOSCFaust -loscpack
+oscioqt :
+	install -d oscioqtdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='oscioqtdir/' ARCH='oscio-qt.cpp' LIB='-ljack $(OSCLIB)' DEFS=$(QTDEFS) -f Makefile.qtcompile
+
+osciogtk :  OSCLIB = -L$(LIB)/faust/osclib -lOSCFaust -loscpack
+osciogtk :
+	install -d osciogtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='osciogtkdir/' ARCH='oscio-gtk.cpp' LIB='`pkg-config --cflags --libs jack gtk+-2.0` $(OSCLIB)' CXXFLAGS=-I$(LIB)/faust/osclib -f Makefile.compile
+
+ladspasch :
+	install -d ladspaschdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ladspaschdir/' ARCH='ladspa.cpp' VEC='-sch -vs $(VSIZE)' EXT='.so' CXXFLAGS=$(MYGCCFLAGS) -f Makefile.ladspacompile
+
+jackwx :
+	install -d jackwxdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='jackwxdir/' ARCH='jack-wx.cpp' LIB='`pkg-config jack  --cflags --libs` `wx-config --cflags --libs`' -f Makefile.compile
+
+ossgtk :
+	install -d ossgtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ossgtkdir/' ARCH='oss-gtk.cpp' LIB='-lpthread  `pkg-config gtk+-2.0  --cflags --libs`' -f Makefile.compile
+
+osswx :
+	install -d osswxdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='osswxdir/' ARCH='oss-wx.cpp' LIB='-lpthread  `wx-config --cflags --libs`' -f Makefile.compile
+
+pagtk :
+	install -d pagtkdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='pagtkdir/' ARCH='pa-gtk.cpp' LIB='-lpthread  -lportaudio `pkg-config gtk+-2.0  --cflags --libs` $(OSCLIB)' CXXFLAGS=$(OSCCTRL) -f Makefile.compile
+
+pawx :
+	install -d pawxdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='pawxdir/' ARCH='pa-wx.cpp' LIB='-lpthread  -lportaudio `wx-config --cflags --libs`' -f Makefile.compile
+
+iphone :
+	install -d iphonedir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='iphonedir/' ARCH='iphone-cocoa.cpp' LIB='' -f Makefile.iphonecompile
+
+iphonenet :
+	install -d iphonenetdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='iphonenetdir/' ARCH='iphone-cocoa-net.cpp' LIB='' -f Makefile.iphonenetcompile
+
+ios :
+	install -d iosdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='iosdir/' ARCH='ios-coreaudio.cpp'  LIB='' -f Makefile.ioscompile
+
+ivecbench :
+	install -d ivecbenchdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ivecbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE)' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+
+ivecjack :
+	install -d ivecjackdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='ivecjackdir/' ARCH='jack-gtk.cpp' VEC='-vec -vs $(VSIZE)' LIB='`pkg-config --cflags --libs jack gtk+-2.0`' CXX='icc' CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+
+iparbench :
+	install -d iparbenchdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='iparbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE) -omp' CXX='icc' CXXFLAGS='-O3 -openmp -xHost -ftz -fno-alias -fp-model fast=2' -f Makefile.compile
+
+gparbench :
+	install -d gparbenchdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='gparbenchdir/' ARCH='bench.cpp' VEC='-vec -vs $(VSIZE) -omp' CXX='g++' CXXFLAGS='-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math' -f Makefile.compile
+
+q :
+	install -d qdir
+	$(MAKE) FAUSTINC="$(FAUSTINC)" DEST='qdir/' ARCH='q.cpp' -f Makefile.qcompile
+
+help:
+	@echo "make alsagtk     [OSC=1] [HTTPD=1] : compile examples as ALSA applications with a GTK Graphical User Interface"
+	@echo "make alsaqt      [OSC=1] [HTTPD=1] : compile examples as ALSA applications with a QT4 Graphical User Interface"
+	@echo "make sndfile             	  : compile examples as sound file processors with a Command line User Interface"
+	@echo "make jackconsole [OSC=1] [HTTPD=1] : compile examples as JACK applications with a Command line User Interface"
+	@echo "make jackgtk     [OSC=1] [HTTPD=1] : compile examples as JACK applications with a GTK Graphical User Interface"
+	@echo "make jackqt      [OSC=1] [HTTPD=1] : compile examples as JACK applications with a QT4 Graphical User Interface"
+	@echo "make jackwx              	  : compile examples as JACK applications with a wxWindows Graphical User Interface"
+	@echo "make ossgtk              	  : compile examples as OSS applications with a GTK Graphical User Interface"
+	@echo "make osswx               	  : compile examples as OSS applications with a wxWindows Graphical User Interface"
+	@echo "make pagtk       [OSC=1] [HTTPD=1] : compile examples as PortAudio applications with a GTK Graphical User Interface"
+	@echo "make paqt        [OSC=1] [HTTPD=1] : compile examples as PortAudio applications with a QT4 Graphical User Interface"
+	@echo "make pawx                	  : compile examples as PortAudio applications with a wxWindows Graphical User Interface"
+	@echo "make caqt        [OSC=1] [HTTPD=1] : compile examples as CoreAudio applications with a QT4 Graphical User Interface"
+	@echo "make oscioqt             	  : compile examples as OSC driven applications with a QT4 Graphical User Interface"
+	@echo "--------------------------------------------"
+	@echo "make ladspa        : compile examples as LADSPA plugins"
+	@echo "make dssi          : compile examples as DSSI plugins"
+	@echo "make csound        : compile examples as CSOUND opcodes"
+	@echo "make csounddouble  : compile examples as double precision CSOUND opcodes"
+	@echo "make maxmsp        : compile examples as Max/MSP externals"
+	@echo "make vst           : compile examples as native VST plugins"
+	@echo "make w32vst        : crosscompile examples as windows VST plugins"
+	@echo "make iphone        : compile examples for Apple iPhone/iPod"
+	@echo "make supercollider : compile examples as Supercollider plugins"
+	@echo "make puredata      : compile examples as Puredata externals"
+	@echo "make q             : compile examples as Q plugins"
+	@echo "--------------------------------------------"
+	@echo "make svg           : generate the examples block-diagrams in SVG format "
+	@echo "make mathdoc       : generate the examples math documentation in TEX and PDF formats "
+	@echo "make bench         : compile examples as command line benchmarks "
+	@echo "make plot          : compile examples as command line programs that print samples for plotting  with, e.g., gnuplot"
+	@echo "make matlabplot    : compile examples as command line programs that print samples in matlab input format"
+	@echo "--------------------------------------------"
+	@echo "make clean         : remove all object files"
+
+clean :
+	rm -rf *dir
+	rm -rf *-svg
+	$(MAKE) -f Makefile.mathdoc clean
diff --git a/examples/Makefile.compile b/examples/faust-tubes/Makefile.compile
similarity index 100%
copy from examples/Makefile.compile
copy to examples/faust-tubes/Makefile.compile
diff --git a/examples/faust-tubes/Makefile.csound b/examples/faust-tubes/Makefile.csound
new file mode 100644
index 0000000..d154b69
--- /dev/null
+++ b/examples/faust-tubes/Makefile.csound
@@ -0,0 +1,42 @@
+
+###--------------------------------------------
+### adjust flags to the system
+###
+
+system			:= $(shell uname -s)
+
+
+ifeq ($(system), Darwin)
+LIB := -I/Library/Frameworks/CsoundLib.framework/Headers -I/usr/local/include -framework CsoundLib -L/usr/local/lib -dynamiclib
+#LIB := -F/Library/Frameworks -framework CsoundLib -dynamiclib -arch i386
+else
+#LIB := -I/usr/local/include -lsndfile -lcsound -shared
+LIB := -I/usr/include/csound -shared -fPIC
+endif
+
+###For Windows with gcc/mingw:(if headers in /usr/local/include and libs in /usr/local/lib)
+###g++ -O2  -shared -o myopcode.dylib myopcode.cpp -DOPCODE_NAME=myopcode -I/usr/local/include -lsndfile -lcsound32
+
+
+###--------------------------------------------
+### Build csound opcodes on Darwin or Linux (fx.dsp -> fx.cpp -> fx.dylib)
+###
+
+dspsrc  := $(wildcard *.dsp)
+##cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
+opcodes := $(addprefix $(DEST), $(dspsrc:.dsp=.dylib))
+
+
+
+all :  $(opcodes)
+
+
+$(DEST)%.dylib : %.dsp
+	faust $(VEC) -i -uim -double -a csound.cpp $< -o $@.cpp
+	g++ $(CXXFLAGS) $(LIB) -I$(FAUSTINC) -I$(PWD)/valve/  -DOPCODE_NAME=$(notdir $(@:.dylib=)) $@.cpp -o $@
+	
+
+
+
+clean :
+	rm -f $(DEST)
diff --git a/examples/faust-stk/Makefile.ladspacompile b/examples/faust-tubes/Makefile.ladspacompile
similarity index 100%
rename from examples/faust-stk/Makefile.ladspacompile
rename to examples/faust-tubes/Makefile.ladspacompile
diff --git a/examples/faust-tubes/Makefile.mspcompile b/examples/faust-tubes/Makefile.mspcompile
new file mode 100644
index 0000000..dbe0c96
--- /dev/null
+++ b/examples/faust-tubes/Makefile.mspcompile
@@ -0,0 +1,51 @@
+#-------------------------------------------------------------------------------#
+# 				Makefile to produce Max MSP externals on MacOSX
+#
+#-------------------------------------------------------------------------------
+
+# Lists dsp file we have to compile
+dspsrc  := $(wildcard *.dsp)
+cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
+appl 	:= $(addprefix $(DEST), $(dspsrc:.dsp=~.mxo))
+processor := $(shell uname -p)
+
+# Path to Max/MSP SDK
+SDK		:=/usr/local/include/c74support/
+MAXINC	:=$(SDK)/max-includes
+MSPINC	:=$(SDK)/msp-includes
+
+# MacOSX Frameworks we are going to use
+FRAMEWORKS	:= -framework Carbon -I$(MAXINC) -I$(MSPINC) -F$(MAXINC) -F$(MSPINC)  -I$(FAUSTINC) -I$(PWD)/valve/  -framework MaxAPI -framework MaxAudioAPI
+
+# Compilation and optimisation options
+OPTIONS		:= -arch i386 -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -Wl,-Y,1455 -bundle
+
+# Which compiler we use
+CC=g++
+#CC=/Developer/usr/bin/llvm-g++
+
+
+all :  $(appl)
+
+$(DEST)%~.mxo : %.dsp Info.plist.template
+	install -d $@/Contents/MacOS
+	faust $(VEC) -a $(ARCH) $< -o $@/$(<:.dsp=.cpp)
+	$(CC) $(FRAMEWORKS) $(OPTIONS) $@/$(<:.dsp=.cpp) -o $@/Contents/MacOS/$(<:.dsp=~)
+	sed s/FOO/$(<:.dsp=~)/ <Info.plist.template >$@/Contents/Info.plist
+
+Info.plist.template :
+	echo '<?xml version="1.0" encoding="UTF-8"?>' > Info.plist.template
+	echo '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'  >> Info.plist.template
+	echo '<plist version="1.0">'  		>> Info.plist.template
+	echo '<dict>'  				>> Info.plist.template
+	echo '	<key>CFBundleExecutable</key>'  >> Info.plist.template
+	echo '	<string>FOO</string>'  		>> Info.plist.template
+	echo '	<key>CFBundleName</key>'  	>> Info.plist.template
+	echo '	<string>FOO</string>'  		>> Info.plist.template
+	echo '	<key>CFBundlePackageType</key>'  >> Info.plist.template
+	echo '	<string>iLaX</string>'  	>> Info.plist.template
+	echo '</dict>'  			>> Info.plist.template
+	echo '</plist>'  			>> Info.plist.template
+
+clean :
+	rm -f $(DEST)
diff --git a/examples/faust-tubes/Makefile.pdcompile b/examples/faust-tubes/Makefile.pdcompile
new file mode 100644
index 0000000..399c0ce
--- /dev/null
+++ b/examples/faust-tubes/Makefile.pdcompile
@@ -0,0 +1,75 @@
+
+###--------------------------------------------
+### Build puredata externals on Darwin or Linux
+###
+
+system			:= $(shell uname -s)
+DEST			:= pddir/
+dspsrc  		:= $(wildcard *.dsp)
+cppsrc  		:= $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
+patches			:= $(addprefix $(DEST),  $(dspsrc:.dsp=.pd))
+FAUST2PD 		:= faust2pd
+F2PDFLAGS 		:= -r 10 -s
+
+###--------------------------------------------
+### compilation flags for Linux
+###
+LINUXCFLAGS 	:= -DPD -fPIC -Wall -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math
+LINUXINCLUDE 	:= -I/usr/include/pdextended  -I$(PWD)/valve/
+
+###--------------------------------------------
+### compilation flags for Darwin
+###
+DARWINCFLAGS 	:= -DPD -fPIC -Wall -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math
+DYNLOAD_FLAGS	:= -bundle -undefined suppress -flat_namespace
+DARWININCLUDE 	:= -I/Applications/Pd-extended.app/Contents/Resources/include/ -I$(PWD)/valve/  
+
+###--------------------------------------------
+### check what type of modules to build (MacOSX Darwin or Linux)
+###
+ifeq ($(system), Darwin)
+modules 		:= $(addprefix $(DEST),  $(dspsrc:.dsp=~.pd_darwin))
+else
+modules			:= $(addprefix $(DEST),  $(dspsrc:.dsp=~.pd_linux))
+endif
+
+
+###--------------------------------------------
+### Will use faust2pd to create the GUI patches
+### only if it is installed
+
+helper:=$(shell which faust2pd)
+hasfaust2pd := $(findstring /faust2pd, $(helper))
+
+ifeq ($(hasfaust2pd),)
+	todo:=$(modules)
+else
+	todo:=$(modules) $(patches)
+endif
+
+###--------------------------------------------
+
+
+allmodules: $(todo)
+
+$(DEST)%.cpp: %.dsp
+	faust -a $(ARCH) $< -o $@
+	
+$(DEST)%.pd: %.dsp
+	faust -xml $< -o /dev/null
+	$(FAUST2PD) $(F2PDFLAGS) $<.xml
+	mv $(<:.dsp=.pd) $(DEST)
+	rm -f $<.xml
+
+$(DEST)%~.pd_linux: $(DEST)%.cpp
+	$(CXX) $(LINUXCFLAGS) $(LINUXINCLUDE) -shared -Dmydsp=$(patsubst %~.pd_linux,%,$(notdir $@)) $< -o $@
+
+# On Darwin we create both 32-bits and 64-bits intel code
+$(DEST)%~.pd_darwin: $(DEST)%.cpp
+	$(CXX) -arch i386 $(DARWINCFLAGS) $(DARWININCLUDE) $(DYNLOAD_FLAGS) -Dmydsp=$(patsubst %~.pd_darwin,%,$(notdir $@)) $< -o $@.i386
+	$(CXX) -arch x86_64 $(DARWINCFLAGS) $(DARWININCLUDE) $(DYNLOAD_FLAGS) -Dmydsp=$(patsubst %~.pd_darwin,%,$(notdir $@)) $< -o $@.x86_64
+	lipo -create $@.i386 $@.x86_64  -output $@
+	rm $@.i386 $@.x86_64
+
+clean:
+	rm -rf $(DEST)
diff --git a/examples/faust-tubes/Makefile.qtcompile b/examples/faust-tubes/Makefile.qtcompile
new file mode 100644
index 0000000..5f0c5be
--- /dev/null
+++ b/examples/faust-tubes/Makefile.qtcompile
@@ -0,0 +1,57 @@
+###--------------------------------------------
+### DEST : directory where to put binaries
+### ARCH : faust architecture file
+
+system	:= $(shell uname -s)
+dspsrc  := $(wildcard *.dsp)
+cppsrc  := $(addprefix $(DEST), $(dspsrc:.dsp=.cpp))
+
+
+### check what type of applications to build (MacOSX Darwin or Linux)
+ifeq ($(system), Darwin)
+appls	:= $(addprefix $(DEST),  $(dspsrc:.dsp=.app))
+SPEC	:= -spec macx-g++
+else
+appls	:= $(addprefix $(DEST),  $(dspsrc:.dsp=))
+SPEC	:= 
+endif
+### --------------------------------------------
+
+
+### allocate a unique directory
+TDR := $(shell mktemp -d -t FAUST.XXXXXX)
+TMP = $(TDR)/$(<:.dsp=)
+### --------------------------------------------
+
+
+all : $(appls)
+
+
+### Darwin 
+$(DEST)%.app : %.dsp
+	install -d $(TMP)
+	faust -i -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
+	cd $(TMP); qmake -project "$(DEFS)" "INCLUDEPATH+=$(FAUSTINC)" "INCLUDEPATH+=$(PWD)/valve/" "INCLUDEPATH+=$(FAUSTINC)/osclib" "LIBS+=$(LIB)" "HEADERS+=$(FAUSTINC)/gui/faustqt.h" 
+	cd $(TMP); qmake $(SPEC)
+	make -C $(TMP)
+	rm -rf $@
+	mv $(TMP)/$(<:.dsp=.app) $(DEST)
+	rm -rf $(TDR)
+
+
+### Linux
+qm4 := $(shell which qmake-qt4)
+qm := $(if $(qm4),$(qm4),qmake)
+
+$(DEST)% : %.dsp
+	rm -rf $(TMP)
+	install -d $(TMP)
+	faust -i -a $(ARCH) $(VEC) $< -o $(TMP)/$<.cpp
+	cd $(TMP); $(qm) -project "$(DEFS)" "INCLUDEPATH+=$(FAUSTINC)" "INCLUDEPATH+=$(PWD)/valve/" "INCLUDEPATH+=$(FAUSTINC)/osclib" "LIBS+=$(LIB)" "HEADERS+=$(FAUSTINC)/gui/faustqt.h" 
+	cd $(TMP); $(qm) $(SPEC)
+	make -C $(TMP)
+	mv $(TMP)/$(<:.dsp=) $@
+	rm -rf $(TMP)
+
+clean:
+	rm -rf $(DEST)
diff --git a/examples/faust-stk/Makefile.svgcompile b/examples/faust-tubes/Makefile.svgcompile
similarity index 100%
rename from examples/faust-stk/Makefile.svgcompile
rename to examples/faust-tubes/Makefile.svgcompile
diff --git a/examples/faust-tubes/preamp.dsp b/examples/faust-tubes/preamp.dsp
new file mode 100644
index 0000000..6abeac3
--- /dev/null
+++ b/examples/faust-tubes/preamp.dsp
@@ -0,0 +1,34 @@
+declare name        "Tube Preamp";
+declare version     "0.28";
+declare author      "Guitarix project";
+
+/****************************************************************
+ ** Basic Tube Preamp Emulation stage 1 - 2 - tonestack
+ */
+
+filter = library("filter.lib");
+tube   = library("tube.lib");
+tone   = library("tonestack.lib");
+        
+preamp = hgroup("preamp: 12AX7", stage1 : stage2 : 
+         hgroup("tonestack: jcm2000", tstack)) with {
+
+    stage1 = tube.T1_12AX7 : *(preamp): filter.lowpass(1,6531.0) : 
+             tube.T2_12AX7 : *(preamp) with {
+                preamp = vslider("[0] Pregain [style:knob]",-6,-20,20,0.1) : 
+                  filter.db2linear : filter.smooth(0.999);
+             }; 
+
+    stage2 = filter.lowpass(1,6531.0) : tube.T3_12AX7 : *(gain) with {
+                gain = vslider("[1] Gain [style:knob]",-6,-20.0,20.0,0.1) : 
+                  filter.db2linear : filter.smooth(0.999);
+             };
+
+    tstack = tone.jcm2000(t, m, l) with {
+        t = vslider("[2] Treble [style:knob]",0.5,0,1,0.01);
+        m = vslider("[3] Middle [style:knob]",0.5,0,1,0.01);
+        l = vslider("[4] Bass [style:knob]",0.5,0,1,0.01);
+    };
+};
+
+process = preamp; 
diff --git a/examples/faust-tubes/tonestack.lib b/examples/faust-tubes/tonestack.lib
new file mode 100644
index 0000000..242ff17
--- /dev/null
+++ b/examples/faust-tubes/tonestack.lib
@@ -0,0 +1,427 @@
+/**
+ **  Guitar tone stacks (based on the work from D.T. Yeh)
+ **  some values are taken from CAPS plugin tonestack 
+ ** 
+ **  this tonestack library provide the following tonestack models:
+ **  bassman, mesa, twin, princeton, jcm800, jcm2000, jtm45, mlead,
+ **  m2199, ac30, ac15, soldano, sovtek, peavey, ibanez, roland, 
+ **  ampeg, ampeg_rev, bogner, groove, crunch, fender_blues,
+ **  fender_default, fender_deville, gibsen
+ **  
+ **  USAGE :
+ **        _:component("tonestack.lib").model(t,m,l):_
+ **  WHERE :
+ **       model is on of the models above.
+ **       t is treble freq control in range of (0.0 - 1.0)
+ **       m is middle freq control in range of (0.0 - 1.0)
+ **       l is low freq control in range of (0.0 - 1.0)
+ ** 
+ **  EXAMPLE :
+ **       process = component("tonestack.lib").jcm2000(t,m,l) 
+ **       with {
+ **         t = vslider("Treble ", 0.5, 0, 1, 0.01);
+ **         m = vslider("Middle ", 0.5, 0, 1, 0.01);
+ **         l = vslider("Bass ", 0.5, 0, 1, 0.01);
+ **       };
+ **/
+
+declare name      "Tonestack Emulation Library";
+declare author    "Guitarix project (http://guitarix.sourceforge.net/)";
+declare copyright "Guitarix project";
+declare version   "0.28";
+declare license   "LGPL";
+
+
+import("filter.lib");
+
+/****************************************************************
+ **           Equalisation 3 bandes
+ **                    C1
+ **       IN >---------||---------
+ **            |                 |
+ **            |                 |
+ **           | | R4            | | R1 Treble
+ **           | |               | |<------<  Out
+ **           | |               | | 
+ **            |       C2        |
+ **            |-------||--------|------
+ **            |                 |     |
+ **            |                | |    |
+ **            |                | |<---- R2 Bass
+ **            |                | |
+ **            |                 |
+ **            |       C3       | |
+ **            --------||------>| |  R3 Middle
+ **                             | |
+ **                              |
+ **                             _|_
+ **                              -
+ **
+ ****************************************************************/
+
+tonestack(C1,C2,C3,R1,R2,R3,R4,t,m,L) = 
+    1/A0*iir((B0,B1,B2,B3),(A1/A0,A2/A0,A3/A0)) 
+    with {
+    
+    l = L : (_-1)*3.4 : exp;
+    
+    b1 = t*C1*R1 + m*C3*R3 + l*(C1*R2 + C2*R2) + (C1*R3 + C2*R3);
+
+    b2 = t*(C1*C2*R1*R4 + C1*C3*R1*R4) - m*m*(C1*C3*R3*R3 + C2*C3*R3*R3)
+         + m*(C1*C3*R1*R3 + C1*C3*R3*R3 + C2*C3*R3*R3)
+         + l*(C1*C2*R1*R2 + C1*C2*R2*R4 + C1*C3*R2*R4)
+         + l*m*(C1*C3*R2*R3 + C2*C3*R2*R3)
+         + (C1*C2*R1*R3 + C1*C2*R3*R4 + C1*C3*R3*R4);
+
+    b3 = l*m*(C1*C2*C3*R1*R2*R3 + C1*C2*C3*R2*R3*R4)
+         - m*m*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4)
+         + m*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4)
+         + t*C1*C2*C3*R1*R3*R4 - t*m*C1*C2*C3*R1*R3*R4
+         + t*l*C1*C2*C3*R1*R2*R4;
+
+    a0 = 1;
+
+    a1 = (C1*R1 + C1*R3 + C2*R3 + C2*R4 + C3*R4)
+         + m*C3*R3 + l*(C1*R2 + C2*R2);
+
+    a2 = m*(C1*C3*R1*R3 - C2*C3*R3*R4 + C1*C3*R3*R3 + C2*C3*R3*R3)
+         + l*m*(C1*C3*R2*R3 + C2*C3*R2*R3)
+         - m*m*(C1*C3*R3*R3 + C2*C3*R3*R3)
+         + l*(C1*C2*R2*R4 + C1*C2*R1*R2 + C1*C3*R2*R4 + C2*C3*R2*R4)
+         + (C1*C2*R1*R4 + C1*C3*R1*R4 + C1*C2*R3*R4 + C1*C2*R1*R3 + C1*C3*R3*R4 + C2*C3*R3*R4);
+
+    a3 = l*m*(C1*C2*C3*R1*R2*R3 + C1*C2*C3*R2*R3*R4)
+         - m*m*(C1*C2*C3*R1*R3*R3 + C1*C2*C3*R3*R3*R4)
+         + m*(C1*C2*C3*R3*R3*R4 + C1*C2*C3*R1*R3*R3 - C1*C2*C3*R1*R3*R4)
+         + l*C1*C2*C3*R1*R2*R4
+         + C1*C2*C3*R1*R3*R4;
+
+    c = 2*float(SR);
+
+    B0 = -b1*c - b2*pow(c,2) - b3*pow(c,3);
+    B1 = -b1*c + b2*pow(c,2) + 3*b3*pow(c,3);
+    B2 = b1*c + b2*pow(c,2) - 3*b3*pow(c,3);
+    B3 = b1*c - b2*pow(c,2) + b3*pow(c,3);
+    A0 = -a0 - a1*c - a2*pow(c,2) - a3*pow(c,3);
+    A1 = -3*a0 - a1*c + a2*pow(c,2) + 3*a3*pow(c,3);
+    A2 = -3*a0 + a1*c + a2*pow(c,2) - 3*a3*pow(c,3);
+    A3 = -a0 + a1*c - a2*pow(c,2) + a3*pow(c,3);
+};
+
+ts = environment {
+    k = *(1e3);
+    M = *(1e6);
+    nF = *(1e-9);
+    pF = *(1e-12);
+
+    /* Fender */
+
+    bassman = environment { /* 59 Bassman 5F6-A */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 56:k;
+        C1 = 250:pF;
+        C2 = 20:nF;
+        C3 = 20:nF;
+        };
+        
+    mesa = environment { /* Mesa Boogie Mark */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    twin = environment { /* 69 Twin Reverb AA270 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 120:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+
+    princeton = environment { /* 64 Princeton AA1164 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 4.8:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+
+    /* Marshall */
+
+    jcm800 = environment { /* 59/81 JCM-800 Lead 100 2203 */
+        R1 = 220:k;
+        R2 = 1:M;
+        R3 = 22:k;
+        R4 = 33:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+    /* 90 JCM-900 Master 2100: same as JCM-800 */
+
+    jcm2000 = environment { /* 81 2000 Lead */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 56:k; /* a 10 k fixed + 100 k pot in series actually */
+        C1 = 500:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    jtm45 = environment { /* JTM 45 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 33:k; 
+        C1 = 270:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+
+    /* parameter order is R1 - R4, C1 - C3 */
+    mlead = environment { /* 67 Major Lead 200 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 33:k;
+        C1 = 500:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+
+    m2199 = environment { /* undated M2199 30W solid state */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 56:k;
+        C1 = 250:pF;
+        C2 = 47:nF;
+        C3 = 47:nF;
+        };
+
+    /* Vox */
+    ac30 = environment { /* 59/86 AC-30 */
+        /* R3 is fixed (circuit differs anyway) */
+        R1 = 1:M;
+        R2 = 1:M;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 50:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    ac15 = environment { /* VOX AC-15 */
+        R1 = 220:k;
+        R2 = 220:k;
+        R3 = 220:k;
+        R4 = 100:k;
+        C1 = 470:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    soldano = environment { /* Soldano SLO 100 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 47:k;
+        C1 = 470:pF;
+        C2 = 20:nF;
+        C3 = 20:nF;
+        };
+        
+    sovtek = environment { /* MIG 100 H*/
+        R1 = 500:k;
+        R2 = 1:M;
+        R3 = 10:k;
+        R4 = 47:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+
+    peavey = environment { /* c20*/
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 20:k;
+        R4 = 68:k;
+        C1 = 270:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    ibanez = environment { /* gx20 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 270:pF;
+        C2 = 100:nF;
+        C3 = 40:nF;
+        };
+        
+    roland = environment { /* Cube 60 */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 41:k;
+        C1 = 240:pF;
+        C2 = 33:nF;
+        C3 = 82:nF;
+        };
+        
+    ampeg = environment { /* VL 501 */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 25:k;
+        R4 = 32:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+    
+    ampeg_rev = environment { /* reverbrocket*/
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 100:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    bogner = environment { /* Triple Giant Preamp  */
+        R1 = 250:k;
+        R2 = 1:M;
+        R3 = 33:k;
+        R4 = 51:k;
+        C1 = 220:pF;
+        C2 = 15:nF;
+        C3 = 47:nF;
+        };
+        
+    groove = environment { /* Trio Preamp  */
+        R1 = 220:k;
+        R2 = 1:M;
+        R3 = 22:k;
+        R4 = 68:k;
+        C1 = 470:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    crunch = environment { /* Hughes&Kettner  */
+        R1 = 220:k;
+        R2 = 220:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 220:pF;
+        C2 = 47:nF;
+        C3 = 47:nF;
+        };
+        
+    fender_blues = environment { /* Fender blues junior  */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 22:nF;
+        C3 = 22:nF;
+        };
+        
+    fender_default = environment { /* Fender   */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 10:k;
+        R4 = 100:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 47:nF;
+        };
+        
+    fender_deville = environment { /* Fender Hot Rod  */
+        R1 = 250:k;
+        R2 = 250:k;
+        R3 = 25:k;
+        R4 = 130:k;
+        C1 = 250:pF;
+        C2 = 100:nF;
+        C3 = 22:nF;
+        };
+        
+    gibsen = environment { /* gs12 reverbrocket   */
+        R1 = 1:M;
+        R2 = 1:M;
+        R3 = 94:k;  // 47k fixed
+        R4 = 270:k;
+        C1 = 25:pF;
+        C2 = 60:nF;
+        C3 = 20:nF;
+        };
+
+};
+
+bassman(T,M,L)  = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.bassman;};
+mesa(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.mesa;};
+twin(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.twin;};
+princeton(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.princeton;};
+jcm800(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.jcm800;};
+jcm2000(T,M,L)  = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.jcm2000;};
+jtm45(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.jtm45;};
+mlead(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.mlead;};
+m2199(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.m2199;};
+ac30(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ac30;};
+ac15(T,M,L)     = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ac15;};
+soldano(T,M,L)  = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.soldano;};
+sovtek(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.sovtek;};
+peavey(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.peavey;};
+ibanez(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ibanez;};
+roland(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.roland;};
+ampeg(T,M,L)    = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ampeg;};
+ampeg_rev(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.ampeg_rev;};
+bogner(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.bogner;};
+groove(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.groove;};
+crunch(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.crunch;};
+fender_blues(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.fender_blues;};
+fender_default(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.fender_default;};
+fender_deville(T,M,L)= tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.fender_deville;};
+gibsen(T,M,L)   = tonestack(t.C1,t.C2,t.C3,t.R1,t.R2,t.R3,t.R4,T,M,L) 
+                    with {t = ts.gibsen;};
+
diff --git a/examples/faust-tubes/tube.lib b/examples/faust-tubes/tube.lib
new file mode 100644
index 0000000..443cbe8
--- /dev/null
+++ b/examples/faust-tubes/tube.lib
@@ -0,0 +1,82 @@
+/**
+ **  tube.lib  Guitar(ix) tube amp emulations
+ **  
+ **  
+ **  this tube library provide the following tube models:
+ **  T1_12AX7, T2_12AX7, T3_12AX7, T1_12AT7, T2_12AT7, T3_12AT7, 
+ **  T1_12AU7, T2_12AU7, T3_12AU7, T1_6V6, T2_6V6, T3_6V6, 
+ **  T1_6DJ8, T2_6DJ8, T3_6DJ8, T1_6C16, T2_6C16, T3_6C16 
+ **
+ **  
+ **  USAGE:
+ **        _:component("tube.lib").model:_
+ **  where
+ **       model is on of the models above.
+ ** 
+ **  EXAMPLE 2 STAGE TUBE PREAMP:
+ **    process = component("tube.lib").T1_12AX7 : *(preamp):
+ **      lowpass(1,6531.0) : component("tube.lib").T2_12AX7 : *(preamp): 
+ **      lowpass(1,6531.0) : component("tube.lib").T3_12AX7 : *(gain) with {
+ **      preamp = vslider("Pregain",-6,-20,20,0.1) : db2linear : smooth(0.999);
+ **      gain  = vslider("Gain", -6, -20.0, 20.0, 0.1) : db2linear : smooth(0.999);
+ **    };  
+ **
+ **/
+
+declare name      "Tube Emulation Library";
+declare author    "Guitarix project (http://guitarix.sourceforge.net/)";
+declare copyright "Guitarix project";
+declare version   "0.28";
+declare license   "LGPL";
+
+
+import("filter.lib");
+
+// simple triode circuit emulation
+
+Ftube = ffunction(float Ftube(int,float), "valve.h", "");
+
+TB_12AX7_68k  = fconstant(int TUBE_TABLE_12AX7_68k,  "valve.h");
+TB_12AX7_250k = fconstant(int TUBE_TABLE_12AX7_250k, "valve.h");
+TB_12AT7_68k  = fconstant(int TUBE_TABLE_12AT7_68k,  "valve.h");
+TB_12AT7_250k = fconstant(int TUBE_TABLE_12AT7_250k, "valve.h");
+TB_12AU7_68k  = fconstant(int TUBE_TABLE_12AU7_68k,  "valve.h");
+TB_12AU7_250k = fconstant(int TUBE_TABLE_12AU7_250k, "valve.h");
+TB_6V6_68k    = fconstant(int TUBE_TABLE_6V6_68k,    "valve.h");
+TB_6V6_250k   = fconstant(int TUBE_TABLE_6V6_250k,   "valve.h");
+TB_6DJ8_68k   = fconstant(int TUBE_TABLE_6DJ8_68k,   "valve.h");
+TB_6DJ8_250k  = fconstant(int TUBE_TABLE_6DJ8_250k,  "valve.h");
+TB_6C16_68k   = fconstant(int TUBE_TABLE_6C16_68k,   "valve.h");
+TB_6C16_250k  = fconstant(int TUBE_TABLE_6C16_250k,  "valve.h");
+
+tubestageF(tb,vplus,divider,fck,Rk,Vk0) = tube : hpf with {
+    lpfk = lowpass(1,fck);
+    Rp = 100.0e3;
+    VkC = Vk0 * (Rp/Rk);
+    tube = (+ : -(Vk0) : Ftube(tb) : +(VkC-vplus)) ~ (*(Rk/Rp) : lpfk) : /(divider);
+    hpf = highpass(1,31.0);
+};
+
+tubestage(tb,fck,Rk,Vk0)       = tubestageF(tb,250.0,40.0,fck,Rk,Vk0);
+tubestage130_20(tb,fck,Rk,Vk0) = tubestageF(tb,130.0,20.0,fck,Rk,Vk0);
+
+// basic tube settings to model stage 1 - 2
+
+T1_12AX7 = tubestage(TB_12AX7_68k,86.0,2700.0,1.581656);
+T2_12AX7 = tubestage(TB_12AX7_250k,132.0,1500.0,1.204285);
+T3_12AX7 = tubestage(TB_12AX7_250k,194.0,820.0,0.840703);
+T1_12AT7 = tubestage(TB_12AT7_68k,86.0,2700.0,2.617753);
+T2_12AT7 = tubestage(TB_12AT7_250k,132.0,1500.0,1.887332);
+T3_12AT7 = tubestage(TB_12AT7_250k,194.0,820.0,1.256962);
+T1_12AU7 = tubestage(TB_12AU7_68k,86.0,2700.0,3.718962);
+T2_12AU7 = tubestage(TB_12AU7_250k,132.0,1500.0,2.314844);
+T3_12AU7 = tubestage(TB_12AU7_250k,194.0,820.0,1.356567);
+T1_6V6   = tubestage(TB_6V6_68k,86.0,2700.0,2.296150);
+T2_6V6   = tubestage(TB_6V6_250k,132.0,1500.0,1.675587);
+T3_6V6   = tubestage(TB_6V6_250k,194.0,820.0,1.130462);
+T1_6DJ8  = tubestage130_20(TB_6DJ8_68k,86.0,2700.0,1.863946);
+T2_6DJ8  = tubestage130_20(TB_6DJ8_250k,132.0,1500.0,1.271609);
+T3_6DJ8  = tubestage130_20(TB_6DJ8_68k,194.0,820.0,0.799031);
+T1_6C16  = tubestage(TB_6C16_68k,86.0,2700.0,2.921806);
+T2_6C16  = tubestage(TB_6C16_250k,132.0,1500.0,2.097743);
+T3_6C16  = tubestage(TB_6C16_250k,194.0,820.0,1.378742);
diff --git a/examples/faust-tubes/valve/12AT7.cc b/examples/faust-tubes/valve/12AT7.cc
new file mode 100644
index 0000000..d031206
--- /dev/null
+++ b/examples/faust-tubes/valve/12AT7.cc
@@ -0,0 +1,819 @@
+// generated by ../../tools/tube_transfer.py
+// tube: 12AT7
+// plate current function: triode
+// mu: 60
+// kx: 1.35
+// kg1: 460
+// kp: 300
+// kvb: 300
+
+table1d_imp<2001> tubetable_12AT7[2] = {
+	{ // Ri = 68k
+	-5,5,200,2001, {
+	223.484971051,223.38189846,223.278606859,223.175096438,223.071367386,
+	222.967419894,222.863254153,222.758870355,222.654268692,222.549449358,
+	222.444412546,222.339158451,222.233687268,222.127999193,222.022094421,
+	221.915973151,221.809635579,221.703081904,221.596312324,221.489327039,
+	221.382126248,221.274710152,221.167078951,221.059232846,220.951172041,
+	220.842896736,220.734407134,220.62570344,220.516785857,220.407654588,
+	220.298309839,220.188751814,220.078980719,219.96899676,219.858800143,
+	219.748391075,219.637769762,219.526936413,219.415891235,219.304634436,
+	219.193166225,219.081486809,218.9695964,218.857495205,218.745183435,
+	218.6326613,218.519929009,218.406986775,218.293834807,218.180473316,
+	218.066902515,217.953122614,217.839133825,217.724936362,217.610530435,
+	217.495916257,217.381094042,217.266064002,217.150826349,217.035381299,
+	216.919729063,216.803869855,216.68780389,216.571531381,216.455052541,
+	216.338367587,216.22147673,216.104380187,215.987078171,215.869570897,
+	215.75185858,215.633941434,215.515819675,215.397493517,215.278963175,
+	215.160228865,215.041290801,214.922149198,214.802804272,214.683256238,
+	214.563505311,214.443551707,214.32339564,214.203037325,214.082476979,
+	213.961714816,213.840751051,213.719585899,213.598219576,213.476652297,
+	213.354884277,213.232915731,213.110746873,212.988377919,212.865809083,
+	212.74304058,212.620072625,212.496905433,212.373539217,212.249974193,
+	212.126210573,212.002248574,211.878088408,211.75373029,211.629174433,
+	211.504421051,211.379470357,211.254322565,211.128977889,211.003436541,
+	210.877698734,210.751764681,210.625634594,210.499308686,210.37278717,
+	210.246070256,210.119158158,209.992051086,209.864749253,209.737252869,
+	209.609562146,209.481677294,209.353598524,209.225326046,209.096860071,
+	208.968200809,208.839348469,208.710303261,208.581065394,208.451635077,
+	208.322012519,208.192197928,208.062191513,207.931993481,207.801604041,
+	207.671023398,207.540251762,207.409289338,207.278136334,207.146792955,
+	207.015259407,206.883535897,206.75162263,206.61951981,206.487227642,
+	206.354746332,206.222076083,206.089217099,205.956169583,205.82293374,
+	205.689509771,205.555897879,205.422098267,205.288111136,205.153936688,
+	205.019575125,204.885026646,204.750291453,204.615369746,204.480261724,
+	204.344967587,204.209487534,204.073821763,203.937970474,203.801933864,
+	203.66571213,203.52930547,203.392714081,203.255938159,203.1189779,
+	202.9818335,202.844505154,202.706993058,202.569297405,202.43141839,
+	202.293356206,202.155111047,202.016683105,201.878072574,201.739279645,
+	201.60030451,201.46114736,201.321808386,201.182287779,201.042585728,
+	200.902702422,200.762638052,200.622392806,200.481966872,200.341360438,
+	200.200573691,200.059606819,199.918460008,199.777133444,199.635627312,
+	199.493941798,199.352077087,199.210033363,199.067810809,198.92540961,
+	198.782829948,198.640072006,198.497135966,198.354022009,198.210730316,
+	198.067261068,197.923614446,197.779790629,197.635789796,197.491612126,
+	197.347257797,197.202726987,197.058019875,196.913136635,196.768077446,
+	196.622842482,196.477431919,196.331845933,196.186084697,196.040148386,
+	195.894037174,195.747751232,195.601290734,195.454655852,195.307846758,
+	195.160863622,195.013706614,194.866375906,194.718871667,194.571194065,
+	194.423343269,194.275319448,194.127122768,193.978753398,193.830211503,
+	193.681497249,193.532610803,193.383552329,193.234321992,193.084919955,
+	192.935346382,192.785601437,192.635685281,192.485598078,192.335339987,
+	192.18491117,192.034311788,191.883542,191.732601966,191.581491845,
+	191.430211795,191.278761974,191.127142539,190.975353646,190.823395453,
+	190.671268115,190.518971788,190.366506625,190.213872781,190.061070409,
+	189.908099664,189.754960697,189.60165366,189.448178705,189.294535983,
+	189.140725644,188.986747838,188.832602715,188.678290424,188.523811112,
+	188.369164928,188.214352019,188.059372531,187.904226611,187.748914404,
+	187.593436056,187.43779171,187.281981512,187.126005604,186.96986413,
+	186.813557231,186.65708505,186.500447728,186.343645406,186.186678223,
+	186.029546321,185.872249837,185.71478891,185.55716368,185.399374282,
+	185.241420854,185.083303532,184.925022452,184.766577751,184.607969561,
+	184.449198018,184.290263255,184.131165406,183.971904602,183.812480977,
+	183.652894661,183.493145785,183.33323448,183.173160876,183.012925102,
+	182.852527286,182.691967557,182.531246043,182.37036287,182.209318165,
+	182.048112054,181.886744663,181.725216116,181.563526537,181.401676051,
+	181.239664781,181.077492849,180.915160377,180.752667487,180.590014299,
+	180.427200936,180.264227515,180.101094157,179.93780098,179.774348102,
+	179.610735642,179.446963716,179.283032441,179.118941932,178.954692305,
+	178.790283676,178.625716158,178.460989865,178.29610491,178.131061407,
+	177.965859466,177.8004992,177.634980719,177.469304135,177.303469556,
+	177.137477092,176.971326852,176.805018943,176.638553475,176.471930553,
+	176.305150284,176.138212774,175.971118129,175.803866452,175.63645785,
+	175.468892424,175.301170279,175.133291517,174.965256239,174.797064548,
+	174.628716544,174.460212328,174.291551999,174.122735656,173.953763399,
+	173.784635325,173.615351532,173.445912117,173.276317175,173.106566804,
+	172.936661098,172.766600153,172.596384061,172.426012917,172.255486814,
+	172.084805844,171.9139701,171.742979672,171.571834651,171.400535128,
+	171.229081192,171.057472933,170.885710438,170.713793796,170.541723094,
+	170.36949842,170.197119859,170.024587497,169.851901419,169.679061711,
+	169.506068455,169.332921736,169.159621635,168.986168237,168.812561622,
+	168.638801872,168.464889067,168.290823288,168.116604613,167.942233123,
+	167.767708895,167.593032007,167.418202536,167.24322056,167.068086154,
+	166.892799395,166.717360356,166.541769112,166.366025738,166.190130307,
+	166.014082891,165.837883563,165.661532395,165.485029456,165.308374819,
+	165.131568552,164.954610726,164.777501409,164.60024067,164.422828575,
+	164.245265193,164.06755059,163.889684831,163.711667983,163.533500109,
+	163.355181276,163.176711545,162.998090981,162.819319646,162.640397602,
+	162.46132491,162.282101632,162.102727828,161.923203558,161.743528881,
+	161.563703855,161.383728539,161.20360299,161.023327265,160.842901421,
+	160.662325513,160.481599598,160.300723728,160.11969796,159.938522345,
+	159.757196938,159.57572179,159.394096954,159.212322481,159.030398422,
+	158.848324827,158.666101745,158.483729225,158.301207317,158.118536068,
+	157.935715525,157.752745735,157.569626745,157.3863586,157.202941345,
+	157.019375024,156.835659683,156.651795363,156.467782109,156.283619962,
+	156.099308963,155.914849155,155.730240578,155.545483271,155.360577274,
+	155.175522626,154.990319366,154.80496753,154.619467157,154.433818283,
+	154.248020943,154.062075174,153.87598101,153.689738486,153.503347636,
+	153.316808491,153.130121087,152.943285453,152.756301622,152.569169625,
+	152.381889493,152.194461254,152.006884938,151.819160575,151.631288191,
+	151.443267815,151.255099474,151.066783193,150.878318999,150.689706918,
+	150.500946973,150.312039189,150.122983589,149.933780197,149.744429035,
+	149.554930124,149.365283487,149.175489143,148.985547114,148.795457417,
+	148.605220074,148.414835102,148.224302518,148.033622341,147.842794587,
+	147.651819272,147.460696413,147.269426023,147.078008117,146.88644271,
+	146.694729815,146.502869444,146.31086161,146.118706324,145.926403598,
+	145.733953442,145.541355866,145.348610879,145.15571849,144.962678708,
+	144.76949154,144.576156994,144.382675075,144.18904579,143.995269144,
+	143.801345143,143.60727379,143.413055089,143.218689043,143.024175656,
+	142.829514928,142.634706862,142.439751458,142.244648717,142.049398638,
+	141.854001221,141.658456465,141.462764367,141.266924924,141.070938135,
+	140.874803995,140.678522501,140.482093647,140.285517428,140.088793838,
+	139.891922871,139.694904521,139.497738779,139.300425637,139.102965087,
+	138.905357119,138.707601724,138.509698892,138.311648611,138.113450871,
+	137.915105658,137.716612961,137.517972767,137.319185062,137.120249831,
+	136.921167061,136.721936735,136.522558838,136.323033353,136.123360263,
+	135.923539552,135.7235712,135.52345519,135.323191502,135.122780116,
+	134.922221012,134.72151417,134.520659568,134.319657184,134.118506996,
+	133.917208981,133.715763115,133.514169375,133.312427735,133.110538172,
+	132.908500658,132.706315168,132.503981676,132.301500154,132.098870574,
+	131.896092908,131.693167128,131.490093204,131.286871106,131.083500803,
+	130.879982266,130.676315463,130.472500361,130.268536929,130.064425133,
+	129.860164941,129.655756317,129.451199229,129.24649364,129.041639516,
+	128.836636821,128.631485518,128.426185571,128.220736941,128.015139592,
+	127.809393485,127.603498581,127.397454841,127.191262225,126.984920693,
+	126.778430205,126.57179072,126.365002195,126.158064589,125.950977859,
+	125.743741963,125.536356858,125.328822499,125.121138842,124.913305843,
+	124.705323458,124.497191639,124.288910343,124.080479522,123.87189913,
+	123.66316912,123.454289445,123.245260057,123.036080908,122.82675195,
+	122.617273133,122.407644409,122.197865728,121.987937041,121.777858298,
+	121.567629447,121.357250439,121.146721222,120.936041745,120.725211957,
+	120.514231806,120.30310124,120.091820207,119.880388654,119.668806528,
+	119.457073777,119.245190347,119.033156186,118.82097124,118.608635455,
+	118.396148777,118.183511154,117.970722531,117.757782854,117.544692069,
+	117.331450122,117.118056958,116.904512525,116.690816767,116.476969631,
+	116.262971063,116.048821008,115.834519413,115.620066224,115.405461388,
+	115.19070485,114.975796559,114.76073646,114.545524502,114.330160631,
+	114.114644796,113.898976945,113.683157025,113.467184988,113.25106078,
+	113.034784354,112.818355658,112.601774644,112.385041264,112.168155469,
+	111.951117213,111.733926449,111.516583131,111.299087215,111.081438657,
+	110.863637413,110.645683442,110.427576702,110.209317154,109.990904759,
+	109.772339479,109.553621277,109.334750119,109.115725972,108.896548803,
+	108.677218581,108.457735278,108.238098866,108.01830932,107.798366617,
+	107.578270734,107.358021653,107.137619356,106.917063827,106.696355055,
+	106.475493028,106.25447774,106.033309184,105.81198736,105.590512267,
+	105.36888391,105.147102295,104.925167434,104.703079339,104.480838028,
+	104.258443522,104.035895848,103.813195034,103.590341113,103.367334124,
+	103.14417411,102.920861118,102.697395202,102.473776418,102.250004831,
+	102.02608051,101.802003529,101.577773971,101.353391923,101.128857479,
+	100.904170741,100.679331818,100.454340825,100.229197888,100.003903138,
+	99.778456717,99.5528587734,99.3271094667,99.1012089653,98.8751574477,
+	98.6489551024,98.4226021292,98.1960987386,97.969445153,97.7426416069,
+	97.5156883471,97.2885856338,97.0613337405,96.833932955,96.6063835797,
+	96.3786859321,96.1508403457,95.9228471705,95.6947067733,95.4664195391,
+	95.2379858709,95.0094061912,94.7806809423,94.5518105871,94.3227956102,
+	94.0936365183,93.8643338415,93.6348881337,93.405299974,93.1755699676,
+	92.9456987464,92.7156869704,92.4855353287,92.2552445406,92.0248153569,
+	91.7942485605,91.5635449686,91.3327054332,91.1017308426,90.8706221232,
+	90.6393802404,90.4080062002,90.1765010512,89.9448658855,89.7131018408,
+	89.4812101019,89.2491919027,89.0170485276,88.784781314,88.5523916537,
+	88.3198809952,88.0872508458,87.8545027735,87.6216384098,87.3886594513,
+	87.1555676628,86.9223648793,86.6890530085,86.4556340339,86.2221100172,
+	85.9884831011,85.7547555124,85.5209295646,85.2870076616,85.0529923004,
+	84.8188860745,84.5846916773,84.3504119056,84.1160496633,83.8816079647,
+	83.647089939,83.4124988332,83.1778380171,82.9431109867,82.7083213689,
+	82.4734729256,82.2385695581,82.0036153116,81.7686143804,81.5335711119,
+	81.2984900118,81.0633757495,80.8282331624,80.5930672616,80.3578832372,
+	80.1226864634,79.8874825043,79.6522771191,79.417076268,79.1818861179,
+	78.946713048,78.7115636561,78.4764447639,78.2413634234,78.0063269226,
+	77.7713427919,77.5364188098,77.3015630089,77.0667836823,76.832089389,
+	76.5974889606,76.3629915064,76.1286064198,75.8943433838,75.6602123765,
+	75.4262236766,75.1923878688,74.9587158488,74.7252188281,74.4919083386,
+	74.2587962373,74.0258947099,73.7932162747,73.5607737859,73.3285804366,
+	73.0966497613,72.8649956377,72.6336322885,72.4025742822,72.1718365333,
+	71.9414343025,71.7113831952,71.4816991604,71.2523984878,71.0234978052,
+	70.7950140739,70.5669645844,70.3393669505,70.1122391024,69.8855992793,
+	69.659466021,69.4338581579,69.2087948004,68.9842953275,68.7603793738,
+	68.5370668156,68.3143777559,68.0923325085,67.8709515808,67.6502556556,
+	67.4302655713,67.2110023025,66.9924869376,66.7747406569,66.5577847094,
+	66.341640388,66.1263290049,65.9118718655,65.6982902415,65.485605344,
+	65.2738382953,65.0630101007,64.8531416195,64.644253536,64.4363663304,
+	64.2295002488,64.0236752742,63.8189110973,63.6152270868,63.4126422611,
+	63.2111752599,63.0108443162,62.8116672294,62.613661339,62.4168434988,
+	62.2212300529,62.026836812,61.8336790312,61.6417713894,61.4511279693,
+	61.2617622392,61.0736870367,60.8869145531,60.7014563202,60.5173231979,
+	60.3345253642,60.1530723064,59.9729728143,59.7942349746,59.6168661678,
+	59.4408730656,59.2662616311,59.0930371202,58.9212040837,58.7507663728,
+	58.5817271438,58.4140888665,58.2478533317,58.0830216621,57.9195943226,
+	57.757571133,57.5969512811,57.437733337,57.2799152681,57.1234944552,
+	56.9684677091,56.8148312878,56.6625809145,56.5117117958,56.3622186407,
+	56.2140956792,56.0673366819,55.9219349798,55.777883483,55.6351747015,
+	55.4938007636,55.3537534367,55.2150241456,55.0776039925,54.9414837759,
+	54.8066540091,54.6731049389,54.5408265635,54.4098086506,54.2800407545,
+	54.1515122329,54.0242122639,53.8981298612,53.7732538906,53.6495730842,
+	53.5270760555,53.4057513131,53.2855872745,53.166572279,53.0486945999,
+	52.9319424571,52.816304028,52.7017674586,52.5883208741,52.4759523889,
+	52.3646501157,52.2544021747,52.1451967025,52.0370218595,51.9298658379,
+	51.8237168688,51.718563229,51.6143932475,51.5111953109,51.4089578697,
+	51.3076694432,51.2073186239,51.1078940829,51.0093845734,50.9117789348,
+	50.815066096,50.7192350793,50.6242750025,50.5301750825,50.4369246372,
+	50.3445130879,50.2529299611,50.1621648909,50.0722076197,49.9830480004,
+	49.894675997,49.8070816859,49.7202552566,49.6341870125,49.5488673716,
+	49.4642868666,49.3804361451,49.2973059702,49.2148872203,49.1331708887,
+	49.052148084,48.9718100296,48.892148063,48.8131536359,48.7348183134,
+	48.6571337734,48.5800918059,48.5036843125,48.4279033056,48.3527409073,
+	48.2781893488,48.2042409693,48.1308882153,48.0581236393,47.9859398991,
+	47.9143297565,47.8432860762,47.772801825,47.7028700705,47.6334839797,
+	47.5646368183,47.4963219495,47.4285328322,47.3612630208,47.2945061629,
+	47.2282559993,47.1625063616,47.0972511721,47.0324844415,46.9682002687,
+	46.9043928391,46.8410564231,46.7781853756,46.7157741343,46.6538172188,
+	46.5923092291,46.5312448446,46.4706188231,46.4104259995,46.3506612843,
+	46.2913196632,46.2323961953,46.1738860123,46.1157843173,46.0580863839,
+	46.0007875547,45.9438832405,45.8873689195,45.8312401357,45.7754924981,
+	45.7201216798,45.665123417,45.6104935076,45.5562278108,45.5023222456,
+	45.4487727904,45.3955754813,45.3427264119,45.2902217321,45.238057647,
+	45.1862304162,45.1347363532,45.0835718238,45.0327332461,44.982217089,
+	44.9320198716,44.8821381626,44.8325685792,44.7833077865,44.7343524964,
+	44.6856994674,44.6373455033,44.5892874528,44.5415222087,44.4940467071,
+	44.4468579267,44.3999528883,44.3533286537,44.3069823257,44.2609110467,
+	44.2151119985,44.1695824018,44.124319515,44.0793206341,44.034583092,
+	43.9901042576,43.9458815358,43.9019123661,43.8581942231,43.8147246147,
+	43.7715010829,43.728521202,43.6857825789,43.6432828524,43.6010196926,
+	43.5589908004,43.5171939069,43.4756267733,43.4342871901,43.3931729766,
+	43.3522819807,43.3116120784,43.2711611731,43.2309271955,43.1909081027,
+	43.1511018785,43.1115065323,43.0721200993,43.0329406393,42.9939662373,
+	42.9551950023,42.9166250673,42.878254589,42.8400817471,42.8021047443,
+	42.7643218057,42.7267311786,42.6893311322,42.6521199569,42.6150959646,
+	42.5782574877,42.5416028795,42.5051305131,42.4688387817,42.4327260982,
+	42.3967908945,42.3610316219,42.32544675,42.2900347672,42.2547941799,
+	42.2197235125,42.184821307,42.1500861227,42.1155165361,42.0811111406,
+	42.0468685461,42.0127873789,41.9788662816,41.9451039126,41.9114989459,
+	41.8780500709,41.8447559925,41.8116154303,41.7786271187,41.7457898069,
+	41.7131022583,41.6805632504,41.6481715748,41.6159260367,41.5838254549,
+	41.5518686617,41.5200545023,41.4883818353,41.4568495316,41.4254564751,
+	41.394201562,41.3630837008,41.3321018122,41.3012548286,41.2705416944,
+	41.2399613655,41.2095128092,41.1791950042,41.1490069403,41.1189476183,
+	41.0890160496,41.0592112567,41.0295322723,40.9999781396,40.970547912,
+	40.9412406531,40.9120554366,40.8829913457,40.8540474735,40.8252229228,
+	40.7965168056,40.7679282435,40.7394563671,40.7111003161,40.6828592393,
+	40.6547322942,40.626718647,40.5988174728,40.5710279548,40.5433492849,
+	40.5157806631,40.4883212976,40.4609704049,40.433727209,40.4065909422,
+	40.3795608443,40.3526361629,40.3258161531,40.2991000774,40.2724872058,
+	40.2459768155,40.2195681909,40.1932606236,40.1670534118,40.1409458612,
+	40.114937284,40.089026999,40.063214332,40.0374986152,40.0118791874,
+	39.9863553935,39.9609265851,39.9355921199,39.9103513619,39.8852036809,
+	39.8601484532,39.8351850605,39.8103128908,39.7855313379,39.7608398011,
+	39.7362376854,39.7117244017,39.6872993662,39.6629620004,39.6387117317,
+	39.6145479924,39.5904702202,39.5664778582,39.5425703542,39.5187471617,
+	39.4950077387,39.4713515484,39.447778059,39.4242867434,39.4008770793,
+	39.3775485493,39.3543006404,39.3311328446,39.3080446582,39.2850355821,
+	39.2621051218,39.2392527869,39.2164780918,39.193780555,39.1711596991,
+	39.1486150512,39.1261461426,39.1037525085,39.0814336882,39.0591892253,
+	39.0370186672,39.0149215651,38.9928974745,38.9709459543,38.9490665676,
+	38.9272588811,38.9055224652,38.883856894,38.8622617454,38.8407366006,
+	38.8192810448,38.7978946663,38.7765770572,38.7553278128,38.7341465321,
+	38.7130328173,38.6919862739,38.6710065108,38.6500931402,38.6292457774,
+	38.608464041,38.5877475528,38.5670959377,38.5465088236,38.5259858415,
+	38.5055266257,38.485130813,38.4647980436,38.4445279604,38.4243202094,
+	38.4041744393,38.3840903017,38.3640674511,38.3441055447,38.3242042424,
+	38.3043632069,38.2845821037,38.2648606009,38.2451983691,38.2255950817,
+	38.2060504147,38.1865640465,38.1671356581,38.1477649333,38.1284515578,
+	38.1091952204,38.0899956119,38.0708524256,38.0517653574,38.0327341052,
+	38.0137583696,37.9948378534,37.9759722615,37.9571613012,37.9384046823,
+	37.9197021164,37.9010533177,37.8824580021,37.8639158882,37.8454266964,
+	37.8269901493,37.8086059716,37.7902738901,37.7719936336,37.753764933,
+	37.7355875212,37.717461133,37.6993855054,37.6813603772,37.6633854891,
+	37.6454605838,37.6275854059,37.6097597018,37.59198322,37.5742557106,
+	37.5565769256,37.5389466189,37.521364546,37.5038304645,37.4863441334,
+	37.4689053137,37.4515137681,37.4341692609,37.4168715581,37.3996204275,
+	37.3824156386,37.3652569623,37.3481441714,37.3310770401,37.3140553445,
+	37.297078862,37.2801473717,37.2632606542,37.2464184918,37.2296206681,
+	37.2128669684,37.1961571795,37.1794910896,37.1628684884,37.1462891671,
+	37.1297529184,37.1132595362,37.0968088162,37.0804005552,37.0640345515,
+	37.0477106048,37.0314285162,37.0151880881,36.9989891244,36.9828314301,
+	36.9667148116,36.9506390768,36.9346040347,36.9186094956,36.9026552713,
+	36.8867411745,36.8708670195,36.8550326217,36.8392377978,36.8234823655,
+	36.807766144,36.7920889536,36.7764506158,36.7608509532,36.7452897896,
+	36.7297669502,36.714282261,36.6988355493,36.6834266436,36.6680553734,
+	36.6527215694,36.6374250634,36.6221656883,36.606943278,36.5917576675,
+	36.5766086929,36.5614961915,36.5464200014,36.5313799619,36.5163759132,
+	36.5014076967,36.4864751547,36.4715781305,36.4567164685,36.4418900139,
+	36.4270986131,36.4123421134,36.3976203629,36.382933211,36.3682805076,
+	36.353662104,36.3390778522,36.324527605,36.3100112165,36.2955285412,
+	36.2810794351,36.2666637545,36.252281357,36.237932101,36.2236158457,
+	36.2093324512,36.1950817784,36.1808636892,36.1666780462,36.152524713,
+	36.1384035538,36.1243144338,36.1102572191,36.0962317763,36.0822379733,
+	36.0682756782,36.0543447604,36.0404450898,36.0265765373,36.0127389743,
+	35.9989322732,35.9851563071,35.9714109499,35.957696076,35.944011561,
+	35.9303572808,35.9167331123,35.903138933,35.8895746213,35.8760400561,
+	35.8625351171,35.8490596847,35.8356136401,35.822196865,35.808809242,
+	35.7954506543,35.7821209857,35.7688201207,35.7555479447,35.7423043434,
+	35.7290892035,35.715902412,35.7027438569,35.6896134267,35.6765110104,
+	35.663436498,35.6503897796,35.6373707465,35.6243792901,35.6114153029,
+	35.5984786777,35.5855693079,35.5726870876,35.5598319116,35.5470036751,
+	35.534202274,35.5214276048,35.5086795644,35.4959580506,35.4832629614,
+	35.4705941957,35.4579516528,35.4453352325,35.4327448353,35.4201803622,
+	35.4076417148,35.3951287951,35.3826415057,35.3701797498,35.3577434311,
+	35.3453324539,35.3329467228,35.3205861432,35.3082506207,35.2959400619,
+	35.2836543733,35.2713934625,35.2591572371,35.2469456055,35.2347584766,
+	35.2225957595,35.2104573643,35.198343201,35.1862531805,35.174187214,
+	35.1621452133,35.1501270905,35.1381327583,35.1261621298,35.1142151186,
+	35.1022916388,35.0903916048,35.0785149317,35.0666615348,35.0548313299,
+	35.0430242335,35.0312401621,35.0194790329,35.0077407637,34.9960252724,
+	34.9843324774,34.9726622977,34.9610146526,34.9493894618,34.9377866455,
+	34.9262061242,34.9146478189,34.903111651,34.8915975423,34.880105415,
+	34.8686351915,34.8571867951,34.845760149,34.8343551769,34.8229718032,
+	34.8116099522,34.800269549,34.7889505189,34.7776527876,34.7663762811,
+	34.7551209259,34.7438866488,34.732673377,34.7214810381,34.7103095599,
+	34.6991588708,34.6880288994,34.6769195746,34.665830826,34.654762583,
+	34.6437147759,34.632687335,34.6216801911,34.6106932752,34.5997265188,
+	34.5887798536,34.5778532119,34.5669465259,34.5560597285,34.5451927529,
+	34.5343455323,34.5235180007,34.5127100921,34.5019217408,34.4911528817,
+	34.4804034497,34.4696733802,34.458962609,34.4482710719,34.4375987053,
+	34.4269454458,34.4163112303,34.405695996,34.3950996804,34.3845222213,
+	34.373963557,34.3634236256,34.3529023661,34.3423997173,34.3319156186,
+	34.3214500095,34.3110028299,34.30057402,34.2901635202,34.2797712711,
+	34.2693972139,34.2590412897,34.2487034402,34.2383836071,34.2280817325,
+	34.2177977589,34.2075316288,34.1972832853,34.1870526713,34.1768397305,
+	34.1666444064,34.1564666431,34.1463063848,34.1361635759,34.1260381613,
+	34.1159300859,34.1058392949,34.0957657339,34.0857093486,34.075670085,
+	34.0656478894,34.0556427083,34.0456544884,34.0356831767,34.0257287205,
+	34.0157910671,34.0058701643,33.9959659601,33.9860784026,33.9762074403,
+	33.9663530217,33.9565150959,33.9466936118,33.9368885189,33.9270997666,
+	33.9173273049,33.9075710837,33.8978310533,33.8881071641,33.8783993668,
+	33.8687076124,33.8590318519,33.8493720367,33.8397281184,33.8301000487,
+	33.8204877797,33.8108912635,33.8013104526,33.7917452996,33.7821957572,
+	33.7726617786,33.763143317,33.7536403258,33.7441527588,33.7346805697,
+	33.7252237126,33.7157821418,33.7063558118,33.6969446771,33.6875486927,
+	33.6781678136,33.6688019951,33.6594511925,33.6501153616,33.6407944581,
+	33.631488438,33.6221972577,33.6129208733,33.6036592416,33.5944123194,
+	33.5851800634,33.575962431,33.5667593793,33.5575708659,33.5483968486,
+	33.539237285,33.5300921334,33.5209613518,33.5118448987,33.5027427327,
+	33.4936548125,33.484581097,33.4755215454,33.4664761168,33.4574447707,
+	33.4484274668,33.4394241647,33.4304348245,33.4214594063,33.4124978703,
+	33.403550177,33.3946162869,33.3856961609,33.3767897599,33.367897045,
+	33.3590179775,33.3501525187,33.3413006302,33.3324622739,33.3236374115,
+	33.3148260051,33.3060280169,33.2972434094,33.2884721449,33.2797141863,
+	33.2709694962,33.2622380377,33.2535197739,33.2448146681,33.2361226837,
+	33.2274437842,33.2187779335,33.2101250953,33.2014852337,33.1928583128,
+	33.184244297,33.1756431507,33.1670548384,33.158479325,33.1499165753,
+	33.1413665542,33.1328292271,33.124304559,33.1157925156,33.1072930624,
+	33.098806165,33.0903317894,33.0818699015,33.0734204674,33.0649834534,
+	33.0565588258,33.0481465513,33.0397465963,33.0313589278,33.0229835126,
+	33.0146203178,33.0062693106,32.9979304582,32.989603728,32.9812890877,
+	32.972986505,32.9646959476,32.9564173834,32.9481507806,32.9398961073,
+	32.9316533318,32.9234224226,32.9152033482,32.9069960773,32.8988005787,
+	32.8906168214,32.8824447742,32.8742844065,32.8661356875,32.8579985866,
+	32.8498730732,32.8417591171,32.833656688,32.8255657557,32.8174862902,
+	32.8094182617,32.8013616402,32.7933163962,32.7852825001,32.7772599223,
+	32.7692486337,32.7612486048,32.7532598067,32.7452822103,32.7373157867,
+	32.7293605071,32.7214163428,32.7134832652,32.705561246,32.6976502567,
+	32.689750269,32.6818612548,32.6739831862,32.666116035,32.6582597736,
+	32.6504143741,32.6425798089,32.6347560506,32.6269430716,32.6191408447,
+	32.6113493427,32.6035685384,32.5957984048,32.588038915,32.5802900421,
+	32.5725517595,32.5648240406,32.5571068587,32.5494001875,32.5417040007,
+	32.5340182719,32.5263429752,32.5186780844,32.5110235735,32.5033794168,
+	32.4957455885,32.4881220628,32.4805088143,32.4729058175,32.4653130469,
+	32.4577304774,32.4501580835,32.4425958404,32.4350437229,32.4275017061,
+	32.4199697652,32.4124478754,32.404936012,32.3974341505,32.3899422665,
+	32.3824603354,32.374988333,32.3675262351,32.3600740175,32.3526316561,
+	32.3451991271,32.3377764065,32.3303634705,32.3229602955,32.3155668577,
+	32.3081831337,32.3008091,32.2934447331,32.2860900099,32.2787449071,
+	32.2714094015,32.2640834702,32.2567670901,32.2494602383,32.2421628922,
+	32.2348750288,32.2275966256,32.22032766,32.2130681096,32.2058179518,
+	32.1985771644,32.1913457251,32.1841236118,32.1769108022,32.1697072745,
+	32.1625130066,32.1553279767,32.148152163,32.1409855437,32.1338280972,
+	32.126679802,32.1195406365,32.1124105793,32.1052896091,32.0981777045,
+	32.0910748445,32.0839810077,32.0768961733,32.0698203201,32.0627534273,
+	32.0556954741,32.0486464396,32.0416063031,32.0345750441,32.0275526419,
+	32.020539076,32.0135343261,32.0065383718,31.9995511928,31.9925727688,
+	31.9856030797,31.9786421055,31.9716898261,31.9647462215,31.957811272,
+	31.9508849576,31.9439672587,31.9370581555,31.9301576284,31.9232656579,
+	31.9163822245,31.9095073088,31.9026408914,31.895782953,31.8889334744,
+	31.8820924364,31.87525982,31.8684356061,31.8616197757,31.8548123099,
+	31.8480131899,31.8412223968,31.834439912,31.8276657168,31.8208997926,
+	31.8141421208,31.8073926829,31.8006514606,31.7939184355,31.7871935893,
+	31.7804769038,31.7737683607,31.7670679419,31.7603756294,31.7536914052,
+	31.7470152514,31.74034715,31.7336870832,31.7270350332,31.7203909824,
+	31.7137549131,31.7071268077,31.7005066486,31.6938944183,31.6872900995,
+	31.6806936748,31.6741051267,31.6675244382,31.6609515919,31.6543865707,
+	31.6478293576,31.6412799354,31.6347382873,31.6282043961,31.6216782452,
+	31.6151598176,31.6086490966,31.6021460655,31.5956507075,31.5891630062,
+	31.5826829449,31.576210507,31.5697456763,31.5632884362,31.5568387704,
+	31.5503966626,31.5439620966,31.5375350561,31.5311155251,31.5247034874,
+	31.5182989269,31.5119018277,31.5055121739,31.4991299494,31.4927551386,
+	31.4863877255,31.4800276945,31.4736750299,31.4673297159,31.4609917371,
+	31.4546610778,31.4483377225,31.4420216558,31.4357128623,31.4294113266,
+	31.4231170334,31.4168299674,31.4105501135,31.4042774564,31.398011981,
+	31.3917536723,31.3855025152,31.3792584947,31.3730215959,31.3667918039,
+	31.3605691038,31.3543534809,31.3481449203,31.3419434074,31.3357489276,
+	31.329561466,31.3233810083,31.3172075399,31.3110410462,31.3048815128,
+	31.2987289254,31.2925832695,31.2864445309,31.2803126952,31.2741877483,
+	31.2680696759,31.261958464,31.2558540983,31.249756565,31.2436658498,
+	31.2375819389,31.2315048184,31.2254344742,31.2193708927,31.2133140599,
+	31.2072639622,31.2012205857,31.1951839169,31.189153942,31.1831306474,
+	31.1771140197,31.1711040452,31.1651007105,31.1591040022,31.1531139068,
+	31.1471304109,31.1411535014,31.1351831648,31.1292193879,31.1232621575,
+	31.1173114605,31.1113672838,31.1054296141,31.0994984385,31.0935737441,
+	31.0876555177,31.0817437464,31.0758384175,31.0699395179,31.0640470349,
+	31.0581609557,31.0522812675,31.0464079577,31.0405410135,31.0346804223,
+	31.0288261716,31.0229782487,31.0171366411,31.0113013363,31.0054723219,
+	30.9996495855,30.9938331146,30.988022897,30.9822189203,30.9764211722,
+	30.9706296405,30.9648443129,30.9590651774,30.9532922218,30.9475254339,
+	30.9417648017
+	}},
+	{ // Ri = 250k
+	-5,5,200,2001, {
+	223.484971051,223.38189846,223.278606859,223.175096438,223.071367386,
+	222.967419894,222.863254153,222.758870355,222.654268692,222.549449358,
+	222.444412546,222.339158451,222.233687268,222.127999193,222.022094421,
+	221.915973151,221.809635579,221.703081904,221.596312324,221.489327039,
+	221.382126248,221.274710152,221.167078951,221.059232846,220.951172041,
+	220.842896736,220.734407134,220.62570344,220.516785857,220.407654588,
+	220.298309839,220.188751814,220.078980719,219.96899676,219.858800143,
+	219.748391075,219.637769762,219.526936413,219.415891235,219.304634436,
+	219.193166225,219.081486809,218.9695964,218.857495205,218.745183435,
+	218.6326613,218.519929009,218.406986775,218.293834807,218.180473316,
+	218.066902515,217.953122614,217.839133825,217.724936362,217.610530435,
+	217.495916257,217.381094042,217.266064002,217.150826349,217.035381299,
+	216.919729063,216.803869855,216.68780389,216.571531381,216.455052541,
+	216.338367587,216.22147673,216.104380187,215.987078171,215.869570897,
+	215.75185858,215.633941434,215.515819675,215.397493517,215.278963175,
+	215.160228865,215.041290801,214.922149198,214.802804272,214.683256238,
+	214.563505311,214.443551707,214.32339564,214.203037325,214.082476979,
+	213.961714816,213.840751051,213.719585899,213.598219576,213.476652297,
+	213.354884277,213.232915731,213.110746873,212.988377919,212.865809083,
+	212.74304058,212.620072625,212.496905433,212.373539217,212.249974193,
+	212.126210573,212.002248574,211.878088408,211.75373029,211.629174433,
+	211.504421051,211.379470357,211.254322565,211.128977889,211.003436541,
+	210.877698734,210.751764681,210.625634594,210.499308686,210.37278717,
+	210.246070256,210.119158158,209.992051086,209.864749253,209.737252869,
+	209.609562146,209.481677294,209.353598524,209.225326046,209.096860071,
+	208.968200809,208.839348469,208.710303261,208.581065394,208.451635077,
+	208.322012519,208.192197928,208.062191513,207.931993481,207.801604041,
+	207.671023398,207.540251762,207.409289338,207.278136334,207.146792955,
+	207.015259407,206.883535897,206.75162263,206.61951981,206.487227642,
+	206.354746332,206.222076083,206.089217099,205.956169583,205.82293374,
+	205.689509771,205.555897879,205.422098267,205.288111136,205.153936688,
+	205.019575125,204.885026646,204.750291453,204.615369746,204.480261724,
+	204.344967587,204.209487534,204.073821763,203.937970474,203.801933864,
+	203.66571213,203.52930547,203.392714081,203.255938159,203.1189779,
+	202.9818335,202.844505154,202.706993058,202.569297405,202.43141839,
+	202.293356206,202.155111047,202.016683105,201.878072574,201.739279645,
+	201.60030451,201.46114736,201.321808386,201.182287779,201.042585728,
+	200.902702422,200.762638052,200.622392806,200.481966872,200.341360438,
+	200.200573692,200.059606819,199.918460008,199.777133444,199.635627312,
+	199.493941798,199.352077087,199.210033363,199.067810809,198.92540961,
+	198.782829948,198.640072006,198.497135966,198.354022009,198.210730316,
+	198.067261068,197.923614446,197.779790629,197.635789796,197.491612126,
+	197.347257797,197.202726987,197.058019875,196.913136635,196.768077446,
+	196.622842482,196.477431919,196.331845933,196.186084697,196.040148386,
+	195.894037174,195.747751232,195.601290734,195.454655852,195.307846758,
+	195.160863622,195.013706614,194.866375906,194.718871667,194.571194065,
+	194.423343269,194.275319448,194.127122768,193.978753398,193.830211503,
+	193.681497249,193.532610803,193.383552329,193.234321992,193.084919955,
+	192.935346382,192.785601437,192.635685281,192.485598078,192.335339987,
+	192.18491117,192.034311788,191.883542,191.732601966,191.581491845,
+	191.430211795,191.278761974,191.127142539,190.975353646,190.823395454,
+	190.671268116,190.518971788,190.366506625,190.213872781,190.06107041,
+	189.908099664,189.754960697,189.60165366,189.448178705,189.294535983,
+	189.140725644,188.986747838,188.832602716,188.678290424,188.523811112,
+	188.369164928,188.214352019,188.059372531,187.904226611,187.748914404,
+	187.593436056,187.43779171,187.281981512,187.126005604,186.96986413,
+	186.813557231,186.65708505,186.500447728,186.343645406,186.186678223,
+	186.029546321,185.872249837,185.714788911,185.55716368,185.399374282,
+	185.241420854,185.083303532,184.925022453,184.766577751,184.607969561,
+	184.449198018,184.290263255,184.131165406,183.971904603,183.812480977,
+	183.652894661,183.493145785,183.333234481,183.173160876,183.012925102,
+	182.852527286,182.691967558,182.531246043,182.37036287,182.209318165,
+	182.048112055,181.886744663,181.725216116,181.563526538,181.401676052,
+	181.239664781,181.077492849,180.915160377,180.752667487,180.5900143,
+	180.427200936,180.264227516,180.101094157,179.937800981,179.774348103,
+	179.610735643,179.446963717,179.283032441,179.118941933,178.954692306,
+	178.790283677,178.625716159,178.460989866,178.296104912,178.131061408,
+	177.965859467,177.800499201,177.634980721,177.469304136,177.303469557,
+	177.137477093,176.971326853,176.805018945,176.638553477,176.471930555,
+	176.305150286,176.138212776,175.971118131,175.803866455,175.636457852,
+	175.468892427,175.301170281,175.133291519,174.965256242,174.797064551,
+	174.628716547,174.460212331,174.291552002,174.12273566,173.953763402,
+	173.784635329,173.615351536,173.44591212,173.276317179,173.106566808,
+	172.936661103,172.766600157,172.596384066,172.426012922,172.255486819,
+	172.084805849,171.913970105,171.742979677,171.571834657,171.400535134,
+	171.229081198,171.057472939,170.885710445,170.713793803,170.541723102,
+	170.369498428,170.197119867,170.024587505,169.851901428,169.67906172,
+	169.506068464,169.332921745,169.159621646,168.986168248,168.812561633,
+	168.638801884,168.464889079,168.2908233,168.116604626,167.942233136,
+	167.767708909,167.593032021,167.418202552,167.243220576,167.068086171,
+	166.892799412,166.717360374,166.541769131,166.366025758,166.190130327,
+	166.014082912,165.837883585,165.661532417,165.48502948,165.308374843,
+	165.131568578,164.954610753,164.777501437,164.600240698,164.422828605,
+	164.245265224,164.067550622,163.889684865,163.711668018,163.533500146,
+	163.355181313,163.176711584,162.998091022,162.819319688,162.640397646,
+	162.461324957,162.28210168,162.102727878,161.92320361,161.743528935,
+	161.563703911,161.383728597,161.203603051,161.023327328,160.842901487,
+	160.662325582,160.481599669,160.300723803,160.119698037,159.938522426,
+	159.757197022,159.575721877,159.394097045,159.212322576,159.03039852,
+	158.848324929,158.666101851,158.483729336,158.301207432,158.118536187,
+	157.935715649,157.752745864,157.569626879,157.38635874,157.20294149,
+	157.019375176,156.83565984,156.651795527,156.467782279,156.283620139,
+	156.099309148,155.914849347,155.730240777,155.545483478,155.36057749,
+	155.175522851,154.9903196,154.804967774,154.61946741,154.433818546,
+	154.248021217,154.062075459,153.875981307,153.689738795,153.503347956,
+	153.316808825,153.130121434,152.943285814,152.756301998,152.569170017,
+	152.3818899,152.194461677,152.006885379,151.819161033,151.631288668,
+	151.443268311,151.25509999,151.06678373,150.878319558,150.689707498,
+	150.500947577,150.312039817,150.122984243,149.933780877,149.744429742,
+	149.55493086,149.365284253,149.17548994,148.985547943,148.79545828,
+	148.605220971,148.414836035,148.224303489,148.033623351,147.842795638,
+	147.651820366,147.46069755,147.269427206,147.078009348,146.886443991,
+	146.694731147,146.50287083,146.310863051,146.118707824,145.926405158,
+	145.733955065,145.541357554,145.348612635,145.155720318,144.962680609,
+	144.769493518,144.576159051,144.382677215,144.189048016,143.995271461,
+	143.801347552,143.607276296,143.413057696,143.218691756,143.024178478,
+	142.829517864,142.634709916,142.439754635,142.244652022,142.049402077,
+	141.854004798,141.658460186,141.462768238,141.266928951,141.070942324,
+	140.874808353,140.678527034,140.482098363,140.285522334,140.088798942,
+	139.891928181,139.694910044,139.497744525,139.300431614,139.102971305,
+	138.905363588,138.707608454,138.509705892,138.311655894,138.113458446,
+	137.915113539,137.71662116,137.517981296,137.319193934,137.120259061,
+	136.921176662,136.721946723,136.522569228,136.323044162,136.123371508,
+	135.923551249,135.723583369,135.523467849,135.32320467,135.122793815,
+	134.922235263,134.721528995,134.52067499,134.319673227,134.118523685,
+	133.917226342,133.715781176,133.514188163,133.31244728,133.110558503,
+	132.908521808,132.70633717,132.504004564,132.301523963,132.098895342,
+	131.896118674,131.693193931,131.490121086,131.286900111,131.083530977,
+	130.880013655,130.676348115,130.472534329,130.268572264,130.064461891,
+	129.860203179,129.655796095,129.451240608,129.246536686,129.041684295,
+	128.836683403,128.631533975,128.426235979,128.220789379,128.015194141,
+	127.80945023,127.603557611,127.397516247,127.191326104,126.984987144,
+	126.778499331,126.571862629,126.365076999,126.158142404,125.951058808,
+	125.74382617,125.536444455,125.328913622,125.121233634,124.913404451,
+	124.705426035,124.497298346,124.289021346,124.080594993,123.87201925,
+	123.663294075,123.45441943,123.245395274,123.036221568,122.826898272,
+	122.617425345,122.407802748,122.198030441,121.988108384,121.778036537,
+	121.567814861,121.357443316,121.146921862,120.936250462,120.725429075,
+	120.514457662,120.303336187,120.09206461,119.880642893,119.669071,
+	119.457348893,119.245476537,119.033453894,118.821280929,118.608957608,
+	118.396483896,118.18385976,117.971085166,117.758160083,117.545084479,
+	117.331858324,117.118481589,116.904954244,116.691276262,116.477447617,
+	116.263468283,116.049338237,115.835057456,115.620625918,115.406043603,
+	115.191310494,114.976426573,114.761391825,114.546206237,114.330869797,
+	114.115382497,113.899744328,113.683955284,113.468015365,113.251924567,
+	113.035682894,112.819290349,112.60274694,112.386052677,112.169207573,
+	111.952211643,111.735064908,111.517767389,111.300319114,111.082720112,
+	110.864970417,110.647070067,110.429019104,110.210817576,109.992465532,
+	109.77396303,109.55531013,109.336506899,109.117553408,108.898449735,
+	108.679195963,108.459792182,108.240238489,108.020534985,107.800681781,
+	107.580678994,107.360526749,107.140225178,106.919774422,106.69917463,
+	106.478425962,106.257528585,106.036482676,105.815288423,105.593946025,
+	105.372455689,105.150817638,104.929032102,104.707099327,104.48501957,
+	104.262793102,104.040420207,103.817901185,103.595236351,103.372426033,
+	103.149470578,102.926370349,102.703125726,102.479737108,102.256204914,
+	102.032529581,101.808711566,101.58475135,101.360649435,101.136406344,
+	100.912022628,100.687498859,100.462835637,100.23803359,100.013093371,
+	99.7880156641,99.5628011832,99.3374506734,99.1119649126,98.8863447123,
+	98.6605909195,98.4347044173,98.2086861271,97.9825370096,97.7562580661,
+	97.5298503407,97.3033149214,97.076652942,96.8498655839,96.6229540776,
+	96.3959197048,96.1687638004,95.9414877543,95.7140930135,95.4865810843,
+	95.2589535346,95.0312119958,94.8033581658,94.5753938109,94.3473207683,
+	94.1191409492,93.8908563411,93.6624690106,93.4339811063,93.205394862,
+	92.9767125993,92.7479367311,92.5190697648,92.2901143054,92.0610730592,
+	91.8319488373,91.602744559,91.373463256,91.1441080758,90.9146822859,
+	90.6851892779,90.4556325714,90.2260158187,89.9963428088,89.7666174721,
+	89.536843885,89.3070262745,89.0771690233,88.8472766741,88.6173539356,
+	88.3874056866,88.1574369818,87.9274530572,87.697459335,87.4674614297,
+	87.237465153,87.0074765201,86.7775017551,86.5475472965,86.3176198036,
+	86.087726162,85.8578734896,85.6280691424,85.3983207206,85.1686360744,
+	84.9390233102,84.7094907959,84.4800471675,84.2507013342,84.0214624844,
+	83.7923400915,83.5633439187,83.334484025,83.1057707701,82.8772148192,
+	82.6488271479,82.4206190466,82.1926021248,81.9647883147,81.7371898752,
+	81.5098193947,81.282689794,81.0558143286,80.8292065906,80.6028805099,
+	80.3768503551,80.1511307336,79.9257365914,79.7006832114,79.4759862124,
+	79.2516615459,79.0277254929,78.80419466,78.5810859742,78.3584166771,
+	78.1362043179,77.914466746,77.6932221017,77.4724888073,77.2522855555,
+	77.0326312982,76.8135452334,76.5950467914,76.3771556195,76.1598915665,
+	75.943274665,75.7273251137,75.5120632578,75.297509569,75.0836846242,
+	74.8706090831,74.6583036656,74.4467891271,74.2360862344,74.0262157397,
+	73.8171983546,73.609054723,73.4018053941,73.195470794,72.9900711983,
+	72.7856267028,72.5821571954,72.3796823271,72.1782214839,71.9777937575,
+	71.7784179177,71.5801123841,71.3828951991,71.1867840008,70.9917959968,
+	70.7979479394,70.6052561006,70.413736249,70.2234036275,70.0342729319,
+	69.8463582915,69.6596732499,69.4742307486,69.2900431108,69.1071220272,
+	68.925478544,68.7451230512,68.5660652733,68.3883142621,68.2118783899,
+	68.0367653452,67.8629821298,67.6905350579,67.5194297558,67.349671164,
+	67.1812635406,67.0142104662,66.8485148499,66.6841789368,66.5212043171,
+	66.359591936,66.1993421046,66.0404545127,65.8829282415,65.7267617781,
+	65.5719530301,65.4184993417,65.2663975098,65.1156438011,64.9662339694,
+	64.8181632736,64.6714264963,64.5260179616,64.3819315545,64.2391607398,
+	64.0976985804,63.9575377573,63.8186705879,63.6810890449,63.5447847755,
+	63.4097491195,63.2759731279,63.1434475806,63.0121630047,62.8821096914,
+	62.7532777134,62.6256569412,62.4992370596,62.3740075834,62.2499578725,
+	62.1270771474,62.0053545027,61.8847789218,61.7653392897,61.6470244065,
+	61.5298229991,61.4137237339,61.2987152275,61.1847860581,61.0719247757,
+	60.9601199122,60.8493599906,60.7396335345,60.630929076,60.5232351645,
+	60.4165403737,60.3108333094,60.2061026159,60.1023369826,59.9995251502,
+	59.8976559158,59.7967181389,59.6967007458,59.5975927344,59.4993831786,
+	59.4020612319,59.3056161312,59.2100372005,59.1153138535,59.0214355966,
+	58.9283920315,58.8361728577,58.7447678742,58.6541669817,58.5643601843,
+	58.4753375907,58.3870894158,58.2996059815,58.2128777181,58.1268951645,
+	58.0416489694,57.9571298914,57.8733287998,57.7902366743,57.7078446055,
+	57.6261437948,57.5451255545,57.4647813073,57.3851025863,57.3060810344,
+	57.2277084041,57.1499765569,57.0728774627,56.9964031993,56.9205459515,
+	56.8452980105,56.7706517731,56.6965997408,56.6231345189,56.5502488157,
+	56.4779354416,56.4061873078,56.3349974256,56.2643589053,56.1942649551,
+	56.12470888,56.0556840808,55.9871840529,55.9192023854,55.8517327594,
+	55.7847689478,55.7183048131,55.6523343072,55.5868514695,55.5218504263,
+	55.4573253892,55.3932706543,55.3296806009,55.2665496903,55.2038724646,
+	55.1416435458,55.0798576345,55.0185095087,54.9575940229,54.8971061066,
+	54.8370407637,54.7773930709,54.718158177,54.6593313016,54.6009077341,
+	54.5428828326,54.4852520229,54.4280107972,54.3711547138,54.3146793951,
+	54.2585805273,54.2028538591,54.147495201,54.092500424,54.0378654587,
+	53.9835862945,53.9296589787,53.8760796154,53.8228443647,53.7699494418,
+	53.7173911161,53.6651657104,53.6132695999,53.5616992114,53.5104510228,
+	53.4595215617,53.408907405,53.358605178,53.3086115536,53.2589232516,
+	53.2095370379,53.1604497237,53.1116581648,53.0631592611,53.0149499554,
+	52.9670272332,52.9193881217,52.8720296893,52.8249490449,52.7781433372,
+	52.7316097539,52.6853455215,52.6393479043,52.5936142039,52.5481417587,
+	52.5029279432,52.4579701673,52.4132658761,52.3688125489,52.3246076991,
+	52.2806488732,52.2369336506,52.193459643,52.1502244938,52.1072258777,
+	52.0644615,52.0219290964,51.9796264325,51.9375513029,51.8957015313,
+	51.8540749699,51.8126694984,51.7714830245,51.7305134827,51.6897588342,
+	51.6492170664,51.6088861928,51.568764252,51.5288493078,51.4891394485,
+	51.4496327869,51.4103274594,51.3712216261,51.3323134703,51.2936011979,
+	51.2550830374,51.2167572394,51.1786220761,51.1406758414,51.1029168502,
+	51.065343438,51.0279539611,50.9907467956,50.9537203379,50.9168730035,
+	50.8802032274,50.8437094637,50.8073901849,50.7712438821,50.7352690645,
+	50.6994642591,50.6638280107,50.6283588811,50.5930554497,50.5579163121,
+	50.522940081,50.4881253853,50.4534708698,50.4189751955,50.3846370388,
+	50.3504550916,50.3164280609,50.2825546688,50.2488336522,50.2152637622,
+	50.1818437647,50.1485724393,50.1154485799,50.0824709937,50.0496385019,
+	50.0169499386,49.9844041515,49.9520000008,49.9197363597,49.8876121142,
+	49.8556261623,49.8237774146,49.7920647936,49.7604872338,49.7290436813,
+	49.6977330941,49.6665544412,49.6355067033,49.6045888718,49.5737999493,
+	49.5431389491,49.5126048954,49.4821968226,49.4519137756,49.4217548096,
+	49.3917189898,49.3618053914,49.3320130994,49.3023412085,49.2727888229,
+	49.2433550565,49.2140390322,49.1848398821,49.1557567476,49.1267887789,
+	49.0979351349,49.0691949835,49.040567501,49.0120518721,48.9836472901,
+	48.9553529564,48.9271680807,48.8990918806,48.8711235817,48.8432624174,
+	48.815507629,48.7878584653,48.7603141827,48.732874045,48.7055373233,
+	48.6783032962,48.6511712493,48.6241404752,48.5972102736,48.5703799512,
+	48.5436488213,48.517016204,48.4904814261,48.464043821,48.4377027285,
+	48.4114574948,48.3853074723,48.35925202,48.3332905028,48.3074222917,
+	48.2816467637,48.2559633019,48.2303712951,48.204870138,48.179459231,
+	48.1541379801,48.1289057971,48.103762099,48.0787063085,48.0537378537,
+	48.0288561678,48.0040606896,47.9793508627,47.9547261362,47.9301859641,
+	47.9057298055,47.8813571243,47.8570673896,47.832860075,47.8087346591,
+	47.7846906251,47.7607274611,47.7368446597,47.7130417179,47.6893181375,
+	47.6656734245,47.6421070895,47.6186186475,47.5952076176,47.5718735233,
+	47.5486158923,47.5254342566,47.5023281519,47.4792971185,47.4563407004,
+	47.4334584457,47.4106499063,47.3879146382,47.3652522011,47.3426621586,
+	47.3201440779,47.2976975301,47.27532209,47.2530173358,47.2307828496,
+	47.2086182168,47.1865230265,47.1644968713,47.142539347,47.1206500531,
+	47.0988285923,47.0770745708,47.0553875978,47.033767286,47.0122132513,
+	46.9907251128,46.9693024927,46.9479450163,46.926652312,46.9054240114,
+	46.884259749,46.8631591622,46.8421218916,46.8211475806,46.8002358755,
+	46.7793864255,46.7585988825,46.7378729014,46.7172081399,46.6966042582,
+	46.6760609195,46.6555777895,46.6351545368,46.6147908322,46.5944863497,
+	46.5742407654,46.5540537582,46.5339250095,46.5138542031,46.4938410254,
+	46.4738851652,46.4539863139,46.434144165,46.4143584145,46.394628761,
+	46.374954905,46.3553365498,46.3357734005,46.3162651648,46.2968115526,
+	46.2774122759,46.258067049,46.2387755882,46.2195376123,46.200352842,
+	46.181221,46.1621418113,46.143115003,46.124140304,46.1052174456,
+	46.0863461607,46.0675261845,46.0487572541,46.0300391084,46.0113714885,
+	45.9927541372,45.9741867993,45.9556692215,45.9372011522,45.9187823419,
+	45.9004125427,45.8820915086,45.8638189954,45.8455947607,45.8274185639,
+	45.8092901659,45.7912093296,45.7731758195,45.7551894018,45.7372498443,
+	45.7193569166,45.7015103899,45.683710037,45.6659556324,45.648246952,
+	45.6305837735,45.6129658761,45.5953930405,45.5778650491,45.5603816856,
+	45.5429427354,45.5255479853,45.5081972237,45.4908902404,45.4736268266,
+	45.4564067751,45.4392298799,45.4220959367,45.4050047424,45.3879560955,
+	45.3709497956,45.3539856439,45.3370634429,45.3201829964,45.3033441096,
+	45.286546589,45.2697902423,45.2530748788,45.2364003088,45.2197663439,
+	45.2031727971,45.1866194827,45.170106216,45.1536328136,45.1371990936,
+	45.120804875,45.1044499781,45.0881342244,45.0718574366,45.0556194386,
+	45.0394200553,45.0232591129,45.0071364388,44.9910518613,44.97500521,
+	44.9589963155,44.9430250097,44.9270911254,44.9111944966,44.8953349582,
+	44.8795123463,44.8637264982,44.8479772519,44.8322644468,44.816587923,
+	44.8009475218,44.7853430856,44.7697744577,44.7542414822,44.7387440046,
+	44.7232818711,44.7078549288,44.6924630261,44.677106012,44.6617837367,
+	44.6464960512,44.6312428075,44.6160238584,44.6008390578,44.5856882605,
+	44.570571322,44.5554880988,44.5404384485,44.5254222292,44.5104393001,
+	44.4954895213,44.4805727536,44.4656888589,44.4508376997,44.4360191394,
+	44.4212330422,44.4064792734,44.3917576987,44.3770681849,44.3624105996,
+	44.347784811,44.3331906883,44.3186281014,44.3040969209,44.2895970184,
+	44.2751282661,44.2606905369,44.2462837046,44.2319076438,44.2175622296,
+	44.2032473381,44.188962846,44.1747086307,44.1604845704,44.1462905441,
+	44.1321264312,44.1179921121,44.1038874679,44.0898123802,44.0757667314,
+	44.0617504046,44.0477632835,44.0338052526,44.0198761971,44.0059760025,
+	43.9921045555,43.978261743,43.9644474528,43.9506615732,43.9369039933,
+	43.9231746028,43.9094732918,43.8957999513,43.8821544728,43.8685367485,
+	43.854946671,43.8413841338,43.8278490309,43.8143412567,43.8008607064,
+	43.7874072758,43.7739808611,43.7605813594,43.747208668,43.733862685,
+	43.720543309,43.7072504393,43.6939839756,43.6807438181,43.6675298677,
+	43.6543420258,43.6411801944,43.628044276,43.6149341734,43.6018497904,
+	43.5887910309,43.5757577997,43.5627500017,43.5497675426,43.5368103287,
+	43.5238782665,43.5109712632,43.4980892264,43.4852320645,43.4723996859,
+	43.459592,43.4468089162,43.4340503448,43.4213161963,43.4086063818,
+	43.395920813,43.3832594017,43.3706220606,43.3580087026,43.3454192411,
+	43.33285359,43.3203116637,43.3077933769,43.2952986449,43.2828273833,
+	43.2703795084,43.2579549366,43.2455535849,43.2331753709,43.2208202124,
+	43.2084880276,43.1961787354,43.1838922548,43.1716285054,43.1593874071,
+	43.1471688805,43.1349728462,43.1227992256,43.1106479402,43.0985189119,
+	43.0864120634,43.0743273173,43.0622645969,43.0502238257,43.0382049278,
+	43.0262078276,43.0142324497,43.0022787194,42.9903465622,42.9784359039,
+	42.9665466709,42.9546787897,42.9428321874,42.9310067914,42.9192025293,
+	42.9074193294,42.89565712,42.88391583,42.8721953886,42.8604957252,
+	42.8488167698,42.8371584525,42.825520704,42.8139034551,42.8023066371,
+	42.7907301817,42.7791740206,42.7676380862,42.7561223111,42.7446266282,
+	42.7331509707,42.7216952722,42.7102594667,42.6988434883,42.6874472716,
+	42.6760707514,42.664713863,42.6533765417,42.6420587235,42.6307603444,
+	42.6194813408,42.6082216494,42.5969812074,42.5857599519,42.5745578207,
+	42.5633747516,42.5522106829,42.5410655531,42.529939301,42.5188318657,
+	42.5077431866,42.4966732034,42.485621856,42.4745890847,42.4635748299,
+	42.4525790326,42.4416016337,42.4306425747,42.4197017972,42.4087792431,
+	42.3978748545,42.3869885739,42.3761203441,42.365270108,42.3544378088,
+	42.3436233901,42.3328267957,42.3220479695,42.3112868559,42.3005433995,
+	42.2898175449,42.2791092374,42.2684184221,42.2577450447,42.2470890509,
+	42.2364503869,42.2258289989,42.2152248334,42.2046378373,42.1940679577,
+	42.1835151416,42.1729793368,42.1624604909,42.1519585519,42.1414734681,
+	42.1310051879,42.1205536599,42.1101188331,42.0997006567,42.08929908,
+	42.0789140527,42.0685455244,42.0581934454,42.0478577658,42.0375384362,
+	42.0272354073,42.0169486299,42.0066780553,41.9964236349,41.9861853201,
+	41.9759630629,41.9657568151,41.955566529,41.9453921571,41.935233652,
+	41.9250909665,41.9149640537,41.9048528668,41.8947573593,41.8846774848,
+	41.8746131972,41.8645644507,41.8545311993,41.8445133977,41.8345110004,
+	41.8245239623,41.8145522385,41.8045957842,41.7946545548,41.784728506,
+	41.7748175936,41.7649217736,41.7550410021,41.7451752356,41.7353244307,
+	41.725488544,41.7156675325,41.7058613534,41.696069964,41.6862933217,
+	41.6765313841,41.6667841092,41.657051455,41.6473333796,41.6376298415,
+	41.6279407991,41.6182662112,41.6086060367,41.5989602347,41.5893287644,
+	41.5797115852,41.5701086567,41.5605199386,41.5509453909,41.5413849736,
+	41.531838647,41.5223063714,41.5127881076,41.5032838162,41.493793458,
+	41.4843169943,41.4748543861,41.4654055949,41.4559705822,41.4465493097,
+	41.4371417393,41.427747833,41.4183675529,41.4090008614,41.3996477209,
+	41.3903080941,41.3809819438,41.3716692328,41.3623699242,41.3530839814,
+	41.3438113676,41.3345520464,41.3253059814,41.3160731366,41.3068534757,
+	41.2976469631,41.2884535628,41.2792732394,41.2701059573,41.2609516812,
+	41.251810376,41.2426820066,41.2335665381,41.2244639357,41.2153741649,
+	41.2062971912,41.1972329801,41.1881814975,41.1791427094,41.1701165817,
+	41.1611030807,41.1521021727,41.1431138241,41.1341380016,41.1251746718,
+	41.1162238016,41.1072853581,41.0983593082,41.0894456193,41.0805442586,
+	41.0716551938,41.0627783924,41.0539138221,41.0450614508,41.0362212466,
+	41.0273931776,41.0185772119,41.0097733179,41.0009814642,40.9922016194,
+	40.9834337521,40.9746778312,40.9659338257,40.9572017046,40.9484814373,
+	40.9397729929,40.931076341,40.9223914511,40.9137182928,40.905056836,
+	40.8964070505,40.8877689064,40.8791423738,40.8705274229,40.8619240242,
+	40.853332148,40.8447517649,40.8361828457,40.8276253611,40.8190792821,
+	40.8105445796,40.8020212248,40.7935091889,40.7850084433,40.7765189594,
+	40.7680407088,40.7595736631,40.7511177941,40.7426730737,40.7342394738,
+	40.7258169666,40.7174055242,40.7090051189,40.7006157231,40.6922373093,
+	40.68386985,40.6755133181,40.6671676862,40.6588329272,40.6505090143,
+	40.6421959203,40.6338936187,40.6256020825,40.6173212853,40.6090512004,
+	40.6007918016,40.5925430624,40.5843049567,40.5760774582,40.567860541,
+	40.5596541792,40.5514583468,40.5432730181,40.5350981675,40.5269337693,
+	40.5187797982,40.5106362286,40.5025030354,40.4943801934,40.4862676773,
+	40.4781654622,40.4700735231,40.4619918353,40.4539203738,40.4458591142,
+	40.4378080318,40.429767102,40.4217363005,40.4137156031,40.4057049853,
+	40.3977044232,40.3897138925,40.3817333695,40.37376283,40.3658022505,
+	40.357851607,40.3499108761,40.3419800341,40.3340590575,40.3261479229,
+	40.3182466072,40.3103550869,40.302473339,40.2946013404,40.2867390681,
+	40.2788864992,40.2710436109,40.2632103804,40.2553867851,40.2475728023,
+	40.2397684096,40.2319735845,40.2241883047,40.2164125479,40.2086462918,
+	40.2008895143,40.1931421935,40.1854043073,40.1776758338,40.1699567512,
+	40.1622470377,40.1545466718,40.1468556316,40.1391738959,40.131501443,
+	40.1238382516,40.1161843004,40.1085395682,40.1009040337,40.093277676,
+	40.0856604739,40.0780524066,40.0704534531,40.0628635927,40.0552828046,
+	40.0477110681,40.0401483626,40.0325946677,40.0250499628,40.0175142275,
+	40.0099874416,40.0024695847,39.9949606367,39.9874605775,39.979969387,
+	39.9724870452,39.9650135322,39.9575488282,39.9500929133,39.9426457678,
+	39.9352073722,39.9277777067,39.9203567518,39.9129444882,39.9055408964,
+	39.898145957,39.8907596508,39.8833819586,39.8760128612,39.8686523396,
+	39.8613003748,39.8539569477,39.8466220395,39.8392956313,39.8319777044,
+	39.8246682402,39.8173672198,39.8100746247,39.8027904365,39.7955146366,
+	39.7882472066,39.7809881283,39.7737373832,39.7664949532,39.75926082,
+	39.7520349657,39.7448173721,39.7376080212,39.7304068951,39.7232139759,
+	39.7160292458,39.708852687,39.7016842819,39.6945240127,39.6873718619,
+	39.6802278119,39.6730918453,39.6659639446,39.6588440925,39.6517322716,
+	39.6446284646,39.6375326544,39.6304448239,39.6233649558,39.6162930333,
+	39.6092290392,39.6021729567,39.5951247688,39.5880844588,39.5810520098,
+	39.5740274052,39.5670106282,39.5600016623,39.5530004909,39.5460070974,
+	39.5390214655,39.5320435786,39.5250734205,39.5181109748,39.5111562253,
+	39.5042091557,39.4972697499,39.4903379919,39.4834138654,39.4764973546,
+	39.4695884435,39.4626871162,39.4557933567,39.4489071494,39.4420284784,
+	39.435157328,39.4282936826,39.4214375266,39.4145888443,39.4077476203,
+	39.4009138391,39.3940874853,39.3872685434,39.3804569982,39.3736528344,
+	39.3668560367,39.36006659,39.353284479,39.3465096888,39.3397422042,
+	39.3329820103,39.3262290921,39.3194834346,39.3127450231,39.3060138426,
+	39.2992898784,39.2925731158,39.2858635401,39.2791611366,39.2724658907,
+	39.2657777879,39.2590968136,39.2524229534,39.2457561929,39.2390965176,
+	39.2324439132,39.2257983655,39.2191598602,39.212528383,39.2059039198,
+	39.1992864564,39.1926759788,39.186072473,39.1794759249,39.1728863205,
+	39.166303646,39.1597278875,39.153159031,39.1465970629,39.1400419694,
+	39.1334937368,39.1269523513,39.1204177994,39.1138900674,39.1073691419,
+	39.1008550092,39.094347656,39.0878470687,39.081353234,39.0748661385,
+	39.068385769,39.0619121121,39.0554451545,39.0489848832,39.0425312849,
+	39.0360843464,39.0296440548,39.023210397,39.0167833599,39.0103629306,
+	39.0039490962,38.9975418437,38.9911411603,38.9847470331,38.9783594495,
+	38.9719783965,38.9656038616,38.959235832,38.9528742952,38.9465192384,
+	38.9401706492,38.933828515,38.9274928232,38.9211635616,38.9148407175,
+	38.9085242787,38.9022142328,38.8959105674,38.8896132703,38.8833223293,
+	38.877037732,38.8707594665,38.8644875204,38.8582218817,38.8519625383,
+	38.8457094782,38.8394626894,38.8332221598,38.8269878777,38.8207598309,
+	38.8145380078,38.8083223964,38.802112985,38.7959097617,38.7897127148,
+	38.7835218327,38.7773371036,38.7711585159,38.7649860581,38.7588197184,
+	38.7526594855,38.7465053477,38.7403572936,38.7342153118,38.7280793908,
+	38.7219495192,38.7158256858,38.7097078791,38.7035960879,38.697490301,
+	38.691390507,38.6852966949,38.6792088534,38.6731269715,38.667051038,
+	38.6609810418
+	}}
+};
diff --git a/examples/faust-tubes/valve/12AU7.cc b/examples/faust-tubes/valve/12AU7.cc
new file mode 100644
index 0000000..e02be4d
--- /dev/null
+++ b/examples/faust-tubes/valve/12AU7.cc
@@ -0,0 +1,819 @@
+// generated by ../../tools/tube_transfer.py
+// tube: 12AU7
+// plate current function: pentode
+// mu: 21.5
+// kx: 1.3
+// kg1: 1180
+// kp: 84
+// kvb: 300
+
+table1d_imp<2001> tubetable_12AU7[2] = {
+	{ // Ri = 68k
+	-5,5,200,2001, {
+	127.202255052,127.144735521,127.087208545,127.029674135,126.972132303,
+	126.914583061,126.857026422,126.799462397,126.741890998,126.684312237,
+	126.626726127,126.569132679,126.511531906,126.45392382,126.396308434,
+	126.338685759,126.281055807,126.223418592,126.165774125,126.108122418,
+	126.050463485,125.992797338,125.935123988,125.877443449,125.819755734,
+	125.762060854,125.704358822,125.646649651,125.588933353,125.531209942,
+	125.473479429,125.415741829,125.357997152,125.300245413,125.242486624,
+	125.184720797,125.126947947,125.069168085,125.011381225,124.953587379,
+	124.895786561,124.837978784,124.780164061,124.722342404,124.664513828,
+	124.606678345,124.548835968,124.490986711,124.433130587,124.375267609,
+	124.317397791,124.259521146,124.201637688,124.143747429,124.085850383,
+	124.027946564,123.970035986,123.912118661,123.854194604,123.796263828,
+	123.738326347,123.680382175,123.622431324,123.56447381,123.506509646,
+	123.448538845,123.390561421,123.332577389,123.274586763,123.216589556,
+	123.158585782,123.100575455,123.04255859,122.984535201,122.926505301,
+	122.868468905,122.810426027,122.752376682,122.694320883,122.636258645,
+	122.578189982,122.520114909,122.46203344,122.40394559,122.345851372,
+	122.287750803,122.229643895,122.171530664,122.113411125,122.055285291,
+	121.997153178,121.939014801,121.880870174,121.822719312,121.76456223,
+	121.706398942,121.648229465,121.590053812,121.531871999,121.47368404,
+	121.415489952,121.357289748,121.299083444,121.240871056,121.182652598,
+	121.124428085,121.066197534,121.007960959,120.949718376,120.891469799,
+	120.833215245,120.77495473,120.716688268,120.658415874,120.600137566,
+	120.541853358,120.483563266,120.425267305,120.366965492,120.308657843,
+	120.250344372,120.192025096,120.133700031,120.075369193,120.017032598,
+	119.958690261,119.900342199,119.841988428,119.783628965,119.725263824,
+	119.666893023,119.608516578,119.550134505,119.49174682,119.433353539,
+	119.37495468,119.316550259,119.258140292,119.199724795,119.141303785,
+	119.08287728,119.024445295,118.966007847,118.907564953,118.84911663,
+	118.790662894,118.732203763,118.673739253,118.615269382,118.556794165,
+	118.498313621,118.439827767,118.381336619,118.322840194,118.26433851,
+	118.205831585,118.147319435,118.088802077,118.03027953,117.97175181,
+	117.913218935,117.854680922,117.796137789,117.737589554,117.679036234,
+	117.620477847,117.56191441,117.503345942,117.444772459,117.386193981,
+	117.327610524,117.269022108,117.210428748,117.151830465,117.093227275,
+	117.034619197,116.97600625,116.91738845,116.858765817,116.800138368,
+	116.741506123,116.682869099,116.624227315,116.565580789,116.50692954,
+	116.448273586,116.389612947,116.330947639,116.272277683,116.213603098,
+	116.1549239,116.096240111,116.037551747,115.97885883,115.920161376,
+	115.861459406,115.802752938,115.744041992,115.685326586,115.62660674,
+	115.567882473,115.509153805,115.450420754,115.39168334,115.332941582,
+	115.274195501,115.215445115,115.156690443,115.097931507,115.039168325,
+	114.980400916,114.921629302,114.862853501,114.804073533,114.745289419,
+	114.686501178,114.62770883,114.568912395,114.510111894,114.451307346,
+	114.392498772,114.333686192,114.274869626,114.216049094,114.157224618,
+	114.098396216,114.039563911,113.980727722,113.92188767,113.863043775,
+	113.804196059,113.745344542,113.686489244,113.627630187,113.568767392,
+	113.509900879,113.451030669,113.392156784,113.333279244,113.274398071,
+	113.215513286,113.156624909,113.097732963,113.038837469,112.979938447,
+	112.92103592,112.862129909,112.803220436,112.744307521,112.685391187,
+	112.626471456,112.567548349,112.508621887,112.449692094,112.39075899,
+	112.331822598,112.272882939,112.213940036,112.154993911,112.096044586,
+	112.037092083,111.978136425,111.919177633,111.860215731,111.801250739,
+	111.742282682,111.683311582,111.624337461,111.565360341,111.506380246,
+	111.447397198,111.38841122,111.329422335,111.270430566,111.211435936,
+	111.152438467,111.093438183,111.034435107,110.975429263,110.916420672,
+	110.857409359,110.798395347,110.73937866,110.68035932,110.621337352,
+	110.562312778,110.503285623,110.44425591,110.385223663,110.326188906,
+	110.267151662,110.208111956,110.149069811,110.090025251,110.030978301,
+	109.971928984,109.912877325,109.853823348,109.794767077,109.735708537,
+	109.676647751,109.617584745,109.558519543,109.49945217,109.440382649,
+	109.381311006,109.322237266,109.263161453,109.204083592,109.145003709,
+	109.085921827,109.026837972,108.96775217,108.908664445,108.849574822,
+	108.790483327,108.731389985,108.672294822,108.613197862,108.554099132,
+	108.494998657,108.435896462,108.376792573,108.317687016,108.258579817,
+	108.199471001,108.140360595,108.081248624,108.022135114,107.963020092,
+	107.903903583,107.844785615,107.785666212,107.726545401,107.667423209,
+	107.608299663,107.549174788,107.490048611,107.430921159,107.371792458,
+	107.312662535,107.253531418,107.194399132,107.135265705,107.076131164,
+	107.016995535,106.957858847,106.898721125,106.839582398,106.780442692,
+	106.721302034,106.662160454,106.603017976,106.54387463,106.484730443,
+	106.425585442,106.366439655,106.30729311,106.248145835,106.188997857,
+	106.129849205,106.070699906,106.011549989,105.952399482,105.893248413,
+	105.83409681,105.774944701,105.715792116,105.656639082,105.597485627,
+	105.538331781,105.479177572,105.420023029,105.360868181,105.301713056,
+	105.242557683,105.183402091,105.124246309,105.065090367,105.005934293,
+	104.946778117,104.887621867,104.828465574,104.769309266,104.710152973,
+	104.650996725,104.591840551,104.532684481,104.473528544,104.41437277,
+	104.35521719,104.296061832,104.236906727,104.177751906,104.118597397,
+	104.059443232,104.00028944,103.941136051,103.881983097,103.822830607,
+	103.763678612,103.704527143,103.64537623,103.586225903,103.527076194,
+	103.467927133,103.408778751,103.34963108,103.290484149,103.231337991,
+	103.172192635,103.113048115,103.05390446,102.994761702,102.935619872,
+	102.876479002,102.817339124,102.758200268,102.699062467,102.639925752,
+	102.580790156,102.521655709,102.462522444,102.403390393,102.344259588,
+	102.285130061,102.226001843,102.166874968,102.107749468,102.048625375,
+	101.989502721,101.930381539,101.871261862,101.812143721,101.753027151,
+	101.693912183,101.634798851,101.575687186,101.516577224,101.457468995,
+	101.398362534,101.339257873,101.280155047,101.221054087,101.161955028,
+	101.102857902,101.043762744,100.984669587,100.925578465,100.86648941,
+	100.807402458,100.748317642,100.689234995,100.630154552,100.571076347,
+	100.512000413,100.452926786,100.393855498,100.334786586,100.275720082,
+	100.216656021,100.157594438,100.098535367,100.039478843,99.9804249014,
+	99.9213735758,99.8623249014,99.8032789131,99.7442356459,99.6851951348,
+	99.626157415,99.5671225215,99.5080904897,99.4490613547,99.390035152,
+	99.3310119171,99.2719916853,99.2129744923,99.1539603737,99.0949493652,
+	99.0359415025,98.9769368215,98.9179353582,98.8589371484,98.7999422282,
+	98.7409506337,98.681962401,98.6229775665,98.5639961663,98.5050182369,
+	98.4460438148,98.3870729363,98.3281056381,98.2691419569,98.2101819292,
+	98.151225592,98.092272982,98.0333241361,97.9743790913,97.9154378847,
+	97.8565005533,97.7975671344,97.7386376651,97.6797121827,97.6207907248,
+	97.5618733286,97.5029600316,97.4440508716,97.3851458861,97.3262451127,
+	97.2673485894,97.2084563538,97.149568444,97.0906848979,97.0318057536,
+	96.972931049,96.9140608226,96.8551951123,96.7963339567,96.737477394,
+	96.6786254626,96.6197782012,96.5609356482,96.5020978424,96.4432648223,
+	96.3844366268,96.3256132947,96.2667948649,96.2079813764,96.1491728683,
+	96.0903693795,96.0315709494,95.9727776171,95.9139894219,95.8552064032,
+	95.7964286005,95.7376560531,95.6788888008,95.6201268831,95.5613703397,
+	95.5026192104,95.443873535,95.3851333534,95.3263987056,95.2676696315,
+	95.2089461714,95.1502283653,95.0915162534,95.0328098761,94.9741092737,
+	94.9154144866,94.8567255554,94.7980425205,94.7393654225,94.6806943022,
+	94.6220292003,94.5633701577,94.5047172151,94.4460704135,94.387429794,
+	94.3287953976,94.2701672655,94.2115454388,94.1529299589,94.094320867,
+	94.0357182045,93.977122013,93.918532334,93.859949209,93.8013726797,
+	93.7428027879,93.6842395753,93.6256830838,93.5671333553,93.5085904318,
+	93.4500543553,93.391525168,93.3330029121,93.2744876298,93.2159793634,
+	93.1574781553,93.098984048,93.0404970839,92.9820173057,92.923544756,
+	92.8650794774,92.8066215128,92.7481709051,92.689727697,92.6312919317,
+	92.572863652,92.5144429013,92.4560297225,92.397624159,92.3392262541,
+	92.2808360511,92.2224535935,92.1640789248,92.1057120886,92.0473531285,
+	91.9890020883,91.9306590116,91.8723239425,91.8139969247,91.7556780023,
+	91.6973672194,91.63906462,91.5807702484,91.5224841489,91.4642063657,
+	91.4059369434,91.3476759263,91.289423359,91.2311792862,91.1729437526,
+	91.1147168029,91.0564984821,90.9982888349,90.9400879065,90.8818957418,
+	90.8237123861,90.7655378846,90.7073722826,90.6492156254,90.5910679586,
+	90.5329293276,90.4747997782,90.4166793559,90.3585681067,90.3004660764,
+	90.2423733109,90.1842898562,90.1262157586,90.0681510643,90.0100958195,
+	89.9520500706,89.8940138642,89.8359872468,89.7779702652,89.719962966,
+	89.6619653962,89.6039776027,89.5459996326,89.4880315331,89.4300733515,
+	89.3721251352,89.3141869316,89.2562587884,89.1983407533,89.1404328741,
+	89.0825351988,89.0246477754,88.9667706523,88.9089038776,88.8510474998,
+	88.7932015676,88.7353661296,88.6775412346,88.6197269318,88.5619232702,
+	88.5041302991,88.446348068,88.3885766264,88.3308160242,88.2730663111,
+	88.2153275374,88.1575997532,88.099883009,88.0421773555,87.9844828434,
+	87.9267995237,87.8691274477,87.8114666667,87.7538172323,87.6961791964,
+	87.6385526111,87.5809375286,87.5233340014,87.4657420824,87.4081618245,
+	87.350593281,87.2930365055,87.2354915517,87.1779584739,87.1204373264,
+	87.062928164,87.0054310416,86.9479460146,86.8904731388,86.8330124701,
+	86.775564065,86.7181279803,86.6607042731,86.6032930011,86.545894222,
+	86.4885079945,86.4311343773,86.3737734298,86.3164252117,86.2590897832,
+	86.2017672053,86.1444575392,86.0871608467,86.0298771904,85.9726066331,
+	85.9153492385,85.858105071,85.8008741953,85.743656677,85.6864525825,
+	85.6292619788,85.5720849335,85.5149215154,85.4577717937,85.4006358386,
+	85.3435137212,85.2864055135,85.2293112884,85.1722311199,85.1151650827,
+	85.058113253,85.0010757077,84.9440525249,84.8870437842,84.830049566,
+	84.7730699521,84.7161050257,84.6591548713,84.6022195749,84.5452992237,
+	84.4883939067,84.4315037144,84.3746287389,84.317769074,84.2609248154,
+	84.2040960603,84.1472829082,84.0904854603,84.03370382,83.9769380928,
+	83.9201883863,83.8634548107,83.8067374781,83.7500365035,83.6933520043,
+	83.6366841005,83.580032915,83.5233985736,83.4667812049,83.4101809407,
+	83.3535979161,83.2970322693,83.2404841423,83.1839536804,83.1274410328,
+	83.0709463526,83.0144697967,82.9580115264,82.9015717072,82.8451505094,
+	82.7887481075,82.7323646812,82.676000415,82.619655499,82.5633301282,
+	82.5070245037,82.4507388321,82.3944733263,82.3382282053,82.2820036947,
+	82.2258000269,82.1696174413,82.1134561847,82.0573165111,82.0011986828,
+	81.9451029699,81.8890296512,81.8329790139,81.7769513547,81.7209469793,
+	81.6649662036,81.6090093531,81.5530767642,81.4971687841,81.4412857711,
+	81.3854280954,81.3295961391,81.2737902971,81.2180109771,81.1622586004,
+	81.1065336021,81.0508364319,80.9951675546,80.9395274501,80.8839166148,
+	80.8283355615,80.7727848202,80.7172649388,80.6617764836,80.60632004,
+	80.550896213,80.4955056283,80.4401489323,80.3848267936,80.3295399031,
+	80.2742889753,80.2190747483,80.1638979857,80.1087594762,80.0536600356,
+	79.9986005067,79.9435817607,79.8886046981,79.8336702492,79.7787793757,
+	79.7239330709,79.6691323614,79.6143783076,79.5596720049,79.5050145846,
+	79.4504072153,79.3958511034,79.3413474946,79.2868976751,79.232502972,
+	79.1781647554,79.1238844387,79.0696634799,79.0155033833,78.9614056998,
+	78.9073720286,78.8534040181,78.7995033671,78.745671826,78.6919111977,
+	78.6382233388,78.5846101608,78.5310736309,78.4776157733,78.4242386699,
+	78.3709444615,78.3177353487,78.2646135927,78.2115815159,78.1586415033,
+	78.1057960025,78.0530475247,78.0003986452,77.947852004,77.8954103058,
+	77.8430763209,77.7908528846,77.738742898,77.6867493276,77.6348752053,
+	77.5831236277,77.5314977563,77.4800008163,77.4286360961,77.3774069467,
+	77.3263167799,77.2753690679,77.2245673409,77.1739151864,77.1234162467,
+	77.0730742172,77.0228928441,76.9728759219,76.9230272907,76.8733508334,
+	76.8238504726,76.7745301674,76.7253939097,76.6764457203,76.6276896455,
+	76.5791297525,76.530770125,76.4826148588,76.4346680573,76.3869338259,
+	76.3394162677,76.2921194775,76.245047537,76.1982045089,76.1515944315,
+	76.1052213127,76.0590891244,76.0132017967,75.9675632117,75.9221771979,
+	75.8770475238,75.8321778926,75.787571936,75.7432332085,75.6991651814,
+	75.6553712381,75.6118546675,75.5686186599,75.5256663009,75.4830005672,
+	75.4406243218,75.3985403095,75.3567511527,75.3152593478,75.2740672612,
+	75.2331771266,75.1925910414,75.1523109648,75.1123387149,75.0726759671,
+	75.0333242522,74.9942849556,74.9555593161,74.9171484253,74.8790532275,
+	74.84127452,74.8038129532,74.7666690316,74.729843115,74.6933354196,
+	74.6571460201,74.6212748514,74.5857217107,74.5504862605,74.5155680309,
+	74.4809664224,74.4466807098,74.4127100446,74.3790534589,74.3457098694,
+	74.3126780802,74.2799567878,74.2475445842,74.2154399613,74.183641315,
+	74.1521469494,74.1209550808,74.0900638421,74.0594712869,74.0291753936,
+	73.9991740699,73.9694651566,73.940046432,73.9109156157,73.8820703727,
+	73.8535083174,73.8252270172,73.7972239966,73.7694967405,73.7420426981,
+	73.7148592861,73.6879438923,73.6612938788,73.6349065851,73.608779331,
+	73.5829094199,73.5572941414,73.5319307741,73.5068165879,73.481948847,
+	73.4573248118,73.4329417415,73.408796896,73.3848875381,73.3612109353,
+	73.337764362,73.3145451007,73.2915504439,73.2687776959,73.2462241737,
+	73.2238872088,73.2017641484,73.1798523562,73.1581492141,73.1366521227,
+	73.1153585028,73.0942657956,73.073371464,73.0526729932,73.0321678913,
+	73.01185369,72.9917279452,72.9717882373,72.9520321718,72.9324573797,
+	72.9130615179,72.8938422692,72.8747973428,72.8559244746,72.8372214272,
+	72.8186859901,72.8003159797,72.7821092396,72.7640636405,72.7461770802,
+	72.7284474836,72.7108728027,72.6934510167,72.6761801314,72.6590581798,
+	72.6420832213,72.6252533423,72.6085666551,72.5920212986,72.5756154379,
+	72.5593472636,72.5432149922,72.5272168657,72.5113511511,72.4956161407,
+	72.4800101513,72.4645315244,72.4491786254,72.433949844,72.4188435934,
+	72.4038583105,72.388992455,72.3742445097,72.3596129798,72.3450963931,
+	72.3306932992,72.3164022693,72.3022218964,72.2881507943,72.2741875978,
+	72.2603309624,72.2465795636,72.232932097,72.2193872781,72.2059438415,
+	72.192600541,72.1793561494,72.1662094579,72.1531592761,72.1402044315,
+	72.1273437694,72.1145761524,72.1019004605,72.0893155905,72.0768204558,
+	72.0644139862,72.0520951278,72.0398628423,72.0277161072,72.0156539153,
+	72.0036752745,71.9917792075,71.9799647519,71.9682309594,71.956576896,
+	71.9450016415,71.9335042896,71.9220839473,71.9107397349,71.8994707857,
+	71.888276246,71.8771552744,71.8661070421,71.8551307324,71.8442255407,
+	71.8333906741,71.8226253513,71.8119288024,71.8013002686,71.7907390024,
+	71.7802442669,71.7698153359,71.7594514938,71.7491520351,71.7389162647,
+	71.7287434971,71.718633057,71.7085842785,71.6985965052,71.6886690901,
+	71.6788013952,71.6689927918,71.6592426597,71.6495503876,71.6399153729,
+	71.6303370213,71.6208147466,71.6113479711,71.6019361248,71.592578646,
+	71.5832749802,71.574024581,71.5648269093,71.5556814334,71.5465876288,
+	71.5375449783,71.5285529715,71.5196111052,71.5107188828,71.5018758143,
+	71.4930814165,71.4843352126,71.4756367321,71.4669855107,71.4583810906,
+	71.4498230196,71.4413108518,71.432844147,71.424422471,71.416045395,
+	71.407712496,71.3994233563,71.3911775639,71.3829747119,71.3748143987,
+	71.366696228,71.3586198085,71.3505847537,71.3425906823,71.3346372179,
+	71.3267239885,71.3188506271,71.3110167714,71.3032220633,71.2954661496,
+	71.2877486811,71.2800693133,71.2724277058,71.2648235225,71.2572564313,
+	71.2497261043,71.2422322176,71.2347744514,71.2273524895,71.2199660198,
+	71.212614734,71.2052983272,71.1980164986,71.1907689508,71.18355539,
+	71.1763755258,71.1692290714,71.1621157434,71.1550352617,71.1479873495,
+	71.1409717334,71.133988143,71.1270363112,71.1201159739,71.1132268703,
+	71.1063687424,71.0995413353,71.0927443969,71.0859776782,71.0792409329,
+	71.0725339177,71.0658563918,71.0592081174,71.0525888592,71.0459983846,
+	71.0394364638,71.0329028693,71.0263973764,71.0199197628,71.0134698085,
+	71.0070472963,71.0006520112,70.9942837405,70.9879422739,70.9816274037,
+	70.9753389239,70.9690766313,70.9628403246,70.9566298047,70.9504448748,
+	70.94428534,70.9381510078,70.9320416875,70.9259571906,70.9198973305,
+	70.9138619226,70.9078507843,70.901863735,70.8959005958,70.8899611899,
+	70.8840453422,70.8781528795,70.8722836304,70.8664374253,70.8606140963,
+	70.8548134773,70.8490354038,70.8432797131,70.8375462442,70.8318348376,
+	70.8261453356,70.8204775819,70.814831422,70.8092067028,70.8036032728,
+	70.7980209821,70.7924596821,70.7869192259,70.7813994679,70.7759002642,
+	70.7704214719,70.7649629499,70.7595245583,70.7541061588,70.748707614,
+	70.7433287883,70.7379695473,70.7326297578,70.7273092879,70.722008007,
+	70.7167257859,70.7114624965,70.7062180119,70.7009922065,70.6957849559,
+	70.6905961368,70.6854256272,70.6802733061,70.6751390538,70.6700227516,
+	70.664924282,70.6598435285,70.6547803759,70.6497347097,70.6447064169,
+	70.6396953852,70.6347015035,70.6297246618,70.6247647509,70.6198216628,
+	70.6148952904,70.6099855275,70.6050922689,70.6002154106,70.5953548492,
+	70.5905104824,70.5856822089,70.580869928,70.5760735403,70.5712929469,
+	70.5665280502,70.5617787532,70.5570449596,70.5523265745,70.5476235032,
+	70.5429356523,70.5382629289,70.5336052413,70.5289624981,70.5243346092,
+	70.5197214849,70.5151230364,70.5105391758,70.5059698158,70.5014148699,
+	70.4968742524,70.4923478781,70.4878356629,70.4833375231,70.4788533759,
+	70.4743831391,70.4699267312,70.4654840714,70.4610550798,70.4566396767,
+	70.4522377835,70.447849322,70.4434742148,70.439112385,70.4347637566,
+	70.4304282539,70.426105802,70.4217963266,70.4174997541,70.4132160112,
+	70.4089450256,70.4046867254,70.4004410391,70.3962078961,70.3919872262,
+	70.3877789598,70.3835830278,70.3793993618,70.3752278939,70.3710685566,
+	70.3669212831,70.3627860071,70.3586626627,70.3545511847,70.3504515084,
+	70.3463635694,70.3422873042,70.3382226493,70.3341695421,70.3301279203,
+	70.3260977221,70.3220788863,70.3180713521,70.314075059,70.3100899473,
+	70.3061159575,70.3021530306,70.2982011081,70.2942601321,70.2903300448,
+	70.2864107891,70.2825023083,70.278604546,70.2747174464,70.270840954,
+	70.2669750137,70.263119571,70.2592745716,70.2554399617,70.2516156878,
+	70.2478016971,70.2439979368,70.2402043547,70.2364208989,70.2326475181,
+	70.2288841612,70.2251307773,70.2213873163,70.2176537281,70.2139299631,
+	70.2102159721,70.2065117062,70.2028171169,70.1991321561,70.1954567758,
+	70.1917909286,70.1881345674,70.1844876454,70.180850116,70.1772219332,
+	70.1736030512,70.1699934245,70.1663930079,70.1628017565,70.159219626,
+	70.155646572,70.1520825507,70.1485275185,70.1449814321,70.1414442485,
+	70.1379159251,70.1343964195,70.1308856895,70.1273836935,70.1238903898,
+	70.1204057374,70.1169296952,70.1134622226,70.1100032792,70.1065528249,
+	70.10311082,70.0996772248,70.0962520002,70.0928351069,70.0894265065,
+	70.0860261602,70.08263403,70.0792500778,70.0758742659,70.072506557,
+	70.0691469136,70.065795299,70.0624516764,70.0591160093,70.0557882615,
+	70.052468397,70.0491563801,70.0458521752,70.0425557471,70.0392670607,
+	70.0359860812,70.032712774,70.0294471048,70.0261890395,70.022938544,
+	70.0196955847,70.0164601282,70.0132321412,70.0100115905,70.0067984435,
+	70.0035926675,70.0003942301,69.997203099,69.9940192423,69.9908426281,
+	69.987673225,69.9845110014,69.9813559263,69.9782079686,69.9750670975,
+	69.9719332824,69.968806493,69.9656866989,69.9625738702,69.9594679771,
+	69.9563689898,69.9532768789,69.9501916152,69.9471131695,69.9440415128,
+	69.9409766166,69.9379184521,69.934866991,69.9318222051,69.9287840663,
+	69.9257525469,69.922727619,69.9197092551,69.916697428,69.9136921103,
+	69.9106932751,69.9077008955,69.9047149448,69.9017353964,69.898762224,
+	69.8957954014,69.8928349024,69.8898807013,69.8869327721,69.8839910894,
+	69.8810556276,69.8781263615,69.875203266,69.872286316,69.8693754867,
+	69.8664707534,69.8635720915,69.8606794767,69.8577928846,69.8549122911,
+	69.8520376723,69.8491690042,69.8463062633,69.843449426,69.8405984687,
+	69.8377533682,69.8349141014,69.8320806452,69.8292529768,69.8264310733,
+	69.8236149122,69.820804471,69.8179997272,69.8152006587,69.8124072433,
+	69.809619459,69.806837284,69.8040606966,69.8012896751,69.798524198,
+	69.7957642439,69.7930097917,69.7902608201,69.7875173082,69.7847792351,
+	69.7820465799,69.7793193221,69.7765974411,69.7738809164,69.7711697277,
+	69.7684638549,69.7657632778,69.7630679764,69.760377931,69.7576931216,
+	69.7550135287,69.7523391328,69.7496699143,69.747005854,69.7443469326,
+	69.741693131,69.7390444302,69.7364008113,69.7337622555,69.731128744,
+	69.7285002583,69.7258767798,69.7232582901,69.720644771,69.7180362043,
+	69.7154325717,69.7128338553,69.7102400373,69.7076510997,69.7050670248,
+	69.702487795,69.6999133929,69.6973438008,69.6947790015,69.6922189777,
+	69.6896637122,69.6871131881,69.6845673881,69.6820262956,69.6794898936,
+	69.6769581654,69.6744310945,69.6719086642,69.669390858,69.6668776597,
+	69.6643690529,69.6618650215,69.6593655492,69.65687062,69.6543802181,
+	69.6518943274,69.6494129323,69.646936017,69.6444635658,69.6419955633,
+	69.6395319939,69.6370728423,69.6346180932,69.6321677312,69.6297217413,
+	69.6272801083,69.6248428174,69.6224098534,69.6199812016,69.6175568472,
+	69.6151367755,69.6127209718,69.6103094217,69.6079021105,69.605499024,
+	69.6031001477,69.6007054674,69.5983149688,69.595928638,69.5935464607,
+	69.5911684231,69.5887945111,69.586424711,69.5840590089,69.5816973912,
+	69.5793398442,69.5769863543,69.5746369081,69.5722914919,69.5699500926,
+	69.5676126967,69.565279291,69.5629498624,69.5606243976,69.5583028837,
+	69.5559853076,69.5536716564,69.5513619173,69.5490560774,69.546754124,
+	69.5444560444,69.542161826,69.5398714561,69.5375849224,69.5353022123,
+	69.5330233135,69.5307482137,69.5284769005,69.5262093618,69.5239455854,
+	69.5216855592,69.5194292712,69.5171767094,69.5149278619,69.5126827168,
+	69.5104412624,69.5082034867,69.5059693782,69.5037389252,69.5015121161,
+	69.4992889393,69.4970693835,69.4948534371,69.4926410887,69.4904323271,
+	69.488227141,69.4860255191,69.4838274503,69.4816329235,69.4794419275,
+	69.4772544515,69.4750704843,69.4728900152,69.4707130332,69.4685395275,
+	69.4663694874,69.4642029021,69.462039761,69.4598800535,69.4577237689,
+	69.4555708968,69.4534214266,69.451275348,69.4491326506,69.446993324,
+	69.444857358,69.4427247423,69.4405954667,69.438469521,69.4363468952,
+	69.4342275792,69.4321115629,69.4299988365,69.42788939,69.4257832134,
+	69.4236802971,69.421580631,69.4194842056,69.4173910112,69.4153010379,
+	69.4132142763,69.4111307167,69.4090503496,69.4069731655,69.404899155,
+	69.4028283086,69.400760617,69.3986960708,69.3966346607,69.3945763775,
+	69.392521212,69.390469155,69.3884201974,69.3863743301,69.384331544,
+	69.3822918302,69.3802551795,69.3782215832,69.3761910323,69.374163518,
+	69.3721390314,69.3701175638,69.3680991063,69.3660836504,69.3640711872,
+	69.3620617083,69.360055205,69.3580516687,69.3560510909,69.3540534631,
+	69.3520587769,69.3500670239,69.3480781956,69.3460922837,69.34410928,
+	69.3421291761,69.3401519637,69.3381776348,69.3362061811,69.3342375944,
+	69.3322718667,69.3303089899,69.328348956,69.3263917569,69.3244373848,
+	69.3224858315,69.3205370893,69.3185911503,69.3166480066,69.3147076504,
+	69.312770074,69.3108352696,69.3089032295,69.306973946,69.3050474114,
+	69.3031236182,69.3012025588,69.2992842255,69.297368611,69.2954557076,
+	69.293545508,69.2916380046,69.2897331902,69.2878310572,69.2859315985,
+	69.2840348066,69.2821406742,69.2802491942,69.2783603593,69.2764741623,
+	69.274590596,69.2727096534,69.2708313271,69.2689556103,69.2670824959,
+	69.2652119768,69.263344046,69.2614786965,69.2596159215,69.2577557139,
+	69.255898067,69.2540429739,69.2521904276,69.2503404215,69.2484929487,
+	69.2466480025,69.2448055761,69.2429656629,69.2411282562,69.2392933493,
+	69.2374609357,69.2356310086,69.2338035617,69.2319785882,69.2301560817,
+	69.2283360358,69.2265184438,69.2247032995,69.2228905963,69.2210803279,
+	69.2192724879,69.21746707,69.2156640679,69.2138634751,69.2120652856,
+	69.210269493,69.2084760912,69.2066850738,69.2048964348,69.203110168,
+	69.2013262672,69.1995447265,69.1977655395,69.1959887005,69.1942142031,
+	69.1924420416,69.1906722099,69.1889047019,69.1871395119,69.1853766338,
+	69.1836160617,69.1818577899,69.1801018123,69.1783481232,69.1765967169,
+	69.1748475874,69.173100729,69.171356136,69.1696138026,69.1678737232,
+	69.1661358921,69.1644003035,69.162666952,69.1609358317,69.1592069373,
+	69.157480263,69.1557558033,69.1540335526,69.1523135056,69.1505956566,
+	69.1488800002,69.1471665309,69.1454552434,69.1437461321,69.1420391917,
+	69.1403344169,69.1386318022,69.1369313423,69.1352330319,69.1335368658,
+	69.1318428385,69.130150945,69.1284611799,69.126773538,69.1250880141,
+	69.1234046031,69.1217232997,69.1200440988,69.1183669953,69.1166919841,
+	69.1150190601,69.1133482182,69.1116794534,69.1100127607,69.1083481349,
+	69.1066855712,69.1050250645,69.1033666098,69.1017102023,69.100055837,
+	69.098403509,69.0967532133,69.0951049452,69.0934586997,69.0918144721,
+	69.0901722574,69.0885320509,69.0868938478,69.0852576434,69.0836234328,
+	69.0819912113,69.0803609742,69.0787327168,69.0771064344,69.0754821223,
+	69.0738597759,69.0722393905,69.0706209615,69.0690044844,69.0673899544,
+	69.065777367,69.0641667177,69.0625580019,69.0609512151,69.0593463528,
+	69.0577434105,69.0561423836,69.0545432678,69.0529460585,69.0513507514,
+	69.049757342,69.0481658259,69.0465761987,69.0449884561,69.0434025936,
+	69.041818607,69.0402364919,69.0386562439,69.0370778589,69.0355013325,
+	69.0339266603,69.0323538383,69.0307828621,69.0292137275,69.0276464302,
+	69.0260809661,69.0245173311,69.0229555208,69.0213955313,69.0198373582,
+	69.0182809975,69.0167264451,69.0151736969,69.0136227488,69.0120735967,
+	69.0105262365,69.0089806642,69.0074368758,69.0058948672,69.0043546345,
+	69.0028161736,69.0012794806,68.9997445515,68.9982113823,68.9966799691,
+	68.995150308,68.993622395,68.9920962263,68.990571798,68.9890491061,
+	68.9875281469,68.9860089165,68.984491411,68.9829756266,68.9814615595,
+	68.9799492059,68.978438562,68.976929624,68.9754223882,68.9739168508,
+	68.9724130081,68.9709108564,68.9694103919,68.9679116109,68.9664145098,
+	68.9649190848,68.9634253323,68.9619332487,68.9604428303,68.9589540734,
+	68.9574669745,68.95598153,68.9544977362,68.9530155895,68.9515350864,
+	68.9500562234,68.9485789968,68.9471034032,68.945629439,68.9441571007,
+	68.9426863847,68.9412172877,68.9397498061,68.9382839364,68.9368196752,
+	68.935357019,68.9338959644,68.932436508,68.9309786463,68.929522376,
+	68.9280676936,68.9266145957,68.9251630791,68.9237131402,68.9222647759,
+	68.9208179827,68.9193727572,68.9179290963,68.9164869965,68.9150464545,
+	68.9136074672,68.9121700311,68.9107341431,68.9092997998,68.907866998,
+	68.9064357345,68.9050060061,68.9035778095,68.9021511415,68.9007259989,
+	68.8993023786,68.8978802773,68.8964596919,68.8950406192,68.8936230561,
+	68.8922069994,68.890792446,68.8893793928,68.8879678367,68.8865577745,
+	68.8851492032,68.8837421197,68.8823365209,68.8809324038,68.8795297653,
+	68.8781286023,68.8767289119,68.8753306909,68.8739339364,68.8725386454,
+	68.8711448149,68.8697524418,68.8683615232,68.8669720562,68.8655840377,
+	68.8641974648,68.8628123346,68.8614286441,68.8600463904,68.8586655705,
+	68.8572861817,68.8559082209,68.8545316853,68.853156572,68.8517828781,
+	68.8504106007,68.8490397371,68.8476702843,68.8463022395,68.8449355998,
+	68.8435703625,68.8422065248,68.8408440837,68.8394830366,68.8381233807,
+	68.836765113,68.835408231,68.8340527318,68.8326986126,68.8313458707,
+	68.8299945034,68.8286445079,68.8272958816,68.8259486216,68.8246027253,
+	68.8232581899,68.8219150129,68.8205731915,68.8192327229,68.8178936047,
+	68.816555834,68.8152194082,68.8138843248,68.812550581,68.8112181742,
+	68.8098871018,68.8085573612,68.8072289498,68.8059018649,68.804576104,
+	68.8032516645,68.8019285438,68.8006067394,68.7992862487,68.797967069,
+	68.796649198,68.795332633,68.7940173715,68.7927034109,68.7913907488,
+	68.7900793827,68.78876931,68.7874605283,68.786153035,68.7848468276,
+	68.7835419038
+	}},
+	{ // Ri = 250k
+	-5,5,200,2001, {
+	127.202255052,127.144735521,127.087208545,127.029674135,126.972132303,
+	126.914583061,126.857026422,126.799462397,126.741890998,126.684312237,
+	126.626726127,126.569132679,126.511531906,126.45392382,126.396308434,
+	126.338685759,126.281055807,126.223418592,126.165774125,126.108122418,
+	126.050463485,125.992797338,125.935123988,125.877443449,125.819755734,
+	125.762060854,125.704358822,125.646649651,125.588933353,125.531209942,
+	125.473479429,125.415741829,125.357997152,125.300245413,125.242486624,
+	125.184720797,125.126947947,125.069168085,125.011381225,124.953587379,
+	124.895786561,124.837978784,124.780164061,124.722342404,124.664513828,
+	124.606678345,124.548835968,124.490986711,124.433130587,124.375267609,
+	124.317397791,124.259521146,124.201637688,124.143747429,124.085850383,
+	124.027946564,123.970035986,123.912118661,123.854194604,123.796263828,
+	123.738326347,123.680382175,123.622431324,123.56447381,123.506509646,
+	123.448538845,123.390561421,123.332577389,123.274586763,123.216589556,
+	123.158585782,123.100575455,123.04255859,122.984535201,122.926505301,
+	122.868468905,122.810426027,122.752376682,122.694320883,122.636258645,
+	122.578189982,122.520114909,122.46203344,122.40394559,122.345851372,
+	122.287750803,122.229643895,122.171530664,122.113411125,122.055285291,
+	121.997153178,121.939014801,121.880870174,121.822719312,121.76456223,
+	121.706398942,121.648229465,121.590053812,121.531871999,121.47368404,
+	121.415489952,121.357289748,121.299083444,121.240871056,121.182652598,
+	121.124428085,121.066197534,121.007960959,120.949718376,120.891469799,
+	120.833215245,120.77495473,120.716688268,120.658415874,120.600137566,
+	120.541853358,120.483563266,120.425267305,120.366965492,120.308657843,
+	120.250344372,120.192025096,120.133700031,120.075369193,120.017032598,
+	119.958690261,119.900342199,119.841988428,119.783628965,119.725263824,
+	119.666893023,119.608516578,119.550134505,119.49174682,119.433353539,
+	119.37495468,119.316550259,119.258140292,119.199724795,119.141303786,
+	119.08287728,119.024445295,118.966007847,118.907564953,118.84911663,
+	118.790662894,118.732203763,118.673739253,118.615269382,118.556794165,
+	118.498313621,118.439827767,118.381336619,118.322840194,118.26433851,
+	118.205831585,118.147319435,118.088802077,118.03027953,117.97175181,
+	117.913218935,117.854680922,117.796137789,117.737589554,117.679036234,
+	117.620477847,117.56191441,117.503345942,117.444772459,117.386193981,
+	117.327610524,117.269022108,117.210428748,117.151830465,117.093227275,
+	117.034619197,116.97600625,116.91738845,116.858765817,116.800138368,
+	116.741506123,116.682869099,116.624227315,116.565580789,116.50692954,
+	116.448273586,116.389612947,116.330947639,116.272277683,116.213603098,
+	116.1549239,116.096240111,116.037551747,115.97885883,115.920161376,
+	115.861459406,115.802752938,115.744041992,115.685326586,115.62660674,
+	115.567882473,115.509153805,115.450420754,115.39168334,115.332941582,
+	115.274195501,115.215445115,115.156690443,115.097931507,115.039168325,
+	114.980400916,114.921629302,114.862853501,114.804073533,114.745289419,
+	114.686501178,114.62770883,114.568912395,114.510111894,114.451307346,
+	114.392498772,114.333686192,114.274869626,114.216049094,114.157224618,
+	114.098396216,114.039563911,113.980727722,113.92188767,113.863043775,
+	113.804196059,113.745344542,113.686489244,113.627630188,113.568767392,
+	113.509900879,113.451030669,113.392156784,113.333279244,113.274398071,
+	113.215513286,113.156624909,113.097732963,113.038837469,112.979938447,
+	112.92103592,112.862129909,112.803220436,112.744307521,112.685391187,
+	112.626471456,112.567548349,112.508621888,112.449692094,112.39075899,
+	112.331822598,112.272882939,112.213940037,112.154993911,112.096044586,
+	112.037092083,111.978136425,111.919177633,111.860215731,111.80125074,
+	111.742282682,111.683311582,111.624337461,111.565360341,111.506380246,
+	111.447397198,111.38841122,111.329422336,111.270430566,111.211435936,
+	111.152438467,111.093438183,111.034435107,110.975429263,110.916420672,
+	110.857409359,110.798395347,110.73937866,110.68035932,110.621337352,
+	110.562312778,110.503285623,110.44425591,110.385223663,110.326188906,
+	110.267151662,110.208111956,110.149069811,110.090025251,110.030978301,
+	109.971928984,109.912877325,109.853823348,109.794767077,109.735708537,
+	109.676647752,109.617584746,109.558519543,109.49945217,109.440382649,
+	109.381311006,109.322237266,109.263161453,109.204083593,109.145003709,
+	109.085921827,109.026837973,108.96775217,108.908664445,108.849574822,
+	108.790483327,108.731389986,108.672294822,108.613197863,108.554099132,
+	108.494998657,108.435896462,108.376792573,108.317687016,108.258579817,
+	108.199471001,108.140360595,108.081248624,108.022135115,107.963020092,
+	107.903903584,107.844785615,107.785666212,107.726545402,107.66742321,
+	107.608299663,107.549174788,107.490048611,107.430921159,107.371792458,
+	107.312662536,107.253531418,107.194399133,107.135265706,107.076131165,
+	107.016995536,106.957858848,106.898721126,106.839582398,106.780442692,
+	106.721302035,106.662160454,106.603017977,106.543874631,106.484730444,
+	106.425585443,106.366439656,106.307293111,106.248145836,106.188997858,
+	106.129849206,106.070699908,106.011549991,105.952399484,105.893248414,
+	105.834096811,105.774944703,105.715792117,105.656639083,105.597485629,
+	105.538331783,105.479177574,105.420023031,105.360868183,105.301713058,
+	105.242557685,105.183402093,105.124246312,105.065090369,105.005934295,
+	104.946778119,104.88762187,104.828465577,104.769309269,104.710152976,
+	104.650996728,104.591840554,104.532684484,104.473528547,104.414372774,
+	104.355217194,104.296061836,104.236906732,104.17775191,104.118597402,
+	104.059443236,104.000289445,103.941136056,103.881983102,103.822830613,
+	103.763678618,103.704527149,103.645376236,103.586225909,103.527076201,
+	103.46792714,103.408778759,103.349631087,103.290484157,103.231337999,
+	103.172192644,103.113048124,103.053904469,102.994761711,102.935619882,
+	102.876479012,102.817339134,102.758200279,102.699062479,102.639925765,
+	102.580790168,102.521655722,102.462522458,102.403390407,102.344259603,
+	102.285130076,102.226001859,102.166874985,102.107749485,102.048625393,
+	101.989502739,101.930381558,101.871261882,101.812143742,101.753027172,
+	101.693912205,101.634798874,101.575687211,101.516577249,101.457469021,
+	101.398362561,101.339257902,101.280155076,101.221054117,101.161955059,
+	101.102857935,101.043762779,100.984669623,100.925578502,100.866489449,
+	100.807402498,100.748317684,100.689235038,100.630154597,100.571076394,
+	100.512000462,100.452926836,100.393855551,100.33478664,100.275720138,
+	100.21665608,100.157594499,100.098535431,100.03947891,99.9804249704,
+	99.9213736475,99.8623249759,99.8032789906,99.7442357264,99.6851952186,
+	99.626157502,99.567122612,99.5080905837,99.4490614525,99.3900352536,
+	99.3310120227,99.2719917951,99.2129746064,99.1539604923,99.0949494884,
+	99.0359416307,98.9769369548,98.9179354966,98.8589372923,98.7999423778,
+	98.7409507892,98.6819625626,98.6229777345,98.563996341,98.5050184185,
+	98.4460440035,98.3870731325,98.328105842,98.2691421688,98.2101821495,
+	98.151225821,98.09227322,98.0333243835,97.9743793485,97.915438152,
+	97.8565008311,97.7975674231,97.7386379652,97.6797124948,97.6207910491,
+	97.5618736657,97.5029603821,97.4440512358,97.3851462647,97.3262455062,
+	97.2673489984,97.208456779,97.149568886,97.0906853573,97.031806231,
+	96.9729315454,96.9140613384,96.8551956486,96.7963345141,96.7374779733,
+	96.6786260648,96.6197788271,96.5609362988,96.5020985186,96.4432655252,
+	96.3844373574,96.3256140541,96.2667956543,96.2079821969,96.1491737211,
+	96.090370266,96.0315718708,95.9727785748,95.9139904174,95.8552074379,
+	95.796429676,95.737657171,95.6788899628,95.6201280909,95.5613715951,
+	95.5026205153,95.4438748913,95.3851347632,95.3264001709,95.2676711546,
+	95.2089477545,95.1502300108,95.0915179637,95.0328116538,94.9741111215,
+	94.9154164072,94.8567275516,94.7980445954,94.7393675792,94.6806965439,
+	94.6220315304,94.5633725795,94.5047197323,94.44607303,94.3874325135,
+	94.3287982243,94.2701702035,94.2115484926,94.152933133,94.0943241661,
+	94.0357216337,93.9771255772,93.9185360386,93.8599530596,93.801376682,
+	93.7428069478,93.684243899,93.6256875779,93.5671380264,93.5085952869,
+	93.4500594017,93.3915304132,93.3330083638,93.2744932962,93.215985253,
+	93.1574842769,93.0989904107,93.0405036972,92.9820241794,92.9235519003,
+	92.8650869031,92.806629231,92.7481789271,92.689736035,92.631300598,
+	92.5728726596,92.5144522635,92.4560394534,92.397634273,92.3392367663,
+	92.2808469772,92.2224649498,92.1640907283,92.1057243567,92.0473658796,
+	91.9890153414,91.9306727865,91.8723382596,91.8140118055,91.7556934689,
+	91.6973832947,91.6390813282,91.5807876143,91.5225021983,91.4642251255,
+	91.4059564416,91.3476961919,91.2894444223,91.2312011785,91.1729665065,
+	91.1147404523,91.0565230622,90.9983143824,90.9401144593,90.8819233396,
+	90.8237410699,90.7655676971,90.7074032682,90.6492478303,90.5911014307,
+	90.5329641168,90.4748359361,90.4167169366,90.3586071659,90.3005066723,
+	90.242415504,90.1843337093,90.1262613369,90.0681984356,90.0101450544,
+	89.9521012424,89.8940670489,89.8360425236,89.7780277163,89.7200226769,
+	89.6620274557,89.6040421032,89.54606667,89.4881012072,89.4301457658,
+	89.3722003975,89.3142651538,89.2563400868,89.1984252488,89.1405206923,
+	89.0826264704,89.0247426361,88.966869243,88.9090063449,88.8511539961,
+	88.7933122511,88.7354811649,88.6776607928,88.6198511904,88.5620524139,
+	88.5042645199,88.4464875652,88.3887216073,88.3309667042,88.2732229142,
+	88.2154902961,88.1577689093,88.1000588138,88.04236007,87.9846727391,
+	87.9269968825,87.8693325627,87.8116798425,87.7540387854,87.6964094557,
+	87.6387919184,87.5811862391,87.5235924843,87.4660107213,87.408441018,
+	87.3508834435,87.2933380675,87.2358049606,87.1782841946,87.1207758422,
+	87.0632799768,87.0057966733,86.9483260074,86.8908680562,86.8334228976,
+	86.7759906111,86.7185712772,86.661164978,86.6037717966,86.5463918178,
+	86.4890251277,86.4316718142,86.3743319664,86.3170056754,86.2596930337,
+	86.2023941359,86.145109078,86.0878379584,86.0305808771,85.9733379363,
+	85.9161092405,85.8588948961,85.8016950119,85.7445096993,85.687339072,
+	85.6301832461,85.5730423407,85.5159164775,85.4588057811,85.4017103791,
+	85.3446304022,85.2875659842,85.2305172625,85.1734843777,85.1164674741,
+	85.0594666999,85.0024822069,84.945514151,84.8885626925,84.8316279957,
+	84.7747102297,84.717809568,84.6609261892,84.6040602768,84.5472120195,
+	84.4903816116,84.4335692527,84.3767751485,84.3199995108,84.2632425574,
+	84.2065045129,84.1497856085,84.0930860825,84.0364061805,83.9797461556,
+	83.9231062687,83.866486789,83.809887994,83.75331017,83.6967536122,
+	83.6402186255,83.5837055244,83.5272146335,83.470746288,83.4143008337,
+	83.3578786281,83.3014800399,83.2451054504,83.1887552531,83.1324298546,
+	83.0761296751,83.0198551485,82.9636067233,82.9073848632,82.8511900471,
+	82.79502277,82.7388835436,82.682772897,82.6266913768,82.5706395482,
+	82.5146179955,82.4586273228,82.4026681544,82.346741136,82.290846935,
+	82.2349862413,82.1791597684,82.1233682537,82.0676124596,82.0118931742,
+	81.9562112123,81.9005674161,81.844962656,81.7893978318,81.7338738734,
+	81.6783917418,81.6229524301,81.5675569644,81.5122064049,81.456901847,
+	81.4016444219,81.3464352983,81.291275683,81.2361668221,81.1811100021,
+	81.1261065514,81.0711578405,81.0162652843,80.9614303422,80.90665452,
+	80.8519393705,80.7972864951,80.7426975448,80.6881742212,80.6337182778,
+	80.579331521,80.5250158115,80.470773065,80.4166052536,80.3625144069,
+	80.3085026127,80.2545720181,80.2007248309,80.1469633197,80.0932898155,
+	80.0397067122,79.9862164673,79.9328216025,79.8795247049,79.8263284265,
+	79.7732354857,79.7202486668,79.6673708208,79.6146048653,79.5619537845,
+	79.5094206291,79.4570085162,79.4047206287,79.352560215,79.3005305881,
+	79.2486351248,79.1968772648,79.1452605095,79.0937884205,79.042464618,
+	78.9912927792,78.9402766362,78.8894199741,78.838726628,78.7882004811,
+	78.7378454614,78.6876655389,78.6376647223,78.5878470553,78.5382166134,
+	78.4887774995,78.4395338398,78.3904897799,78.3416494797,78.2930171091,
+	78.2445968429,78.1963928557,78.1484093165,78.1006503837,78.053120199,
+	78.0058228821,77.958762525,77.9119431858,77.8653688829,77.819043589,
+	77.7729712253,77.7271556551,77.6816006782,77.6363100247,77.591287349,
+	77.5465362241,77.5020601362,77.4578624787,77.4139465467,77.3703155323,
+	77.3269725192,77.2839204776,77.2411622604,77.1987005979,77.1565380947,
+	77.1146772253,77.0731203307,77.0318696155,76.990927145,76.9502948426,
+	76.909974488,76.8699677149,76.8302760101,76.7909007119,76.7518430099,
+	76.7131039444,76.6746844061,76.636585137,76.5988067306,76.5613496329,
+	76.5242141439,76.4874004191,76.4509084712,76.4147381725,76.3788892573,
+	76.3433613242,76.3081538394,76.2732661397,76.2386974356,76.2044468146,
+	76.1705132456,76.1368955816,76.1035925643,76.070602828,76.0379249031,
+	76.0055572212,75.9734981182,75.9417458394,75.9102985434,75.8791543063,
+	75.848311126,75.8177669265,75.7875195623,75.7575668221,75.7279064333,
+	75.6985360662,75.6694533373,75.6406558142,75.6121410187,75.5839064308,
+	75.5559494925,75.5282676111,75.5008581629,75.4737184964,75.4468459357,
+	75.4202377835,75.3938913241,75.3678038265,75.3419725471,75.3163947322,
+	75.291067621,75.2659884475,75.2411544433,75.2165628397,75.1922108698,
+	75.1680957703,75.1442147838,75.1205651605,75.0971441596,75.0739490514,
+	75.0509771182,75.0282256564,75.0056919772,74.9833734085,74.9612672952,
+	74.9393710013,74.9176819098,74.8961974247,74.874914971,74.8538319958,
+	74.8329459692,74.8122543847,74.7917547597,74.7714446366,74.7513215823,
+	74.7313831897,74.7116270773,74.6920508898,74.6726522985,74.6534290013,
+	74.634378723,74.6154992156,74.5967882581,74.578243657,74.5598632461,
+	74.5416448865,74.5235864667,74.5056859027,74.4879411377,74.470350142,
+	74.4529109135,74.4356214765,74.4184798829,74.4014842108,74.3846325653,
+	74.3679230776,74.3513539054,74.3349232322,74.3186292676,74.3024702466,
+	74.2864444294,74.2705501017,74.2547855738,74.2391491806,74.2236392814,
+	74.2082542598,74.1929925227,74.177852501,74.1628326486,74.1479314424,
+	74.133147382,74.1184789894,74.1039248086,74.0894834054,74.0751533673,
+	74.0609333028,74.0468218415,74.0328176334,74.0189193491,74.0051256791,
+	73.9914353336,73.9778470424,73.9643595544,73.9509716375,73.937682078,
+	73.9244896808,73.9113932687,73.8983916822,73.8854837795,73.8726684358,
+	73.8599445434,73.8473110113,73.8347667649,73.8223107457,73.8099419111,
+	73.7976592344,73.785461704,73.7733483235,73.7613181117,73.7493701016,
+	73.737503341,73.7257168917,73.7140098296,73.7023812443,73.6908302387,
+	73.6793559292,73.6679574452,73.6566339291,73.6453845356,73.6342084321,
+	73.6231047982,73.6120728253,73.6011117169,73.590220688,73.579398965,
+	73.5686457855,73.5579603984,73.547342063,73.5367900498,73.5263036396,
+	73.5158821233,73.5055248024,73.495230988,73.4850000013,73.474831173,
+	73.4647238434,73.4546773621,73.4446910879,73.4347643887,73.4248966411,
+	73.4150872306,73.4053355513,73.3956410057,73.3860030047,73.3764209671,
+	73.3668943202,73.3574224987,73.3480049456,73.3386411111,73.3293304532,
+	73.3200724372,73.3108665357,73.3017122285,73.2926090024,73.2835563511,
+	73.2745537752,73.2656007821,73.2566968855,73.2478416058,73.2390344699,
+	73.2302750107,73.2215627675,73.2128972856,73.2042781163,73.1957048168,
+	73.1871769501,73.178694085,73.1702557957,73.1618616621,73.1535112694,
+	73.1452042084,73.1369400749,73.12871847,73.1205389999,73.1124012759,
+	73.104304914,73.0962495354,73.0882347658,73.0802602359,73.0723255807,
+	73.0644304401,73.0565744583,73.0487572841,73.0409785705,73.0332379747,
+	73.0255351586,73.0178697878,73.0102415321,73.0026500655,72.9950950659,
+	72.9875762151,72.9800931987,72.9726457062,72.9652334309,72.9578560697,
+	72.950513323,72.9432048951,72.9359304935,72.9286898295,72.9214826175,
+	72.9143085755,72.9071674247,72.9000588896,72.8929826981,72.885938581,
+	72.8789262723,72.8719455093,72.8649960321,72.8580775839,72.8511899108,
+	72.844332762,72.8375058893,72.8307090475,72.8239419941,72.8172044895,
+	72.8104962966,72.8038171811,72.7971669113,72.7905452582,72.7839519951,
+	72.7773868982,72.7708497458,72.764340319,72.757858401,72.7514037776,
+	72.7449762369,72.7385755693,72.7322015676,72.7258540266,72.7195327435,
+	72.7132375179,72.7069681511,72.7007244468,72.694506211,72.6883132513,
+	72.6821453778,72.6760024024,72.6698841391,72.6637904036,72.6577210139,
+	72.6516757897,72.6456545528,72.6396571265,72.6336833363,72.6277330094,
+	72.6218059746,72.6159020628,72.6100211064,72.6041629397,72.5983273985,
+	72.5925143204,72.5867235447,72.5809549122,72.5752082655,72.5694834485,
+	72.5637803071,72.5580986883,72.5524384409,72.5467994152,72.5411814629,
+	72.5355844373,72.530008193,72.5244525861,72.5189174741,72.5134027161,
+	72.5079081723,72.5024337044,72.4969791754,72.4915444497,72.4861293931,
+	72.4807338724,72.475357756,72.4700009133,72.4646632153,72.4593445339,
+	72.4540447423,72.448763715,72.4435013277,72.4382574572,72.4330319815,
+	72.4278247797,72.4226357321,72.4174647202,72.4123116263,72.4071763341,
+	72.4020587284,72.3969586948,72.3918761201,72.3868108923,72.3817629002,
+	72.3767320336,72.3717181837,72.3667212421,72.3617411019,72.3567776569,
+	72.3518308019,72.3469004328,72.3419864461,72.3370887397,72.332207212,
+	72.3273417625,72.3224922916,72.3176587005,72.3128408914,72.3080387673,
+	72.3032522319,72.2984811901,72.2937255474,72.2889852101,72.2842600854,
+	72.2795500813,72.2748551066,72.2701750709,72.2655098845,72.2608594586,
+	72.2562237051,72.2516025367,72.2469958667,72.2424036093,72.2378256794,
+	72.2332619927,72.2287124653,72.2241770145,72.2196555578,72.2151480137,
+	72.2106543013,72.2061743404,72.2017080515,72.1972553556,72.1928161746,
+	72.1883904309,72.1839780475,72.1795789482,72.1751930572,72.1708202995,
+	72.1664606008,72.1621138871,72.1577800852,72.1534591226,72.1491509271,
+	72.1448554274,72.1405725526,72.1363022322,72.1320443967,72.1277989769,
+	72.123565904,72.1193451101,72.1151365275,72.1109400894,72.1067557292,
+	72.1025833809,72.0984229793,72.0942744593,72.0901377566,72.0860128072,
+	72.0818995479,72.0777979156,72.073707848,72.0696292831,72.0655621596,
+	72.0615064164,72.0574619931,72.0534288296,72.0494068663,72.0453960442,
+	72.0413963045,72.0374075891,72.0334298402,72.0294630004,72.0255070128,
+	72.0215618211,72.017627369,72.0137036011,72.009790462,72.0058878971,
+	72.0019958519,71.9981142724,71.9942431051,71.9903822968,71.9865317947,
+	71.9826915465,71.9788615,71.9750416037,71.9712318063,71.967432057,
+	71.9636423053,71.959862501,71.9560925943,71.9523325359,71.9485822768,
+	71.9448417681,71.9411109616,71.9373898094,71.9336782636,71.9299762771,
+	71.9262838028,71.9226007941,71.9189272048,71.9152629889,71.9116081006,
+	71.9079624947,71.9043261262,71.9006989504,71.8970809229,71.8934719996,
+	71.8898721369,71.8862812912,71.8826994194,71.8791264786,71.8755624264,
+	71.8720072205,71.8684608189,71.8649231799,71.8613942621,71.8578740245,
+	71.8543624263,71.8508594268,71.8473649859,71.8438790635,71.8404016199,
+	71.8369326157,71.8334720117,71.8300197691,71.826575849,71.8231402132,
+	71.8197128235,71.816293642,71.8128826312,71.8094797536,71.806084972,
+	71.8026982497,71.79931955,71.7959488366,71.7925860731,71.7892312238,
+	71.785884253,71.7825451252,71.7792138052,71.775890258,71.7725744489,
+	71.7692663434,71.7659659071,71.762673106,71.7593879063,71.7561102742,
+	71.7528401764,71.7495775796,71.746322451,71.7430747576,71.7398344669,
+	71.7366015466,71.7333759644,71.7301576886,71.7269466872,71.7237429288,
+	71.7205463819,71.7173570156,71.7141747987,71.7109997006,71.7078316906,
+	71.7046707384,71.7015168139,71.698369887,71.6952299278,71.6920969069,
+	71.6889707947,71.685851562,71.6827391798,71.679633619,71.676534851,
+	71.6734428473,71.6703575795,71.6672790193,71.6642071389,71.6611419102,
+	71.6580833057,71.6550312978,71.6519858592,71.6489469627,71.6459145813,
+	71.6428886881,71.6398692565,71.6368562598,71.6338496718,71.6308494663,
+	71.6278556171,71.6248680983,71.6218868843,71.6189119494,71.6159432682,
+	71.6129808154,71.6100245659,71.6070744946,71.6041305767,71.6011927875,
+	71.5982611025,71.5953354972,71.5924159474,71.589502429,71.5865949179,
+	71.5836933903,71.5807978225,71.577908191,71.5750244723,71.5721466431,
+	71.5692746802,71.5664085606,71.5635482615,71.56069376,71.5578450334,
+	71.5550020594,71.5521648155,71.5493332795,71.5465074292,71.5436872426,
+	71.5408726979,71.5380637733,71.5352604472,71.532462698,71.5296705045,
+	71.5268838452,71.5241026992,71.5213270452,71.5185568625,71.5157921303,
+	71.5130328278,71.5102789345,71.5075304299,71.5047872938,71.5020495058,
+	71.4993170459,71.4965898941,71.4938680305,71.4911514352,71.4884400887,
+	71.4857339713,71.4830330636,71.4803373463,71.4776468,71.4749614057,
+	71.4722811443,71.4696059969,71.4669359446,71.4642709687,71.4616110506,
+	71.4589561717,71.4563063136,71.453661458,71.4510215867,71.4483866814,
+	71.4457567242,71.4431316972,71.4405115824,71.4378963621,71.4352860186,
+	71.4326805345,71.4300798922,71.4274840743,71.4248930635,71.4223068427,
+	71.4197253947,71.4171487025,71.4145767492,71.412009518,71.409446992,
+	71.4068891546,71.4043359893,71.4017874795,71.3992436089,71.3967043611,
+	71.3941697198,71.3916396689,71.3891141924,71.3865932742,71.3840768985,
+	71.3815650494,71.3790577112,71.3765548681,71.3740565047,71.3715626054,
+	71.3690731547,71.3665881374,71.3641075382,71.3616313418,71.3591595332,
+	71.3566920973,71.3542290191,71.3517702838,71.3493158765,71.3468657825,
+	71.3444199871,71.3419784758,71.3395412339,71.3371082471,71.334679501,
+	71.3322549813,71.3298346737,71.3274185641,71.3250066384,71.3225988825,
+	71.3201952826,71.3177958246,71.3154004948,71.3130092795,71.3106221649,
+	71.3082391374,71.3058601835,71.3034852898,71.3011144427,71.2987476289,
+	71.2963848352,71.2940260482,71.2916712549,71.2893204422,71.286973597,
+	71.2846307063,71.2822917573,71.279956737,71.2776256327,71.2752984317,
+	71.2729751214,71.270655689,71.2683401221,71.2660284081,71.2637205347,
+	71.2614164895,71.2591162602,71.2568198345,71.2545272002,71.2522383453,
+	71.2499532575,71.247671925,71.2453943357,71.2431204777,71.2408503393,
+	71.2385839085,71.2363211736,71.234062123,71.2318067451,71.2295550282,
+	71.2273069608,71.2250625314,71.2228217287,71.2205845412,71.2183509577,
+	71.2161209669,71.2138945576,71.2116717186,71.2094524388,71.2072367071,
+	71.2050245127,71.2028158444,71.2006106914,71.1984090428,71.1962108879,
+	71.1940162159,71.191825016,71.1896372776,71.1874529901,71.1852721429,
+	71.1830947256,71.1809207276,71.1787501385,71.176582948,71.1744191456,
+	71.1722587212,71.1701016646,71.1679479654,71.1657976135,71.163650599,
+	71.1615069116,71.1593665414,71.1572294785,71.1550957128,71.1529652346,
+	71.1508380339,71.1487141011,71.1465934263,71.1444759999,71.1423618121,
+	71.1402508534,71.1381431141,71.1360385848,71.133937256,71.1318391181,
+	71.1297441618,71.1276523777,71.1255637565,71.1234782889,71.1213959656,
+	71.1193167774,71.1172407152,71.1151677698,71.1130979321,71.1110311931,
+	71.1089675437,71.106906975,71.1048494781,71.102795044,71.1007436639,
+	71.098695329,71.0966500304,71.0946077595,71.0925685075,71.0905322657,
+	71.0884990255,71.0864687783,71.0844415156,71.0824172287,71.0803959093,
+	71.0783775489,71.0763621389,71.0743496712,71.0723401372,71.0703335287,
+	71.0683298374,71.066329055,71.0643311734,71.0623361844,71.0603440798,
+	71.0583548515,71.0563684914,71.0543849915,71.0524043438,71.0504265403,
+	71.048451573,71.0464794341,71.0445101156,71.0425436098,71.0405799088,
+	71.0386190048,71.03666089,71.0347055568,71.0327529975,71.0308032044,
+	71.0288561699,71.0269118863,71.0249703462,71.023031542,71.0210954661,
+	71.0191621112,71.0172314698,71.0153035344,71.0133782977,71.0114557523,
+	71.009535891,71.0076187064,71.0057041912,71.0037923382,71.0018831403,
+	70.9999765902,70.9980726807,70.9961714049,70.9942727555,70.9923767255,
+	70.9904833079,70.9885924957,70.9867042819,70.9848186595,70.9829356216,
+	70.9810551613,70.9791772718,70.9773019462,70.9754291776,70.9735589594,
+	70.9716912847,70.9698261468,70.9679635389,70.9661034545,70.9642458868,
+	70.9623908292,70.9605382751,70.958688218,70.9568406512,70.9549955682,
+	70.9531529626,70.9513128279,70.9494751575,70.9476399451,70.9458071843,
+	70.9439768687,70.9421489919,70.9403235476,70.9385005294,70.9366799312,
+	70.9348617467,70.9330459695,70.9312325936,70.9294216127,70.9276130206,
+	70.9258068113,70.9240029785,70.9222015163,70.9204024184,70.918605679,
+	70.9168112919,70.9150192512,70.9132295508,70.9114421849,70.9096571474,
+	70.9078744325,70.9060940343,70.904315947,70.9025401645,70.9007666812,
+	70.8989954913,70.8972265889,70.8954599683,70.8936956238,70.8919335496,
+	70.89017374,70.8884161894,70.8866608922,70.8849078426,70.8831570351,
+	70.8814084641,70.879662124,70.8779180092,70.8761761143,70.8744364337,
+	70.8726989619,70.8709636935,70.869230623,70.867499745,70.865771054,
+	70.8640445448,70.8623202118,70.8605980499,70.8588780535,70.8571602175,
+	70.8554445365,70.8537310053,70.8520196185,70.850310371,70.8486032576,
+	70.846898273,70.8451954121,70.8434946697,70.8417960407,70.8400995199,
+	70.8384051023,70.8367127827,70.8350225561,70.8333344174,70.8316483616,
+	70.8299643837,70.8282824787,70.8266026417,70.8249248675,70.8232491514,
+	70.8215754884,70.8199038735,70.8182343019,70.8165667687,70.8149012691,
+	70.8132377981,70.8115763511,70.8099169231,70.8082595094,70.8066041053,
+	70.8049507059,70.8032993065,70.8016499024,70.8000024889,70.7983570614,
+	70.796713615,70.7950721452,70.7934326474,70.7917951169,70.7901595491,
+	70.7885259394,70.7868942832,70.785264576,70.7836368132,70.7820109903,
+	70.7803871028,70.7787651462,70.777145116,70.7755270077,70.7739108169,
+	70.7722965391,70.77068417,70.769073705,70.7674651399,70.7658584703,
+	70.7642536917,70.7626507999,70.7610497905,70.7594506591,70.7578534016,
+	70.7562580136,70.7546644907,70.7530728289,70.7514830237,70.7498950711,
+	70.7483089667,70.7467247064,70.745142286,70.7435617013,70.7419829481,
+	70.7404060224,70.7388309199,70.7372576365,70.7356861682,70.7341165109,
+	70.7325486605,70.7309826128,70.729418364,70.7278559098,70.7262952464,
+	70.7247363697,70.7231792756,70.7216239603,70.7200704198,70.71851865,
+	70.716968647,70.715420407,70.713873926,70.7123292001,70.7107862253,
+	70.7092449979,70.707705514,70.7061677696,70.704631761,70.7030974843,
+	70.7015649357,70.7000341115,70.6985050077,70.6969776207,70.6954519467,
+	70.6939279818,70.6924057225,70.6908851648,70.6893663052,70.68784914,
+	70.6863336653,70.6848198776,70.6833077731,70.6817973482,70.6802885993,
+	70.6787815228,70.6772761149,70.6757723721,70.6742702908,70.6727698674,
+	70.6712710983,70.66977398,70.6682785089,70.6667846814,70.6652924941,
+	70.6638019434,70.6623130257,70.6608257377,70.6593400758,70.6578560365,
+	70.6563736163,70.6548928119,70.6534136197,70.6519360364,70.6504600585,
+	70.6489856826,70.6475129053,70.6460417232,70.6445721329,70.6431041311,
+	70.6416377145,70.6401728795,70.638709623,70.6372479416,70.635787832,
+	70.6343292908,70.6328723148,70.6314169007,70.6299630452,70.6285107451,
+	70.6270599971,70.6256107979,70.6241631443,70.6227170332,70.6212724612,
+	70.6198294252,70.618387922,70.6169479483,70.6155095011,70.6140725771,
+	70.6126371732,70.6112032863,70.6097709132,70.6083400508,70.6069106959,
+	70.6054828456,70.6040564965,70.6026316458,70.6012082902,70.5997864268,
+	70.5983660524,70.5969471641,70.5955297587,70.5941138333,70.5926993847,
+	70.5912864101,70.5898749064,70.5884648705,70.5870562996,70.5856491906,
+	70.5842435406,70.5828393466,70.5814366056,70.5800353147,70.578635471,
+	70.5772370716,70.5758401135,70.5744445938,70.5730505096,70.5716578581,
+	70.5702666363,70.5688768414,70.5674884705,70.5661015208,70.5647159894,
+	70.5633318734,70.5619491701,70.5605678767,70.5591879902,70.5578095079,
+	70.5564324271,70.5550567448,70.5536824584,70.552309565,70.550938062,
+	70.5495679464,70.5481992157,70.546831867,70.5454658977,70.5441013049,
+	70.542738086,70.5413762383,70.5400157591,70.5386566456,70.5372988952,
+	70.5359425053,70.534587473,70.5332337959,70.5318814712,70.5305304963,
+	70.5291808686,70.5278325853,70.526485644,70.5251400419,70.5237957765,
+	70.5224528452,70.5211112453,70.5197709744,70.5184320297,70.5170944088,
+	70.5157581091,70.514423128,70.513089463,70.5117571115,70.510426071,
+	70.5090963391,70.507767913,70.5064407904,70.5051149688,70.5037904455,
+	70.5024672183,70.5011452845,70.4998246417,70.4985052874,70.4971872192,
+	70.4958704345,70.494554931,70.4932407063,70.4919277578,70.4906160832,
+	70.48930568,70.4879965458,70.4866886782,70.4853820748,70.4840767332,
+	70.4827726511,70.481469826,70.4801682555,70.4788679374,70.4775688692,
+	70.4762710486,70.4749744732,70.4736791407,70.4723850488,70.4710921952,
+	70.4698005774,70.4685101933,70.4672210404,70.4659331165,70.4646464193,
+	70.4633609466
+	}}
+};
diff --git a/examples/faust-tubes/valve/12ax7.cc b/examples/faust-tubes/valve/12ax7.cc
new file mode 100644
index 0000000..ac1b0c1
--- /dev/null
+++ b/examples/faust-tubes/valve/12ax7.cc
@@ -0,0 +1,819 @@
+// generated by ../../tools/tube_transfer.py
+// tube: 12AX7
+// plate current function: triode
+// mu: 100
+// kx: 1.4
+// kg1: 1060
+// kp: 600
+// kvb: 300
+
+table1d_imp<2001> tubetable_12AX7[2] = {
+	{ // Ri = 68k
+	-5,5,200,2001, {
+	249.98706929,249.986851225,249.986629489,249.986404021,249.986174757,
+	249.985941635,249.985704589,249.985463554,249.985218463,249.984969247,
+	249.984715838,249.984458166,249.984196158,249.983929743,249.983658846,
+	249.983383392,249.983103306,249.982818508,249.982528921,249.982234464,
+	249.981935056,249.981630613,249.981321052,249.981006287,249.98068623,
+	249.980360793,249.980029887,249.979693419,249.979351296,249.979003424,
+	249.978649708,249.978290048,249.977924346,249.9775525,249.977174409,
+	249.976789967,249.976399069,249.976001606,249.97559747,249.975186548,
+	249.974768727,249.974343893,249.973911927,249.973472711,249.973026125,
+	249.972572044,249.972110345,249.9716409,249.971163579,249.970678252,
+	249.970184785,249.969683043,249.969172887,249.968654177,249.968126772,
+	249.967590526,249.967045292,249.96649092,249.965927258,249.965354153,
+	249.964771446,249.964178978,249.963576587,249.962964107,249.962341372,
+	249.961708211,249.96106445,249.960409914,249.959744424,249.959067797,
+	249.95837985,249.957680393,249.956969237,249.956246188,249.955511048,
+	249.954763616,249.95400369,249.953231063,249.952445523,249.951646857,
+	249.950834849,249.950009276,249.949169916,249.94831654,249.947448916,
+	249.946566809,249.945669979,249.944758184,249.943831177,249.942888706,
+	249.941930516,249.940956349,249.93996594,249.938959023,249.937935324,
+	249.936894568,249.935836475,249.934760758,249.933667127,249.932555289,
+	249.931424944,249.930275788,249.929107511,249.9279198,249.926712337,
+	249.925484796,249.92423685,249.922968162,249.921678394,249.9203672,
+	249.91903423,249.917679127,249.916301529,249.914901069,249.913477372,
+	249.912030061,249.910558748,249.909063042,249.907542547,249.905996856,
+	249.904425561,249.902828244,249.901204482,249.899553844,249.897875894,
+	249.896170188,249.894436274,249.892673696,249.890881989,249.889060679,
+	249.887209288,249.885327328,249.883414305,249.881469716,249.879493052,
+	249.877483793,249.875441414,249.87336538,249.87125515,249.869110171,
+	249.866929885,249.864713724,249.86246111,249.860171458,249.857844173,
+	249.855478652,249.853074281,249.850630438,249.848146491,249.845621799,
+	249.843055711,249.840447565,249.837796689,249.835102404,249.832364016,
+	249.829580824,249.826752115,249.823877166,249.820955243,249.8179856,
+	249.81496748,249.811900117,249.80878273,249.80561453,249.802394713,
+	249.799122465,249.795796959,249.792417358,249.788982809,249.785492449,
+	249.781945403,249.778340779,249.774677678,249.770955183,249.767172365,
+	249.763328284,249.759421981,249.75545249,249.751418824,249.747319988,
+	249.743154968,249.738922738,249.734622257,249.730252468,249.725812301,
+	249.72130067,249.716716471,249.712058589,249.70732589,249.702517225,
+	249.697631429,249.692667321,249.687623703,249.682499361,249.677293063,
+	249.672003562,249.666629592,249.661169871,249.655623098,249.649987954,
+	249.644263106,249.638447197,249.632538857,249.626536694,249.620439299,
+	249.614245244,249.607953082,249.601561346,249.59506855,249.588473189,
+	249.581773739,249.574968653,249.568056367,249.561035295,249.553903831,
+	249.546660348,249.5393032,249.531830718,249.524241211,249.516532969,
+	249.508704259,249.500753327,249.492678397,249.48447767,249.476149326,
+	249.467691521,249.459102391,249.450380046,249.441522576,249.432528047,
+	249.423394501,249.414119957,249.404702411,249.395139834,249.385430176,
+	249.37557136,249.365561287,249.355397831,249.345078845,249.334602156,
+	249.323965565,249.313166851,249.302203767,249.291074039,249.27977537,
+	249.268305439,249.256661896,249.244842368,249.232844458,249.220665739,
+	249.208303762,249.195756051,249.183020104,249.170093394,249.156973366,
+	249.143657441,249.130143014,249.116427453,249.102508098,249.088382267,
+	249.074047249,249.059500307,249.044738677,249.029759572,249.014560175,
+	248.999137645,248.983489114,248.967611688,248.951502446,248.935158442,
+	248.918576704,248.901754233,248.884688005,248.867374969,248.84981205,
+	248.831996145,248.813924127,248.795592843,248.776999115,248.75813974,
+	248.739011488,248.719611106,248.699935316,248.679980814,248.659744274,
+	248.639222342,248.618411645,248.597308781,248.575910327,248.554212837,
+	248.532212841,248.509906845,248.487291335,248.464362771,248.441117595,
+	248.417552224,248.393663055,248.369446462,248.344898801,248.320016406,
+	248.29479559,248.269232647,248.243323852,248.217065459,248.190453706,
+	248.163484811,248.136154974,248.108460379,248.080397191,248.05196156,
+	248.02314962,247.993957487,247.964381265,247.934417041,247.904060889,
+	247.87330887,247.84215703,247.810601403,247.778638011,247.746262866,
+	247.713471967,247.680261303,247.646626855,247.612564592,247.578070476,
+	247.543140461,247.507770494,247.471956513,247.435694453,247.398980241,
+	247.3618098,247.32417905,247.286083906,247.247520279,247.208484082,
+	247.168971222,247.128977607,247.088499146,247.047531747,247.00607132,
+	246.964113777,246.921655031,246.878691002,246.835217611,246.791230785,
+	246.746726457,246.701700566,246.656149058,246.610067887,246.563453015,
+	246.516300414,246.468606066,246.420365964,246.371576111,246.322232524,
+	246.272331232,246.221868279,246.170839722,246.119241634,246.067070104,
+	246.014321237,245.960991157,245.907076004,245.852571939,245.79747514,
+	245.74178181,245.685488167,245.628590455,245.571084939,245.512967907,
+	245.454235672,245.394884569,245.334910961,245.274311236,245.213081807,
+	245.151219115,245.08871963,245.02557985,244.9617963,244.897365536,
+	244.832284146,244.766548747,244.700155987,244.633102547,244.565385141,
+	244.497000515,244.427945449,244.358216758,244.287811291,244.216725932,
+	244.144957602,244.072503257,243.999359889,243.92552453,243.850994248,
+	243.775766147,243.699837372,243.623205106,243.545866572,243.467819032,
+	243.389059786,243.309586179,243.229395592,243.148485449,243.066853216,
+	242.984496398,242.901412546,242.817599248,242.733054138,242.647774892,
+	242.561759227,242.475004906,242.387509732,242.299271553,242.210288262,
+	242.120557793,242.030078124,241.938847279,241.846863324,241.754124371,
+	241.660628575,241.566374134,241.471359294,241.375582341,241.279041608,
+	241.181735472,241.083662355,240.984820721,240.885209081,240.784825989,
+	240.683670043,240.581739885,240.479034203,240.375551726,240.271291229,
+	240.166251531,240.060431493,239.95383002,239.846446061,239.738278607,
+	239.629326695,239.5195894,239.409065844,239.29775519,239.185656641,
+	239.072769446,238.959092892,238.84462631,238.729369072,238.61332059,
+	238.496480317,238.378847747,238.260422414,238.141203892,238.021191795,
+	237.900385775,237.778785524,237.656390773,237.533201291,237.409216884,
+	237.284437398,237.158862715,237.032492753,236.905327469,236.777366855,
+	236.648610938,236.519059783,236.388713489,236.257572188,236.125636051,
+	235.992905278,235.859380107,235.725060807,235.58994768,235.454041062,
+	235.31734132,235.179848852,235.041564089,234.902487493,234.762619556,
+	234.6219608,234.480511776,234.338273067,234.195245283,234.051429062,
+	233.906825072,233.761434008,233.615256591,233.468293572,233.320545726,
+	233.172013855,233.022698786,232.872601372,232.721722492,232.570063047,
+	232.417623965,232.264406196,232.110410713,231.955638512,231.800090614,
+	231.643768059,231.48667191,231.328803251,231.170163188,231.010752847,
+	230.850573373,230.689625933,230.527911712,230.365431915,230.202187764,
+	230.0381805,229.873411384,229.707881693,229.541592719,229.374545774,
+	229.206742186,229.038183299,228.868870471,228.698805078,228.527988509,
+	228.356422169,228.184107477,228.011045867,227.837238785,227.662687692,
+	227.487394061,227.311359378,227.134585141,226.957072863,226.778824064,
+	226.59984028,226.420123056,226.239673947,226.058494521,225.876586355,
+	225.693951036,225.510590161,225.326505336,225.141698178,224.956170309,
+	224.769923365,224.582958985,224.39527882,224.206884527,224.017777772,
+	223.827960226,223.637433569,223.446199487,223.254259674,223.061615828,
+	222.868269655,222.674222866,222.479477179,222.284034315,222.087896002,
+	221.891063973,221.693539966,221.495325721,221.296422987,221.096833513,
+	220.896559053,220.695601367,220.493962216,220.291643365,220.088646583,
+	219.884973642,219.680626315,219.475606381,219.269915618,219.063555809,
+	218.856528737,218.64883619,218.440479954,218.231461819,218.021783577,
+	217.811447019,217.600453941,217.388806137,217.176505402,216.963553533,
+	216.749952328,216.535703584,216.3208091,216.105270675,215.889090106,
+	215.672269193,215.454809735,215.23671353,215.017982376,214.798618071,
+	214.578622412,214.357997196,214.136744219,213.914865275,213.692362159,
+	213.469236664,213.245490582,213.021125704,212.796143819,212.570546714,
+	212.344336178,212.117513994,211.890081946,211.662041815,211.433395383,
+	211.204144425,210.97429072,210.74383604,210.512782158,210.281130844,
+	210.048883865,209.816042987,209.582609974,209.348586585,209.113974579,
+	208.878775712,208.642991738,208.406624407,208.169675468,207.932146665,
+	207.694039743,207.455356441,207.216098496,206.976267643,206.735865613,
+	206.494894135,206.253354936,206.011249738,205.76858026,205.52534822,
+	205.281555332,205.037203306,204.792293851,204.54682867,204.300809466,
+	204.054237936,203.807115776,203.559444679,203.311226332,203.062462422,
+	202.813154631,202.563304638,202.312914121,202.06198475,201.810518197,
+	201.558516128,201.305980206,201.05291209,200.799313438,200.545185904,
+	200.290531137,200.035350786,199.779646493,199.5234199,199.266672645,
+	199.009406363,198.751622683,198.493323236,198.234509646,197.975183536,
+	197.715346523,197.455000226,197.194146256,196.932786223,196.670921736,
+	196.408554398,196.145685811,195.882317572,195.618451279,195.354088524,
+	195.089230896,194.823879985,194.558037374,194.291704646,194.024883381,
+	193.757575156,193.489781546,193.221504124,192.952744459,192.68350412,
+	192.413784672,192.143587679,191.872914702,191.601767301,191.330147033,
+	191.058055454,190.785494118,190.512464577,190.238968382,189.965007082,
+	189.690582224,189.415695355,189.14034802,188.864541763,188.588278126,
+	188.311558653,188.034384883,187.756758358,187.478680617,187.200153199,
+	186.921177645,186.641755492,186.36188828,186.081577548,185.800824834,
+	185.519631679,185.237999622,184.955930205,184.673424969,184.390485457,
+	184.107113213,183.823309782,183.539076713,183.254415552,182.969327853,
+	182.683815168,182.397879052,182.111521065,181.824742767,181.537545724,
+	181.249931504,180.961901678,180.673457823,180.384601519,180.095334351,
+	179.805657909,179.515573788,179.225083588,178.934188917,178.642891387,
+	178.351192617,178.059094236,177.766597877,177.473705181,177.1804178,
+	176.886737393,176.592665628,176.298204182,176.003354745,175.708119016,
+	175.412498704,175.116495531,174.820111234,174.523347558,174.226206264,
+	173.92868913,173.630797944,173.332534512,173.033900658,172.734898219,
+	172.435529055,172.13579504,171.835698069,171.53524006,171.234422948,
+	170.933248694,170.631719279,170.32983671,170.027603019,169.725020263,
+	169.422090529,169.118815931,168.815198611,168.511240746,168.206944541,
+	167.902312237,167.597346111,167.292048474,166.986421676,166.680468107,
+	166.374190197,166.06759042,165.760671293,165.453435381,165.145885296,
+	164.8380237,164.529853307,164.221376886,163.912597261,163.603517315,
+	163.294139991,162.984468296,162.674505303,162.36425415,162.05371805,
+	161.742900285,161.431804217,161.120433284,160.808791007,160.496880994,
+	160.184706939,159.872272629,159.559581944,159.246638866,158.933447477,
+	158.620011964,158.306336627,157.992425878,157.678284247,157.363916386,
+	157.049327076,156.734521226,156.419503883,156.104280235,155.788855613,
+	155.473235502,155.15742554,154.841431529,154.525259436,154.2089154,
+	153.89240574,153.575736958,153.258915746,152.941948993,152.624843791,
+	152.307607442,151.990247462,151.672771591,151.3551878,151.037504296,
+	150.719729528,150.4018722,150.083941272,149.765945972,149.4478958,
+	149.129800541,148.811670267,148.493515348,148.17534646,147.857174591,
+	147.539011052,147.220867482,146.90275586,146.584688509,146.266678104,
+	145.948737684,145.630880657,145.313120806,144.995472301,144.677949704,
+	144.360567975,144.043342481,143.726289002,143.409423738,143.092763314,
+	142.776324787,142.46012565,142.144183838,141.828517734,141.513146167,
+	141.198088421,140.883364237,140.56899381,140.254997798,139.941397314,
+	139.628213931,139.31546968,139.003187046,138.691388964,138.380098818,
+	138.069340432,137.759138065,137.449516402,137.140500548,136.832116012,
+	136.524388701,136.217344903,135.911011273,135.605414819,135.300582882,
+	134.99654312,134.693323486,134.390952204,134.089457749,133.788868823,
+	133.489214324,133.190523322,132.89282503,132.596148773,132.300523955,
+	132.005980028,131.712546456,131.420252683,131.129128093,130.839201977,
+	130.550503492,130.263061625,129.97690515,129.692062595,129.408562198,
+	129.126431866,128.845699141,128.566391153,128.288534586,128.012155639,
+	127.737279983,127.463932729,127.19213839,126.921920841,126.653303293,
+	126.386308253,126.120957494,125.857272028,125.595272075,125.334977038,
+	125.076405477,124.819575089,124.564502686,124.311204176,124.059694549,
+	123.809987864,123.562097233,123.316034816,123.071811813,122.829438459,
+	122.588924021,122.3502768,122.113504129,121.878612383,121.645606978,
+	121.414492385,121.185272137,120.957948844,120.732524201,120.508999009,
+	120.287373188,120.067645798,119.849815055,119.633878355,119.419832294,
+	119.207672691,118.997394612,118.788992394,118.582459671,118.377789395,
+	118.174973871,117.974004772,117.774873176,117.577569586,117.382083958,
+	117.188405731,116.996523847,116.806426787,116.618102586,116.431538869,
+	116.246722869,116.063641457,115.882281163,115.702628206,115.524668508,
+	115.348387726,115.173771271,115.000804328,114.82947188,114.659758727,
+	114.491649506,114.325128711,114.160180708,113.996789759,113.834940032,
+	113.674615621,113.515800563,113.358478849,113.20263444,113.048251282,
+	112.895313317,112.743804495,112.593708787,112.445010196,112.297692766,
+	112.151740591,112.007137828,111.863868702,111.721917517,111.581268659,
+	111.441906608,111.303815943,111.166981347,111.031387613,110.897019652,
+	110.763862493,110.63190129,110.501121329,110.371508026,110.243046933,
+	110.115723745,109.989524294,109.864434561,109.740440669,109.617528892,
+	109.495685656,109.374897534,109.255151254,109.1364337,109.018731905,
+	108.902033061,108.786324515,108.671593767,108.557828476,108.445016453,
+	108.333145667,108.222204241,108.112180452,108.003062732,107.894839664,
+	107.787499986,107.681032587,107.575426505,107.470670928,107.366755194,
+	107.263668787,107.161401337,107.059942619,106.959282552,106.859411195,
+	106.760318751,106.661995559,106.564432098,106.467618982,106.37154696,
+	106.276206914,106.181589858,106.087686935,105.994489418,105.901988705,
+	105.81017632,105.719043911,105.628583246,105.538786217,105.44964483,
+	105.361151211,105.273297602,105.186076356,105.09947994,105.013500931,
+	104.928132016,104.843365988,104.759195746,104.675614294,104.592614738,
+	104.510190286,104.428334244,104.347040018,104.266301109,104.186111115,
+	104.106463726,104.027352725,103.948771984,103.870715468,103.793177227,
+	103.716151398,103.639632204,103.563613952,103.48809103,103.41305791,
+	103.33850914,103.26443935,103.190843246,103.117715611,103.045051301,
+	102.972845249,102.901092457,102.829788,102.758927024,102.688504742,
+	102.618516438,102.54895746,102.479823222,102.411109205,102.342810952,
+	102.274924068,102.207444221,102.140367139,102.07368861,102.007404481,
+	101.941510654,101.876003092,101.810877811,101.746130883,101.681758433,
+	101.617756641,101.554121738,101.490850007,101.427937781,101.365381444,
+	101.303177428,101.241322214,101.179812331,101.118644352,101.057814898,
+	100.997320637,100.937158279,100.877324577,100.817816329,100.758630377,
+	100.6997636,100.641212922,100.582975306,100.525047756,100.467427312,
+	100.410111057,100.353096108,100.296379621,100.23995879,100.183830844,
+	100.127993045,100.072442696,100.017177128,99.9621937113,99.9074898464,
+	99.8530629679,99.7989105427,99.7450300696,99.6914190787,99.6380751312,
+	99.5849958187,99.5321787628,99.4796216147,99.4273220547,99.3752777916,
+	99.3234865625,99.2719461323,99.2206542933,99.1696088648,99.1188076924,
+	99.0682486481,99.0179296296,98.9678485599,98.918003387,98.8683920837,
+	98.8190126467,98.769863097,98.7209414788,98.6722458598,98.6237743302,
+	98.5755250031,98.5274960135,98.4796855184,98.4320916962,98.3847127468,
+	98.3375468908,98.2905923695,98.2438474444,98.1973103972,98.1509795293,
+	98.1048531614,98.0589296337,98.013207305,97.9676845528,97.922359773,
+	97.8772313798,97.8322978049,97.7875574979,97.7430089255,97.6986505718,
+	97.6544809376,97.6104985402,97.5667019136,97.5230896077,97.4796601886,
+	97.4364122381,97.3933443532,97.3504551465,97.3077432458,97.2652072933,
+	97.2228459464,97.1806578767,97.1386417702,97.0967963268,97.0551202605,
+	97.0136122989,96.9722711833,96.931095668,96.8900845209,96.8492365225,
+	96.8085504664,96.7680251586,96.7276594179,96.687452075,96.6474019731,
+	96.6075079673,96.5677689244,96.528183723,96.4887512533,96.4494704166,
+	96.4103401258,96.3713593045,96.3325268876,96.2938418206,96.2553030595,
+	96.2169095712,96.1786603327,96.1405543314,96.1025905648,96.0647680402,
+	96.0270857751,95.9895427965,95.9521381411,95.9148708551,95.8777399941,
+	95.840744623,95.8038838156,95.767156655,95.7305622332,95.6940996508,
+	95.6577680174,95.621566451,95.5854940781,95.5495500336,95.5137334607,
+	95.4780435108,95.4424793434,95.4070401257,95.3717250333,95.3365332491,
+	95.3014639639,95.2665163763,95.231689692,95.1969831244,95.1623958942,
+	95.1279272293,95.0935763647,95.0593425426,95.0252250121,94.9912230293,
+	94.957335857,94.9235627648,94.889903029,94.8563559325,94.8229207646,
+	94.7895968211,94.7563834042,94.7232798225,94.6902853904,94.6573994289,
+	94.6246212649,94.5919502312,94.5593856666,94.5269269159,94.4945733296,
+	94.4623242638,94.4301790804,94.398137147,94.3661978366,94.3343605276,
+	94.3026246041,94.2709894553,94.2394544758,94.2080190654,94.1766826291,
+	94.145444577,94.1143043243,94.0832612913,94.052314903,94.0214645895,
+	93.9907097857,93.9600499313,93.9294844707,93.899012853,93.8686345319,
+	93.8383489659,93.8081556177,93.7780539548,93.7480434489,93.7181235762,
+	93.6882938173,93.658553657,93.6289025843,93.5993400927,93.5698656795,
+	93.5404788464,93.5111790989,93.4819659468,93.4528389037,93.4237974873,
+	93.3948412191,93.3659696245,93.3371822327,93.3084785767,93.2798581933,
+	93.2513206229,93.2228654096,93.1944921013,93.1662002492,93.1379894083,
+	93.109859137,93.0818089971,93.0538385542,93.0259473769,92.9981350374,
+	92.9704011112,92.9427451771,92.9151668171,92.8876656167,92.8602411644,
+	92.8328930518,92.8056208739,92.7784242286,92.7513027171,92.7242559433,
+	92.6972835146,92.670385041,92.6435601356,92.6168084145,92.5901294966,
+	92.5635230038,92.5369885607,92.5105257949,92.4841343366,92.4578138189,
+	92.4315638777,92.4053841514,92.3792742812,92.353233911,92.3272626873,
+	92.3013602592,92.2755262785,92.2497603994,92.2240622787,92.1984315757,
+	92.1728679522,92.1473710724,92.1219406032,92.0965762136,92.0712775751,
+	92.0460443617,92.0208762495,91.9957729173,91.9707340457,91.9457593182,
+	91.9208484199,91.8960010388,91.8712168645,91.8464955894,91.8218369075,
+	91.7972405155,91.7727061118,91.7482333973,91.7238220746,91.6994718488,
+	91.6751824268,91.6509535176,91.6267848322,91.6026760837,91.5786269871,
+	91.5546372594,91.5307066197,91.5068347888,91.4830214895,91.4592664466,
+	91.4355693866,91.4119300382,91.3883481315,91.3648233988,91.3413555741,
+	91.3179443931,91.2945895935,91.2712909146,91.2480480975,91.224860885,
+	91.2017290219,91.1786522542,91.1556303301,91.1326629992,91.1097500128,
+	91.086891124,91.0640860873,91.041334659,91.0186365969,90.9959916605,
+	90.9733996109,90.9508602106,90.9283732238,90.9059384162,90.883555555,
+	90.8612244091,90.8389447485,90.8167163451,90.7945389721,90.7724124041,
+	90.7503364174,90.7283107894,90.7063352991,90.6844097271,90.6625338551,
+	90.6407074663,90.6189303453,90.5972022781,90.5755230521,90.5538924558,
+	90.5323102793,90.510776314,90.4892903525,90.4678521887,90.4464616179,
+	90.4251184365,90.4038224425,90.3825734349,90.3613712139,90.3402155812,
+	90.3191063395,90.2980432928,90.2770262463,90.2560550065,90.2351293809,
+	90.2142491783,90.1934142087,90.1726242833,90.1518792142,90.131178815,
+	90.1105229001,90.0899112853,90.0693437874,90.0488202242,90.0283404148,
+	90.0079041793,89.9875113389,89.9671617157,89.9468551333,89.9265914158,
+	89.9063703888,89.8861918787,89.866055713,89.8459617203,89.82590973,
+	89.8058995729,89.7859310803,89.7660040849,89.7461184202,89.7262739206,
+	89.7064704218,89.68670776,89.6669857728,89.6473042984,89.6276631762,
+	89.6080622464,89.5885013501,89.5689803294,89.5494990274,89.5300572878,
+	89.5106549554,89.491291876,89.4719678961,89.4526828632,89.4334366256,
+	89.4142290324,89.3950599338,89.3759291805,89.3568366244,89.3377821181,
+	89.3187655149,89.2997866691,89.2808454357,89.2619416708,89.2430752308,
+	89.2242459734,89.2054537569,89.1866984403,89.1679798835,89.1492979471,
+	89.1306524926,89.1120433823,89.0934704789,89.0749336464,89.056432749,
+	89.0379676522,89.0195382218,89.0011443245,88.9827858277,88.9644625997,
+	88.9461745092,88.927921426,88.9097032202,88.8915197629,88.8733709258,
+	88.8552565813,88.8371766024,88.8191308631,88.8011192377,88.7831416014,
+	88.7651978299,88.7472877998,88.7294113881,88.7115684728,88.6937589321,
+	88.6759826453,88.658239492,88.6405293526,88.6228521081,88.6052076402,
+	88.5875958312,88.5700165638,88.5524697217,88.5349551889,88.5174728501,
+	88.5000225908,88.4826042968,88.4652178545,88.4478631513,88.4305400746,
+	88.413248513,88.3959883551,88.3787594905,88.3615618091,88.3443952016,
+	88.3272595591,88.3101547733,88.2930807364,88.2760373414,88.2590244815,
+	88.2420420507,88.2250899434,88.2081680546,88.1912762799,88.1744145152,
+	88.1575826573,88.1407806031,88.1240082504,88.1072654973,88.0905522424,
+	88.0738683849,88.0572138245,88.0405884613,88.0239921962,88.0074249301,
+	87.9908865649,87.9743770026,87.9578961459,87.941443898,87.9250201625,
+	87.9086248434,87.8922578454,87.8759190734,87.859608433,87.8433258301,
+	87.8270711713,87.8108443633,87.7946453135,87.7784739298,87.7623301204,
+	87.746213794,87.7301248597,87.7140632271,87.6980288064,87.6820215078,
+	87.6660412424,87.6500879215,87.6341614567,87.6182617604,87.6023887451,
+	87.5865423238,87.57072241,87.5549289176,87.5391617608,87.5234208543,
+	87.5077061131,87.4920174528,87.4763547894,87.4607180389,87.4451071183,
+	87.4295219444,87.4139624349,87.3984285076,87.3829200807,87.3674370729,
+	87.3519794032,87.3365469909,87.321139756,87.3057576185,87.2904004989,
+	87.2750683183,87.2597609977,87.2444784589,87.2292206238,87.2139874149,
+	87.1987787547,87.1835945665,87.1684347736,87.1532992998,87.1381880693,
+	87.1231010065,87.1080380363,87.0929990838,87.0779840746,87.0629929344,
+	87.0480255896,87.0330819666,87.0181619923,87.0032655939,86.988392699,
+	86.9735432353,86.9587171311,86.9439143149,86.9291347155,86.914378262,
+	86.899644884,86.8849345112,86.8702470737,86.855582502,86.8409407267,
+	86.8263216789,86.81172529,86.7971514915,86.7826002155,86.7680713942,
+	86.7535649602,86.7390808462,86.7246189855,86.7101793115,86.695761758,
+	86.681366259,86.6669927487,86.6526411619,86.6383114334,86.6240034983,
+	86.6097172923,86.5954527509,86.5812098103,86.5669884067,86.5527884768,
+	86.5386099573,86.5244527855,86.5103168987,86.4962022346,86.4821087312,
+	86.4680363266,86.4539849594,86.4399545682,86.4259450922,86.4119564705,
+	86.3979886428,86.3840415487,86.3701151284,86.356209322,86.3423240703,
+	86.328459314,86.3146149941,86.3007910521,86.2869874293,86.2732040677,
+	86.2594409093,86.2456978963,86.2319749714,86.2182720773,86.204589157,
+	86.1909261539,86.1772830113,86.1636596731,86.1500560831,86.1364721857,
+	86.1229079253,86.1093632464,86.0958380941,86.0823324135,86.0688461498,
+	86.0553792488,86.0419316561,86.0285033179,86.0150941804,86.0017041901,
+	85.9883332936,85.9749814379,85.9616485701,85.9483346376,85.935039588,
+	85.9217633689,85.9085059285,85.8952672149,85.8820471765,85.868845762,
+	85.8556629201,85.8424986001,85.829352751,85.8162253223,85.8031162638,
+	85.7900255253,85.7769530568,85.7638988086,85.7508627312,85.7378447752,
+	85.7248448915,85.7118630312,85.6988991455,85.6859531858,85.6730251039,
+	85.6601148515,85.6472223807,85.6343476437,85.6214905929,85.608651181,
+	85.5958293606,85.5830250847,85.5702383066,85.5574689796,85.5447170572,
+	85.531982493,85.5192652411,85.5065652554,85.4938824903,85.4812169001,
+	85.4685684394,85.4559370631,85.4433227262,85.4307253837,85.4181449909,
+	85.4055815034,85.3930348768,85.380505067,85.36799203,85.3554957218,
+	85.3430160989,85.3305531178,85.3181067352,85.3056769079,85.2932635929,
+	85.2808667474,85.2684863287,85.2561222943,85.243774602,85.2314432095,
+	85.2191280748,85.2068291561,85.1945464117,85.1822798,85.1700292797,
+	85.1577948095,85.1455763484,85.1333738555,85.1211872901,85.1090166115,
+	85.0968617793,85.0847227531,85.0725994929,85.0604919587,85.0484001106,
+	85.036323909,85.0242633142,85.0122182869,85.0001887879,84.988174778,
+	84.9761762183,84.96419307,84.9522252944,84.940272853,84.9283357074,
+	84.9164138193,84.9045071507,84.8926156637,84.8807393203,84.8688780829,
+	84.8570319141,84.8452007763,84.8333846323,84.821583445,84.8097971775,
+	84.7980257927,84.7862692541,84.7745275251,84.7628005691,84.7510883499,
+	84.7393908313,84.7277079772,84.7160397517,84.704386119,84.6927470434,
+	84.6811224894,84.6695124216,84.6579168048,84.6463356037,84.6347687833,
+	84.6232163088,84.6116781453,84.6001542582,84.588644613,84.5771491752,
+	84.5656679107,84.5542007852,84.5427477647,84.5313088153,84.5198839031,
+	84.5084729946,84.4970760562,84.4856930544,84.4743239558,84.4629687275,
+	84.4516273361,84.4402997488,84.4289859327,84.4176858551,84.4063994834,
+	84.395126785,84.3838677277,84.372622279,84.3613904068,84.3501720791,
+	84.338967264,84.3277759297,84.3165980443,84.3054335763,84.2942824943,
+	84.2831447667,84.2720203625,84.2609092503,84.2498113991,84.238726778,
+	84.2276553561,84.2165971027,84.2055519872,84.194519979,84.1835010476,
+	84.1724951629,84.1615022946,84.1505224125,84.1395554866,84.1286014871,
+	84.1176603842,84.1067321481,84.0958167492,84.0849141581,84.0740243453,
+	84.0631472816,84.0522829378,84.0414312847,84.0305922934,84.0197659349,
+	84.0089521804,83.9981510014,83.987362369,83.9765862548,83.9658226305,
+	83.9550714676,83.944332738,83.9336064135,83.922892466,83.9121908677,
+	83.9015015907,83.8908246072,83.8801598895,83.8695074102,83.8588671416,
+	83.8482390564,83.8376231274,83.8270193272,83.8164276289,83.8058480053,
+	83.7952804295,83.7847248747,83.774181314,83.763649721,83.7531300688,
+	83.7426223311,83.7321264815,83.7216424936,83.7111703411,83.700709998,
+	83.6902614382,83.6798246356,83.6693995644,83.6589861988,83.648584513,
+	83.6381944814,83.6278160785,83.6174492788,83.6070940568,83.5967503873,
+	83.586418245,83.5760976048,83.5657884417,83.5554907305,83.5452044465,
+	83.5349295648,83.5246660606,83.5144139094,83.5041730864,83.4939435673,
+	83.4837253275,83.4735183427,83.4633225887,83.4531380413,83.4429646763,
+	83.4328024696,83.4226513974,83.4125114358,83.4023825609,83.392264749,
+	83.3821579764,83.3720622196,83.361977455,83.3519036592,83.3418408089,
+	83.3317888807,83.3217478514,83.3117176979,83.3016983972,83.2916899262,
+	83.281692262,83.2717053817,83.2617292627,83.251763882,83.2418092172,
+	83.2318652457,83.2219319449,83.2120092924,83.2020972659,83.1921958431,
+	83.1823050018,83.1724247198,83.162554975,83.1526957454,83.1428470091,
+	83.1330087443,83.123180929,83.1133635416,83.1035565603,83.0937599636,
+	83.08397373,83.0741978379,83.064432266,83.0546769929,83.0449319973,
+	83.035197258,83.0254727539,83.0157584639,83.006054367,82.9963604422,
+	82.9866766686,82.9770030254,82.9673394918,82.9576860472,82.9480426709,
+	82.9384093423,82.9287860409,82.9191727463,82.9095694381,82.8999760959,
+	82.8903926995,82.8808192286,82.8712556633,82.8617019832,82.8521581685,
+	82.8426241992,82.8331000553,82.8235857171,82.8140811647,82.8045863785,
+	82.7951013386,82.7856260257,82.77616042,82.7667045022,82.7572582527,
+	82.7478216522,82.7383946815,82.7289773211,82.719569552,82.710171355,
+	82.700782711,82.6914036009,82.6820340059,82.6726739069,82.6633232851,
+	82.6539821217,82.644650398,82.6353280953,82.6260151948,82.6167116781,
+	82.6074175266,82.5981327217,82.5888572452,82.5795910786,82.5703342036,
+	82.5610866019,82.5518482554,82.5426191458,82.5333992551,82.5241885652,
+	82.5149870582,82.505794716,82.4966115208,82.4874374547,82.4782724999,
+	82.4691166388,82.4599698535,82.4508321266,82.4417034403,82.4325837772,
+	82.4234731197,82.4143714505,82.4052787521,82.3961950073,82.3871201986,
+	82.378054309,82.3689973211,82.3599492179,82.3509099823,82.3418795973,
+	82.3328580457,82.3238453108,82.3148413756,82.3058462233,82.296859837,
+	82.2878822
+	}},
+	{ // Ri = 250k
+	-5,5,200,2001, {
+	249.98706929,249.986851225,249.986629489,249.986404021,249.986174757,
+	249.985941635,249.985704589,249.985463554,249.985218463,249.984969247,
+	249.984715838,249.984458166,249.984196158,249.983929743,249.983658846,
+	249.983383392,249.983103306,249.982818508,249.982528921,249.982234464,
+	249.981935056,249.981630613,249.981321052,249.981006287,249.98068623,
+	249.980360793,249.980029887,249.979693419,249.979351296,249.979003424,
+	249.978649708,249.978290048,249.977924346,249.9775525,249.977174409,
+	249.976789967,249.976399069,249.976001606,249.97559747,249.975186548,
+	249.974768727,249.974343893,249.973911927,249.973472711,249.973026125,
+	249.972572044,249.972110345,249.9716409,249.971163579,249.970678252,
+	249.970184785,249.969683043,249.969172887,249.968654177,249.968126772,
+	249.967590526,249.967045292,249.96649092,249.965927258,249.965354153,
+	249.964771446,249.964178978,249.963576587,249.962964107,249.962341372,
+	249.961708211,249.96106445,249.960409914,249.959744424,249.959067797,
+	249.95837985,249.957680393,249.956969237,249.956246188,249.955511048,
+	249.954763616,249.95400369,249.953231063,249.952445523,249.951646857,
+	249.950834849,249.950009276,249.949169916,249.94831654,249.947448916,
+	249.946566809,249.945669979,249.944758184,249.943831177,249.942888706,
+	249.941930516,249.940956349,249.93996594,249.938959023,249.937935324,
+	249.936894568,249.935836475,249.934760758,249.933667127,249.932555289,
+	249.931424944,249.930275788,249.929107511,249.9279198,249.926712337,
+	249.925484796,249.92423685,249.922968162,249.921678394,249.9203672,
+	249.91903423,249.917679127,249.916301529,249.914901069,249.913477372,
+	249.912030061,249.910558748,249.909063042,249.907542547,249.905996856,
+	249.904425561,249.902828244,249.901204482,249.899553844,249.897875894,
+	249.896170188,249.894436274,249.892673696,249.890881989,249.889060679,
+	249.887209288,249.885327328,249.883414305,249.881469716,249.879493052,
+	249.877483793,249.875441414,249.87336538,249.87125515,249.869110171,
+	249.866929885,249.864713724,249.86246111,249.860171458,249.857844173,
+	249.855478652,249.853074281,249.850630438,249.848146491,249.845621799,
+	249.843055711,249.840447565,249.837796689,249.835102404,249.832364016,
+	249.829580824,249.826752115,249.823877166,249.820955243,249.8179856,
+	249.81496748,249.811900117,249.80878273,249.80561453,249.802394713,
+	249.799122465,249.795796959,249.792417358,249.788982809,249.785492449,
+	249.781945403,249.778340779,249.774677678,249.770955183,249.767172365,
+	249.763328284,249.759421981,249.75545249,249.751418824,249.747319988,
+	249.743154968,249.738922738,249.734622257,249.730252468,249.725812301,
+	249.72130067,249.716716471,249.712058589,249.70732589,249.702517225,
+	249.697631429,249.692667321,249.687623703,249.682499361,249.677293063,
+	249.672003562,249.666629592,249.661169871,249.655623098,249.649987954,
+	249.644263106,249.638447197,249.632538857,249.626536694,249.620439299,
+	249.614245244,249.607953082,249.601561346,249.59506855,249.588473189,
+	249.581773739,249.574968653,249.568056367,249.561035295,249.553903831,
+	249.546660348,249.5393032,249.531830718,249.524241211,249.516532969,
+	249.508704259,249.500753327,249.492678397,249.48447767,249.476149326,
+	249.467691521,249.459102391,249.450380046,249.441522576,249.432528047,
+	249.423394501,249.414119957,249.404702411,249.395139834,249.385430176,
+	249.37557136,249.365561287,249.355397831,249.345078845,249.334602156,
+	249.323965565,249.313166851,249.302203767,249.291074039,249.27977537,
+	249.268305439,249.256661896,249.244842368,249.232844458,249.220665739,
+	249.208303762,249.195756051,249.183020104,249.170093394,249.156973366,
+	249.143657441,249.130143014,249.116427453,249.102508098,249.088382267,
+	249.074047249,249.059500307,249.044738677,249.029759572,249.014560175,
+	248.999137645,248.983489114,248.967611688,248.951502446,248.935158442,
+	248.918576704,248.901754233,248.884688005,248.867374969,248.84981205,
+	248.831996145,248.813924127,248.795592843,248.776999115,248.75813974,
+	248.739011488,248.719611106,248.699935316,248.679980814,248.659744274,
+	248.639222342,248.618411645,248.597308781,248.575910327,248.554212837,
+	248.532212841,248.509906845,248.487291335,248.464362771,248.441117595,
+	248.417552224,248.393663055,248.369446462,248.344898801,248.320016406,
+	248.29479559,248.269232647,248.243323852,248.217065459,248.190453706,
+	248.163484811,248.136154974,248.108460379,248.080397191,248.05196156,
+	248.02314962,247.993957487,247.964381265,247.934417041,247.90406089,
+	247.87330887,247.84215703,247.810601403,247.778638011,247.746262866,
+	247.713471967,247.680261304,247.646626855,247.612564592,247.578070476,
+	247.543140462,247.507770494,247.471956513,247.435694453,247.398980241,
+	247.361809801,247.32417905,247.286083906,247.24752028,247.208484082,
+	247.168971222,247.128977608,247.088499147,247.047531748,247.006071321,
+	246.964113777,246.921655032,246.878691002,246.835217611,246.791230786,
+	246.746726458,246.701700567,246.656149059,246.610067888,246.563453016,
+	246.516300415,246.468606067,246.420365965,246.371576112,246.322232525,
+	246.272331233,246.22186828,246.170839723,246.119241635,246.067070105,
+	246.014321238,245.960991158,245.907076005,245.85257194,245.797475142,
+	245.741781811,245.685488168,245.628590456,245.57108494,245.512967909,
+	245.454235673,245.394884571,245.334910963,245.274311238,245.213081809,
+	245.151219118,245.088719633,245.025579852,244.961796302,244.897365539,
+	244.832284149,244.76654875,244.70015599,244.633102551,244.565385144,
+	244.497000518,244.427945453,244.358216762,244.287811295,244.216725936,
+	244.144957607,244.072503262,243.999359895,243.925524536,243.850994253,
+	243.775766153,243.699837378,243.623205113,243.545866579,243.467819039,
+	243.389059794,243.309586187,243.2293956,243.148485458,243.066853225,
+	242.984496408,242.901412556,242.817599259,242.733054149,242.647774903,
+	242.561759239,242.475004919,242.387509745,242.299271568,242.210288277,
+	242.120557808,242.03007814,241.938847296,241.846863343,241.75412439,
+	241.660628595,241.566374155,241.471359316,241.375582364,241.279041632,
+	241.181735498,241.083662381,240.984820749,240.88520911,240.78482602,
+	240.683670075,240.581739919,240.479034238,240.375551763,240.271291268,
+	240.166251571,240.060431535,239.953830064,239.846446107,239.738278656,
+	239.629326745,239.519589453,239.4090659,239.297755248,239.185656702,
+	239.072769509,238.959092958,238.84462638,238.729369145,238.613320666,
+	238.496480396,238.37884783,238.260422501,238.141203983,238.02119189,
+	237.900385875,237.778785628,237.656390882,237.533201405,237.409217004,
+	237.284437524,237.158862846,237.03249289,236.905327613,236.777367005,
+	236.648611095,236.519059947,236.38871366,236.257572368,236.125636239,
+	235.992905475,235.859380313,235.725061022,235.589947905,235.454041297,
+	235.317341565,235.179849108,235.041564357,234.902487774,234.762619849,
+	234.621961106,234.480512096,234.338273402,234.195245633,234.051429428,
+	233.906825454,233.761434407,233.615257009,233.468294009,233.320546182,
+	233.172014331,233.022699284,232.872601892,232.721723035,232.570063615,
+	232.417624559,232.264406816,232.110411361,231.955639189,231.800091321,
+	231.643768797,231.486672681,231.328804057,231.17016403,231.010753726,
+	230.850574292,230.689626893,230.527912715,230.365432962,230.202188857,
+	230.038181642,229.873412577,229.707882938,229.541594019,229.374547132,
+	229.206743604,229.038184779,228.868872017,228.698806692,228.527990194,
+	228.356423928,228.184109314,228.011047785,227.837240787,227.662689782,
+	227.487396243,227.311361655,227.134587519,226.957075345,226.778826655,
+	226.599842984,226.420125878,226.239676893,226.058497596,225.876589564,
+	225.693954385,225.510593656,225.326508984,225.141701984,224.956174281,
+	224.769927509,224.58296331,224.395283333,224.206889237,224.017782686,
+	223.827965353,223.637438918,223.446205069,223.254265497,223.061621903,
+	222.868275994,222.674229479,222.479484077,222.284041512,222.08790351,
+	221.891071805,221.693548135,221.495334244,221.296431876,221.096842785,
+	220.896568725,220.695611455,220.493972738,220.29165434,220.08865803,
+	219.88498558,219.680638766,219.475619366,219.269929161,219.063569932,
+	218.856543466,218.648851549,218.440495971,218.231478522,218.021800994,
+	217.811465182,217.60047288,217.388825884,217.176525993,216.963575003,
+	216.749974714,216.535726925,216.320833437,216.105296048,215.88911656,
+	215.672296774,215.45483849,215.236743508,215.018013629,214.798650652,
+	214.578656378,214.358032605,214.136781131,213.914903754,213.692402271,
+	213.469278477,213.245534168,213.021171136,212.796191175,212.570596077,
+	212.344387629,212.117567622,211.890137843,211.662100076,211.433456105,
+	211.204207714,210.974356681,210.743904787,210.512853806,210.281205515,
+	210.048961685,209.816124088,209.582694492,209.348674664,209.114066368,
+	208.878871366,208.643091418,208.406728281,208.169783711,207.93225946,
+	207.694157278,207.455478915,207.216226114,206.97640062,206.736004172,
+	206.49503851,206.253505367,206.011406477,205.768743571,205.525518376,
+	205.281732618,205.037388018,204.792486297,204.547029172,204.301018358,
+	204.054455568,203.80734251,203.559680893,203.31147242,203.062718793,
+	202.813421712,202.563582874,202.313203973,202.062286701,201.810832747,
+	201.558843799,201.306321542,201.053267658,200.799683826,200.545571726,
+	200.290933032,200.035769418,199.780082556,199.523874114,199.26714576,
+	199.00989916,198.752135977,198.493857873,198.235066508,197.97576354,
+	197.715950626,197.455629421,197.19480158,196.933468754,196.671632596,
+	196.409294756,196.146456882,195.883120624,195.619287629,195.354959544,
+	195.090138015,194.824824689,194.559021212,194.292729229,194.025950385,
+	193.758686328,193.490938703,193.222709157,192.953999338,192.684810894,
+	192.415145475,192.145004731,191.874390314,191.603303879,191.331747082,
+	191.059721579,190.787229033,190.514271105,190.240849462,189.966965773,
+	189.69262171,189.417818949,189.14255917,188.866844059,188.590675304,
+	188.314054599,188.036983645,187.759464146,187.481497813,187.203086365,
+	186.924231527,186.64493503,186.365198614,186.085024028,185.804413028,
+	185.523367379,185.241888858,184.95997925,184.677640352,184.394873972,
+	184.11168193,183.828066057,183.544028199,183.259570217,182.974693983,
+	182.689401387,182.403694334,182.117574747,181.831044563,181.544105742,
+	181.25676026,180.969010115,180.680857324,180.392303929,180.103351992,
+	179.814003602,179.524260869,179.234125934,178.943600962,178.652688148,
+	178.361389716,178.069707923,177.777645057,177.485203439,177.192385426,
+	176.899193414,176.605629834,176.311697159,176.017397903,175.722734622,
+	175.42770992,175.132326446,174.836586898,174.540494025,174.244050629,
+	173.947259568,173.650123755,173.352646164,173.054829832,172.756677859,
+	172.458193411,172.159379726,171.860240112,171.560777954,171.260996712,
+	170.960899932,170.660491239,170.359774348,170.058753063,169.757431286,
+	169.455813011,169.153902337,168.851703468,168.549220714,168.246458503,
+	167.943421374,167.640113993,167.336541149,167.032707762,166.728618886,
+	166.424279716,166.119695592,165.814872003,165.509814594,165.204529171,
+	164.899021704,164.593298336,164.287365388,163.981229364,163.674896958,
+	163.36837506,163.061670761,162.754791362,162.447744379,162.140537551,
+	161.833178847,161.525676469,161.218038867,160.91027474,160.602393044,
+	160.294403003,159.986314114,159.678136154,159.369879193,159.061553594,
+	158.753170027,158.444739474,158.13627324,157.827782957,157.519280595,
+	157.21077847,156.90228925,156.593825964,156.285402011,155.977031166,
+	155.668727586,155.360505823,155.052380826,154.744367948,154.436482957,
+	154.128742038,153.821161801,153.513759285,153.206551968,152.899557763,
+	152.592795032,152.286282581,151.980039672,151.674086016,151.368441781,
+	151.063127591,150.758164527,150.453574123,150.149378371,149.84559971,
+	149.542261029,149.239385659,148.936997368,148.635120356,148.333779243,
+	148.032999061,147.732805244,147.433223619,147.134280384,146.836002101,
+	146.538415678,146.241548349,145.945427656,145.650081429,145.355537765,
+	145.061825,144.768971689,144.477006578,144.185958573,143.895856717,
+	143.606730155,143.318608101,143.031519811,142.745494544,142.460561528,
+	142.176749925,141.894088794,141.612607053,141.33233344,141.053296478,
+	140.775524432,140.499045269,140.223886626,139.950075761,139.677639521,
+	139.406604303,139.13699601,138.86884002,138.602161147,138.336983605,
+	138.073330973,137.811226163,137.550691387,137.291748127,137.034417106,
+	136.778718261,136.524670718,136.272292766,136.021601842,135.772614503,
+	135.525346418,135.279812345,135.036026122,134.79400066,134.553747926,
+	134.315278945,134.078603792,133.843731591,133.610670518,133.379427799,
+	133.150009719,132.922421627,132.696667945,132.472752176,132.25067692,
+	132.030443888,131.812053912,131.595506968,131.380802191,131.167937895,
+	130.956911595,130.747720026,130.540359167,130.334824266,130.13110986,
+	129.929209804,129.729117294,129.53082489,129.334324549,129.139607641,
+	128.946664984,128.755486867,128.566063074,128.378382911,128.192435235,
+	128.008208475,127.82569066,127.644869442,127.465732122,127.288265674,
+	127.112456765,126.938291784,126.765756859,126.594837879,126.425520519,
+	126.257790258,126.091632396,125.92703208,125.763974314,125.602443985,
+	125.442425874,125.283904673,125.126865007,124.971291439,124.817168494,
+	124.664480664,124.51321243,124.363348265,124.214872655,124.067770102,
+	123.922025141,123.777622345,123.634546339,123.492781803,123.352313488,
+	123.213126215,123.075204892,122.938534511,122.803100162,122.668887034,
+	122.535880424,122.404065739,122.273428504,122.143954363,122.015629084,
+	121.888438563,121.76236883,121.637406044,121.513536504,121.390746648,
+	121.269023054,121.148352444,121.028721683,120.910117783,120.792527903,
+	120.675939349,120.560339577,120.445716191,120.332056945,120.219349742,
+	120.107582636,119.996743831,119.886821679,119.777804682,119.669681491,
+	119.562440905,119.45607187,119.350563481,119.245904975,119.142085739,
+	119.039095299,118.936923328,118.835559639,118.734994187,118.635217064,
+	118.536218503,118.437988872,118.340518677,118.243798555,118.147819277,
+	118.052571748,117.958046998,117.864236189,117.771130609,117.678721671,
+	117.587000912,117.495959991,117.405590688,117.315884902,117.226834649,
+	117.138432063,117.050669391,116.963538993,116.87703334,116.791145014,
+	116.705866704,116.621191207,116.537111424,116.453620361,116.370711124,
+	116.288376922,116.206611062,116.125406949,116.044758083,115.964658061,
+	115.885100572,115.806079397,115.727588408,115.649621564,115.572172916,
+	115.495236596,115.418806826,115.342877908,115.267444229,115.192500255,
+	115.118040534,115.04405969,114.970552425,114.89751352,114.824937826,
+	114.752820271,114.681155856,114.60993965,114.539166794,114.4688325,
+	114.398932045,114.329460774,114.260414097,114.191787491,114.123576494,
+	114.055776708,113.988383796,113.921393483,113.854801553,113.788603846,
+	113.722796265,113.657374766,113.592335361,113.527674118,113.463387161,
+	113.399470663,113.335920853,113.27273401,113.209906463,113.147434593,
+	113.085314829,113.023543648,112.962117574,112.901033179,112.840287082,
+	112.779875944,112.719796474,112.660045423,112.600619585,112.541515797,
+	112.482730939,112.42426193,112.36610573,112.308259341,112.250719802,
+	112.19348419,112.136549623,112.079913253,112.023572271,111.967523904,
+	111.911765414,111.856294098,111.801107289,111.746202353,111.691576689,
+	111.637227729,111.583152939,111.529349816,111.475815888,111.422548715,
+	111.369545886,111.316805023,111.264323773,111.212099817,111.160130862,
+	111.108414643,111.056948924,111.005731497,110.954760178,110.904032814,
+	110.853547274,110.803301456,110.75329328,110.703520696,110.653981674,
+	110.60467421,110.555596324,110.50674606,110.458121485,110.409720688,
+	110.361541782,110.313582902,110.265842202,110.218317863,110.171008082,
+	110.123911081,110.077025099,110.030348399,109.983879261,109.937615986,
+	109.891556896,109.845700329,109.800044645,109.754588221,109.709329453,
+	109.664266754,109.619398556,109.57472331,109.530239481,109.485945553,
+	109.441840028,109.397921423,109.354188272,109.310639125,109.267272548,
+	109.224087122,109.181081447,109.138254133,109.095603809,109.053129118,
+	109.010828717,108.968701278,108.926745487,108.884960045,108.843343665,
+	108.801895077,108.760613021,108.719496253,108.67854354,108.637753663,
+	108.597125417,108.556657609,108.516349056,108.476198591,108.436205057,
+	108.39636731,108.356684217,108.317154657,108.277777521,108.238551712,
+	108.199476141,108.160549735,108.121771427,108.083140165,108.044654905,
+	108.006314614,107.96811827,107.930064861,107.892153386,107.854382852,
+	107.816752278,107.77926069,107.741907128,107.704690637,107.667610274,
+	107.630665104,107.593854203,107.557176653,107.520631548,107.48421799,
+	107.447935087,107.41178196,107.375757736,107.339861549,107.304092545,
+	107.268449875,107.2329327,107.197540188,107.162271514,107.127125864,
+	107.092102428,107.057200405,107.022419004,106.987757437,106.953214926,
+	106.9187907,106.884483995,106.850294054,106.816220127,106.78226147,
+	106.748417348,106.714687031,106.681069796,106.647564927,106.614171713,
+	106.580889453,106.547717448,106.514655009,106.48170145,106.448856093,
+	106.416118267,106.383487304,106.350962545,106.318543335,106.286229026,
+	106.254018974,106.221912543,106.189909101,106.158008021,106.126208684,
+	106.094510473,106.06291278,106.031414999,106.000016532,105.968716784,
+	105.937515166,105.906411094,105.87540399,105.844493279,105.813678393,
+	105.782958766,105.752333841,105.721803061,105.691365878,105.661021745,
+	105.630770122,105.600610472,105.570542264,105.540564971,105.51067807,
+	105.480881041,105.451173372,105.421554551,105.392024073,105.362581436,
+	105.333226143,105.3039577,105.274775617,105.245679411,105.216668597,
+	105.1877427,105.158901246,105.130143764,105.101469788,105.072878857,
+	105.04437051,105.015944294,104.987599757,104.959336451,104.931153932,
+	104.903051759,104.875029495,104.847086706,104.819222962,104.791437835,
+	104.763730902,104.736101743,104.708549941,104.681075081,104.653676754,
+	104.626354551,104.599108068,104.571936905,104.544840663,104.517818946,
+	104.490871364,104.463997527,104.437197048,104.410469545,104.383814638,
+	104.357231948,104.330721102,104.304281728,104.277913457,104.251615922,
+	104.225388761,104.199231613,104.173144119,104.147125925,104.121176677,
+	104.095296026,104.069483624,104.043739125,104.018062189,103.992452474,
+	103.966909643,103.941433361,103.916023296,103.890679118,103.865400498,
+	103.840187112,103.815038637,103.789954751,103.764935137,103.739979478,
+	103.715087461,103.690258774,103.665493107,103.640790154,103.616149609,
+	103.59157117,103.567054536,103.542599408,103.51820549,103.493872487,
+	103.469600108,103.445388062,103.42123606,103.397143817,103.373111047,
+	103.34913747,103.325222804,103.301366771,103.277569095,103.253829501,
+	103.230147716,103.206523469,103.182956493,103.159446518,103.13599328,
+	103.112596516,103.089255964,103.065971363,103.042742456,103.019568986,
+	102.996450698,102.97338734,102.950378659,102.927424406,102.904524334,
+	102.881678195,102.858885746,102.836146742,102.813460943,102.790828108,
+	102.768247999,102.74572038,102.723245015,102.700821671,102.678450115,
+	102.656130116,102.633861446,102.611643877,102.589477183,102.567361139,
+	102.545295522,102.523280109,102.501314681,102.479399019,102.457532905,
+	102.435716122,102.413948457,102.392229695,102.370559624,102.348938035,
+	102.327364716,102.305839461,102.284362062,102.262932314,102.241550013,
+	102.220214956,102.198926941,102.177685768,102.156491237,102.135343152,
+	102.114241314,102.093185529,102.072175603,102.051211342,102.030292555,
+	102.009419051,101.98859064,101.967807134,101.947068347,101.926374091,
+	101.905724182,101.885118436,101.864556671,101.844038704,101.823564356,
+	101.803133447,101.782745799,101.762401235,101.742099578,101.721840653,
+	101.701624287,101.681450305,101.661318537,101.641228811,101.621180958,
+	101.601174808,101.581210193,101.561286947,101.541404903,101.521563896,
+	101.501763763,101.482004341,101.462285466,101.442606979,101.422968719,
+	101.403370526,101.383812242,101.36429371,101.344814774,101.325375276,
+	101.305975064,101.286613983,101.267291879,101.248008601,101.228763999,
+	101.20955792,101.190390216,101.171260738,101.152169339,101.133115871,
+	101.114100189,101.095122146,101.076181599,101.057278403,101.038412416,
+	101.019583497,101.000791503,100.982036294,100.96331773,100.944635673,
+	100.925989984,100.907380526,100.888807163,100.870269758,100.851768177,
+	100.833302284,100.814871947,100.796477033,100.778117409,100.759792944,
+	100.741503507,100.723248969,100.705029199,100.68684407,100.668693453,
+	100.650577222,100.632495249,100.614447409,100.596433577,100.578453629,
+	100.56050744,100.542594887,100.524715848,100.506870202,100.489057826,
+	100.471278601,100.453532406,100.435819123,100.418138632,100.400490816,
+	100.382875557,100.365292739,100.347742246,100.330223961,100.312737771,
+	100.29528356,100.277861215,100.260470623,100.243111672,100.225784249,
+	100.208488243,100.191223543,100.17399004,100.156787623,100.139616184,
+	100.122475614,100.105365804,100.088286649,100.07123804,100.054219871,
+	100.037232038,100.020274434,100.003346955,99.9864494965,99.9695819554,
+	99.9527442284,99.935936213,99.9191578071,99.9024089092,99.8856894183,
+	99.8689992338,99.8523382559,99.8357063851,99.8191035222,99.8025295689,
+	99.7859844271,99.7694679993,99.7529801885,99.7365208981,99.7200900321,
+	99.7036874949,99.6873131914,99.6709670269,99.6546489073,99.6383587388,
+	99.6220964281,99.6058618826,99.5896550097,99.5734757178,99.5573239152,
+	99.5411995111,99.5251024148,99.5090325364,99.492989786,99.4769740745,
+	99.460985313,99.4450234132,99.4290882872,99.4131798474,99.3972980067,
+	99.3814426785,99.3656137764,99.3498112147,99.3340349078,99.3182847708,
+	99.3025607191,99.2868626683,99.2711905347,99.2555442348,99.2399236857,
+	99.2243288047,99.2087595095,99.1932157183,99.1776973497,99.1622043225,
+	99.146736556,99.1312939699,99.1158764842,99.1004840195,99.0851164964,
+	99.0697738362,99.0544559603,99.0391627907,99.0238942497,99.0086502598,
+	98.993430744,98.9782356258,98.9630648287,98.9479182768,98.9327958945,
+	98.9176976065,98.902623338,98.8875730143,98.8725465613,98.857543905,
+	98.8425649718,98.8276096887,98.8126779826,98.7977697811,98.7828850119,
+	98.7680236031,98.7531854831,98.7383705808,98.7235788251,98.7088101455,
+	98.6940644717,98.6793417336,98.6646418617,98.6499647867,98.6353104394,
+	98.6206787511,98.6060696534,98.5914830783,98.5769189578,98.5623772246,
+	98.5478578113,98.533360651,98.5188856772,98.5044328236,98.490002024,
+	98.4755932127,98.4612063243,98.4468412937,98.4324980559,98.4181765464,
+	98.4038767009,98.3895984552,98.3753417457,98.361106509,98.3468926817,
+	98.332700201,98.3185290043,98.3043790291,98.2902502134,98.2761424952,
+	98.2620558131,98.2479901058,98.2339453121,98.2199213714,98.205918223,
+	98.1919358068,98.1779740627,98.164032931,98.1501123522,98.136212267,
+	98.1223326165,98.108473342,98.0946343849,98.080815687,98.0670171904,
+	98.0532388372,98.03948057,98.0257423315,98.0120240648,97.9983257129,
+	97.9846472195,97.9709885281,97.9573495827,97.9437303276,97.930130707,
+	97.9165506656,97.9029901484,97.8894491003,97.8759274667,97.8624251931,
+	97.8489422254,97.8354785095,97.8220339916,97.8086086182,97.795202336,
+	97.7818150918,97.7684468328,97.7550975062,97.7417670596,97.7284554407,
+	97.7151625976,97.7018884783,97.6886330313,97.6753962052,97.6621779488,
+	97.648978211,97.6357969412,97.6226340887,97.6094896032,97.5963634346,
+	97.5832555327,97.570165848,97.5570943308,97.5440409318,97.5310056019,
+	97.5179882919,97.5049889533,97.4920075374,97.4790439958,97.4660982804,
+	97.4531703431,97.4402601362,97.427367612,97.4144927232,97.4016354224,
+	97.3887956627,97.3759733971,97.3631685791,97.350381162,97.3376110997,
+	97.3248583459,97.3121228548,97.2994045805,97.2867034775,97.2740195003,
+	97.2613526038,97.2487027429,97.2360698727,97.2234539485,97.2108549257,
+	97.1982727601,97.1857074075,97.1731588237,97.1606269651,97.1481117878,
+	97.1356132485,97.1231313037,97.1106659104,97.0982170254,97.0857846061,
+	97.0733686096,97.0609689935,97.0485857155,97.0362187333,97.0238680049,
+	97.0115334885,96.9992151424,96.9869129251,96.974626795,96.9623567111,
+	96.9501026322,96.9378645174,96.925642326,96.9134360174,96.901245551,
+	96.8890708866,96.8769119841,96.8647688034,96.8526413048,96.8405294484,
+	96.8284331947,96.8163525044,96.8042873382,96.792237657,96.7802034217,
+	96.7681845937,96.7561811342,96.7441930046,96.7322201667,96.7202625821,
+	96.7083202128,96.6963930208,96.6844809683,96.6725840175,96.660702131,
+	96.6488352713,96.6369834012,96.6251464835,96.6133244813,96.6015173576,
+	96.5897250758,96.5779475993,96.5661848916,96.5544369164,96.5427036375,
+	96.5309850188,96.5192810244,96.5075916186,96.4959167655,96.4842564298,
+	96.472610576,96.4609791688,96.449362173,96.4377595536,96.4261712758,
+	96.4145973047,96.4030376057,96.3914921443,96.379960886,96.3684437966,
+	96.3569408419,96.3454519879,96.3339772007,96.3225164464,96.3110696914,
+	96.2996369022,96.2882180452,96.2768130873,96.2654219951,96.2540447357,
+	96.242681276,96.2313315832,96.2199956245,96.2086733674,96.1973647793,
+	96.1860698279,96.1747884809,96.1635207061,96.1522664715,96.1410257451,
+	96.1297984951,96.1185846898,96.1073842976,96.096197287,96.0850236266,
+	96.0738632851,96.0627162315,96.0515824345,96.0404618634,96.0293544871,
+	96.018260275,96.0071791965,95.9961112211,95.9850563182,95.9740144577,
+	95.9629856092,95.9519697427,95.9409668282,95.9299768358,95.9189997356,
+	95.908035498,95.8970840934,95.8861454923,95.8752196653,95.8643065831,
+	95.8534062165,95.8425185365,95.8316435139,95.82078112,95.8099313258,
+	95.7990941028,95.7882694223,95.7774572558,95.7666575748,95.7558703512,
+	95.7450955566,95.7343331628,95.723583142,95.7128454661,95.7021201073,
+	95.6914070379,95.6807062301,95.6700176564,95.6593412894,95.6486771016,
+	95.6380250658,95.6273851547,95.6167573413,95.6061415985,95.5955378994,
+	95.5849462171,95.5743665249,95.5637987962,95.5532430042,95.5426991226,
+	95.532167125,95.521646985,95.5111386764,95.500642173,95.4901574488,
+	95.4796844778,95.4692232342,95.4587736921,95.4483358257,95.4379096096,
+	95.4274950181,95.4170920257,95.406700607,95.3963207368,95.3859523898,
+	95.375595541,95.3652501651,95.3549162373,95.3445937326,95.3342826263,
+	95.3239828935,95.3136945097,95.3034174503,95.2931516907,95.2828972066,
+	95.2726539735,95.2624219673,95.2522011637,95.2419915386,95.231793068,
+	95.221605728,95.2114294947,95.2012643442,95.1911102528,95.1809671969,
+	95.1708351529,95.1607140973,95.1506040066,95.1405048576,95.1304166269,
+	95.1203392913,95.1102728277,95.100217213,95.0901724243,95.0801384386,
+	95.070115233,95.0601027849,95.0501010715,95.0401100701,95.0301297583,
+	95.0201601135,95.0102011132,95.0002527353,94.9903149573,94.9803877571,
+	94.9704711125,94.9605650015,94.950669402,94.9407842921,94.93090965,
+	94.9210454538,94.9111916818,94.9013483124,94.8915153239,94.8816926948,
+	94.8718804037,94.8620784292,94.8522867499,94.8425053445,94.8327341919,
+	94.8229732709,94.8132225604,94.8034820394,94.793751687,94.7840314824,
+	94.7743214046,94.7646214329,94.7549315467,94.7452517252,94.7355819481,
+	94.7259221946,94.7162724445,94.7066326773,94.6970028726,94.6873830104,
+	94.6777730702,94.6681730321,94.658582876,94.6490025817,94.6394321295,
+	94.6298714993,94.6203206714,94.610779626,94.6012483433,94.5917268037,
+	94.5822149877,94.5727128756,94.563220448,94.5537376855,94.5442645687,
+	94.5348010783,94.525347195,94.5159028997,94.5064681732,94.4970429965,
+	94.4876273505,94.4782212162,94.4688245748,94.4594374074,94.4500596952,
+	94.4406914195,94.4313325615,94.4219831026,94.4126430243,94.403312308,
+	94.3939909353,94.3846788878,94.375376147,94.3660826947,94.3567985126,
+	94.3475235826,94.3382578864,94.329001406,94.3197541234,94.3105160205,
+	94.3012870794,94.2920672823,94.2828566112,94.2736550485,94.2644625763,
+	94.255279177,94.2461048331,94.2369395268,94.2277832407,94.2186359572,
+	94.2094976591,94.2003683288,94.1912479492,94.1821365028,94.1730339724,
+	94.163940341,94.1548555913,94.1457797063,94.136712669,94.1276544623,
+	94.1186050694,94.1095644733,94.1005326572,94.0915096044,94.082495298,
+	94.0734897214,94.064492858,94.0555046911,94.0465252043,94.0375543809,
+	94.0285922045,94.0196386587,94.0106937272,94.0017573936,93.9928296417,
+	93.9839104552,93.974999818,93.9660977138,93.9572041267,93.9483190405,
+	93.9394424393,93.9305743071,93.921714628,93.9128633861,93.9040205657,
+	93.8951861508,93.8863601258,93.8775424751,93.8687331828,93.8599322335,
+	93.8511396116,93.8423553016,93.8335792879,93.8248115552,93.816052088,
+	93.8073008711,93.798557889,93.7898231266,93.7810965686,93.7723781999,
+	93.7636680053
+	}}
+};
diff --git a/examples/faust-tubes/valve/6C16.cc b/examples/faust-tubes/valve/6C16.cc
new file mode 100644
index 0000000..2795e35
--- /dev/null
+++ b/examples/faust-tubes/valve/6C16.cc
@@ -0,0 +1,819 @@
+// generated by ../../tools/tube_transfer.py
+// tube: 6C16
+// plate current function: triode
+// mu: 42.2
+// kx: 2.21
+// kg1: 393
+// kp: 629
+// kvb: 446
+
+table1d_imp<2001> tubetable_6C16[2] = {
+	{ // Ri = 68k
+	-5,5,200,2001, {
+	214.806581677,214.650587712,214.494441388,214.338143449,214.181694635,
+	214.025095677,213.868347304,213.711450238,213.554405194,213.397212884,
+	213.239874013,213.082389282,212.924759385,212.766985013,212.60906685,
+	212.451005576,212.292801864,212.134456385,211.975969802,211.817342776,
+	211.658575961,211.499670005,211.340625555,211.181443251,211.022123727,
+	210.862667614,210.703075539,210.543348122,210.383485982,210.22348973,
+	210.063359973,209.903097317,209.742702359,209.582175694,209.421517913,
+	209.260729602,209.099811343,208.938763714,208.777587287,208.616282633,
+	208.454850316,208.293290899,208.131604938,207.969792986,207.807855593,
+	207.645793304,207.483606661,207.321296202,207.15886246,206.996305965,
+	206.833627244,206.67082682,206.507905211,206.344862933,206.181700497,
+	206.018418412,205.855017182,205.691497309,205.527859289,205.364103618,
+	205.200230785,205.036241278,204.872135582,204.707914176,204.543577538,
+	204.379126141,204.214560458,204.049880955,203.885088096,203.720182343,
+	203.555164155,203.390033984,203.224792285,203.059439505,202.893976089,
+	202.728402482,202.562719123,202.396926447,202.23102489,202.065014882,
+	201.898896852,201.732671223,201.56633842,201.399898861,201.233352963,
+	201.066701141,200.899943805,200.733081363,200.566114223,200.399042787,
+	200.231867455,200.064588626,199.897206695,199.729722054,199.562135094,
+	199.394446202,199.226655764,199.058764161,198.890771775,198.722678983,
+	198.554486159,198.386193678,198.217801909,198.04931122,197.880721977,
+	197.712034543,197.54324928,197.374366545,197.205386696,197.036310087,
+	196.86713707,196.697867994,196.528503206,196.359043053,196.189487877,
+	196.019838019,195.850093818,195.680255611,195.510323732,195.340298515,
+	195.170180288,194.999969382,194.829666122,194.659270832,194.488783835,
+	194.318205451,194.147535999,193.976775794,193.805925153,193.634984386,
+	193.463953805,193.292833719,193.121624434,192.950326255,192.778939486,
+	192.607464428,192.43590138,192.264250641,192.092512505,191.920687267,
+	191.74877522,191.576776653,191.404691857,191.232521118,191.060264721,
+	190.887922951,190.715496088,190.542984415,190.370388209,190.197707747,
+	190.024943305,189.852095157,189.679163575,189.50614883,189.33305119,
+	189.159870923,188.986608295,188.813263571,188.639837013,188.466328882,
+	188.292739439,188.119068941,187.945317645,187.771485807,187.597573681,
+	187.423581518,187.249509571,187.075358088,186.901127317,186.726817506,
+	186.552428899,186.377961741,186.203416274,186.028792738,185.854091375,
+	185.679312422,185.504456116,185.329522693,185.154512388,184.979425434,
+	184.804262062,184.629022504,184.453706988,184.278315742,184.102848994,
+	183.927306968,183.751689889,183.57599798,183.400231463,183.224390558,
+	183.048475484,182.872486461,182.696423704,182.520287429,182.344077852,
+	182.167795186,181.991439642,181.815011432,181.638510767,181.461937854,
+	181.285292902,181.108576118,180.931787707,180.754927872,180.577996819,
+	180.400994749,180.223921863,180.046778361,179.869564443,179.692280306,
+	179.514926148,179.337502164,179.16000855,178.982445499,178.804813204,
+	178.627111857,178.449341649,178.27150277,178.093595408,177.915619752,
+	177.737575989,177.559464305,177.381284884,177.203037911,177.024723568,
+	176.846342039,176.667893504,176.489378144,176.310796138,176.132147665,
+	175.953432902,175.774652027,175.595805214,175.416892639,175.237914476,
+	175.058870898,174.879762077,174.700588185,174.521349393,174.342045871,
+	174.162677786,173.983245308,173.803748604,173.624187839,173.444563181,
+	173.264874792,173.085122839,172.905307483,172.725428887,172.545487212,
+	172.365482621,172.185415271,172.005285324,171.825092937,171.644838268,
+	171.464521474,171.284142712,171.103702136,170.923199902,170.742636163,
+	170.562011074,170.381324785,170.20057745,170.019769219,169.838900242,
+	169.65797067,169.476980651,169.295930334,169.114819866,168.933649395,
+	168.752419065,168.571129024,168.389779415,168.208370384,168.026902072,
+	167.845374625,167.663788182,167.482142887,167.300438881,167.118676302,
+	166.936855292,166.754975989,166.573038531,166.391043057,166.208989703,
+	166.026878606,165.844709901,165.662483725,165.480200212,165.297859496,
+	165.11546171,164.933006988,164.750495462,164.567927263,164.385302523,
+	164.202621372,164.019883941,163.837090358,163.654240754,163.471335255,
+	163.288373991,163.105357087,162.922284672,162.739156871,162.555973809,
+	162.372735612,162.189442404,162.00609431,161.822691453,161.639233955,
+	161.45572194,161.272155529,161.088534844,160.904860005,160.721131134,
+	160.537348349,160.353511771,160.169621519,159.98567771,159.801680463,
+	159.617629896,159.433526124,159.249369266,159.065159437,158.880896752,
+	158.696581327,158.512213277,158.327792715,158.143319755,157.958794511,
+	157.774217096,157.589587621,157.4049062,157.220172943,157.035387961,
+	156.850551366,156.665663268,156.480723775,156.295732998,156.110691046,
+	155.925598028,155.74045405,155.555259222,155.37001365,155.184717441,
+	154.999370702,154.813973539,154.628526057,154.443028363,154.25748056,
+	154.071882754,153.886235049,153.700537548,153.514790354,153.328993572,
+	153.143147302,152.957251649,152.771306713,152.585312596,152.3992694,
+	152.213177225,152.027036171,151.840846339,151.654607829,151.46832074,
+	151.28198517,151.09560122,150.909168986,150.722688568,150.536160062,
+	150.349583566,150.162959178,149.976286994,149.78956711,149.602799623,
+	149.415984628,149.22912222,149.042212495,148.855255548,148.668251473,
+	148.481200364,148.294102315,148.106957419,147.919765771,147.732527463,
+	147.545242587,147.357911237,147.170533503,146.983109479,146.795639255,
+	146.608122923,146.420560573,146.232952297,146.045298185,145.857598327,
+	145.669852813,145.482061732,145.294225174,145.106343228,144.918415983,
+	144.730443527,144.542425949,144.354363336,144.166255777,143.978103358,
+	143.789906168,143.601664294,143.413377821,143.225046837,143.036671428,
+	142.848251681,142.65978768,142.471279512,142.282727262,142.094131015,
+	141.905490856,141.71680687,141.528079142,141.339307755,141.150492794,
+	140.961634343,140.772732485,140.583787303,140.394798882,140.205767303,
+	140.016692651,139.827575006,139.638414453,139.449211072,139.259964947,
+	139.070676158,138.881344788,138.691970919,138.50255463,138.313096004,
+	138.123595121,137.934052062,137.744466908,137.554839739,137.365170636,
+	137.175459677,136.985706944,136.795912515,136.606076471,136.416198891,
+	136.226279854,136.036319439,135.846317724,135.65627479,135.466190714,
+	135.276065574,135.08589945,134.895692419,134.70544456,134.515155949,
+	134.324826666,134.134456787,133.94404639,133.753595552,133.563104351,
+	133.372572864,133.182001167,132.991389337,132.800737452,132.610045587,
+	132.41931382,132.228542226,132.037730882,131.846879864,131.655989247,
+	131.465059109,131.274089524,131.083080569,130.892032318,130.700944849,
+	130.509818235,130.318652552,130.127447876,129.936204281,129.744921843,
+	129.553600637,129.362240737,129.170842219,128.979405156,128.787929624,
+	128.596415698,128.404863451,128.213272959,128.021644295,127.829977533,
+	127.638272749,127.446530017,127.254749409,127.062931001,126.871074867,
+	126.679181079,126.487249713,126.295280842,126.103274541,125.911230881,
+	125.719149938,125.527031786,125.334876497,125.142684145,124.950454804,
+	124.758188548,124.565885449,124.373545582,124.18116902,123.988755837,
+	123.796306105,123.603819898,123.41129729,123.218738354,123.026143164,
+	122.833511792,122.640844313,122.448140799,122.255401324,122.062625961,
+	121.869814784,121.676967866,121.484085281,121.291167101,121.098213401,
+	120.905224253,120.712199732,120.51913991,120.326044862,120.132914661,
+	119.93974938,119.746549093,119.553313874,119.360043796,119.166738933,
+	118.973399359,118.780025148,118.586616373,118.393173109,118.19969543,
+	118.006183409,117.81263712,117.619056639,117.425442039,117.231793394,
+	117.038110779,116.844394268,116.650643936,116.456859857,116.263042107,
+	116.069190759,115.87530589,115.681387573,115.487435884,115.293450898,
+	115.09943269,114.905381337,114.711296912,114.517179492,114.323029153,
+	114.128845971,113.93463002,113.740381379,113.546100122,113.351786326,
+	113.157440068,112.963061424,112.768650472,112.574207287,112.379731948,
+	112.185224531,111.990685114,111.796113774,111.601510589,111.406875638,
+	111.212208997,111.017510746,110.822780964,110.628019727,110.433227116,
+	110.238403209,110.043548087,109.848661827,109.65374451,109.458796215,
+	109.263817024,109.068807015,108.87376627,108.678694869,108.483592894,
+	108.288460425,108.093297545,107.898104334,107.702880875,107.507627251,
+	107.312343543,107.117029835,106.921686209,106.726312749,106.530909539,
+	106.335476663,106.140014205,105.944522249,105.749000881,105.553450185,
+	105.357870248,105.162261155,104.966622992,104.770955847,104.575259805,
+	104.379534954,104.183781382,103.987999177,103.792188428,103.596349222,
+	103.40048165,103.204585801,103.008661765,102.812709632,102.616729493,
+	102.420721441,102.224685566,102.02862196,101.832530717,101.636411929,
+	101.440265691,101.244092096,101.047891239,100.851663216,100.655408121,
+	100.459126052,100.262817104,100.066481377,99.8701189658,99.673729971,
+	99.477314491,99.2808726256,99.0844044752,98.8879101407,98.6913897236,
+	98.4948433264,98.2982710519,98.1016730037,97.9050492862,97.7084000044,
+	97.5117252641,97.3150251718,97.1182998349,96.9215493615,96.7247738603,
+	96.5279734411,96.3311482144,96.1342982917,95.9374237851,95.7405248079,
+	95.5436014741,95.3466538988,95.1496821978,94.9526864881,94.7556668877,
+	94.5586235156,94.3615564917,94.1644659371,93.9673519741,93.7702147259,
+	93.5730543171,93.3758708733,93.1786645213,92.9814353893,92.7841836066,
+	92.5869093039,92.3896126132,92.1922936679,91.9949526028,91.7975895541,
+	91.6002046595,91.4027980582,91.205369891,91.0079203002,90.8104494298,
+	90.6129574255,90.4154444347,90.2179106065,90.0203560919,89.8227810438,
+	89.6251856168,89.4275699678,89.2299342554,89.0322786405,88.8346032859,
+	88.636908357,88.4391940209,88.2414604476,88.0437078089,87.8459362796,
+	87.6481460367,87.4503372598,87.2525101312,87.0546648361,86.8568015623,
+	86.6589205007,86.461021845,86.2631057922,86.0651725422,85.8672222985,
+	85.6692552677,85.47127166,85.2732716892,85.0752555725,84.8772235314,
+	84.6791757908,84.4811125799,84.2830341322,84.084940685,83.8868324806,
+	83.6887097654,83.4905727907,83.2924218127,83.0942570925,82.8960788963,
+	82.6978874958,82.499683168,82.3014661959,82.1032368679,81.9049954788,
+	81.7067423296,81.5084777275,81.3102019866,81.1119154278,80.9136183791,
+	80.7153111759,80.516994161,80.3186676851,80.1203321072,79.9219877944,
+	79.7236351224,79.5252744761,79.3269062494,79.1285308459,78.9301486789,
+	78.7317601719,78.533365759,78.3349658854,78.1365610071,77.9381515922,
+	77.7397381206,77.5413210848,77.34290099,77.1444783551,76.9460537123,
+	76.7476276085,76.5492006051,76.350773279,76.1523462226,75.9539200451,
+	75.7554953721,75.5570728472,75.3586531317,75.160236906,74.9618248697,
+	74.7634177425,74.5650162649,74.3666211991,74.1682333293,73.969853463,
+	73.7714824312,73.57312109,73.3747703208,73.1764310315,72.9781041575,
+	72.7797906624,72.5814915392,72.3832078112,72.1849405333,71.9866907928,
+	71.7884597106,71.5902484426,71.3920581808,71.1938901544,70.9957456312,
+	70.7976259192,70.5995323675,70.4014663683,70.203429358,70.0054228187,
+	69.8074482801,69.6095073209,69.4116015707,69.2137327114,69.0159024793,
+	68.8181126671,68.6203651253,68.4226617647,68.2250045581,68.0273955426,
+	67.8298368217,67.6323305676,67.4348790234,67.2374845055,67.0401494061,
+	66.8428761956,66.6456674255,66.4485257304,66.2514538315,66.0544545389,
+	65.8575307545,65.6606854752,65.4639217957,65.2672429117,65.070652123,
+	64.8741528369,64.6777485713,64.4814429582,64.2852397473,64.0891428094,
+	63.89315614,63.6972838629,63.5015302341,63.3058996458,63.1103966298,
+	62.9150258617,62.7197921649,62.5247005146,62.3297560418,62.1349640375,
+	61.9403299569,61.7458594236,61.5515582334,61.3574323592,61.1634879547,
+	60.9697313588,60.7761690999,60.5828078998,60.3896546781,60.1967165562,
+	60.0040008615,59.811515131,59.6192671154,59.427264783,59.2355163231,
+	59.0440301495,58.852814904,58.6618794596,58.4712329231,58.2808846382,
+	58.090844188,57.9011213969,57.7117263328,57.5226693086,57.3339608836,
+	57.1456118642,56.9576333046,56.7700365068,56.58283302,56.3960346403,
+	56.2096534086,56.0237016094,55.8381917678,55.6531366466,55.4685492428,
+	55.284442783,55.1008307186,54.9177267197,54.7351446693,54.5530986556,
+	54.3716029642,54.1906720696,54.0103206254,53.8305634543,53.6514155368,
+	53.4728919991,53.295008101,53.1177792216,52.9412208454,52.7653485472,
+	52.5901779759,52.4157248378,52.2420048797,52.0690338701,51.8968275811,
+	51.7254017683,51.5547721516,51.3849543941,51.2159640815,51.0478167004,
+	50.8805276169,50.7141120546,50.5485850721,50.3839615409,50.220256123,
+	50.0574832487,49.895657094,49.7347915589,49.5749002458,49.4159964377,
+	49.2580930777,49.1012027484,48.9453376526,48.7905095938,48.6367299582,
+	48.4840096974,48.3323593121,48.1817888365,48.0323078239,47.8839253338,
+	47.7366499195,47.5904896174,47.4454519373,47.3015438542,47.1587718012,
+	47.0171416637,46.876658775,46.7373279131,46.5991532994,46.4621385973,
+	46.326286914,46.1916008015,46.0580822608,45.9257327457,45.7945531685,
+	45.6645439069,45.5357048113,45.4080352138,45.2815339377,45.1561993078,
+	45.032029162,44.9090208631,44.7871713114,44.6664769582,44.5469338196,
+	44.4285374906,44.3112831602,44.195165626,44.08017931,43.9663182736,
+	43.8535762342,43.7419465802,43.6314223873,43.5219964345,43.4136612197,
+	43.3064089756,43.2002316854,43.0951210982,42.9910687444,42.8880659502,
+	42.7861038533,42.6851734163,42.5852654418,42.4863705854,42.3884793696,
+	42.2915821966,42.1956693612,42.1007310628,42.0067574174,41.913738469,
+	41.8216642003,41.7305245439,41.6403093918,41.5510086055,41.4626120252,
+	41.3751094786,41.2884907892,41.2027457849,41.1178643049,41.0338362075,
+	40.9506513767,40.8682997286,40.7867712177,40.7060558425,40.6261436509,
+	40.5470247451,40.4686892867,40.3911275007,40.3143296798,40.238286188,
+	40.1629874645,40.0884240263,40.0145864718,39.9414654832,39.869051829,
+	39.7973363663,39.7263100428,39.6559638986,39.5862890679,39.5172767805,
+	39.4489183628,39.381205239,39.3141289323,39.2476810652,39.1818533604,
+	39.1166376415,39.0520258329,38.9880099602,38.9245821507,38.861734633,
+	38.799459737,38.7377498939,38.6765976358,38.6159955956,38.5559365061,
+	38.4964132002,38.4374186098,38.3789457655,38.3209877958,38.2635379265,
+	38.20658948,38.1501358741,38.0941706218,38.03868733,37.9836796987,
+	37.9291415199,37.8750666772,37.821449144,37.7682829833,37.7155623461,
+	37.6632814707,37.6114346815,37.5600163879,37.5090210835,37.4584433446,
+	37.4082778296,37.3585192774,37.3091625068,37.260202415,37.2116339769,
+	37.1634522436,37.1156523417,37.0682294717,37.0211789077,36.9744959955,
+	36.9281761519,36.882214864,36.8366076874,36.7913502455,36.7464382288,
+	36.7018673933,36.6576335597,36.6137326126,36.5701604991,36.5269132281,
+	36.4839868692,36.4413775518,36.3990814641,36.3570948521,36.3154140187,
+	36.2740353227,36.2329551782,36.1921700533,36.1516764693,36.1114710002,
+	36.0715502713,36.0319109585,35.9925497878,35.953463534,35.9146490203,
+	35.8761031172,35.8378227417,35.7998048569,35.7620464706,35.7245446353,
+	35.6872964468,35.6502990438,35.6135496072,35.5770453592,35.5407835628,
+	35.5047615211,35.4689765763,35.4334261096,35.3981075401,35.3630183243,
+	35.3281559555,35.2935179634,35.2591019128,35.2249054039,35.190926071,
+	35.1571615823,35.1236096394,35.0902679764,35.0571343594,35.0242065864,
+	34.9914824864,34.9589599188,34.9266367732,34.8945109687,34.8625804535,
+	34.8308432042,34.7992972259,34.7679405508,34.7367712388,34.7057873762,
+	34.6749870757,34.6443684758,34.6139297407,34.5836690592,34.553584645,
+	34.523674736,34.4939375938,34.4643715034,34.4349747732,34.4057457337,
+	34.3766827382,34.3477841616,34.3190484007,34.2904738733,34.2620590183,
+	34.2338022949,34.2057021827,34.1777571813,34.1499658098,34.1223266066,
+	34.094838129,34.067498953,34.0403076731,34.0132629019,33.9863632696,
+	33.9596074241,33.9329940306,33.906521771,33.8801893442,33.8539954655,
+	33.8279388664,33.8020182942,33.7762325121,33.7505802987,33.7250604478,
+	33.6996717682,33.6744130834,33.6492832315,33.624281065,33.5994054503,
+	33.5746552679,33.5500294117,33.5255267892,33.5011463214,33.4768869419,
+	33.4527475975,33.4287272476,33.404824864,33.3810394309,33.3573699445,
+	33.333815413,33.3103748565,33.2870473064,33.2638318058,33.2407274087,
+	33.2177331806,33.1948481976,33.1720715466,33.1494023254,33.1268396418,
+	33.1043826143,33.0820303713,33.0597820513,33.0376368026,33.0155937833,
+	32.9936521611,32.971811113,32.9500698254,32.928427494,32.9068833234,
+	32.885436527,32.8640863273,32.8428319553,32.8216726506,32.8006076611,
+	32.7796362431,32.7587576613,32.7379711881,32.7172761042,32.696671698,
+	32.6761572657,32.6557321111,32.6353955456,32.615146888,32.5949854646,
+	32.5749106086,32.5549216607,32.5350179685,32.5151988864,32.4954637759,
+	32.4758120052,32.4562429491,32.4367559889,32.4173505127,32.3980259148,
+	32.3787815958,32.3596169627,32.3405314284,32.3215244122,32.3025953392,
+	32.2837436404,32.2649687528,32.246270119,32.2276471875,32.2090994121,
+	32.1906262525,32.1722271737,32.1539016461,32.1356491454,32.1174691527,
+	32.0993611542,32.0813246412,32.0633591103,32.0454640627,32.027639005,
+	32.0098834483,31.9921969088,31.9745789073,31.9570289692,31.9395466249,
+	31.922131409,31.9047828608,31.8875005241,31.870283947,31.8531326821,
+	31.8360462862,31.8190243203,31.8020663499,31.7851719442,31.768340677,
+	31.7515721256,31.7348658718,31.7182215011,31.7016386029,31.6851167705,
+	31.6686556011,31.6522546954,31.6359136583,31.6196320978,31.603409626,
+	31.5872458584,31.571140414,31.5550929153,31.5391029884,31.5231702628,
+	31.5072943712,31.49147495,31.4757116385,31.4600040794,31.4443519189,
+	31.4287548061,31.4132123933,31.3977243359,31.3822902925,31.3669099247,
+	31.3515828971,31.3363088772,31.3210875356,31.3059185458,31.2908015839,
+	31.2757363292,31.2607224636,31.245759672,31.2308476417,31.2159860631,
+	31.2011746291,31.1864130351,31.1717009795,31.1570381631,31.1424242891,
+	31.1278590637,31.1133421951,31.0988733943,31.0844523748,31.0700788523,
+	31.0557525451,31.0414731739,31.0272404614,31.0130541332,30.9989139168,
+	30.9848195421,30.9707707411,30.9567672485,30.9428088006,30.9288951362,
+	30.9150259964,30.9012011241,30.8874202647,30.8736831652,30.8599895751,
+	30.8463392459,30.8327319308,30.8191673854,30.805645367,30.7921656351,
+	30.778727951,30.7653320779,30.751977781,30.7386648273,30.7253929858,
+	30.7121620271,30.6989717239,30.6858218505,30.6727121831,30.6596424997,
+	30.64661258,30.6336222053,30.6206711589,30.6077592256,30.5948861919,
+	30.582051846,30.5692559778,30.5564983788,30.543778842,30.5310971622,
+	30.5184531356,30.5058465602,30.4932772352,30.4807449617,30.4682495421,
+	30.4557907804,30.4433684821,30.430982454,30.4186325047,30.4063184439,
+	30.394040083,30.3817972346,30.369589713,30.3574173335,30.3452799132,
+	30.3331772701,30.3211092241,30.309075596,30.2970762081,30.285110884,
+	30.2731794486,30.2612817281,30.24941755,30.237586743,30.2257891371,
+	30.2140245634,30.2022928546,30.1905938442,30.1789273672,30.1672932596,
+	30.1556913586,30.1441215028,30.1325835317,30.1210772861,30.1096026079,
+	30.09815934,30.0867473267,30.0753664132,30.0640164459,30.0526972721,
+	30.0414087405,30.0301507006,30.018923003,30.0077254995,29.9965580428,
+	29.9854204867,29.974312686,29.9632344964,29.9521857749,29.9411663791,
+	29.930176168,29.9192150012,29.9082827395,29.8973792446,29.8865043791,
+	29.8756580067,29.8648399918,29.8540501999,29.8432884974,29.8325547515,
+	29.8218488304,29.8111706032,29.8005199399,29.7898967112,29.7793007888,
+	29.7687320454,29.7581903544,29.74767559,29.7371876273,29.7267263422,
+	29.7162916116,29.705883313,29.6955013249,29.6851455263,29.6748157973,
+	29.6645120188,29.6542340722,29.64398184,29.6337552052,29.6235540517,
+	29.6133782642,29.6032277281,29.5931023295,29.5830019553,29.5729264931,
+	29.5628758312,29.5528498587,29.5428484654,29.5328715418,29.5229189789,
+	29.5129906688,29.503086504,29.4932063777,29.4833501839,29.4735178172,
+	29.4637091728,29.4539241467,29.4441626356,29.4344245366,29.4247097476,
+	29.4150181672,29.4053496945,29.3957042294,29.3860816723,29.3764819242,
+	29.3669048868,29.3573504624,29.3478185538,29.3383090646,29.3288218988,
+	29.3193569611,29.3099141568,29.3004933916,29.2910945721,29.2817176051,
+	29.2723623983,29.2630288597,29.2537168981,29.2444264227,29.2351573433,
+	29.2259095701,29.2166830142,29.2074775868,29.1982931999,29.189129766,
+	29.1799871982,29.1708654098,29.161764315,29.1526838283,29.1436238647,
+	29.1345843399,29.1255651698,29.1165662711,29.1075875607,29.0986289563,
+	29.0896903759,29.0807717379,29.0718729614,29.0629939658,29.054134671,
+	29.0452949975,29.0364748662,29.0276741982,29.0188929155,29.0101309403,
+	29.0013881953,28.9926646035,28.9839600886,28.9752745746,28.9666079859,
+	28.9579602474,28.9493312845,28.9407210228,28.9321293887,28.9235563085,
+	28.9150017094,28.9064655188,28.8979476644,28.8894480746,28.880966678,
+	28.8725034037,28.864058181,28.8556309398,28.8472216105,28.8388301235,
+	28.8304564099,28.8221004011,28.813762029,28.8054412256,28.7971379235,
+	28.7888520556,28.7805835552,28.772332356,28.764098392,28.7558815975,
+	28.7476819073,28.7394992566,28.7313335807,28.7231848155,28.7150528972,
+	28.7069377621,28.6988393474,28.69075759,28.6826924275,28.6746437979,
+	28.6666116394,28.6585958904,28.6505964899,28.6426133771,28.6346464915,
+	28.626695773,28.6187611617,28.6108425982,28.6029400232,28.595053378,
+	28.5871826039,28.5793276427,28.5714884365,28.5636649277,28.5558570589,
+	28.5480647731,28.5402880136,28.532526724,28.5247808482,28.5170503302,
+	28.5093351147,28.5016351463,28.4939503701,28.4862807313,28.4786261758,
+	28.4709866492,28.4633620978,28.4557524681,28.4481577067,28.4405777608,
+	28.4330125775,28.4254621044,28.4179262893,28.4104050804,28.4028984259,
+	28.3954062746,28.3879285752,28.3804652769,28.3730163292,28.3655816816,
+	28.3581612841,28.3507550868,28.3433630402,28.3359850949,28.3286212019,
+	28.3212713123,28.3139353775,28.3066133492,28.2993051793,28.2920108199,
+	28.2847302234,28.2774633423,28.2702101296,28.2629705384,28.2557445219,
+	28.2485320337,28.2413330275,28.2341474574,28.2269752777,28.2198164427,
+	28.2126709072,28.205538626,28.1984195544,28.1913136475,28.1842208611,
+	28.1771411508,28.1700744728,28.1630207831,28.1559800382,28.1489521948,
+	28.1419372097,28.13493504,28.1279456429,28.1209689759,28.1140049966,
+	28.107053663,28.1001149332,28.0931887653,28.0862751179,28.0793739497,
+	28.0724852196,28.0656088866,28.0587449099,28.0518932492,28.0450538639,
+	28.038226714,28.0314117595,28.0246089606,28.0178182778,28.0110396715,
+	28.0042731028,27.9975185324,27.9907759215,27.9840452315,27.9773264239,
+	27.9706194605,27.9639243029,27.9572409134,27.9505692542,27.9439092876,
+	27.9372609763,27.9306242829,27.9239991704,27.917385602,27.9107835408,
+	27.9041929503,27.8976137942,27.8910460361,27.8844896401,27.8779445702,
+	27.8714107907,27.8648882661,27.8583769608,27.8518768397,27.8453878678,
+	27.8389100099,27.8324432315,27.8259874979,27.8195427746,27.8131090273,
+	27.806686222,27.8002743245,27.7938733011,27.7874831181,27.781103742,
+	27.7747351393,27.7683772768,27.7620301215,27.7556936405,27.7493678008,
+	27.74305257,27.7367479154,27.7304538047,27.7241702058,27.7178970865,
+	27.7116344149,27.7053821593,27.6991402879,27.6929087694,27.6866875722,
+	27.6804766652,27.6742760174,27.6680855976,27.6619053752,27.6557353194,
+	27.6495753996,27.6434255855,27.6372858468,27.6311561533,27.6250364749,
+	27.6189267819,27.6128270443,27.6067372327,27.6006573174,27.594587269,
+	27.5885270585,27.5824766565,27.5764360341,27.5704051624,27.5643840127,
+	27.5583725563,27.5523707647,27.5463786095,27.5403960625,27.5344230955,
+	27.5284596804,27.5225057894,27.5165613947,27.5106264685,27.5047009834,
+	27.4987849119,27.4928782266,27.4869809004,27.4810929061,27.4752142168,
+	27.4693448056,27.4634846457,27.4576337105,27.4517919735,27.4459594082,
+	27.4401359884,27.4343216877,27.4285164802,27.4227203398,27.4169332407,
+	27.411155157,27.4053860632,27.3996259336,27.3938747428,27.3881324655,
+	27.3823990764,27.3766745503,27.3709588622,27.3652519873,27.3595539006,
+	27.3538645774,27.3481839931,27.3425121231,27.3368489431,27.3311944287,
+	27.3255485556,27.3199112998,27.3142826371,27.3086625437,27.3030509957,
+	27.2974479694,27.291853441,27.2862673871,27.2806897842,27.2751206089,
+	27.2695598379,27.2640074481,27.2584634164,27.2529277198,27.2474003354,
+	27.2418812403,27.2363704118,27.2308678274,27.2253734644,27.2198873005,
+	27.2144093132,27.2089394803,27.2034777796,27.1980241889,27.1925786864,
+	27.18714125,27.181711858,27.1762904885,27.1708771199,27.1654717306,
+	27.1600742991,27.1546848041,27.1493032241,27.1439295379,27.1385637244,
+	27.1332057625,27.1278556311,27.1225133094,27.1171787765,27.1118520117,
+	27.1065329942,27.1012217036,27.0959181192,27.0906222206,27.0853339875,
+	27.0800533996,27.0747804366,27.0695150786,27.0642573053,27.0590070968,
+	27.0537644333,27.048529295,27.0433016619,27.0380815146,27.0328688334,
+	27.0276635988,27.0224657913,27.0172753915,27.0120923803,27.0069167383,
+	27.0017484463,26.9965874854,26.9914338364,26.9862874805,26.9811483988,
+	26.9760165725,26.9708919829,26.9657746112,26.960664439,26.9555614477,
+	26.9504656189,26.9453769341,26.9402953751,26.9352209236,26.9301535615,
+	26.9250932707,26.920040033,26.9149938306,26.9099546455,26.9049224599,
+	26.899897256,26.8948790161,26.8898677226,26.8848633578,26.8798659043,
+	26.8748753447,26.8698916614,26.8649148373,26.8599448551,26.8549816974,
+	26.8500253473,26.8450757877,26.8401330015,26.8351969718,26.8302676817,
+	26.8253451143,26.820429253,26.815520081,26.8106175817,26.8057217385,
+	26.8008325349,26.7959499543,26.7910739805,26.786204597,26.7813417876,
+	26.7764855361,26.7716358262,26.7667926419,26.7619559671,26.7571257859,
+	26.7523020822,26.7474848402,26.7426740441,26.737869678,26.7330717264,
+	26.7282801735,26.7234950037,26.7187162015,26.7139437514,26.7091776379,
+	26.7044178457,26.6996643594,26.6949171638,26.6901762436,26.6854415837,
+	26.680713169,26.6759909844,26.6712750148,26.6665652454,26.6618616612,
+	26.6571642474,26.6524729891,26.6477878717,26.6431088804,26.6384360006,
+	26.6337692177,26.6291085171,26.6244538844,26.6198053051,26.6151627648,
+	26.6105262491,26.6058957438,26.6012712347,26.5966527074,26.592040148,
+	26.5874335422,26.5828328761,26.5782381356,26.5736493067,26.5690663756,
+	26.5644893285,26.5599181514,26.5553528306,26.5507933525,26.5462397032,
+	26.5416918693,26.5371498371,26.5326135931,26.5280831239,26.5235584158,
+	26.5190394557,26.5145262301,26.5100187257,26.5055169292,26.5010208275,
+	26.4965304073,26.4920456556,26.4875665593,26.4830931052,26.4786252805,
+	26.4741630721,26.4697064672,26.4652554529,26.4608100163,26.4563701447,
+	26.4519358254,26.4475070456,26.4430837927,26.4386660541,26.4342538172,
+	26.4298470695,26.4254457985,26.4210499918,26.4166596369,26.4122747215,
+	26.4078952332,26.4035211598,26.3991524891,26.3947892088,26.3904313068,
+	26.3860787709,26.3817315891,26.3773897493,26.3730532396,26.3687220479,
+	26.3643961623,26.360075571,26.3557602621,26.3514502237,26.3471454442,
+	26.3428459118,26.3385516148,26.3342625415,26.3299786803,26.3257000197,
+	26.3214265481,26.3171582539,26.3128951257,26.3086371522,26.3043843218,
+	26.3001366232,26.2958940452,26.2916565763,26.2874242055,26.2831969213,
+	26.2789747128,26.2747575687,26.2705454778,26.2663384293,26.2621364119,
+	26.2579394148,26.2537474269,26.2495604373,26.2453784351,26.2412014095,
+	26.2370293495,26.2328622446,26.2287000837,26.2245428563,26.2203905517,
+	26.2162431591,26.212100668,26.2079630678,26.2038303479,26.1997024978,
+	26.1955795069,26.1914613649,26.1873480613,26.1832395857,26.1791359278,
+	26.1750370772,26.1709430235,26.1668537567,26.1627692664,26.1586895424,
+	26.1546145745,26.1505443526,26.1464788667,26.1424181066,26.1383620622,
+	26.1343107237,26.1302640809,26.1262221239,26.1221848429,26.1181522279,
+	26.114124269,26.1101009565,26.1060822805,26.1020682313,26.098058799,
+	26.0940539741,26.0900537468,26.0860581075,26.0820670466,26.0780805544,
+	26.0740986214,26.070121238,26.0661483949,26.0621800824,26.0582162911,
+	26.0542570117,26.0503022347,26.0463519507,26.0424061505,26.0384648247,
+	26.0345279641,26.0305955593,26.0266676012,26.0227440806,26.0188249883,
+	26.0149103152,26.0110000522,26.0070941901,26.00319272,25.9992956327,
+	25.9954029194,25.9915145709,25.9876305784,25.983750933,25.9798756257,
+	25.9760046476,25.97213799,25.9682756441,25.9644176009,25.9605638518,
+	25.956714388,25.9528692009,25.9490282816,25.9451916216,25.9413592122,
+	25.9375310449,25.9337071109,25.9298874018,25.9260719091,25.9222606242,
+	25.9184535386,25.9146506439,25.9108519316,25.9070573933,25.9032670207,
+	25.8994808054
+	}},
+	{ // Ri = 250k
+	-5,5,200,2001, {
+	214.806581677,214.650587712,214.494441388,214.338143449,214.181694635,
+	214.025095677,213.868347304,213.711450238,213.554405194,213.397212884,
+	213.239874013,213.082389282,212.924759385,212.766985013,212.60906685,
+	212.451005576,212.292801864,212.134456385,211.975969802,211.817342776,
+	211.658575961,211.499670005,211.340625555,211.181443251,211.022123727,
+	210.862667614,210.703075539,210.543348122,210.383485982,210.22348973,
+	210.063359973,209.903097317,209.742702359,209.582175694,209.421517913,
+	209.260729602,209.099811343,208.938763714,208.777587287,208.616282633,
+	208.454850316,208.293290899,208.131604938,207.969792986,207.807855593,
+	207.645793304,207.483606661,207.321296202,207.15886246,206.996305965,
+	206.833627244,206.67082682,206.507905211,206.344862933,206.181700497,
+	206.018418412,205.855017182,205.691497309,205.527859289,205.364103618,
+	205.200230785,205.036241278,204.872135582,204.707914176,204.543577538,
+	204.379126141,204.214560458,204.049880955,203.885088096,203.720182343,
+	203.555164155,203.390033984,203.224792285,203.059439505,202.893976089,
+	202.728402482,202.562719123,202.396926447,202.23102489,202.065014882,
+	201.898896852,201.732671223,201.56633842,201.399898861,201.233352963,
+	201.066701141,200.899943805,200.733081363,200.566114223,200.399042787,
+	200.231867455,200.064588626,199.897206695,199.729722054,199.562135094,
+	199.394446202,199.226655764,199.058764161,198.890771775,198.722678983,
+	198.554486159,198.386193678,198.217801909,198.04931122,197.880721977,
+	197.712034543,197.54324928,197.374366545,197.205386696,197.036310087,
+	196.86713707,196.697867994,196.528503206,196.359043053,196.189487877,
+	196.019838019,195.850093818,195.680255611,195.510323732,195.340298515,
+	195.170180288,194.999969382,194.829666122,194.659270832,194.488783835,
+	194.318205451,194.147535999,193.976775794,193.805925153,193.634984386,
+	193.463953805,193.292833719,193.121624434,192.950326255,192.778939486,
+	192.607464428,192.43590138,192.264250641,192.092512505,191.920687267,
+	191.74877522,191.576776653,191.404691857,191.232521118,191.060264721,
+	190.887922951,190.715496088,190.542984415,190.370388209,190.197707747,
+	190.024943305,189.852095157,189.679163575,189.50614883,189.33305119,
+	189.159870923,188.986608295,188.813263571,188.639837013,188.466328882,
+	188.292739439,188.119068941,187.945317645,187.771485807,187.597573681,
+	187.423581518,187.249509571,187.075358088,186.901127317,186.726817506,
+	186.552428899,186.377961741,186.203416274,186.028792738,185.854091375,
+	185.679312422,185.504456116,185.329522693,185.154512388,184.979425434,
+	184.804262062,184.629022504,184.453706988,184.278315742,184.102848994,
+	183.927306968,183.751689889,183.57599798,183.400231463,183.224390558,
+	183.048475484,182.872486461,182.696423704,182.520287429,182.344077852,
+	182.167795186,181.991439642,181.815011432,181.638510767,181.461937854,
+	181.285292902,181.108576118,180.931787707,180.754927872,180.577996819,
+	180.400994749,180.223921863,180.046778361,179.869564443,179.692280306,
+	179.514926148,179.337502164,179.16000855,178.982445499,178.804813204,
+	178.627111857,178.449341649,178.27150277,178.093595408,177.915619752,
+	177.737575989,177.559464305,177.381284884,177.203037911,177.024723568,
+	176.846342039,176.667893504,176.489378144,176.310796138,176.132147665,
+	175.953432902,175.774652027,175.595805214,175.416892639,175.237914476,
+	175.058870898,174.879762077,174.700588185,174.521349393,174.342045871,
+	174.162677786,173.983245308,173.803748604,173.624187839,173.444563181,
+	173.264874793,173.085122839,172.905307483,172.725428887,172.545487212,
+	172.365482621,172.185415272,172.005285324,171.825092937,171.644838268,
+	171.464521475,171.284142712,171.103702136,170.923199902,170.742636163,
+	170.562011074,170.381324785,170.20057745,170.019769219,169.838900242,
+	169.65797067,169.476980651,169.295930334,169.114819867,168.933649395,
+	168.752419065,168.571129024,168.389779415,168.208370384,168.026902072,
+	167.845374625,167.663788183,167.482142888,167.300438881,167.118676302,
+	166.936855292,166.754975989,166.573038531,166.391043057,166.208989703,
+	166.026878606,165.844709901,165.662483725,165.480200212,165.297859496,
+	165.115461711,164.933006988,164.750495462,164.567927263,164.385302523,
+	164.202621372,164.019883941,163.837090359,163.654240754,163.471335256,
+	163.288373991,163.105357088,162.922284672,162.739156871,162.555973809,
+	162.372735612,162.189442405,162.006094311,161.822691453,161.639233956,
+	161.455721941,161.27215553,161.088534844,160.904860006,160.721131134,
+	160.53734835,160.353511772,160.169621519,159.985677711,159.801680464,
+	159.617629896,159.433526125,159.249369267,159.065159438,158.880896753,
+	158.696581328,158.512213278,158.327792716,158.143319756,157.958794512,
+	157.774217097,157.589587623,157.404906201,157.220172944,157.035387963,
+	156.850551368,156.665663269,156.480723777,156.295733,156.110691048,
+	155.925598029,155.740454052,155.555259223,155.370013651,155.184717443,
+	154.999370704,154.813973541,154.62852606,154.443028365,154.257480563,
+	154.071882757,153.886235051,153.70053755,153.514790357,153.328993575,
+	153.143147306,152.957251652,152.771306717,152.5853126,152.399269404,
+	152.213177229,152.027036175,151.840846344,151.654607834,151.468320744,
+	151.281985175,151.095601225,150.909168991,150.722688573,150.536160067,
+	150.349583572,150.162959184,149.976287,149.789567117,149.60279963,
+	149.415984635,149.229122227,149.042212503,148.855255556,148.668251481,
+	148.481200372,148.294102323,148.106957428,147.919765781,147.732527473,
+	147.545242597,147.357911247,147.170533514,146.98310949,146.795639267,
+	146.608122935,146.420560586,146.232952311,146.045298199,145.857598342,
+	145.669852828,145.482061748,145.294225191,145.106343245,144.918416001,
+	144.730443545,144.542425968,144.354363356,144.166255797,143.97810338,
+	143.789906191,143.601664317,143.413377845,143.225046862,143.036671454,
+	142.848251708,142.659787708,142.471279541,142.282727292,142.094131047,
+	141.905490889,141.716806905,141.528079178,141.339307792,141.150492833,
+	140.961634383,140.772732527,140.583787347,140.394798927,140.20576735,
+	140.016692699,139.827575057,139.638414505,139.449211127,139.259965004,
+	139.070676217,138.88134485,138.691970983,138.502554697,138.313096073,
+	138.123595193,137.934052137,137.744466986,137.55483982,137.36517072,
+	137.175459765,136.985707035,136.79591261,136.60607657,136.416198993,
+	136.22627996,136.036319549,135.846317839,135.656274909,135.466190838,
+	135.276065704,135.085899585,134.895692559,134.705444705,134.5151561,
+	134.324826823,134.13445695,133.944046559,133.753595729,133.563104534,
+	133.372573054,133.182001365,132.991389543,132.800737666,132.61004581,
+	132.419314051,132.228542467,132.037731132,131.846880124,131.655989518,
+	131.46505939,131.274089817,131.083080873,130.892032635,130.700945177,
+	130.509818577,130.318652908,130.127448245,129.936204665,129.744922243,
+	129.553601052,129.362241169,129.170842668,128.979405623,128.78793011,
+	128.596416203,128.404863976,128.213273504,128.021644862,127.829978123,
+	127.638273363,127.446530654,127.254750072,127.062931691,126.871075583,
+	126.679181825,126.487250488,126.295281648,126.103275378,125.911231752,
+	125.719150844,125.527032727,125.334877475,125.142685163,124.950455862,
+	124.758189648,124.565886593,124.373546772,124.181170257,123.988757122,
+	123.796307442,123.603821288,123.411298735,123.218739857,123.026144726,
+	122.833513416,122.640846001,122.448142555,122.255403149,122.062627859,
+	121.869816757,121.676969918,121.484087414,121.291169319,121.098215706,
+	120.90522665,120.712202224,120.519142502,120.326047556,120.132917462,
+	119.939752292,119.746552121,119.553317022,119.360047069,119.166742336,
+	118.973402897,118.780028826,118.586620198,118.393177086,118.199699564,
+	118.006187707,117.81264159,117.619061286,117.42544687,117.231798417,
+	117.038116001,116.844399697,116.650649581,116.456865726,116.263048209,
+	116.069197103,115.875312486,115.68139443,115.487443014,115.293458311,
+	115.099440397,114.905389349,114.711305243,114.517188154,114.323038158,
+	114.128855333,113.934639754,113.740391499,113.546110644,113.351797266,
+	113.157451442,112.963073249,112.768662766,112.574220069,112.379745237,
+	112.185238347,111.990699479,111.796128709,111.601526117,111.406891782,
+	111.212225782,111.017528197,110.822799106,110.62803859,110.433246727,
+	110.238423599,110.043569285,109.848683866,109.653767423,109.458820038,
+	109.263841792,109.068832766,108.873793042,108.678722704,108.483621833,
+	108.288490512,108.093328825,107.898136855,107.702914687,107.507662403,
+	107.31238009,107.117067832,106.921725713,106.726353821,106.53095224,
+	106.335521058,106.14006036,105.944570235,105.749050771,105.553502054,
+	105.357924174,105.16231722,104.966681281,104.771016447,104.575322809,
+	104.379600457,104.183849483,103.98806998,103.792262038,103.596425752,
+	103.400561215,103.204668521,103.008747766,102.812799044,102.616822451,
+	102.420818085,102.224786042,102.028726421,101.832639321,101.63652484,
+	101.440383079,101.244214139,101.048018121,100.851795129,100.655545265,
+	100.459268634,100.26296534,100.06663549,99.8702791895,99.6738965474,
+	99.4774876719,99.2810526729,99.0845916608,98.8881047476,98.691592046,
+	98.4950536699,98.2984897344,98.1019003557,97.9052856512,97.7086457396,
+	97.5119807408,97.315290776,97.1185759679,96.9218364403,96.7250723187,
+	96.52828373,96.3314708025,96.1346336663,95.9377724527,95.7408872952,
+	95.5439783285,95.3470456894,95.1500895163,94.9531099497,94.7561071318,
+	94.5590812068,94.3620323212,94.1649606233,93.9678662638,93.7707493956,
+	93.5736101738,93.3764487561,93.1792653025,92.9820599756,92.7848329407,
+	92.5875843657,92.3903144214,92.1930232816,91.9957111228,91.7983781248,
+	91.6010244707,91.4036503465,91.2062559421,91.0088414506,90.8114070689,
+	90.6139529975,90.4164794409,90.2189866076,90.0214747103,89.823943966,
+	89.626394596,89.4288268263,89.2312408877,89.0336370159,88.8360154516,
+	88.6383764408,88.4407202349,88.243047091,88.045357272,87.8476510469,
+	87.6499286907,87.4521904852,87.2544367185,87.0566676858,86.8588836897,
+	86.6610850397,86.4632720534,86.2654450561,86.0676043814,85.8697503714,
+	85.6718833771,85.4740037586,85.2761118852,85.0782081364,84.8802929016,
+	84.6823665808,84.4844295847,84.2864823355,84.0885252669,83.8905588249,
+	83.6925834679,83.4945996672,83.2966079077,83.0986086881,82.9006025218,
+	82.7025899369,82.504571477,82.3065477019,82.1085191881,81.9104865291,
+	81.7124503365,81.5144112404,81.31636989,81.1183269543,80.9202831233,
+	80.7222391079,80.5241956415,80.3261534801,80.1281134038,79.9300762172,
+	79.7320427503,79.5340138598,79.3359904296,79.1379733722,78.9399636292,
+	78.7419621732,78.5439700078,78.3459881699,78.14801773,77.9500597938,
+	77.7521155034,77.5541860386,77.3562726184,77.1583765021,76.960498991,
+	76.7626414298,76.5648052081,76.3669917621,76.1692025763,75.971439185,
+	75.7737031742,75.5759961834,75.3783199075,75.1806760987,74.9830665686,
+	74.78549319,74.5879578994,74.3904626989,74.1930096588,73.9956009193,
+	73.7982386937,73.6009252702,73.4036630149,73.2064543742,73.0093018775,
+	72.8122081401,72.6151758657,72.4182078498,72.2213069825,72.0244762512,
+	71.8277187444,71.6310376545,71.4344362812,71.2379180349,71.0414864401,
+	70.8451451392,70.6488978956,70.4527485979,70.2567012634,70.0607600418,
+	69.8649292195,69.6692132231,69.4736166236,69.2781441408,69.0828006466,
+	68.8875911702,68.6925209014,68.4975951954,68.302819577,68.1081997447,
+	67.9137415753,67.7194511279,67.5253346485,67.3313985744,67.137649538,
+	66.9440943715,66.750740111,66.5575940006,66.3646634965,66.1719562709,
+	65.979480216,65.7872434478,65.5952543092,65.4035213744,65.2120534512,
+	65.0208595845,64.8299490593,64.6393314028,64.4490163873,64.2590140316,
+	64.0693346033,63.8799886194,63.6909868482,63.502340309,63.3140602728,
+	63.1261582616,62.9386460478,62.7515356528,62.5648393451,62.3785696378,
+	62.1927392856,62.0073612811,61.8224488501,61.6380154473,61.4540747498,
+	61.2706406511,61.0877272534,60.9053488602,60.7235199671,60.5422552522,
+	60.3615695659,60.1814779194,60.0019954732,59.8231375236,59.6449194893,
+	59.467356897,59.290465366,59.1142605922,58.9387583312,58.7639743808,
+	58.5899245626,58.4166247035,58.2440906157,58.0723380767,57.9013828089,
+	57.7312404584,57.5619265734,57.3934565824,57.2258457724,57.0591092663,
+	56.8932620005,56.7283187029,56.5642938699,56.4012017447,56.2390562951,
+	56.0778711918,55.9176597869,55.7584350933,55.6002097646,55.442996075,
+	55.2868059006,55.1316507015,54.9775415045,54.8244888866,54.67250296,
+	54.521593358,54.3717692215,54.2230391876,54.0754113787,53.928893393,
+	53.7834922966,53.6392146163,53.4960663344,53.3540528842,53.213179147,
+	53.0734494507,52.9348675694,52.7974367242,52.6611595853,52.5260382756,
+	52.392074375,52.2592689262,52.1276224411,51.9971349089,51.8678058046,
+	51.7396340988,51.6126182678,51.4867563052,51.3620457335,51.2384836172,
+	51.1160665754,50.9947907962,50.8746520501,50.7556457053,50.6377667424,
+	50.5210097692,50.4053690366,50.2908384541,50.177411605,50.0650817627,
+	49.953841906,49.8436847348,49.7346026858,49.626587948,49.5196324774,
+	49.4137280128,49.30886609,49.2050380567,49.1022350863,49.0004481925,
+	48.899668242,48.7998859685,48.7010919851,48.6032767968,48.5064308127,
+	48.4105443574,48.3156076826,48.2216109775,48.1285443795,48.0363979842,
+	47.9451618546,47.8548260307,47.7653805379,47.6768153954,47.5891206244,
+	47.5022862551,47.4163023342,47.3311589317,47.2468461468,47.1633541147,
+	47.0806730113,46.9987930595,46.9177045334,46.8373977633,46.7578631402,
+	46.6790911195,46.6010722248,46.5237970519,46.4472562712,46.3714406313,
+	46.2963409615,46.2219481742,46.1482532672,46.0752473257,46.0029215242,
+	45.9312671284,45.8602754958,45.789938078,45.7202464213,45.6511921675,
+	45.582767055,45.5149629195,45.4477716941,45.3811854103,45.3151961979,
+	45.249796285,45.1849779988,45.1207337645,45.0570561064,44.9939376466,
+	44.9313711053,44.8693493005,44.8078651471,44.746911657,44.686481938,
+	44.6265691936,44.567166722,44.5082679158,44.449866261,44.391955336,
+	44.3345288112,44.2775804481,44.2211040981,44.1650937017,44.1095432878,
+	44.0544469725,43.9997989584,43.9455935331,43.8918250688,43.8384880208,
+	43.7855769268,43.7330864057,43.6810111566,43.6293459579,43.5780856658,
+	43.5272252138,43.4767596114,43.426683943,43.3769933668,43.3276831139,
+	43.2787484874,43.230184861,43.181987678,43.1341524507,43.0866747587,
+	43.0395502487,42.9927746327,42.9463436875,42.9002532535,42.8544992337,
+	42.8090775929,42.7639843566,42.7192156101,42.6747674974,42.6306362206,
+	42.5868180387,42.5433092665,42.5001062744,42.4572054868,42.4146033815,
+	42.3722964889,42.3302813911,42.2885547209,42.2471131613,42.2059534443,
+	42.1650723503,42.1244667073,42.0841333903,42.0440693199,42.0042714625,
+	41.9647368285,41.9254624723,41.8864454915,41.8476830258,41.8091722568,
+	41.7709104067,41.7328947382,41.6951225536,41.6575911941,41.6202980392,
+	41.5832405061,41.5464160489,41.5098221582,41.4734563605,41.4373162174,
+	41.4013993251,41.3657033141,41.3302258481,41.294964624,41.2599173708,
+	41.2250818496,41.1904558528,41.1560372035,41.1218237553,41.0878133915,
+	41.0540040246,41.0203935961,40.9869800759,40.9537614617,40.9207357786,
+	40.8879010787,40.8552554409,40.8227969699,40.7905237962,40.7584340756,
+	40.7265259888,40.694797741,40.6632475612,40.6318737025,40.6006744409,
+	40.5696480755,40.5387929281,40.5081073423,40.477589684,40.4472383402,
+	40.4170517192,40.3870282502,40.3571663827,40.3274645866,40.2979213512,
+	40.2685351859,40.2393046187,40.210228197,40.1813044866,40.1525320716,
+	40.1239095543,40.0954355544,40.0671087095,40.0389276741,40.0108911199,
+	39.982997735,39.955246224,39.9276353079,39.9001637232,39.8728302225,
+	39.8456335736,39.8185725594,39.7916459781,39.7648526423,39.7381913793,
+	39.7116610306,39.6852604519,39.6589885127,39.6328440961,39.6068260988,
+	39.5809334306,39.5551650145,39.5295197862,39.5039966942,39.4785946995,
+	39.4533127753,39.4281499069,39.4031050918,39.3781773388,39.3533656688,
+	39.3286691137,39.304086717,39.2796175331,39.2552606273,39.2310150758,
+	39.2068799653,39.1828543931,39.1589374668,39.1351283041,39.1114260327,
+	39.0878297902,39.064338724,39.0409519911,39.0176687579,38.9944882003,
+	38.9714095031,38.9484318604,38.9255544753,38.9027765596,38.8800973337,
+	38.8575160268,38.8350318765,38.8126441286,38.7903520373,38.7681548648,
+	38.7460518814,38.7240423652,38.7021256022,38.6803008859,38.6585675176,
+	38.636924806,38.6153720669,38.5939086239,38.5725338073,38.5512469547,
+	38.5300474107,38.5089345267,38.4879076609,38.4669661783,38.4461094505,
+	38.4253368556,38.4046477781,38.384041609,38.3635177454,38.3430755908,
+	38.3227145546,38.3024340525,38.2822335058,38.2621123421,38.2420699944,
+	38.2221059018,38.2022195088,38.1824102656,38.1626776278,38.1430210566,
+	38.1234400185,38.1039339853,38.0845024341,38.065144847,38.0458607114,
+	38.0266495197,38.0075107692,37.9884439622,37.9694486057,37.9505242119,
+	37.9316702972,37.912886383,37.8941719953,37.8755266647,37.8569499261,
+	37.838441319,37.8200003873,37.8016266793,37.7833197474,37.7650791485,
+	37.7469044434,37.7287951972,37.7107509792,37.6927713625,37.6748559244,
+	37.6570042459,37.6392159121,37.621490512,37.6038276382,37.5862268871,
+	37.568687859,37.5512101577,37.5337933905,37.5164371687,37.4991411068,
+	37.4819048228,37.4647279384,37.4476100786,37.4305508715,37.4135499491,
+	37.3966069463,37.3797215014,37.3628932558,37.3461218542,37.3294069446,
+	37.3127481779,37.296145208,37.2795976922,37.2631052905,37.2466676661,
+	37.2302844849,37.2139554159,37.197680131,37.1814583048,37.1652896148,
+	37.1491737414,37.1331103675,37.1170991789,37.1011398641,37.0852321142,
+	37.069375623,37.0535700867,37.0378152045,37.0221106777,37.0064562103,
+	36.990851509,36.9752962825,36.9597902425,36.9443331026,36.9289245791,
+	36.9135643906,36.8982522581,36.8829879046,36.8677710558,36.8526014395,
+	36.8374787856,36.8224028263,36.8073732962,36.7923899319,36.7774524719,
+	36.7625606573,36.747714231,36.7329129381,36.7181565255,36.7034447426,
+	36.6887773404,36.6741540721,36.6595746928,36.6450389596,36.6305466316,
+	36.6160974695,36.6016912363,36.5873276967,36.5730066171,36.5587277661,
+	36.5444909137,36.530295832,36.5161422947,36.5020300775,36.4879589576,
+	36.473928714,36.4599391274,36.4459899804,36.4320810569,36.4182121427,
+	36.4043830253,36.3905934937,36.3768433384,36.3631323519,36.3494603278,
+	36.3358270615,36.32223235,36.3086759918,36.2951577868,36.2816775364,
+	36.2682350438,36.2548301133,36.2414625508,36.2281321637,36.2148387608,
+	36.2015821522,36.1883621497,36.1751785661,36.1620312159,36.1489199148,
+	36.1358444799,36.1228047297,36.1098004839,36.0968315636,36.0838977911,
+	36.0709989901,36.0581349856,36.0453056038,36.0325106721,36.0197500193,
+	36.0070234752,35.9943308711,35.9816720393,35.9690468132,35.9564550278,
+	35.9438965189,35.9313711235,35.9188786799,35.9064190275,35.8939920068,
+	35.8815974594,35.869235228,35.8569051565,35.8446070897,35.8323408738,
+	35.8201063558,35.8079033838,35.7957318069,35.7835914756,35.771482241,
+	35.7594039553,35.747356472,35.7353396454,35.7233533306,35.7113973841,
+	35.6994716631,35.6875760259,35.6757103316,35.6638744405,35.6520682136,
+	35.640291513,35.6285442016,35.6168261434,35.6051372032,35.5934772466,
+	35.5818461403,35.5702437517,35.5586699493,35.5471246023,35.5356075808,
+	35.5241187557,35.512657999,35.5012251833,35.489820182,35.4784428696,
+	35.4670931211,35.4557708126,35.4444758209,35.4332080234,35.4219672987,
+	35.4107535258,35.3995665848,35.3884063562,35.3772727218,35.3661655635,
+	35.3550847646,35.3440302088,35.3330017805,35.321999365,35.3110228483,
+	35.300072117,35.2891470586,35.2782475612,35.2673735136,35.2565248054,
+	35.2457013268,35.2349029688,35.2241296228,35.2133811812,35.2026575371,
+	35.1919585838,35.1812842159,35.1706343282,35.1600088162,35.1494075763,
+	35.1388305053,35.1282775008,35.1177484608,35.1072432842,35.0967618704,
+	35.0863041192,35.0758699315,35.0654592084,35.0550718516,35.0447077637,
+	35.0343668477,35.0240490072,35.0137541462,35.0034821697,34.9932329829,
+	34.9830064918,34.9728026027,34.9626212228,34.9524622596,34.9423256212,
+	34.9322112164,34.9221189543,34.9120487447,34.9020004979,34.8919741248,
+	34.8819695366,34.8719866453,34.8620253633,34.8520856033,34.842167279,
+	34.8322703041,34.8223945932,34.8125400611,34.8027066232,34.7928941955,
+	34.7831026943,34.7733320366,34.7635821397,34.7538529214,34.7441443,
+	34.7344561944,34.7247885237,34.7151412076,34.7055141664,34.6959073207,
+	34.6863205914,34.6767539002,34.6672071689,34.6576803201,34.6481732765,
+	34.6386859615,34.6292182987,34.6197702123,34.6103416268,34.6009324673,
+	34.5915426592,34.5821721282,34.5728208006,34.5634886031,34.5541754628,
+	34.544881307,34.5356060638,34.5263496612,34.517112028,34.5078930933,
+	34.4986927864,34.4895110373,34.4803477761,34.4712029334,34.4620764403,
+	34.4529682279,34.4438782282,34.4348063732,34.4257525953,34.4167168273,
+	34.4076990026,34.3986990546,34.3897169172,34.3807525248,34.3718058119,
+	34.3628767135,34.353965165,34.3450711019,34.3361944604,34.3273351768,
+	34.3184931877,34.3096684302,34.3008608417,34.2920703598,34.2832969226,
+	34.2745404684,34.2658009359,34.2570782641,34.2483723923,34.2396832601,
+	34.2310108075,34.2223549748,34.2137157025,34.2050929316,34.1964866032,
+	34.1878966587,34.1793230401,34.1707656894,34.1622245491,34.1536995617,
+	34.1451906704,34.1366978184,34.1282209493,34.1197600069,34.1113149355,
+	34.1028856794,34.0944721833,34.0860743924,34.0776922518,34.0693257072,
+	34.0609747043,34.0526391894,34.0443191087,34.0360144089,34.027725037,
+	34.0194509401,34.0111920657,34.0029483616,33.9947197757,33.9865062562,
+	33.9783077517,33.970124211,33.9619555829,33.9538018168,33.9456628623,
+	33.937538669,33.929429187,33.9213343666,33.9132541583,33.9051885128,
+	33.8971373811,33.8891007144,33.8810784643,33.8730705825,33.8650770208,
+	33.8570977314,33.8491326669,33.8411817798,33.833245023,33.8253223496,
+	33.8174137129,33.8095190666,33.8016383643,33.7937715601,33.7859186082,
+	33.7780794631,33.7702540793,33.7624424119,33.7546444159,33.7468600466,
+	33.7390892595,33.7313320104,33.7235882552,33.7158579501,33.7081410514,
+	33.7004375158,33.6927472999,33.6850703608,33.6774066556,33.6697561417,
+	33.6621187768,33.6544945186,33.646883325,33.6392851544,33.6316999649,
+	33.6241277153,33.6165683642,33.6090218706,33.6014881937,33.5939672928,
+	33.5864591274,33.5789636572,33.5714808422,33.5640106423,33.5565530179,
+	33.5491079294,33.5416753374,33.5342552028,33.5268474865,33.5194521497,
+	33.5120691538,33.5046984602,33.4973400307,33.489993827,33.4826598114,
+	33.475337946,33.4680281931,33.4607305153,33.4534448754,33.4461712362,
+	33.4389095608,33.4316598125,33.4244219546,33.4171959506,33.4099817644,
+	33.4027793597,33.3955887006,33.3884097513,33.3812424763,33.3740868399,
+	33.3669428069,33.3598103421,33.3526894105,33.3455799772,33.3384820076,
+	33.3313954671,33.3243203212,33.3172565359,33.3102040768,33.3031629102,
+	33.2961330022,33.2891143192,33.2821068276,33.2751104942,33.2681252856,
+	33.2611511689,33.254188111,33.2472360793,33.2402950411,33.2333649639,
+	33.2264458153,33.2195375632,33.2126401754,33.20575362,33.1988778652,
+	33.1920128793,33.1851586308,33.1783150883,33.1714822206,33.1646599965,
+	33.157848385,33.1510473553,33.1442568766,33.1374769184,33.1307074501,
+	33.1239484414,33.1171998621,33.1104616821,33.1037338714,33.0970164003,
+	33.090309239,33.0836123579,33.0769257276,33.0702493187,33.063583102,
+	33.0569270484,33.050281129,33.0436453148,33.0370195773,33.0304038877,
+	33.0237982176,33.0172025386,33.0106168224,33.004041041,32.9974751662,
+	32.9909191702,32.9843730252,32.9778367035,32.9713101775,32.9647934199,
+	32.9582864031,32.9517891002,32.9453014838,32.938823527,32.932355203,
+	32.9258964848,32.919447346,32.9130077598,32.9065776998,32.9001571398,
+	32.8937460533,32.8873444143,32.8809521968,32.8745693748,32.8681959225,
+	32.8618318142,32.8554770243,32.8491315272,32.8427952975,32.8364683099,
+	32.8301505393,32.8238419604,32.8175425484,32.8112522782,32.8049711251,
+	32.7986990644,32.7924360713,32.7861821216,32.7799371906,32.7737012541,
+	32.7674742879,32.7612562677,32.7550471697,32.7488469698,32.7426556442,
+	32.7364731692,32.730299521,32.7241346761,32.717978611,32.7118313024,
+	32.705692727,32.6995628615,32.6934416828,32.6873291679,32.6812252939,
+	32.6751300379,32.6690433772,32.6629652891,32.656895751,32.6508347404,
+	32.6447822349,32.6387382122,32.6327026501,32.6266755264,32.620656819,
+	32.614646506,32.6086445654,32.6026509754,32.5966657144,32.5906887606,
+	32.5847200926,32.5787596887,32.5728075277,32.5668635881,32.5609278488,
+	32.5550002886,32.5490808863,32.5431696211,32.537266472,32.5313714181,
+	32.5254844387,32.519605513,32.5137346206,32.5078717408,32.5020168532,
+	32.4961699374,32.4903309731,32.4844999401,32.4786768182,32.4728615874,
+	32.4670542276,32.4612547189,32.4554630416,32.4496791757,32.4439031016,
+	32.4381347996,32.4323742503,32.426621434,32.4208763314,32.4151389231,
+	32.4094091899,32.4036871126,32.3979726719,32.3922658489,32.3865666246,
+	32.38087498,32.3751908962,32.3695143546,32.3638453363,32.3581838227,
+	32.3525297952,32.3468832354,32.3412441247,32.3356124448,32.3299881773,
+	32.3243713041,32.3187618069,32.3131596676,32.3075648682,32.3019773906,
+	32.296397217,32.2908243294,32.2852587101,32.2797003414,32.2741492056,
+	32.268605285,32.2630685622,32.2575390196,32.2520166399,32.2465014056,
+	32.2409932995,32.2354923044,32.229998403,32.2245115783,32.2190318133,
+	32.2135590908,32.208093394,32.202634706,32.1971830101,32.1917382894,
+	32.1863005272,32.1808697069,32.175445812,32.170028826,32.1646187322,
+	32.1592155144,32.1538191563,32.1484296414,32.1430469536,32.1376710768,
+	32.1323019947,32.1269396913,32.1215841506,32.1162353567,32.1108932936,
+	32.1055579455,32.1002292966,32.0949073313,32.0895920337,32.0842833883,
+	32.0789813795,32.0736859917,32.0683972096,32.0631150177,32.0578394006,
+	32.052570343,32.0473078297,32.0420518455,32.0368023751,32.0315594036,
+	32.0263229158,32.0210928968,32.0158693316,32.0106522053,32.0054415031,
+	32.0002372101,31.9950393117,31.989847793,31.9846626396,31.9794838367,
+	31.9743113698,31.9691452245,31.9639853862,31.9588318406,31.9536845733,
+	31.9485435701,31.9434088165,31.9382802985,31.9331580018,31.9280419124,
+	31.9229320162,31.9178282991,31.9127307472,31.9076393466,31.9025540833,
+	31.8974749435,31.8924019134,31.8873349793,31.8822741275,31.8772193443,
+	31.8721706161,31.8671279293,31.8620912705,31.857060626,31.8520359826,
+	31.8470173268,31.8420046452,31.8369979246,31.8319971517,31.8270023133,
+	31.8220133962,31.8170303872,31.8120532733,31.8070820415,31.8021166787,
+	31.797157172,31.7922035084,31.7872556751,31.7823136593,31.7773774481,
+	31.7724470288,31.7675223886,31.762603515,31.7576903953,31.7527830168,
+	31.7478813671,31.7429854336,31.7380952039,31.7332106655,31.728331806,
+	31.7234586132,31.7185910746,31.713729178,31.7088729112,31.7040222619,
+	31.6991772181,31.6943377676,31.6895038984,31.6846755983,31.6798528554,
+	31.6750356577,31.6702239933,31.6654178504,31.660617217,31.6558220813,
+	31.6510324316,31.6462482561,31.6414695432,31.636696281,31.6319284582,
+	31.6271660629,31.6224090837,31.6176575091,31.6129113276,31.6081705277,
+	31.6034350979,31.5987050271,31.5939803036,31.5892609164,31.5845468541,
+	31.5798381054,31.5751346592,31.5704365043,31.5657436296,31.5610560239,
+	31.5563736762,31.5516965754,31.5470247107,31.5423580709,31.5376966452,
+	31.5330404227,31.5283893925,31.5237435438,31.5191028657,31.5144673476,
+	31.5098369787,31.5052117483,31.5005916457,31.4959766602,31.4913667814,
+	31.4867619986,31.4821623013,31.477567679,31.4729781212,31.4683936175,
+	31.4638141574,31.4592397306,31.4546703267,31.4501059355,31.4455465465,
+	31.4409921497,31.4364427347,31.4318982914,31.4273588096,31.4228242792,
+	31.4182946901,31.4137700321,31.4092502953,31.4047354697,31.4002255452,
+	31.395720512,31.39122036,31.3867250795,31.3822346605,31.3777490932,
+	31.3732683678,31.3687924745,31.3643214037,31.3598551455,31.3553936903,
+	31.3509370284,31.3464851502,31.3420380461,31.3375957065,31.3331581218,
+	31.3287252826,31.3242971794,31.3198738027,31.315455143,31.311041191,
+	31.3066319372,31.3022273724,31.2978274871,31.2934322722,31.2890417183,
+	31.2846558161,31.2802745565,31.2758979303,31.2715259284,31.2671585414,
+	31.2627957605,31.2584375764,31.2540839802,31.2497349627,31.245390515,
+	31.2410506282,31.2367152932,31.2323845011,31.228058243,31.2237365101,
+	31.2194192934,31.2151065843,31.2107983738,31.2064946532,31.2021954137,
+	31.1979006466,31.1936103433,31.189324495,31.1850430931,31.180766129,
+	31.176493594,31.1722254796,31.1679617772,31.1637024784,31.1594475745,
+	31.1551970572,31.1509509179,31.1467091483,31.1424717399,31.1382386843,
+	31.1340099732,31.1297855982,31.1255655511,31.1213498235,31.1171384071,
+	31.1129312938,31.1087284753,31.1045299434,31.1003356899,31.0961457067,
+	31.0919599856
+	}}
+};
diff --git a/examples/faust-tubes/valve/6DJ8.cc b/examples/faust-tubes/valve/6DJ8.cc
new file mode 100644
index 0000000..e427e34
--- /dev/null
+++ b/examples/faust-tubes/valve/6DJ8.cc
@@ -0,0 +1,819 @@
+// generated by ../../tools/tube_transfer.py
+// tube: 6DJ8
+// plate current function: triode
+// mu: 28
+// kx: 1.3
+// kg1: 330
+// kp: 320
+// kvb: 300
+
+table1d_imp<2001> tubetable_6DJ8[2] = {
+	{ // Ri = 68k
+	-5,5,200,2001, {
+	137.512728867,137.399223264,137.285690251,137.17212984,137.058542039,
+	136.944926859,136.831284308,136.717614396,136.603917133,136.490192528,
+	136.37644059,136.262661328,136.148854752,136.035020871,135.921159694,
+	135.80727123,135.693355487,135.579412475,135.465442203,135.351444679,
+	135.237419911,135.12336791,135.009288682,134.895182238,134.781048584,
+	134.66688773,134.552699684,134.438484454,134.324242049,134.209972477,
+	134.095675745,133.981351862,133.867000836,133.752622675,133.638217387,
+	133.523784979,133.40932546,133.294838836,133.180325116,133.065784308,
+	132.951216418,132.836621455,132.721999425,132.607350337,132.492674197,
+	132.377971012,132.263240791,132.148483539,132.033699265,131.918887974,
+	131.804049675,131.689184374,131.574292077,131.459372792,131.344426526,
+	131.229453284,131.114453074,130.999425902,130.884371775,130.769290699,
+	130.654182681,130.539047726,130.423885842,130.308697033,130.193481308,
+	130.078238671,129.962969128,129.847672686,129.732349351,129.616999128,
+	129.501622024,129.386218043,129.270787192,129.155329476,129.039844901,
+	128.924333473,128.808795197,128.693230078,128.577638121,128.462019333,
+	128.346373717,128.230701281,128.115002027,127.999275963,127.883523091,
+	127.767743419,127.65193695,127.536103689,127.420243641,127.304356811,
+	127.188443204,127.072502824,126.956535675,126.840541763,126.724521091,
+	126.608473664,126.492399486,126.376298562,126.260170896,126.144016492,
+	126.027835354,125.911627486,125.795392892,125.679131576,125.562843542,
+	125.446528794,125.330187335,125.213819169,125.0974243,124.981002732,
+	124.864554467,124.74807951,124.631577864,124.515049532,124.398494517,
+	124.281912824,124.165304454,124.048669411,123.932007699,123.815319319,
+	123.698604276,123.581862572,123.465094209,123.348299192,123.231477521,
+	123.114629201,122.997754234,122.880852622,122.763924367,122.646969473,
+	122.529987942,122.412979775,122.295944976,122.178883547,122.061795488,
+	121.944680804,121.827539496,121.710371565,121.593177014,121.475955845,
+	121.358708059,121.241433658,121.124132644,121.006805019,120.889450784,
+	120.772069941,120.654662491,120.537228435,120.419767776,120.302280513,
+	120.18476665,120.067226186,119.949659123,119.832065462,119.714445204,
+	119.596798349,119.4791249,119.361424857,119.24369822,119.12594499,
+	119.008165168,118.890358755,118.772525751,118.654666156,118.536779972,
+	118.418867198,118.300927835,118.182961883,118.064969342,117.946950213,
+	117.828904495,117.710832189,117.592733295,117.474607812,117.356455741,
+	117.238277081,117.120071832,117.001839993,116.883581565,116.765296547,
+	116.646984939,116.52864674,116.410281948,116.291890565,116.173472589,
+	116.055028019,115.936556854,115.818059094,115.699534738,115.580983784,
+	115.462406232,115.343802081,115.225171329,115.106513975,114.987830018,
+	114.869119456,114.750382289,114.631618514,114.51282813,114.394011136,
+	114.27516753,114.15629731,114.037400475,113.918477022,113.799526951,
+	113.680550258,113.561546942,113.442517002,113.323460434,113.204377236,
+	113.085267407,112.966130945,112.846967846,112.727778109,112.608561731,
+	112.489318709,112.370049041,112.250752725,112.131429757,112.012080135,
+	111.892703857,111.773300918,111.653871317,111.53441505,111.414932115,
+	111.295422508,111.175886226,111.056323266,110.936733624,110.817117298,
+	110.697474283,110.577804577,110.458108176,110.338385076,110.218635274,
+	110.098858766,109.979055549,109.859225617,109.739368969,109.619485599,
+	109.499575504,109.379638679,109.259675121,109.139684826,109.019667789,
+	108.899624005,108.779553471,108.659456182,108.539332134,108.419181322,
+	108.299003742,108.178799389,108.058568258,107.938310344,107.818025643,
+	107.697714149,107.577375859,107.457010766,107.336618867,107.216200154,
+	107.095754624,106.975282272,106.854783091,106.734257077,106.613704224,
+	106.493124526,106.372517979,106.251884576,106.131224312,106.010537181,
+	105.889823177,105.769082295,105.648314528,105.52751987,105.406698316,
+	105.28584986,105.164974495,105.044072215,104.923143013,104.802186884,
+	104.681203821,104.560193818,104.439156867,104.318092963,104.197002099,
+	104.075884268,103.954739463,103.833567678,103.712368905,103.591143138,
+	103.46989037,103.348610593,103.2273038,103.105969985,102.98460914,
+	102.863221257,102.74180633,102.62036435,102.498895311,102.377399205,
+	102.255876023,102.134325759,102.012748405,101.891143952,101.769512394,
+	101.647853721,101.526167926,101.404455002,101.282714939,101.16094773,
+	101.039153366,100.917331839,100.795483141,100.673607263,100.551704197,
+	100.429773934,100.307816465,100.185831783,100.063819877,99.9417807401,
+	99.8197143622,99.6976207349,99.575499849,99.4533516955,99.3311762653,
+	99.2089735491,99.0867435378,98.964486222,98.8422015924,98.7198896394,
+	98.5975503536,98.4751837255,98.3527897454,98.2303684035,98.1079196902,
+	97.9854435957,97.86294011,97.7404092232,97.6178509253,97.4952652063,
+	97.3726520559,97.250011464,97.1273434204,97.0046479148,96.8819249367,
+	96.7591744756,96.6363965212,96.5135910627,96.3907580897,96.2678975913,
+	96.1450095569,96.0220939755,95.8991508364,95.7761801285,95.6531818408,
+	95.5301559623,95.4071024818,95.2840213882,95.1609126701,95.0377763163,
+	94.9146123152,94.7914206556,94.6682013258,94.5449543144,94.4216796095,
+	94.2983771996,94.1750470729,94.0516892175,93.9283036216,93.8048902731,
+	93.6814491601,93.5579802705,93.4344835922,93.3109591128,93.1874068203,
+	93.0638267021,92.940218746,92.8165829395,92.6929192701,92.5692277251,
+	92.4455082919,92.3217609579,92.1979857102,92.0741825361,91.9503514226,
+	91.8264923567,91.7026053255,91.5786903159,91.4547473147,91.3307763088,
+	91.2067772848,91.0827502295,90.9586951294,90.8346119711,90.7105007411,
+	90.5863614258,90.4621940116,90.3379984848,90.2137748316,90.0895230382,
+	89.9652430908,89.8409349754,89.7165986779,89.5922341844,89.4678414807,
+	89.3434205527,89.218971386,89.0944939665,88.9699882796,88.8454543111,
+	88.7208920464,88.596301471,88.4716825703,88.3470353296,88.2223597342,
+	88.0976557693,87.9729234202,87.8481626718,87.7233735093,87.5985559176,
+	87.4737098817,87.3488353864,87.2239324165,87.0990009569,86.9740409921,
+	86.8490525069,86.7240354858,86.5989899134,86.4739157741,86.3488130523,
+	86.2236817325,86.0985217988,85.9733332355,85.8481160269,85.7228701571,
+	85.5975956101,85.47229237,85.3469604207,85.2215997461,85.0962103302,
+	84.9707921567,84.8453452094,84.719869472,84.5943649281,84.4688315614,
+	84.3432693553,84.2176782934,84.092058359,83.9664095357,83.8407318067,
+	83.7150251553,83.5892895648,83.4635250183,83.337731499,83.2119089899,
+	83.0860574742,82.9601769347,82.8342673545,82.7083287164,82.5823610033,
+	82.456364198,82.3303382832,82.2042832416,82.078199056,81.9520857088,
+	81.8259431828,81.6997714604,81.5735705241,81.4473403564,81.3210809396,
+	81.1947922561,81.0684742883,80.9421270183,80.8157504285,80.6893445011,
+	80.5629092181,80.4364445617,80.309950514,80.1834270571,80.0568741728,
+	79.9302918433,79.8036800504,79.677038776,79.550368002,79.4236677102,
+	79.2969378824,79.1701785004,79.0433895459,78.9165710006,78.7897228462,
+	78.6628450643,78.5359376366,78.4090005446,78.2820337698,78.1550372939,
+	78.0280110983,77.9009551645,77.7738694739,77.6467540081,77.5196087483,
+	77.3924336761,77.2652287728,77.1379940197,77.0107293981,76.8834348895,
+	76.756110475,76.6287561361,76.5013718539,76.3739576098,76.2465133849,
+	76.1190391605,75.9915349179,75.8640006383,75.7364363029,75.6088418928,
+	75.4812173894,75.3535627738,75.2258780272,75.0981631308,74.9704180658,
+	74.8426428134,74.7148373548,74.5870016713,74.459135744,74.3312395542,
+	74.203313083,74.0753563118,73.9473692218,73.8193517943,73.6913040105,
+	73.5632258517,73.4351172993,73.3069783346,73.178808939,73.0506090938,
+	72.9223787804,72.7941179804,72.6658266751,72.537504846,72.4091524748,
+	72.2807695429,72.1523560319,72.0239119235,71.8954371994,71.7669318413,
+	71.6383958309,71.5098291501,71.3812317808,71.2526037048,71.1239449041,
+	70.9952553608,70.866535057,70.7377839747,70.6090020962,70.4801894039,
+	70.3513458799,70.2224715068,70.0935662671,69.9646301433,69.835663118,
+	69.706665174,69.5776362942,69.4485764614,69.3194856586,69.190363869,
+	69.0612110757,68.932027262,68.8028124113,68.6735665071,68.544289533,
+	68.4149814728,68.2856423104,68.1562720296,68.0268706146,67.8974380496,
+	67.767974319,67.6384794072,67.508953299,67.379395979,67.2498074323,
+	67.1201876439,66.990536599,66.8608542831,66.7311406816,66.6013957805,
+	66.4716195655,66.3418120229,66.2119731387,66.0821028996,65.9522012923,
+	65.8222683035,65.6923039203,65.5623081301,65.4322809203,65.3022222787,
+	65.1721321933,65.0420106521,64.9118576437,64.7816731566,64.65145718,
+	64.5212097028,64.3909307146,64.2606202051,64.1302781642,63.9999045824,
+	63.86949945,63.7390627581,63.6085944978,63.4780946606,63.3475632383,
+	63.2170002231,63.0864056074,62.955779384,62.8251215463,62.6944320876,
+	62.563711002,62.4329582837,62.3021739275,62.1713579283,62.0405102818,
+	61.9096309838,61.7787200307,61.6477774192,61.5168031466,61.3857972106,
+	61.2547596093,61.1236903414,60.9925894061,60.8614568029,60.7302925321,
+	60.5990965942,60.4678689907,60.3366097231,60.205318794,60.0739962062,
+	59.9426419632,59.8112560693,59.6798385291,59.5483893481,59.4169085323,
+	59.2853960884,59.1538520239,59.0222763469,58.8906690661,58.7590301912,
+	58.6273597325,58.4956577011,58.3639241087,58.2321589683,58.1003622931,
+	57.9685340977,57.8366743971,57.7047832076,57.5728605462,57.4409064308,
+	57.3089208804,57.1769039148,57.0448555549,56.9127758226,56.7806647409,
+	56.6485223339,56.5163486267,56.3841436456,56.251907418,56.1196399725,
+	55.9873413389,55.8550115484,55.7226506333,55.5902586273,55.4578355654,
+	55.3253814839,55.1928964206,55.0603804149,54.9278335073,54.7952557401,
+	54.6626471571,54.5300078037,54.3973377269,54.2646369754,54.1319055996,
+	53.9991436517,53.8663511857,53.7335282574,53.6006749245,53.4677912468,
+	53.3348772861,53.2019331059,53.0689587724,52.9359543534,52.8029199192,
+	52.6698555425,52.5367612981,52.4036372633,52.2704835179,52.1373001442,
+	52.0040872271,51.8708448542,51.7375731158,51.6042721052,51.4709419183,
+	51.3375826542,51.204194415,51.070777306,50.9373314355,50.8038569154,
+	50.6703538609,50.5368223907,50.4032626271,50.2696746961,50.1360587275,
+	50.0024148551,49.8687432167,49.7350439541,49.6013172136,49.4675631456,
+	49.3337819053,49.1999736524,49.0661385513,48.9322767715,48.7983884873,
+	48.6644738783,48.5305331297,48.3965664318,48.2625739808,48.1285559787,
+	47.9945126336,47.8604441597,47.7263507774,47.592232714,47.4580902033,
+	47.3239234861,47.1897328106,47.0555184321,46.9212806137,46.7870196261,
+	46.6527357484,46.5184292679,46.3841004803,46.2497496903,46.1153772119,
+	45.9809833681,45.846568492,45.7121329263,45.5776770243,45.4432011498,
+	45.3087056776,45.1741909936,45.0396574956,44.9051055933,44.7705357088,
+	44.635948277,44.5013437459,44.3667225771,44.2320852465,44.0974322441,
+	43.962764075,43.8280812598,43.6933843349,43.5586738531,43.4239503843,
+	43.2892145156,43.1544668524,43.0197080186,42.8849386573,42.7501594316,
+	42.6153710249,42.4805741417,42.3457695087,42.2109578746,42.0761400117,
+	41.9413167163,41.8064888093,41.6716571374,41.5368225735,41.401986018,
+	41.2671483992,41.1323106748,40.9974738322,40.8626388899,40.7278068984,
+	40.5929789412,40.4581561358,40.3233396351,40.1885306281,40.0537303414,
+	39.9189400403,39.78416103,39.6493946568,39.5146423098,39.3799054219,
+	39.2451854712,39.1104839826,38.9758025293,38.8411427342,38.7065062715,
+	38.5718948684,38.4373103067,38.3027544245,38.1682291179,38.0337363429,
+	37.8992781174,37.7648565227,37.6304737057,37.4961318809,37.3618333323,
+	37.2275804158,37.093375561,36.9592212736,36.8251201375,36.6910748171,
+	36.55708806,36.4231626987,36.2893016539,36.1555079361,36.0217846488,
+	35.8881349906,35.7545622582,35.6210698488,35.4876612628,35.3543401068,
+	35.2211100958,35.0879750567,34.9549389303,34.822005775,34.6891797689,
+	34.556465213,34.4238665343,34.2913882882,34.1590351614,34.0268119754,
+	33.8947236884,33.7627753988,33.6309723478,33.499319922,33.3678236562,
+	33.236489236,33.1053225003,32.9743294439,32.8435162196,32.7128891409,
+	32.5824546835,32.4522194881,32.3221903615,32.1923742787,32.0627783842,
+	31.9334099937,31.8042765947,31.6753858474,31.5467455858,31.4183638174,
+	31.2902487238,31.1624086599,31.0348521538,30.9075879057,30.7806247864,
+	30.6539718359,30.5276382612,30.4016334335,30.275966886,30.1506483095,
+	30.0256875494,29.9010946007,29.7768796032,29.6530528365,29.5296247133,
+	29.4066057737,29.2840066773,29.1618381963,29.0401112068,28.9188366802,
+	28.7980256739,28.6776893212,28.557838821,28.4384854266,28.3196404341,
+	28.2013151706,28.083520981,27.9662692154,27.8495712153,27.7334382994,
+	27.6178817497,27.502912796,27.3885426015,27.274782247,27.1616427153,
+	27.0491348756,26.9372694673,26.8260570842,26.7155081583,26.605632944,
+	26.4964415017,26.3879436828,26.2801491135,26.1730671799,26.066707013,
+	25.9610774742,25.8561871411,25.7520442943,25.6486569043,25.5460326191,
+	25.4441787527,25.343102274,25.2428097972,25.1433075719,25.0446014749,
+	24.9466970027,24.8495992647,24.7533129776,24.6578424604,24.5631916308,
+	24.4693640021,24.3763626815,24.284190369,24.1928493573,24.102341533,
+	24.0126683781,23.9238309727,23.8358299992,23.7486657456,23.6623381119,
+	23.576846615,23.492190396,23.4083682275,23.3253785212,23.2432193369,
+	23.1618883911,23.0813830671,23.0017004246,22.9228372103,22.8447898684,
+	22.7675545521,22.6911271343,22.6155032194,22.5406781549,22.4666470431,
+	22.3934047528,22.3209459315,22.2492650165,22.1783562475,22.1082136777,
+	22.0388311858,21.9702024871,21.9023211449,21.8351805819,21.7687740907,
+	21.7030948443,21.6381359073,21.573890245,21.5103507342,21.4475101722,
+	21.3853612859,21.3238967417,21.2631091529,21.2029910891,21.1435350836,
+	21.0847336411,21.0265792455,20.9690643664,20.9121814661,20.8559230061,
+	20.800281453,20.7452492842,20.6908189936,20.6369830967,20.5837341354,
+	20.5310646827,20.4789673469,20.4274347758,20.3764596604,20.3260347384,
+	20.2761527978,20.2268066794,20.1779892802,20.1296935556,20.081912522,
+	20.034639259,19.9878669114,19.941588691,19.8957978783,19.8504878237,
+	19.8056519493,19.7612837498,19.7173767936,19.6739247233,19.6309212573,
+	19.5883601896,19.5462353909,19.5045408084,19.4632704669,19.4224184683,
+	19.3819789922,19.3419462957,19.3023147134,19.2630786571,19.2242326162,
+	19.1857711566,19.1476889213,19.109980629,19.0726410748,19.0356651289,
+	18.9990477362,18.9627839162,18.9268687619,18.8912974396,18.8560651877,
+	18.8211673166,18.7865992077,18.7523563125,18.7184341523,18.6848283169,
+	18.6515344643,18.6185483195,18.5858656739,18.5534823845,18.5213943728,
+	18.4895976244,18.4580881876,18.4268621732,18.3959157529,18.3652451591,
+	18.3348466836,18.3047166771,18.2748515479,18.2452477615,18.2159018395,
+	18.1868103586,18.1579699502,18.1293772992,18.1010291432,18.0729222719,
+	18.0450535259,18.0174197962,17.9900180234,17.9628451967,17.9358983531,
+	17.9091745768,17.8826709984,17.856384794,17.8303131846,17.804453435,
+	17.7788028537,17.7533587915,17.7281186413,17.7030798369,17.6782398529,
+	17.6535962035,17.629146442,17.60488816,17.5808189872,17.5569365901,
+	17.5332386719,17.5097229715,17.4863872631,17.4632293556,17.4402470917,
+	17.4174383478,17.3948010329,17.3723330884,17.3500324875,17.3278972343,
+	17.3059253639,17.2841149411,17.2624640605,17.2409708457,17.2196334488,
+	17.19845005,17.177418857,17.1565381047,17.1358060544,17.1152209936,
+	17.0947812357,17.0744851191,17.0543310071,17.0343172874,17.0144423714,
+	16.9947046944,16.9751027147,16.9556349131,16.9362997931,16.9170958798,
+	16.8980217202,16.8790758822,16.8602569547,16.8415635471,16.8229942888,
+	16.804547829,16.7862228364,16.7680179988,16.7499320229,16.7319636336,
+	16.714111574,16.6963746054,16.6787515061,16.661241072,16.6438421159,
+	16.6265534672,16.6093739717,16.5923024914,16.5753379039,16.5584791027,
+	16.5417249963,16.5250745085,16.5085265778,16.4920801573,16.4757342144,
+	16.4594877306,16.4433397013,16.4272891353,16.4113350551,16.3954764962,
+	16.3797125071,16.3640421492,16.3484644962,16.3329786343,16.3175836618,
+	16.3022786889,16.2870628377,16.2719352417,16.2568950459,16.2419414064,
+	16.2270734904,16.2122904759,16.1975915515,16.1829759164,16.1684427801,
+	16.1539913623,16.1396208926,16.1253306106,16.1111197655,16.0969876161,
+	16.0829334306,16.0689564863,16.0550560698,16.0412314765,16.0274820108,
+	16.0138069857,16.0002057227,15.9866775518,15.9732218113,15.9598378476,
+	15.9465250152,15.9332826765,15.9201102017,15.9070069688,15.8939723631,
+	15.8810057776,15.8681066125,15.8552742754,15.8425081808,15.8298077503,
+	15.8171724125,15.8046016028,15.7920947632,15.7796513423,15.7672707954,
+	15.754952584,15.7426961761,15.7305010459,15.7183666735,15.7062925455,
+	15.694278154,15.6823229973,15.6704265793,15.6585884097,15.6468080039,
+	15.6350848828,15.6234185725,15.611808605,15.6002545171,15.5887558512,
+	15.5773121548,15.5659229802,15.5545878851,15.543306432,15.5320781883,
+	15.5209027261,15.5097796223,15.4987084586,15.4876888213,15.476720301,
+	15.465802493,15.454934997,15.4441174172,15.4333493618,15.4226304434,
+	15.4119602788,15.4013384891,15.3907646991,15.3802385379,15.3697596385,
+	15.3593276378,15.3489421765,15.3386028993,15.3283094545,15.3180614942,
+	15.3078586739,15.2977006532,15.2875870947,15.277517665,15.267492034,
+	15.2575098748,15.2475708642,15.2376746822,15.2278210121,15.2180095404,
+	15.208239957,15.1985119547,15.1888252296,15.1791794809,15.1695744108,
+	15.1600097243,15.1504851298,15.1410003383,15.1315550638,15.1221490232,
+	15.1127819361,15.1034535249,15.094163515,15.0849116342,15.0756976132,
+	15.0665211851,15.057382086,15.0482800541,15.0392148306,15.030186159,
+	15.0211937853,15.012237458,15.003316928,14.9944319486,14.9855822755,
+	14.9767676668,14.9679878826,14.9592426857,14.950531841,14.9418551155,
+	14.9332122786,14.9246031017,14.9160273584,14.9074848247,14.8989752782,
+	14.8904984989,14.8820542689,14.8736423721,14.8652625946,14.8569147243,
+	14.8485985512,14.8403138672,14.832060466,14.8238381434,14.8156466968,
+	14.8074859258,14.7993556314,14.7912556167,14.7831856865,14.7751456474,
+	14.7671353076,14.7591544771,14.7512029678,14.7432805929,14.7353871675,
+	14.7275225084,14.7196864338,14.7118787638,14.7040993197,14.6963479248,
+	14.6886244037,14.6809285825,14.6732602889,14.6656193522,14.6580056031,
+	14.6504188737,14.6428589975,14.6353258098,14.6278191469,14.6203388467,
+	14.6128847485,14.6054566928,14.5980545218,14.5906780788,14.5833272083,
+	14.5760017565,14.5687015706,14.5614264991,14.554176392,14.5469511003,
+	14.5397504764,14.532574374,14.5254226477,14.5182951536,14.511191749,
+	14.5041122922,14.4970566428,14.4900246616,14.4830162103,14.476031152,
+	14.4690693508,14.4621306719,14.4552149818,14.4483221476,14.4414520381,
+	14.4346045227,14.427779472,14.4209767576,14.4141962524,14.4074378298,
+	14.4007013648,14.3939867329,14.3872938109,14.3806224764,14.3739726081,
+	14.3673440856,14.3607367896,14.3541506013,14.3475854034,14.3410410791,
+	14.3345175128,14.3280145895,14.3215321954,14.3150702174,14.3086285433,
+	14.3022070619,14.2958056626,14.2894242359,14.283062673,14.276720866,
+	14.2703987079,14.2640960923,14.2578129137,14.2515490676,14.24530445,
+	14.2390789579,14.232872489,14.2266849416,14.2205162152,14.2143662096,
+	14.2082348255,14.2021219646,14.1960275289,14.1899514215,14.1838935459,
+	14.1778538067,14.1718321088,14.165828358,14.1598424609,14.1538743246,
+	14.1479238569,14.1419909664,14.1360755623,14.1301775544,14.1242968532,
+	14.11843337,14.1125870164,14.106757705,14.1009453487,14.0951498615,
+	14.0893711574,14.0836091515,14.0778637594,14.0721348971,14.0664224814,
+	14.0607264296,14.0550466597,14.0493830902,14.0437356402,14.0381042293,
+	14.0324887777,14.0268892062,14.0213054361,14.0157373894,14.0101849885,
+	14.0046481563,13.9991268163,13.9936208926,13.9881303098,13.9826549929,
+	13.9771948675,13.9717498598,13.9663198964,13.9609049044,13.9555048114,
+	13.9501195456,13.9447490356,13.9393932105,13.9340519998,13.9287253336,
+	13.9234131425,13.9181153575,13.91283191,13.9075627319,13.9023077557,
+	13.8970669141,13.8918401405,13.8866273686,13.8814285326,13.876243567,
+	13.871072407,13.865914988,13.860771246,13.8556411172,13.8505245383,
+	13.8454214467,13.8403317797,13.8352554755,13.8301924725,13.8251427093,
+	13.8201061252,13.8150826598,13.8100722531,13.8050748454,13.8000903775,
+	13.7951187905,13.790160026,13.7852140259,13.7802807323,13.775360088,
+	13.7704520359,13.7655565194,13.7606734822,13.7558028685,13.7509446227,
+	13.7460986895,13.7412650141,13.7364435419,13.7316342189,13.7268369912,
+	13.7220518053,13.717278608,13.7125173466,13.7077679684,13.7030304215,
+	13.6983046538,13.693590614,13.6888882508,13.6841975133,13.679518351,
+	13.6748507136,13.6701945512,13.665549814,13.6609164529,13.6562944187,
+	13.6516836627,13.6470841366,13.6424957921,13.6379185813,13.6333524569,
+	13.6287973714,13.6242532779,13.6197201297,13.6151978803,13.6106864838,
+	13.6061858941,13.6016960656,13.5972169532,13.5927485117,13.5882906964,
+	13.5838434627,13.5794067665,13.5749805636,13.5705648106,13.5661594637,
+	13.5617644799,13.5573798162,13.5530054299,13.5486412786,13.54428732,
+	13.5399435123,13.5356098136,13.5312861826,13.526972578,13.5226689589,
+	13.5183752845,13.5140915142,13.5098176079,13.5055535255,13.5012992271,
+	13.4970546733,13.4928198245,13.4885946418,13.4843790862,13.4801731191,
+	13.4759767019,13.4717897965,13.4676123647,13.4634443689,13.4592857713,
+	13.4551365347,13.4509966219,13.4468659959,13.4427446199,13.4386324575,
+	13.4345294722,13.4304356279,13.4263508888,13.422275219,13.418208583,
+	13.4141509456,13.4101022715,13.4060625259,13.4020316739,13.3980096811,
+	13.393996513,13.3899921354,13.3859965145,13.3820096163,13.3780314073,
+	13.374061854,13.3701009232,13.3661485818,13.362204797,13.358269536,
+	13.3543427662,13.3504244554,13.3465145714,13.3426130821,13.3387199557,
+	13.3348351605,13.3309586652,13.3270904383,13.3232304487,13.3193786654,
+	13.3155350575,13.3116995946,13.3078722459,13.3040529813,13.3002417706,
+	13.2964385836,13.2926433907,13.2888561621,13.2850768682,13.2813054797,
+	13.2775419674,13.2737863022,13.2700384552,13.2662983976,13.2625661008,
+	13.2588415363,13.2551246758,13.2514154912,13.2477139545,13.2440200377,
+	13.2403337131,13.2366549531,13.2329837303,13.2293200174,13.2256637873,
+	13.2220150128,13.2183736671,13.2147397235,13.2111131554,13.2074939363,
+	13.2038820398,13.2002774397,13.19668011,13.1930900248,13.1895071582,
+	13.1859314845,13.1823629783,13.178801614,13.1752473665,13.1717002105,
+	13.168160121,13.1646270732,13.1611010422,13.1575820033,13.1540699321,
+	13.1505648041,13.1470665951,13.1435752808,13.1400908372,13.1366132404,
+	13.1331424666,13.1296784921,13.1262212933,13.1227708467,13.1193271291,
+	13.1158901171,13.1124597877,13.1090361179,13.1056190848,13.1022086655,
+	13.0988048375,13.0954075782,13.0920168651,13.0886326759,13.0852549884,
+	13.0818837805,13.0785190301,13.0751607154,13.0718088145,13.0684633057,
+	13.0651241676,13.0617913785,13.0584649171,13.0551447622,13.0518308925,
+	13.048523287,13.0452219246,13.0419267846,13.0386378462,13.0353550886,
+	13.0320784913,13.0288080338,13.0255436958,13.0222854569,13.019033297,
+	13.0157871959,13.0125471336,13.0093130904,13.0060850462,13.0028629815,
+	12.9996468766,12.9964367119,12.993232468,12.9900341256,12.9868416654,
+	12.9836550682,12.9804743149,12.9772993866,12.9741302643,12.9709669292,
+	12.9678093625,12.9646575458,12.9615114602,12.9583710875,12.9552364092,
+	12.9521074069,12.9489840625,12.9458663579,12.9427542749,12.9396477957,
+	12.9365469022,12.9334515768,12.9303618016,12.9272775591,12.9241988316,
+	12.9211256016,12.9180578519,12.9149955649,12.9119387235,12.9088873106,
+	12.9058413089,12.9028007015,12.8997654714,12.8967356018,12.8937110759,
+	12.8906918769,12.8876779882,12.8846693933,12.8816660756,12.8786680187,
+	12.8756752064,12.8726876222,12.86970525,12.8667280736,12.8637560771,
+	12.8607892443,12.8578275594,12.8548710066,12.8519195701,12.848973234,
+	12.8460319829,12.8430958011,12.8401646731,12.8372385835,12.8343175169,
+	12.831401458,12.8284903916,12.8255843025,12.8226831755,12.8197869957,
+	12.8168957481,12.8140094178,12.8111279898,12.8082514496,12.8053797822,
+	12.8025129731,12.7996510076,12.7967938713,12.7939415497,12.7910940284,
+	12.7882512929,12.7854133292,12.7825801228,12.7797516597,12.7769279257,
+	12.7741089069,12.7712945892,12.7684849587,12.7656800016,12.762879704,
+	12.7600840522,12.7572930325,12.7545066312,12.7517248349,12.74894763,
+	12.7461750029,12.7434069404,12.7406434291,12.7378844557,12.7351300068,
+	12.7323800695,12.7296346305,12.7268936767,12.7241571952,12.721425173,
+	12.7186975971,12.7159744547,12.7132557331,12.7105414194,12.7078315009,
+	12.7051259651,12.7024247993,12.699727991,12.6970355276,12.6943473968,
+	12.6916635861,12.6889840833,12.6863088759,12.6836379519,12.680971299,
+	12.678308905,12.6756507579,12.6729968456,12.6703471562,12.6677016776,
+	12.6650603981,12.6624233057,12.6597903887,12.6571616353,12.6545370337,
+	12.6519165725,12.6493002398,12.6466880242,12.6440799142,12.6414758982,
+	12.6388759649,12.6362801029,12.6336883008,12.6311005473,12.6285168312,
+	12.6259371414,12.6233614666,12.6207897957,12.6182221177,12.6156584215,
+	12.6130986962,12.6105429308,12.6079911145,12.6054432363,12.6028992855,
+	12.6003592512,12.5978231229,12.5952908898,12.5927625412,12.5902380665,
+	12.5877174553,12.585200697,12.582687781,12.580178697,12.5776734346,
+	12.5751719835,12.5726743332,12.5701804736,12.5676903943,12.5652040853,
+	12.5627215363,12.5602427373,12.5577676781,12.5552963487,12.5528287392,
+	12.5503648395,12.5479046397,12.54544813,12.5429953005,12.5405461414,
+	12.5381006428,12.5356587952,12.5332205887,12.5307860138,12.5283550607,
+	12.52592772,12.523503982,12.5210838372,12.5186672762,12.5162542895,
+	12.5138448677,12.5114390014,12.5090366814,12.5066378982,12.5042426426,
+	12.5018509054,12.4994626774,12.4970779493,12.4946967122,12.4923189569,
+	12.4899446743,12.4875738554,12.4852064912,12.4828425728,12.4804820912,
+	12.4781250374,12.4757714028,12.4734211784,12.4710743554,12.468730925,
+	12.4663908786,12.4640542075,12.4617209029,12.4593909562,12.4570643588,
+	12.4547411022,12.4524211778,12.4501045771,12.4477912916,12.4454813129,
+	12.4431746326,12.4408712422,12.4385711334,12.4362742979,12.4339807274,
+	12.4316904136,12.4294033483,12.4271195232,12.4248389303,12.4225615613,
+	12.4202874082,12.4180164628,12.4157487171,12.413484163,12.4112227927,
+	12.408964598,12.406709571,12.4044577039,12.4022089887,12.3999634176,
+	12.3977209827,12.3954816763,12.3932454906,12.3910124178,12.3887824501,
+	12.38655558,12.3843317998,12.3821111017,12.3798934782,12.3776789218,
+	12.3754674248,12.3732589797,12.371053579,12.3688512153,12.366651881,
+	12.3644555688,12.3622622713,12.3600719811,12.3578846908,12.3557003931,
+	12.3535190807,12.3513407464,12.3491653829,12.3469929829,12.3448235394,
+	12.342657045,12.3404934928,12.3383328755,12.336175186,12.3340204173,
+	12.3318685624,12.3297196142,12.3275735657,12.3254304099,12.3232901399,
+	12.3211527488,12.3190182296,12.3168865756,12.3147577797,12.3126318353,
+	12.3105087354,12.3083884733,12.3062710423,12.3041564356,12.3020446464,
+	12.2999356681,12.2978294941,12.2957261176,12.2936255321,12.2915277309,
+	12.2894327075,12.2873404553,12.2852509678,12.2831642384,12.2810802607,
+	12.2789990281,12.2769205344,12.2748447729,12.2727717373,12.2707014213,
+	12.2686338185,12.2665689225,12.2645067269,12.2624472256,12.2603904123,
+	12.2583362806,12.2562848243,12.2542360373,12.2521899133,12.2501464462,
+	12.2481056297,12.2460674579,12.2440319245,12.2419990234,12.2399687487,
+	12.2379410942,12.2359160539,12.2338936219,12.231873792,12.2298565583,
+	12.227841915,12.225829856,12.2238203754,12.2218134674,12.2198091261,
+	12.2178073455,12.2158081199,12.2138114435,12.2118173105,12.209825715,
+	12.2078366513,12.2058501137,12.2038660965,12.2018845939,12.1999056003,
+	12.1979291099,12.1959551172,12.1939836165,12.1920146022,12.1900480687,
+	12.1880840104,12.1861224218,12.1841632973,12.1822066314,12.1802524186,
+	12.1783006534,12.1763513304,12.174404444,12.1724599888,12.1705179595,
+	12.1685783507,12.1666411568,12.1647063727,12.1627739928,12.160844012,
+	12.1589164248,12.156991226,12.1550684103,12.1531479725,12.1512299072,
+	12.1493142093,12.1474008735,12.1454898947,12.1435812676,12.1416749871,
+	12.1397710481,12.1378694453,12.1359701738,12.1340732283,12.1321786038,
+	12.1302862953,12.1283962977,12.1265086058,12.1246232148,12.1227401197,
+	12.1208593153,12.1189807968,12.1171045592,12.1152305975,12.1133589068,
+	12.1114894822,12.1096223189,12.1077574118,12.1058947562,12.1040343472,
+	12.1021761799,12.1003202496,12.0984665514,12.0966150806,12.0947658323,
+	12.0929188017,12.0910739843,12.0892313751,12.0873909695,12.0855527628,
+	12.0837167503,12.0818829273,12.0800512891,12.0782218311,12.0763945487,
+	12.0745694373,12.0727464922,12.0709257088,12.0691070826,12.067290609,
+	12.0654762834
+	}},
+	{ // Ri = 250k
+	-5,5,200,2001, {
+	137.512728867,137.399223264,137.285690251,137.17212984,137.058542039,
+	136.944926859,136.831284308,136.717614396,136.603917133,136.490192528,
+	136.37644059,136.262661328,136.148854752,136.035020871,135.921159694,
+	135.80727123,135.693355487,135.579412475,135.465442203,135.351444679,
+	135.237419911,135.12336791,135.009288682,134.895182238,134.781048584,
+	134.66688773,134.552699684,134.438484454,134.324242049,134.209972477,
+	134.095675745,133.981351862,133.867000836,133.752622675,133.638217387,
+	133.523784979,133.40932546,133.294838836,133.180325116,133.065784308,
+	132.951216418,132.836621455,132.721999425,132.607350337,132.492674197,
+	132.377971012,132.263240791,132.148483539,132.033699265,131.918887974,
+	131.804049675,131.689184374,131.574292077,131.459372792,131.344426526,
+	131.229453284,131.114453074,130.999425902,130.884371775,130.769290699,
+	130.654182681,130.539047726,130.423885842,130.308697033,130.193481308,
+	130.078238671,129.962969128,129.847672686,129.732349351,129.616999128,
+	129.501622024,129.386218043,129.270787192,129.155329476,129.039844901,
+	128.924333473,128.808795197,128.693230078,128.577638121,128.462019333,
+	128.346373717,128.230701281,128.115002027,127.999275963,127.883523091,
+	127.767743419,127.65193695,127.536103689,127.420243641,127.304356811,
+	127.188443204,127.072502824,126.956535675,126.840541763,126.724521091,
+	126.608473664,126.492399486,126.376298562,126.260170896,126.144016492,
+	126.027835354,125.911627486,125.795392892,125.679131576,125.562843542,
+	125.446528794,125.330187335,125.213819169,125.0974243,124.981002732,
+	124.864554467,124.74807951,124.631577864,124.515049532,124.398494517,
+	124.281912824,124.165304454,124.048669411,123.932007699,123.815319319,
+	123.698604276,123.581862572,123.465094209,123.348299192,123.231477521,
+	123.114629201,122.997754234,122.880852622,122.763924367,122.646969473,
+	122.529987942,122.412979775,122.295944976,122.178883547,122.061795488,
+	121.944680804,121.827539496,121.710371565,121.593177014,121.475955845,
+	121.358708059,121.241433658,121.124132644,121.006805019,120.889450784,
+	120.772069941,120.654662491,120.537228435,120.419767776,120.302280513,
+	120.18476665,120.067226186,119.949659123,119.832065462,119.714445204,
+	119.596798349,119.4791249,119.361424857,119.24369822,119.12594499,
+	119.008165168,118.890358755,118.772525751,118.654666156,118.536779972,
+	118.418867198,118.300927835,118.182961883,118.064969342,117.946950213,
+	117.828904495,117.710832189,117.592733295,117.474607812,117.356455741,
+	117.238277081,117.120071832,117.001839993,116.883581565,116.765296548,
+	116.646984939,116.52864674,116.410281948,116.291890565,116.173472589,
+	116.055028019,115.936556854,115.818059094,115.699534738,115.580983784,
+	115.462406232,115.343802081,115.225171329,115.106513975,114.987830018,
+	114.869119456,114.750382289,114.631618514,114.51282813,114.394011136,
+	114.27516753,114.15629731,114.037400475,113.918477022,113.799526951,
+	113.680550258,113.561546942,113.442517002,113.323460434,113.204377236,
+	113.085267407,112.966130945,112.846967846,112.727778109,112.608561731,
+	112.489318709,112.370049041,112.250752725,112.131429757,112.012080135,
+	111.892703857,111.773300918,111.653871317,111.53441505,111.414932115,
+	111.295422508,111.175886226,111.056323266,110.936733624,110.817117298,
+	110.697474283,110.577804577,110.458108176,110.338385076,110.218635274,
+	110.098858766,109.979055549,109.859225618,109.739368969,109.619485599,
+	109.499575504,109.379638679,109.259675121,109.139684826,109.019667789,
+	108.899624005,108.779553471,108.659456182,108.539332134,108.419181322,
+	108.299003742,108.178799389,108.058568258,107.938310344,107.818025643,
+	107.69771415,107.577375859,107.457010766,107.336618867,107.216200154,
+	107.095754624,106.975282272,106.854783091,106.734257077,106.613704224,
+	106.493124526,106.372517979,106.251884576,106.131224312,106.010537181,
+	105.889823177,105.769082295,105.648314528,105.52751987,105.406698317,
+	105.28584986,105.164974495,105.044072215,104.923143013,104.802186884,
+	104.681203821,104.560193818,104.439156867,104.318092963,104.197002099,
+	104.075884268,103.954739463,103.833567678,103.712368905,103.591143138,
+	103.46989037,103.348610593,103.227303801,103.105969985,102.98460914,
+	102.863221258,102.74180633,102.620364351,102.498895311,102.377399205,
+	102.255876023,102.134325759,102.012748405,101.891143953,101.769512394,
+	101.647853721,101.526167927,101.404455002,101.282714939,101.16094773,
+	101.039153366,100.917331839,100.795483141,100.673607263,100.551704197,
+	100.429773934,100.307816466,100.185831783,100.063819878,99.9417807406,
+	99.8197143628,99.6976207354,99.5754998496,99.4533516961,99.3311762659,
+	99.2089735498,99.0867435385,98.9644862227,98.8422015931,98.7198896402,
+	98.5975503544,98.4751837263,98.3527897462,98.2303684044,98.1079196912,
+	97.9854435967,97.862940111,97.7404092242,97.6178509264,97.4952652074,
+	97.3726520571,97.2500114653,97.1273434217,97.0046479161,96.881924938,
+	96.759174477,96.6363965227,96.5135910643,96.3907580913,96.267897593,
+	96.1450095586,96.0220939773,95.8991508382,95.7761801304,95.6531818428,
+	95.5301559644,95.407102484,95.2840213905,95.1609126725,95.0377763187,
+	94.9146123178,94.7914206583,94.6682013286,94.5449543172,94.4216796125,
+	94.2983772027,94.1750470761,94.0516892209,93.9283036251,93.8048902767,
+	93.6814491639,93.5579802744,93.4344835962,93.3109591171,93.1874068247,
+	93.0638267067,92.9402187508,92.8165829445,92.6929192752,92.5692277304,
+	92.4455082975,92.3217609637,92.1979857163,92.0741825423,91.9503514291,
+	91.8264923635,91.7026053326,91.5786903232,91.4547473223,91.3307763167,
+	91.206777293,91.082750238,90.9586951383,90.8346119803,90.7105007507,
+	90.5863614358,90.462194022,90.3379984956,90.2137748429,90.0895230499,
+	89.965243103,89.840934988,89.7165986911,89.5922341981,89.467841495,
+	89.3434205675,89.2189714014,89.0944939825,88.9699882963,88.8454543284,
+	88.7208920644,88.5963014897,88.4716825897,88.3470353498,88.2223597552,
+	88.0976557912,87.9729234429,87.8481626954,87.7233735338,87.5985559431,
+	87.4737099082,87.3488354139,87.2239324452,87.0990009867,86.9740410231,
+	86.8490525391,86.7240355193,86.5989899482,86.4739158103,86.34881309,
+	86.2236817716,86.0985218395,85.9733332779,85.8481160709,85.7228702028,
+	85.5975956577,85.4722924194,85.3469604721,85.2215997996,85.0962103858,
+	84.9707922146,84.8453452696,84.7198695345,84.5943649931,84.4688316289,
+	84.3432694255,84.2176783664,84.092058435,83.9664096147,83.8407318888,
+	83.7150252407,83.5892896536,83.4635251106,83.3377315949,83.2119090897,
+	83.0860575779,82.9601770426,82.8342674667,82.708328833,82.5823611245,
+	82.456364324,82.3303384143,82.2042833779,82.0781991977,81.9520858562,
+	81.825943336,81.6997716197,81.5735706898,81.4473405286,81.3210811187,
+	81.1947924423,81.0684744819,80.9421272196,80.8157506378,80.6893447187,
+	80.5629094444,80.436444797,80.3099507586,80.1834273114,80.0568744373,
+	79.9302921182,79.8036803362,79.6770390732,79.550368311,79.4236680315,
+	79.2969382165,79.1701788478,79.0433899071,78.9165713762,78.7897232367,
+	78.6628454704,78.5359380588,78.4090009835,78.2820342262,78.1550377685,
+	78.0280115917,77.9009556775,77.7738700074,77.6467545627,77.519609325,
+	77.3924342757,77.2652293962,77.1379946679,77.0107300721,76.8834355903,
+	76.7561112037,76.6287568937,76.5013726416,76.3739584288,76.2465142365,
+	76.119040046,75.9915358386,75.8640015956,75.7364372982,75.6088429277,
+	75.4812184654,75.3535638926,75.2258791905,75.0981643403,74.9704193234,
+	74.842644121,74.7148387145,74.587003085,74.4591372139,74.3312410825,
+	74.2033146721,74.0753579641,73.9473709398,73.8193535805,73.6913058677,
+	73.5632277828,73.4351193072,73.3069804223,73.1788111097,73.0506113508,
+	72.9223811272,72.7941204204,72.6658292121,72.537507484,72.4091552176,
+	72.2807723947,72.1523589971,72.0239150066,71.8954404051,71.7669351744,
+	71.6383992966,71.5098327536,71.3812355275,71.2526076005,71.1239489547,
+	70.9952595725,70.8665394361,70.7377885279,70.6090068305,70.4801943263,
+	70.3513509981,70.2224768285,70.0935718004,69.9646358965,69.8356691,
+	69.7066713939,69.5776427614,69.4485831857,69.3194926503,69.1903711386,
+	69.0612186344,68.9320351212,68.802820583,68.6735750037,68.5442983675,
+	68.4149906585,68.2856518613,68.1562819603,68.0268809401,67.8974487857,
+	67.7679854819,67.638491014,67.5089653673,67.3794085272,67.2498204794,
+	67.1202012097,66.9905507042,66.8608689491,66.7311559309,66.601411636,
+	66.4716360515,66.3418291643,66.2119909618,66.0821214314,65.9522205608,
+	65.8222883382,65.6923247516,65.5623297897,65.4323034412,65.302245695,
+	65.1721565406,65.0420359675,64.9118839657,64.7817005253,64.6514856368,
+	64.5212392911,64.3909614794,64.2606521931,64.1303114242,63.9999391648,
+	63.8695354075,63.7391001453,63.6086333716,63.47813508,63.3476052649,
+	63.2170439207,63.0864510425,62.9558266257,62.8251706663,62.6944831608,
+	62.5637641059,62.4330134991,62.3022313383,62.1714176218,62.0405723488,
+	61.9096955186,61.7787871314,61.6478471879,61.5168756894,61.3858726377,
+	61.2548380355,61.1237718859,60.9926741928,60.8615449607,60.730384195,
+	60.5991919017,60.4679680876,60.3367127601,60.2054259277,60.0741075994,
+	59.9427577854,59.8113764964,59.6799637443,59.5485195417,59.4170439022,
+	59.2855368404,59.1539983719,59.0224285133,58.8908272824,58.7591946978,
+	58.6275307794,58.4958355482,58.3641090265,58.2323512377,58.1005622064,
+	57.9687419586,57.8368905217,57.7050079243,57.5730941965,57.4411493697,
+	57.3091734771,57.1771665531,57.0451286339,56.9130597573,56.7809599628,
+	56.6488292914,56.5166677863,56.3844754921,56.2522524556,56.1199987253,
+	55.9877143521,55.8553993885,55.7230538895,55.5906779121,55.4582715156,
+	55.3258347616,55.1933677144,55.0608704404,54.9283430087,54.7957854911,
+	54.6631979622,54.5305804991,54.3979331822,54.2652560946,54.1325493226,
+	53.9998129557,53.8670470866,53.7342518116,53.6014272301,53.4685734456,
+	53.3356905649,53.202778699,53.0698379626,52.9368684747,52.8038703584,
+	52.6708437413,52.5377887554,52.4047055373,52.2715942288,52.1384549761,
+	52.005287931,51.8720932505,51.7388710969,51.6056216384,51.4723450489,
+	51.3390415085,51.2057112034,51.0723543264,50.9389710768,50.8055616609,
+	50.6721262922,50.5386651916,50.4051785874,50.271666716,50.1381298218,
+	50.0045681577,49.8709819854,49.7373715755,49.6037372078,49.470079172,
+	49.3363977676,49.2026933043,49.0689661028,48.9352164944,48.8014448221,
+	48.6676514405,48.5338367167,48.40000103,48.2661447731,48.1322683519,
+	47.9983721867,47.8644567117,47.7305223766,47.5965696462,47.4625990014,
+	47.3286109398,47.1946059759,47.0605846422,46.9265474893,46.792495087,
+	46.6584280245,46.5243469117,46.3902523791,46.2561450792,46.122025687,
+	45.9878949008,45.853753443,45.7196020608,45.5854415275,45.4512726429,
+	45.3170962344,45.1829131581,45.0487242995,44.9145305749,44.7803329321,
+	44.6461323516,44.5119298478,44.3777264702,44.2435233043,44.1093214733,
+	43.9751221389,43.8409265029,43.7067358086,43.5725513419,43.4383744332,
+	43.3042064584,43.1700488409,43.0359030526,42.9017706161,42.7676531062,
+	42.6335521515,42.4994694361,42.3654067018,42.2313657496,42.0973484418,
+	41.9633567039,41.8293925267,41.6954579684,41.5615551566,41.4276862907,
+	41.293853644,41.1600595658,41.0263064842,40.8925969082,40.7589334302,
+	40.6253187286,40.4917555701,40.3582468127,40.2247954079,40.0914044039,
+	39.9580769478,39.8248162888,39.691625781,39.5585088858,39.4254691754,
+	39.2925103354,39.1596361679,39.0268505942,38.8941576581,38.7615615286,
+	38.6290665035,38.4966770114,38.3643976159,38.2322330175,38.1001880572,
+	37.9682677194,37.8364771346,37.7048215822,37.5733064936,37.4419374545,
+	37.3107202079,37.1796606565,37.0487648651,36.9180390628,36.7874896455,
+	36.6571231776,36.526946394,36.3969662016,36.2671896813,36.1376240885,
+	36.0082768545,35.8791555875,35.7502680727,35.6216222725,35.4932263267,
+	35.3650885517,35.23721744,35.1096216587,34.9823100482,34.8552916201,
+	34.7285755548,34.6021711986,34.4760880604,34.3503358077,34.2249242626,
+	34.0998633968,33.9751633259,33.8508343041,33.7268867171,33.6033310755,
+	33.4801780068,33.3574382475,33.2351226341,33.1132420942,32.9918076357,
+	32.8708303373,32.7503213367,32.6302918195,32.5107530067,32.3917161423,
+	32.2731924804,32.1551932711,32.037729747,31.9208131085,31.8044545095,
+	31.6886650419,31.5734557206,31.4588374679,31.3448210978,31.2314173004,
+	31.1186366258,31.0064894684,30.8949860509,30.7841364092,30.6739503761,
+	30.5644375666,30.455607363,30.3474688999,30.2400310502,30.1333024117,
+	30.0272912935,29.9220057037,29.8174533375,29.7136415657,29.6105774244,
+	29.5082676055,29.4067184471,29.3059359261,29.2059256507,29.1066928541,
+	29.0082423889,28.9105787231,28.8137059359,28.7176277156,28.6223473578,
+	28.5278677641,28.4341914432,28.3413205108,28.2492566924,28.1580013255,
+	28.0675553634,27.9779193796,27.8890935724,27.8010777713,27.7138714431,
+	27.6274736993,27.5418833035,27.4570986796,27.373117921,27.289938799,
+	27.2075587732,27.1259750009,27.0451843475,26.965183397,26.8859684628,
+	26.8075355984,26.7298806087,26.652999061,26.5768862962,26.5015374399,
+	26.426947414,26.3531109471,26.2800225865,26.2076767084,26.1360675291,
+	26.0651891153,25.9950353953,25.9256001685,25.8568771158,25.7888598095,
+	25.7215417227,25.6549162387,25.5889766601,25.5237162175,25.4591280777,
+	25.3952053525,25.331941106,25.2693283624,25.2073601134,25.1460293249,
+	25.0853289441,25.0252519052,24.9657911364,24.9069395648,24.8486901225,
+	24.7910357516,24.7339694092,24.677484072,24.6215727409,24.5662284448,
+	24.5114442449,24.4572132382,24.4035285609,24.3503833915,24.2977709541,
+	24.2456845208,24.1941174145,24.1430630113,24.0925147424,24.0424660964,
+	23.992910621,23.9438419248,23.8952536784,23.8471396162,23.7994935376,
+	23.7523093077,23.7055808586,23.6593021901,23.6134673704,23.5680705368,
+	23.5231058959,23.4785677245,23.4344503694,23.3907482481,23.3474558483,
+	23.3045677287,23.2620785186,23.2199829176,23.1782756959,23.1369516941,
+	23.0960058224,23.055433061,23.0152284591,22.9753871351,22.9359042758,
+	22.8967751359,22.8579950378,22.8195593706,22.7814635902,22.743703218,
+	22.7062738406,22.6691711094,22.6323907394,22.5959285091,22.5597802593,
+	22.5239418928,22.4884093734,22.4531787255,22.4182460329,22.3836074384,
+	22.3492591431,22.3151974054,22.2814185405,22.2479189191,22.2146949676,
+	22.1817431664,22.1490600496,22.1166422042,22.0844862693,22.0525889354,
+	22.0209469434,21.9895570842,21.9584161977,21.9275211724,21.896868944,
+	21.8664564954,21.8362808557,21.8063390992,21.7766283451,21.7471457566,
+	21.7178885402,21.6888539452,21.6600392626,21.631441825,21.6030590054,
+	21.5748882168,21.5469269116,21.5191725808,21.4916227535,21.4642749962,
+	21.4371269121,21.4101761408,21.3834203573,21.3568572718,21.3304846287,
+	21.3043002064,21.2783018166,21.2524873036,21.2268545441,21.2014014463,
+	21.1761259495,21.1510260236,21.1260996686,21.1013449141,21.0767598189,
+	21.0523424701,21.0280909831,21.004003501,20.9800781938,20.9563132586,
+	20.9327069183,20.9092574221,20.8859630443,20.8628220842,20.8398328657,
+	20.8169937368,20.7943030693,20.7717592581,20.7493607214,20.7271058996,
+	20.7049932554,20.6830212735,20.6611884598,20.6394933414,20.617934466,
+	20.5965104018,20.5752197372,20.5540610799,20.5330330574,20.512134316,
+	20.491363521,20.4707193559,20.4502005225,20.4298057403,20.4095337464,
+	20.3893832953,20.3693531584,20.3494421236,20.3296489955,20.3099725947,
+	20.2904117577,20.2709653368,20.2516321995,20.2324112284,20.2133013213,
+	20.1943013902,20.1754103619,20.1566271772,20.1379507909,20.1193801714,
+	20.1009143009,20.0825521747,20.0642928011,20.0461352015,20.0280784098,
+	20.0101214725,19.9922634483,19.9745034079,19.9568404342,19.9392736215,
+	19.9218020757,19.9044249141,19.8871412651,19.8699502683,19.8528510738,
+	19.8358428425,19.818924746,19.8020959659,19.7853556942,19.7687031328,
+	19.7521374934,19.7356579977,19.7192638768,19.702954371,19.6867287302,
+	19.6705862133,19.6545260883,19.6385476318,19.6226501296,19.6068328756,
+	19.5910951724,19.5754363311,19.5598556707,19.5443525186,19.5289262099,
+	19.5135760879,19.4983015033,19.4831018147,19.4679763881,19.4529245969,
+	19.4379458218,19.4230394509,19.4082048791,19.3934415084,19.3787487479,
+	19.3641260131,19.3495727265,19.3350883172,19.3206722206,19.3063238786,
+	19.2920427395,19.2778282577,19.263679894,19.2495971149,19.2355793932,
+	19.2216262073,19.2077370416,19.1939113861,19.1801487367,19.1664485945,
+	19.1528104664,19.1392338645,19.1257183064,19.1122633148,19.0988684177,
+	19.0855331483,19.0722570446,19.0590396499,19.0458805122,19.0327791844,
+	19.0197352243,19.0067481941,18.993817661,18.9809431967,18.9681243774,
+	18.9553607836,18.9426520006,18.9299976177,18.9173972287,18.9048504315,
+	18.8923568283,18.8799160254,18.8675276332,18.855191266,18.8429065421,
+	18.8306730839,18.8184905175,18.8063584728,18.7942765836,18.7822444873,
+	18.7702618249,18.7583282413,18.7464433847,18.734606907,18.7228184636,
+	18.7110777131,18.6993843177,18.6877379431,18.6761382579,18.6645849344,
+	18.6530776479,18.6416160769,18.6301999032,18.6188288114,18.6075024895,
+	18.5962206284,18.5849829221,18.5737890673,18.5626387639,18.5515317145,
+	18.5404676247,18.5294462029,18.5184671601,18.5075302104,18.4966350702,
+	18.4857814588,18.4749690983,18.4641977132,18.4534670307,18.4427767803,
+	18.4321266945,18.4215165079,18.4109459577,18.4004147836,18.3899227277,
+	18.3794695343,18.3690549502,18.3586787246,18.3483406089,18.3380403567,
+	18.327777724,18.3175524689,18.3073643518,18.2972131352,18.2870985837,
+	18.2770204641,18.2669785453,18.2569725982,18.2470023957,18.2370677129,
+	18.2271683268,18.2173040164,18.2074745625,18.1976797481,18.187919358,
+	18.1781931787,18.1685009989,18.1588426089,18.149217801,18.1396263691,
+	18.1300681091,18.1205428184,18.1110502966,18.1015903445,18.0921627649,
+	18.0827673623,18.0734039429,18.0640723142,18.0547722859,18.0455036688,
+	18.0362662756,18.0270599206,18.0178844194,18.0087395894,17.9996252494,
+	17.9905412198,17.9814873225,17.9724633808,17.9634692195,17.9545046649,
+	17.9455695447,17.9366636879,17.9277869252,17.9189390885,17.9101200109,
+	17.9013295273,17.8925674735,17.883833687,17.8751280064,17.8664502716,
+	17.857800324,17.849178006,17.8405831614,17.8320156354,17.8234752741,
+	17.8149619251,17.8064754372,17.7980156603,17.7895824455,17.7811756451,
+	17.7727951126,17.7644407026,17.7561122709,17.7478096744,17.7395327711,
+	17.7312814201,17.7230554816,17.714854817,17.7066792887,17.69852876,
+	17.6904030955,17.6823021608,17.6742258224,17.6661739479,17.6581464059,
+	17.6501430661,17.642163799,17.6342084763,17.6262769706,17.6183691553,
+	17.6104849049,17.6026240949,17.5947866017,17.5869723025,17.5791810756,
+	17.5714128001,17.5636673559,17.5559446241,17.5482444865,17.5405668256,
+	17.5329115251,17.5252784694,17.5176675436,17.510078634,17.5025116274,
+	17.4949664116,17.4874428751,17.4799409074,17.4724603986,17.4650012398,
+	17.4575633227,17.4501465398,17.4427507845,17.4353759509,17.4280219338,
+	17.4206886288,17.4133759324,17.4060837415,17.3988119541,17.3915604686,
+	17.3843291844,17.3771180014,17.3699268203,17.3627555424,17.35560407,
+	17.3484723057,17.341360153,17.3342675159,17.3271942994,17.3201404088,
+	17.3131057502,17.3060902305,17.2990937569,17.2921162377,17.2851575813,
+	17.2782176971,17.2712964951,17.2643938858,17.2575097803,17.2506440905,
+	17.2437967285,17.2369676075,17.2301566409,17.2233637429,17.2165888281,
+	17.2098318119,17.2030926101,17.1963711391,17.189667316,17.1829810581,
+	17.1763122836,17.1696609112,17.1630268599,17.1564100495,17.1498104003,
+	17.1432278329,17.1366622687,17.1301136294,17.1235818374,17.1170668156,
+	17.1105684871,17.1040867758,17.0976216062,17.0911729029,17.0847405913,
+	17.0783245972,17.0719248468,17.0655412669,17.0591737847,17.0528223279,
+	17.0464868247,17.0401672035,17.0338633936,17.0275753244,17.0213029259,
+	17.0150461285,17.008804863,17.0025790607,16.9963686535,16.9901735733,
+	16.9839937528,16.9778291251,16.9716796235,16.9655451818,16.9594257344,
+	16.9533212159,16.9472315614,16.9411567063,16.9350965866,16.9290511385,
+	16.9230202986,16.9170040041,16.9110021924,16.9050148013,16.8990417691,
+	16.8930830343,16.8871385358,16.8812082131,16.8752920059,16.8693898542,
+	16.8635016985,16.8576274795,16.8517671385,16.8459206169,16.8400878566,
+	16.8342687999,16.8284633893,16.8226715677,16.8168932783,16.8111284648,
+	16.8053770711,16.7996390414,16.7939143204,16.7882028529,16.7825045842,
+	16.7768194599,16.7711474258,16.7654884282,16.7598424137,16.7542093289,
+	16.7485891212,16.7429817379,16.7373871268,16.731805236,16.7262360139,
+	16.7206794092,16.7151353708,16.7096038479,16.7040847902,16.6985781476,
+	16.69308387,16.687601908,16.6821322124,16.676674734,16.6712294241,
+	16.6657962344,16.6603751165,16.6549660228,16.6495689054,16.6441837172,
+	16.6388104109,16.6334489397,16.6280992572,16.6227613169,16.617435073,
+	16.6121204796,16.6068174911,16.6015260624,16.5962461483,16.5909777043,
+	16.5857206857,16.5804750482,16.575240748,16.5700177411,16.5648059841,
+	16.5596054337,16.5544160468,16.5492377806,16.5440705926,16.5389144403,
+	16.5337692817,16.5286350749,16.5235117782,16.5183993502,16.5132977498,
+	16.5082069358,16.5031268677,16.4980575048,16.4929988068,16.4879507336,
+	16.4829132453,16.4778863024,16.4728698652,16.4678638946,16.4628683516,
+	16.4578831973,16.4529083931,16.4479439006,16.4429896815,16.438045698,
+	16.4331119121,16.4281882863,16.4232747832,16.4183713655,16.4134779963,
+	16.4085946388,16.4037212562,16.3988578123,16.3940042707,16.3891605954,
+	16.3843267505,16.3795027004,16.3746884096,16.3698838428,16.3650889649,
+	16.3603037408,16.3555281359,16.3507621156,16.3460056454,16.3412586913,
+	16.336521219,16.3317931948,16.3270745849,16.3223653558,16.3176654741,
+	16.3129749068,16.3082936207,16.303621583,16.298958761,16.2943051222,
+	16.2896606343,16.285025265,16.2803989824,16.2757817546,16.2711735499,
+	16.2665743366,16.2619840836,16.2574027594,16.2528303331,16.2482667737,
+	16.2437120505,16.2391661329,16.2346289903,16.2301005925,16.2255809094,
+	16.2210699108,16.2165675671,16.2120738484,16.2075887252,16.203112168,
+	16.1986441477,16.194184635,16.189733601,16.1852910168,16.1808568537,
+	16.1764310832,16.1720136768,16.1676046063,16.1632038434,16.1588113602,
+	16.1544271288,16.1500511214,16.1456833105,16.1413236685,16.1369721682,
+	16.1326287822,16.1282934836,16.1239662453,16.1196470405,16.1153358426,
+	16.1110326249,16.1067373611,16.1024500248,16.0981705898,16.0938990301,
+	16.0896353196,16.0853794327,16.0811313435,16.0768910266,16.0726584563,
+	16.0684336075,16.0642164549,16.0600069734,16.055805138,16.0516109239,
+	16.0474243062,16.0432452604,16.0390737619,16.0349097864,16.0307533095,
+	16.026604307,16.022462755,16.0183286294,16.0142019064,16.0100825622,
+	16.0059705733,16.0018659161,15.9977685672,15.9936785032,15.9895957011,
+	15.9855201377,15.98145179,15.9773906352,15.9733366504,15.9692898131,
+	15.9652501006,15.9612174904,15.9571919603,15.9531734879,15.949162051,
+	15.9451576277,15.941160196,15.9371697339,15.9331862197,15.9292096318,
+	15.9252399486,15.9212771486,15.9173212104,15.9133721128,15.9094298345,
+	15.9054943544,15.9015656517,15.8976437053,15.8937284944,15.8898199983,
+	15.8859181964,15.8820230682,15.8781345932,15.874252751,15.8703775214,
+	15.8665088841,15.8626468192,15.8587913065,15.8549423262,15.8510998585,
+	15.8472638835,15.8434343817,15.8396113335,15.8357947194,15.8319845199,
+	15.8281807158,15.8243832879,15.8205922169,15.8168074838,15.8130290697,
+	15.8092569556,15.8054911227,15.8017315522,15.7979782256,15.7942311241,
+	15.7904902294,15.7867555229,15.7830269864,15.7793046016,15.7755883502,
+	15.7718782142,15.7681741756,15.7644762164,15.7607843186,15.7570984646,
+	15.7534186365,15.7497448167,15.7460769876,15.7424151318,15.7387592317,
+	15.7351092701,15.7314652295,15.7278270929,15.7241948431,15.720568463,
+	15.7169479355,15.7133332439,15.7097243711,15.7061213004,15.7025240152,
+	15.6989324987,15.6953467343,15.6917667056,15.6881923961,15.6846237894,
+	15.6810608692,15.6775036193,15.6739520235,15.6704060657,15.6668657298,
+	15.6633309998,15.6598018599,15.6562782942,15.652760287,15.6492478224,
+	15.6457408848,15.6422394587,15.6387435286,15.6352530788,15.6317680941,
+	15.6282885592,15.6248144586,15.6213457773,15.6178825,15.6144246117,
+	15.6109720973,15.6075249419,15.6040831305,15.6006466483,15.5972154805,
+	15.5937896123,15.5903690291,15.5869537163,15.5835436592,15.5801388435,
+	15.5767392546,15.5733448782,15.5699556999,15.5665717054,15.5631928806,
+	15.5598192113,15.5564506833,15.5530872827,15.5497289954,15.5463758074,
+	15.543027705,15.5396846742,15.5363467014,15.5330137727,15.5296858744,
+	15.5263629931,15.5230451151,15.5197322269,15.5164243151,15.5131213662,
+	15.5098233669,15.5065303039,15.5032421639,15.4999589337,15.4966806003,
+	15.4934071504,15.4901385711,15.4868748494,15.4836159722,15.4803619267,
+	15.4771127001,15.4738682796,15.4706286523,15.4673938057,15.464163727,
+	15.4609384036,15.457717823,15.4545019727,15.4512908402,15.4480844132,
+	15.4448826791,15.4416856258,15.4384932409,15.4353055122,15.4321224276,
+	15.4289439748,15.4257701418,15.4226009166,15.4194362872,15.4162762415,
+	15.4131207678,15.409969854,15.4068234885,15.4036816594,15.400544355,
+	15.3974115636,15.3942832736,15.3911594733,15.3880401512,15.3849252958,
+	15.3818148956,15.3787089391,15.3756074151,15.3725103121,15.3694176188,
+	15.366329324,15.3632454164,15.3601658849,15.3570907183,15.3540199055,
+	15.3509534355,15.3478912972,15.3448334797,15.341779972,15.3387307632,
+	15.3356858425,15.3326451991,15.3296088221,15.3265767009,15.3235488246,
+	15.3205251828,15.3175057647,15.3144905597,15.3114795573,15.308472747,
+	15.3054701184,15.3024716609,15.2994773642,15.2964872179,15.2935012118,
+	15.2905193354,15.2875415787,15.2845679312,15.281598383,15.2786329238,
+	15.2756715436,15.2727142322,15.2697609796,15.2668117759,15.2638666111,
+	15.2609254752,15.2579883584,15.2550552508,15.2521261426,15.249201024,
+	15.2462798852,15.2433627166,15.2404495084,15.2375402511,15.2346349349,
+	15.2317335503,15.2288360878,15.2259425378,15.2230528908,15.2201671375,
+	15.2172852684,15.2144072741,15.2115331453,15.2086628726,15.2057964467,
+	15.2029338585,15.2000750986,15.197220158,15.1943690274,15.1915216977,
+	15.1886781598,15.1858384047,15.1830024233,15.1801702066,15.1773417457,
+	15.1745170316,15.1716960554,15.1688788083,15.1660652813,15.1632554657,
+	15.1604493526,15.1576469334,15.1548481993,15.1520531416,15.1492617516,
+	15.1464740206,15.1436899402,15.1409095017,15.1381326965,15.1353595161,
+	15.1325899521,15.1298239959,15.1270616392,15.1243028735,15.1215476904,
+	15.1187960816,15.1160480388,15.1133035537,15.1105626179,15.1078252234,
+	15.1050913618,15.1023610249,15.0996342047,15.0969108929,15.0941910815,
+	15.0914747624,15.0887619276,15.086052569,15.0833466786,15.0806442485,
+	15.0779452707,15.0752497372,15.0725576403,15.0698689721,15.0671837246,
+	15.0645018902,15.0618234609,15.0591484291,15.0564767869,15.0538085268,
+	15.051143641,15.0484821218,15.0458239617,15.0431691529,15.0405176879,
+	15.0378695592,15.0352247593,15.0325832805,15.0299451154,15.0273102566,
+	15.0246786966,15.022050428,15.0194254434,15.0168037355,15.0141852968,
+	15.0115701201,15.0089581981,15.0063495236,15.0037440891,15.0011418876,
+	14.9985429119,14.9959471547,14.9933546088,14.9907652673,14.9881791229,
+	14.9855961686,14.9830163972,14.9804398018,14.9778663754,14.9752961109,
+	14.9727290013,14.9701650398,14.9676042193,14.965046533,14.962491974,
+	14.9599405354,14.9573922104,14.9548469921,14.9523048738,14.9497658486,
+	14.9472299098,14.9446970507,14.9421672646,14.9396405447,14.9371168844,
+	14.9345962771,14.932078716,14.9295641947,14.9270527064,14.9245442447,
+	14.9220388029,14.9195363747,14.9170369533,14.9145405324,14.9120471055,
+	14.9095566662,14.9070692079,14.9045847244,14.9021032092,14.8996246559,
+	14.8971490582,14.8946764098,14.8922067044,14.8897399356,14.8872760973,
+	14.884815183,14.8823571867,14.8799021021,14.877449923,14.8750006433,
+	14.8725542567,14.8701107571,14.8676701385,14.8652323947,14.8627975196,
+	14.8603655072,14.8579363515,14.8555100463,14.8530865858,14.8506659638,
+	14.8482481745,14.8458332119,14.84342107,14.841011743,14.8386052248,
+	14.8362015098,14.8338005919,14.8314024654,14.8290071244,14.8266145631,
+	14.8242247756,14.8218377564,14.8194534995,14.8170719992,14.8146932498,
+	14.8123172457,14.809943981,14.8075734502,14.8052056476,14.8028405675,
+	14.8004782043,14.7981185525,14.7957616063,14.7934073604,14.791055809,
+	14.7887069467,14.7863607679,14.7840172671,14.7816764389,14.7793382777,
+	14.7770027781,14.7746699347,14.7723397421,14.7700121947,14.7676872873,
+	14.7653650145,14.7630453708,14.760728351,14.7584139497,14.7561021616,
+	14.7537929814,14.7514864038,14.7491824235,14.7468810354,14.7445822341,
+	14.7422860144,14.7399923711,14.7377012991,14.7354127931,14.733126848,
+	14.7308434587,14.72856262,14.7262843267,14.7240085739,14.7217353563,
+	14.719464669,14.7171965068,14.7149308648,14.7126677378,14.7104071209,
+	14.7081490091
+	}}
+};
diff --git a/examples/faust-tubes/valve/6V6.cc b/examples/faust-tubes/valve/6V6.cc
new file mode 100644
index 0000000..ceee120
--- /dev/null
+++ b/examples/faust-tubes/valve/6V6.cc
@@ -0,0 +1,814 @@
+/*
+ * tube: 6V6
+ * */
+
+table1d_imp<2001> tubetable_6V6[2] = {
+	{ // Ri = 68k
+	-5,5,200,2001, {
+	239.919843376,239.854937108,239.789738489,239.724247218,239.658462996,
+	239.592385535,239.526014546,239.459349752,239.392390878,239.325137654,
+	239.257589818,239.189747112,239.121609284,239.053176087,238.984447281,
+	238.91542263,238.846101903,238.776484877,238.706571332,238.636361055,
+	238.565853836,238.495049475,238.423947772,238.352548536,238.280851579,
+	238.208856722,238.136563787,238.063972604,237.991083007,237.917894835,
+	237.844407935,237.770622155,237.696537352,237.622153385,237.54747012,
+	237.472487429,237.397205186,237.321623273,237.245741575,237.169559984,
+	237.093078396,237.016296711,236.939214835,236.86183268,236.78415016,
+	236.706167196,236.627883714,236.549299644,236.470414921,236.391229484,
+	236.311743279,236.231956253,236.151868362,236.071479563,235.99078982,
+	235.9097991,235.828507376,235.746914624,235.665020826,235.582825967,
+	235.500330038,235.417533033,235.334434951,235.251035796,235.167335575,
+	235.083334301,234.999031988,234.914428659,234.829524337,234.744319051,
+	234.658812834,234.573005723,234.48689776,234.400488988,234.313779459,
+	234.226769224,234.13945834,234.05184687,233.963934876,233.875722429,
+	233.7872096,233.698396466,233.609283107,233.519869606,233.430156051,
+	233.340142534,233.249829147,233.159215991,233.068303166,232.977090779,
+	232.885578937,232.793767753,232.701657342,232.609247824,232.516539321,
+	232.423531959,232.330225867,232.236621177,232.142718023,232.048516546,
+	231.954016887,231.85921919,231.764123605,231.66873028,231.573039372,
+	231.477051037,231.380765434,231.284182727,231.187303082,231.090126667,
+	230.992653654,230.894884217,230.796818534,230.698456783,230.599799147,
+	230.500845813,230.401596966,230.302052798,230.202213502,230.102079273,
+	230.001650309,229.900926811,229.799908981,229.698597024,229.596991149,
+	229.495091566,229.392898486,229.290412124,229.187632698,229.084560426,
+	228.98119553,228.877538233,228.77358876,228.66934734,228.564814202,
+	228.459989578,228.354873701,228.249466808,228.143769136,228.037780925,
+	227.931502416,227.824933853,227.718075481,227.610927548,227.503490301,
+	227.395763992,227.287748873,227.179445197,227.070853221,226.961973202,
+	226.852805398,226.743350071,226.633607482,226.523577894,226.413261574,
+	226.302658786,226.1917698,226.080594885,225.969134311,225.857388351,
+	225.745357278,225.633041366,225.520440893,225.407556135,225.294387371,
+	225.180934881,225.067198945,224.953179846,224.838877868,224.724293293,
+	224.609426409,224.494277501,224.378846857,224.263134765,224.147141516,
+	224.030867399,223.914312706,223.79747773,223.680362764,223.562968102,
+	223.445294038,223.32734087,223.209108892,223.090598404,222.971809703,
+	222.852743088,222.733398858,222.613777314,222.493878757,222.373703489,
+	222.253251812,222.132524028,222.011520442,221.890241357,221.768687078,
+	221.64685791,221.524754159,221.402376131,221.279724132,221.15679847,
+	221.033599452,220.910127386,220.78638258,220.662365343,220.538075983,
+	220.413514811,220.288682136,220.163578268,220.038203517,219.912558193,
+	219.786642608,219.660457072,219.534001897,219.407277394,219.280283874,
+	219.15302165,219.025491033,218.897692335,218.769625868,218.641291945,
+	218.512690877,218.383822977,218.254688558,218.125287932,217.995621411,
+	217.865689308,217.735491935,217.605029605,217.47430263,217.343311321,
+	217.212055993,217.080536955,216.948754521,216.816709003,216.684400712,
+	216.551829959,216.418997057,216.285902317,216.152546049,216.018928564,
+	215.885050174,215.750911189,215.616511919,215.481852673,215.346933762,
+	215.211755495,215.076318182,214.94062213,214.804667649,214.668455047,
+	214.531984632,214.395256711,214.258271591,214.121029579,213.983530982,
+	213.845776106,213.707765256,213.569498737,213.430976855,213.292199913,
+	213.153168215,213.013882065,212.874341767,212.734547621,212.594499931,
+	212.454198998,212.313645122,212.172838605,212.031779746,211.890468845,
+	211.748906201,211.607092111,211.465026874,211.322710786,211.180144145,
+	211.037327247,210.894260386,210.750943858,210.607377956,210.463562975,
+	210.319499207,210.175186945,210.03062648,209.885818102,209.740762104,
+	209.595458773,209.449908399,209.30411127,209.158067675,209.011777899,
+	208.865242228,208.718460949,208.571434346,208.424162703,208.276646303,
+	208.128885428,207.980880361,207.832631382,207.684138772,207.53540281,
+	207.386423774,207.237201943,207.087737593,206.938031001,206.788082442,
+	206.637892191,206.487460522,206.336787708,206.185874021,206.034719731,
+	205.883325111,205.73169043,205.579815955,205.427701956,205.275348699,
+	205.122756451,204.969925477,204.816856041,204.663548407,204.510002838,
+	204.356219595,204.20219894,204.047941132,203.893446431,203.738715095,
+	203.583747381,203.428543545,203.273103843,203.117428529,202.961517858,
+	202.80537208,202.648991449,202.492376215,202.335526628,202.178442936,
+	202.021125388,201.86357423,201.705789708,201.547772068,201.389521553,
+	201.231038406,201.072322869,200.913375184,200.75419559,200.594784326,
+	200.435141631,200.275267741,200.115162893,199.954827322,199.794261261,
+	199.633464944,199.472438602,199.311182467,199.149696769,198.987981736,
+	198.826037597,198.663864578,198.501462905,198.338832802,198.175974495,
+	198.012888205,197.849574154,197.686032562,197.52226365,197.358267635,
+	197.194044735,197.029595166,196.864919145,196.700016884,196.534888597,
+	196.369534496,196.203954793,196.038149697,195.872119417,195.70586416,
+	195.539384134,195.372679544,195.205750595,195.03859749,194.871220431,
+	194.703619619,194.535795255,194.367747539,194.199476666,194.030982836,
+	193.862266242,193.69332708,193.524165544,193.354781825,193.185176116,
+	193.015348605,192.845299483,192.675028937,192.504537154,192.333824319,
+	192.162890617,191.991736232,191.820361346,191.648766139,191.476950793,
+	191.304915485,191.132660394,190.960185696,190.787491567,190.61457818,
+	190.44144571,190.268094328,190.094524205,189.92073551,189.746728413,
+	189.572503081,189.398059679,189.223398374,189.048519329,188.873422706,
+	188.698108668,188.522577375,188.346828986,188.17086366,187.994681553,
+	187.818282821,187.641667619,187.4648361,187.287788416,187.110524719,
+	186.933045159,186.755349884,186.577439042,186.399312779,186.220971241,
+	186.042414571,185.863642913,185.684656407,185.505455195,185.326039416,
+	185.146409208,184.966564707,184.78650605,184.606233371,184.425746802,
+	184.245046478,184.064132527,183.88300508,183.701664266,183.520110212,
+	183.338343043,183.156362885,182.974169862,182.791764095,182.609145707,
+	182.426314816,182.243271543,182.060016004,181.876548316,181.692868595,
+	181.508976953,181.324873504,181.14055836,180.95603163,180.771293424,
+	180.58634385,180.401183013,180.215811021,180.030227975,179.844433981,
+	179.658429138,179.472213549,179.285787311,179.099150523,178.912303282,
+	178.725245682,178.537977819,178.350499785,178.162811672,177.974913571,
+	177.78680557,177.598487758,177.409960222,177.221223046,177.032276316,
+	176.843120113,176.653754521,176.464179619,176.274395486,176.084402201,
+	175.894199839,175.703788477,175.513168189,175.322339047,175.131301123,
+	174.940054487,174.748599208,174.556935354,174.365062992,174.172982186,
+	173.980693001,173.788195499,173.595489741,173.402575787,173.209453697,
+	173.016123528,172.822585335,172.628839174,172.434885098,172.240723159,
+	172.046353409,171.851775896,171.65699067,171.461997778,171.266797264,
+	171.071389174,170.87577355,170.679950435,170.483919869,170.28768189,
+	170.091236537,169.894583847,169.697723853,169.500656591,169.303382093,
+	169.105900389,168.90821151,168.710315484,168.512212338,168.313902098,
+	168.115384789,167.916660433,167.717729053,167.518590668,167.319245298,
+	167.11969296,166.919933671,166.719967446,166.519794298,166.31941424,
+	166.118827282,165.918033434,165.717032704,165.515825098,165.314410622,
+	165.112789281,164.910961076,164.708926008,164.506684078,164.304235284,
+	164.101579623,163.898717091,163.695647681,163.492371386,163.288888199,
+	163.085198108,162.881301103,162.67719717,162.472886295,162.268368463,
+	162.063643656,161.858711857,161.653573044,161.448227196,161.242674291,
+	161.036914304,160.83094721,160.62477298,160.418391588,160.211803002,
+	160.005007191,159.798004121,159.590793759,159.383376069,159.175751012,
+	158.967918551,158.759878644,158.551631251,158.343176326,158.134513827,
+	157.925643705,157.716565915,157.507280405,157.297787126,157.088086025,
+	156.878177048,156.66806014,156.457735244,156.247202301,156.036461253,
+	155.825512036,155.614354589,155.402988847,155.191414744,154.979632212,
+	154.767641183,154.555441585,154.343033346,154.130416393,153.91759065,
+	153.704556041,153.491312486,153.277859907,153.064198221,152.850327345,
+	152.636247195,152.421957684,152.207458725,151.992750227,151.7778321,
+	151.562704251,151.347366586,151.131819009,150.916061423,150.700093728,
+	150.483915823,150.267527608,150.050928976,149.834119824,149.617100043,
+	149.399869526,149.182428161,148.964775837,148.746912439,148.528837853,
+	148.310551961,148.092054646,147.873345786,147.65442526,147.435292944,
+	147.215948713,146.99639244,146.776623997,146.556643254,146.336450078,
+	146.116044336,145.895425893,145.674594613,145.453550356,145.232292983,
+	145.010822352,144.789138319,144.567240739,144.345129466,144.122804351,
+	143.900265243,143.677511992,143.454544443,143.231362442,143.007965832,
+	142.784354453,142.560528148,142.336486752,142.112230104,141.887758038,
+	141.663070388,141.438166985,141.213047659,140.987712238,140.762160551,
+	140.536392421,140.310407672,140.084206127,139.857787605,139.631151926,
+	139.404298906,139.177228362,138.949940108,138.722433955,138.494709716,
+	138.266767199,138.038606213,137.810226563,137.581628056,137.352810494,
+	137.12377368,136.894517415,136.665041496,136.435345723,136.205429892,
+	135.975293798,135.744937235,135.514359995,135.283561869,135.052542648,
+	134.82130212,134.589840073,134.358156292,134.126250564,133.894122672,
+	133.661772399,133.429199528,133.19640384,132.963385115,132.730143131,
+	132.496677668,132.262988503,132.029075413,131.794938175,131.560576562,
+	131.325990352,131.091179317,130.856143233,130.620881872,130.385395008,
+	130.149682414,129.913743863,129.677579128,129.441187981,129.204570195,
+	128.967725544,128.730653801,128.493354739,128.255828133,128.018073758,
+	127.780091388,127.541880801,127.303441774,127.064774085,126.825877513,
+	126.58675184,126.347396848,126.107812322,125.867998046,125.627953809,
+	125.387679402,125.147174616,124.906439246,124.665473091,124.424275951,
+	124.18284763,123.941187934,123.699296676,123.457173669,123.214818733,
+	122.97223169,122.729412369,122.486360602,122.243076228,121.99955909,
+	121.755809038,121.511825927,121.26760962,121.023159987,120.778476904,
+	120.533560256,120.288409935,120.043025842,119.797407887,119.551555992,
+	119.305470084,119.059150105,118.812596006,118.565807749,118.318785311,
+	118.071528678,117.824037853,117.57631285,117.328353699,117.080160446,
+	116.831733152,116.583071896,116.334176775,116.085047901,115.835685411,
+	115.586089457,115.336260215,115.086197883,114.835902681,114.585374855,
+	114.334614673,114.083622432,113.832398456,113.580943098,113.329256739,
+	113.077339793,112.825192708,112.572815961,112.320210071,112.067375588,
+	111.814313105,111.561023251,111.307506702,111.053764172,110.799796425,
+	110.545604269,110.291188564,110.036550219,109.781690197,109.526609517,
+	109.271309257,109.015790552,108.760054603,108.504102673,108.247936094,
+	107.99155627,107.734964676,107.478162863,107.221152462,106.963935187,
+	106.706512834,106.448887292,106.191060538,105.933034646,105.674811791,
+	105.416394248,105.157784399,104.89898474,104.639997879,104.380826542,
+	104.121473582,103.861941977,103.602234839,103.342355417,103.082307103,
+	102.822093435,102.561718104,102.30118496,102.040498015,101.779661449,
+	101.518679619,101.25755706,100.996298495,100.734908838,100.473393204,
+	100.211756913,99.9500054931,99.6881446953,99.4261804934,99.1641190935,
+	98.9019669409,98.6397307266,98.3774173951,98.115034151,97.8525884667,
+	97.5900880897,97.32754105,97.0649556675,96.8023405592,96.5397046474,
+	96.2770571663,96.01440767,95.7517660395,95.4891424902,95.226547579,
+	94.9639922112,94.7014876479,94.4390455122,94.1766777957,93.9143968652,
+	93.6522154685,93.39014674,93.1282042061,92.8664017902,92.6047538171,
+	92.3432750174,92.0819805307,91.820885909,91.5600071186,91.2993605427,
+	91.0389629817,90.7788316539,90.5189841954,90.2594386585,90.0002135096,
+	89.7413276266,89.4828002945,89.2246512005,88.9669004284,88.709568451,
+	88.4526761221,88.196244667,87.940295672,87.6848510727,87.4299331406,
+	87.1755644693,86.9217679583,86.6685667964,86.4159844438,86.1640446119,
+	85.9127712432,85.6621884888,85.4123206855,85.163192331,84.914828058,
+	84.6672526082,84.4204908033,84.1745675171,83.9295076449,83.6853360732,
+	83.4420776478,83.1997571419,82.9583992232,82.7180284205,82.4786690901,
+	82.2403453816,82.0030812043,81.7669001925,81.5318256718,81.2978806254,
+	81.0650876604,80.8334689751,80.6030463265,80.373840999,80.1458737738,
+	79.9191648987,79.6937340602,79.469600356,79.2467822688,79.025297642,
+	78.8051636567,78.5863968102,78.3690128963,78.1530269874,77.9384534185,
+	77.7253057722,77.5135968673,77.3033387471,77.0945426718,76.8872191109,
+	76.6813777391,76.4770274327,76.274176269,76.0728315269,75.8729996892,
+	75.674686447,75.4778967059,75.2826345928,75.0889034655,74.896705923,
+	74.7060438173,74.5169182664,74.3293296689,74.1432777192,73.958761424,
+	73.7757791196,73.5943284902,73.4144065864,73.2360098455,73.0591341108,
+	72.8837746527,72.7099261894,72.5375829084,72.3667384877,72.1973861174,
+	72.0295185219,71.8631279807,71.698206351,71.5347450886,71.3727352695,
+	71.2121676108,71.0530324916,70.895319974,70.7390198224,70.5841215239,
+	70.4306143075,70.2784871629,70.127728859,69.9783279618,69.8302728517,
+	69.6835517406,69.5381526878,69.3940636164,69.251272328,69.1097665175,
+	68.9695337873,68.8305616607,68.692837595,68.556348994,68.4210832195,
+	68.2870276031,68.1541694565,68.0224960825,67.8919947839,67.7626528733,
+	67.6344576819,67.5073965675,67.3814569225,67.2566261813,67.132891827,
+	67.0102413984,66.8886624955,66.7681427857,66.6486700089,66.5302319826,
+	66.4128166063,66.2964118658,66.1810058376,66.0665866919,65.9531426963,
+	65.8406622188,65.7291337307,65.6185458088,65.5088871381,65.4001465135,
+	65.2923128418,65.1853751436,65.0793225539,64.9741443241,64.869829823,
+	64.7663685372,64.6637500722,64.5619641527,64.4610006235,64.3608494493,
+	64.261500715,64.1629446261,64.0651715079,63.9681718061,63.8719360861,
+	63.776455033,63.6817194506,63.5877202614,63.4944485058,63.4018953417,
+	63.3100520431,63.2189100002,63.1284607182,63.038695816,62.9496070262,
+	62.8611861931,62.7734252727,62.6863163309,62.5998515428,62.5140231916,
+	62.4288236674,62.344245466,62.2602811881,62.1769235376,62.094165321,
+	62.0119994454,61.9304189184,61.8494168459,61.7689864313,61.6891209743,
+	61.6098138696,61.5310586057,61.4528487634,61.3751780152,61.2980401233,
+	61.2214289391,61.1453384013,61.0697625353,60.9946954515,60.9201313444,
+	60.8460644913,60.772489251,60.699400063,60.6267914458,60.554657996,
+	60.4829943874,60.4117953693,60.3410557658,60.2707704748,60.2009344661,
+	60.1315427815,60.0625905326,59.9940729003,59.9259851339,59.8583225495,
+	59.7910805294,59.724254521,59.6578400356,59.5918326476,59.5262279936,
+	59.4610217712,59.3962097382,59.3317877115,59.2677515663,59.2040972355,
+	59.140820708,59.0779180285,59.0153852966,58.9532186654,58.8914143412,
+	58.8299685825,58.768877699,58.708138051,58.6477460488,58.5876981511,
+	58.5279908653,58.4686207459,58.4095843943,58.3508784577,58.2924996285,
+	58.2344446436,58.1767102838,58.119293373,58.0621907773,58.005399405,
+	57.948916205,57.892738167,57.8368623204,57.7812857339,57.7260055146,
+	57.6710188078,57.616322796,57.5619146987,57.5077917713,57.4539513053,
+	57.4003906269,57.3471070972,57.2940981111,57.241361097,57.1888935166,
+	57.1366928636,57.084756664,57.0330824751,56.9816678854,56.9305105136,
+	56.8796080089,56.8289580495,56.7785583433,56.7284066266,56.6785006639,
+	56.6288382478,56.5794171979,56.5302353612,56.4812906111,56.432580847,
+	56.3841039945,56.3358580041,56.2878408518,56.2400505378,56.1924850868,
+	56.1451425476,56.0980209921,56.0511185157,56.0044332366,55.9579632956,
+	55.9117068555,55.8656621011,55.8198272387,55.7742004958,55.7287801209,
+	55.6835643831,55.6385515716,55.5937399958,55.5491279849,55.5047138872,
+	55.4604960706,55.4164729216,55.3726428452,55.3290042651,55.2855556227,
+	55.2422953775,55.1992220065,55.1563340038,55.1136298808,55.0711081657,
+	55.0287674032,54.9866061544,54.9446229966,54.9028165229,54.8611853421,
+	54.8197280785,54.7784433715,54.7373298757,54.6963862605,54.6556112098,
+	54.6150034221,54.5745616098,54.5342844997,54.4941708323,54.4542193616,
+	54.4144288551,54.3747980937,54.3353258713,54.2960109948,54.2568522837,
+	54.2178485702,54.1789986988,54.1403015262,54.1017559213,54.0633607649,
+	54.0251149495,53.9870173791,53.9490669694,53.9112626471,53.8736033501,
+	53.8360880275,53.7987156391,53.7614851554,53.7243955574,53.6874458368,
+	53.6506349953,53.6139620448,53.5774260075,53.5410259151,53.5047608095,
+	53.4686297419,53.4326317732,53.3967659736,53.3610314227,53.3254272092,
+	53.2899524309,53.2546061945,53.2193876154,53.184295818,53.149329935,
+	53.1144891078,53.079772486,53.0451792278,53.0107084993,52.9763594747,
+	52.9421313363,52.9080232742,52.8740344864,52.8401641783,52.8064115633,
+	52.772775862,52.7392563025,52.7058521203,52.672562558,52.6393868653,
+	52.6063242993,52.5733741236,52.5405356091,52.5078080332,52.4751906802,
+	52.442682841,52.4102838131,52.3779929004,52.3458094133,52.3137326685,
+	52.281761989,52.2498967038,52.2181361484,52.1864796639,52.1549265977,
+	52.123476303,52.0921281387,52.0608814697,52.0297356664,51.998690105,
+	51.9677441672,51.9368972401,51.9061487165,51.8754979942,51.8449444767,
+	51.8144875727,51.7841266957,51.7538612649,51.7236907043,51.6936144428,
+	51.6636319146,51.6337425585,51.6039458184,51.5742411427,51.544627985,
+	51.5151058032,51.4856740601,51.4563322228,51.4270797633,51.3979161578,
+	51.3688408872,51.3398534365,51.3109532954,51.2821399576,51.2534129212,
+	51.2247716884,51.1962157658,51.1677446638,51.1393578971,51.1110549843,
+	51.0828354481,51.0546988151,51.0266446158,50.9986723845,50.9707816593,
+	50.9429719823,50.9152428991,50.8875939591,50.8600247153,50.8325347244,
+	50.8051235466,50.7777907458,50.7505358892,50.7233585476,50.6962582952,
+	50.6692347097,50.6422873719,50.6154158663,50.5886197804,50.5618987051,
+	50.5352522345,50.5086799659,50.4821814997,50.4557564396,50.4294043921,
+	50.4031249672,50.3769177775,50.3507824389,50.3247185701,50.2987257929,
+	50.2728037319,50.2469520147,50.2211702716,50.1954581358,50.1698152434,
+	50.1442412332,50.1187357466,50.0932984281,50.0679289244,50.0426268854,
+	50.0173919631,49.9922238125,49.967122091,49.9420864588,49.9171165783,
+	49.8922121146,49.8673727353,49.8425981105,49.8178879127,49.7932418167,
+	49.7686594998,49.7441406417,49.7196849244,49.6952920323,49.670961652,
+	49.6466934725,49.622487185,49.5983424828,49.5742590617,49.5502366195,
+	49.5262748563,49.5023734741,49.4785321775,49.4547506727,49.4310286684,
+	49.4073658752,49.3837620058,49.3602167748,49.336729899,49.3133010971,
+	49.28993009,49.2666166002,49.2433603524,49.2201610732,49.197018491,
+	49.1739323363,49.1509023413,49.12792824,49.1050097686,49.0821466646,
+	49.0593386678,49.0365855194,49.0138869628,48.9912427428,48.968652606,
+	48.9461163009,48.9236335776,48.901204188,48.8788278855,48.8565044252,
+	48.8342335641,48.8120150606,48.7898486748,48.7677341684,48.7456713047,
+	48.7236598486,48.7016995666,48.6797902266,48.6579315983,48.6361234527,
+	48.6143655624,48.5926577015,48.5709996457,48.5493911719,48.5278320588,
+	48.5063220864,48.484861036,48.4634486905,48.4420848342,48.4207692528,
+	48.3995017333,48.3782820642,48.3571100353,48.3359854377,48.314908064,
+	48.2938777081,48.272894165,48.2519572313,48.2310667048,48.2102223845,
+	48.1894240707,48.1686715652,48.1479646707,48.1273031914,48.1066869326,
+	48.0861157009,48.0655893041,48.0451075513,48.0246702526,48.0042772194,
+	47.9839282643,47.963623201,47.9433618444,47.9231440105,47.9029695165,
+	47.8828381808,47.8627498227,47.8427042628,47.8227013227,47.8027408252,
+	47.7828225941,47.7629464542,47.7431122316,47.7233197533,47.7035688473,
+	47.6838593428,47.6641910699,47.6445638598,47.6249775446,47.6054319576,
+	47.5859269331,47.5664623061,47.5470379129,47.5276535906,47.5083091774,
+	47.4890045124,47.4697394356,47.450513788,47.4313274116,47.4121801493,
+	47.3930718448,47.3740023428,47.3549714891,47.3359791301,47.3170251133,
+	47.2981092869,47.2792315003,47.2603916035,47.2415894475,47.2228248841,
+	47.2040977659,47.1854079466,47.1667552804,47.1481396226,47.1295608293,
+	47.1110187573,47.0925132644,47.0740442089,47.0556114503,47.0372148487,
+	47.0188542649,47.0005295607,46.9822405986,46.9639872418,46.9457693543,
+	46.9275868009,46.9094394473,46.8913271597,46.8732498052,46.8552072516,
+	46.8371993674,46.8192260219,46.8012870852,46.7833824279,46.7655119216,
+	46.7476754383,46.7298728509,46.712104033,46.6943688588,46.6766672034,
+	46.6589989423,46.6413639518,46.6237621091,46.6061932917,46.5886573779,
+	46.5711542468,46.5536837781,46.5362458519,46.5188403494,46.501467152,
+	46.4841261421,46.4668172024,46.4495402166,46.4322950687,46.4150816434,
+	46.3978998262,46.3807495031,46.3636305605,46.3465428857,46.3294863665,
+	46.3124608912,46.2954663489,46.2785026291,46.261569622,46.2446672182,
+	46.2277953091,46.2109537865,46.1941425428,46.1773614712,46.1606104651,
+	46.1438894186,46.1271982264,46.1105367837,46.0939049864,46.0773027305,
+	46.0607299131,46.0441864315,46.0276721836,46.0111870677,45.9947309829,
+	45.9783038286,45.9619055047,45.9455359118,45.9291949509,45.9128825234,
+	45.8965985314,45.8803428774,45.8641154643,45.8479161957,45.8317449755,
+	45.8156017082,45.7994862988,45.7833986526,45.7673386755,45.751306274,
+	45.7353013548,45.7193238253,45.7033735933,45.6874505668,45.6715546547,
+	45.6556857661,45.6398438106,45.6240286981,45.6082403393,45.5924786449,
+	45.5767435264,45.5610348956,45.5453526646,45.5296967462,45.5140670535,
+	45.4984635,45.4828859995,45.4673344665,45.4518088158,45.4363089625,
+	45.4208348222,45.4053863109,45.3899633451,45.3745658416,45.3591937176,
+	45.3438468908,45.328525279,45.3132288009,45.297957375,45.2827109208,
+	45.2674893576,45.2522926056,45.2371205849,45.2219732164,45.2068504212,
+	45.1917521207,45.1766782368,45.1616286916,45.1466034078,45.1316023084,
+	45.1166253165,45.101672356,45.0867433507,45.0718382252,45.0569569041,
+	45.0420993126,45.027265376,45.0124550203,44.9976681714,44.9829047559,
+	44.9681647005,44.9534479326,44.9387543794,44.924083969,44.9094366294,
+	44.8948122891,44.8802108769,44.865632322,44.8510765539,44.8365435024,
+	44.8220330976,44.8075452698,44.7930799499,44.778637069,44.7642165583,
+	44.7498183497,44.735442375,44.7210885667,44.7067568573,44.6924471798,
+	44.6781594673,44.6638936534,44.6496496719,44.6354274569,44.6212269429,
+	44.6070480645,44.5928907568,44.578754955,44.5646405947,44.5505476118,
+	44.5364759423,44.5224255228,44.50839629,44.4943881808,44.4804011325,
+	44.4664350827,44.4524899692,44.43856573,44.4246623036,44.4107796285,
+	44.3969176438,44.3830762885,44.369255502,44.3554552242,44.341675395,
+	44.3279159545,44.3141768433,44.3004580021,44.2867593719,44.2730808939,
+	44.2594225098,44.2457841612,44.2321657901,44.2185673388,44.2049887499,
+	44.191429966,44.1778909302,44.1643715857,44.150871876,44.1373917448,
+	44.1239311362,44.1104899942,44.0970682634,44.0836658884,44.0702828141,
+	44.0569189857,44.0435743485,44.0302488482,44.0169424307,44.0036550418,
+	43.990386628,43.9771371358,43.9639065119,43.9506947033,43.9375016571,
+	43.9243273208,43.911171642,43.8980345685,43.8849160484,43.8718160299,
+	43.8587344616,43.8456712922,43.8326264705,43.8195999457,43.8065916671,
+	43.7936015843,43.780629647,43.7676758052,43.7547400091,43.7418222089,
+	43.7289223553,43.7160403991,43.7031762912,43.6903299827,43.6775014252,
+	43.66469057,43.6518973691,43.6391217743,43.6263637378,43.613623212,
+	43.6009001494,43.5881945027,43.5755062248,43.5628352689,43.5501815883,
+	43.5375451365,43.524925867,43.5123237339,43.499738691,43.4871706927,
+	43.4746196934,43.4620856476,43.4495685102,43.437068236,43.4245847802,
+	43.4121180981,43.3996681453,43.3872348772,43.3748182499,43.3624182192,
+	43.3500347414,43.3376677729,43.32531727,43.3129831897,43.3006654886,
+	43.2883641239,43.2760790527,43.2638102324,43.2515576206,43.2393211749,
+	43.2271008533,43.2148966136,43.2027084142,43.1905362133,43.1783799696,
+	43.1662396416,43.1541151882,43.1420065683,43.1299137412,43.1178366661,
+	43.1057753025,43.0937296101,43.0816995485,43.0696850777,43.0576861577,
+	43.0457027489,43.0337348116,43.0217823063,43.0098451938,42.9979234347,
+	42.9860169902,42.9741258213,42.9622498893,42.9503891557,42.938543582,
+	42.9267131299,42.9148977612,42.9030974381,42.8913121225,42.8795417768,
+	42.8677863635,42.856045845,42.8443201841,42.8326093436,42.8209132865,
+	42.809231976,42.7975653752,42.7859134476,42.7742761567,42.7626534662,
+	42.7510453398,42.7394517416,42.7278726355,42.7163079857,42.7047577566,
+	42.6932219127,42.6817004185,42.6701932388,42.6587003383,42.6472216822,
+	42.6357572354,42.6243069633,42.6128708311,42.6014488044,42.5900408488,
+	42.57864693,42.5672670139,42.5559010665,42.5445490538,42.5332109421,
+	42.5218866978,42.5105762873,42.4992796772,42.4879968343,42.4767277253,
+	42.4654723173,42.4542305773,42.4430024724,42.4317879701,42.4205870377,
+	42.4093996427,42.3982257529,42.3870653359,42.3759183598,42.3647847924,
+	42.3536646019,42.3425577565,42.3314642245,42.3203839745,42.309316975,
+	42.2982631946,42.2872226021,42.2761951665,42.2651808567,42.2541796418,
+	42.2431914911,42.2322163739,42.2212542596,42.2103051178,42.1993689181,
+	42.1884456302,42.1775352242,42.1666376698,42.1557529372,42.1448809965,
+	42.1340218181,42.1231753722,42.1123416295,42.1015205604,42.0907121357,
+	42.0799163261,42.0691331025,42.058362436,42.0476042976,42.0368586585,
+	42.0261254899,42.0154047634,42.0046964503,41.9940005222,41.9833169508,
+	41.972645708,41.9619867655,41.9513400953,41.9407056694,41.9300834602,
+	41.9194734397,41.9088755803,41.8982898545,41.8877162349,41.8771546939,
+	41.8666052044,41.8560677391,41.845542271,41.8350287731,41.8245272183,
+	41.81403758,41.8035598313,41.7930939457,41.7826398964,41.7721976572,
+	41.7617672016,41.7513485032,41.740941536,41.7305462738,41.7201626905,
+	41.7097907601,41.699430457,41.6890817552,41.6787446291,41.668419053,
+	41.6581050015,41.6478024491,41.6375113705,41.6272317404,41.6169635335,
+	41.6067067249,41.5964612895,41.5862272023,41.5760044385,41.5657929734,
+	41.5555927821,41.5454038401,41.535226123,41.5250596061,41.5149042652,
+	41.5047600759,41.4946270141,41.4845050556,41.4743941762,41.4642943522,
+	41.4542055595,41.4441277743,41.4340609729,41.4240051315,41.4139602267,
+	41.4039262349,41.3939031326,41.3838908964,41.3738895031,41.3638989294,
+	41.3539191523,41.3439501485,41.3339918952,41.3240443693,41.3141075481,
+	41.3041814088,41.2942659286,41.2843610849,41.2744668552,41.2645832169,
+	41.2547101477,41.2448476251,41.234995627,41.225154131,41.2153231151,
+	41.2055025572,41.1956924352,41.1858927273,41.1761034116,41.1663244663,
+	41.1565558696,41.1467976,41.1370496357,41.1273119554,41.1175845375,
+	41.1078673606,41.0981604035,41.0884636448,41.0787770634,41.0691006382,
+	41.059434348,41.049778172,41.0401320891,41.0304960786,41.0208701195,
+	41.0112541912,41.0016482731,40.9920523444,40.9824663846,40.9728903734,
+	40.9633242901,40.9537681146,40.9442218265,40.9346854055,40.9251588316,
+	40.9156420845,40.9061351443,40.8966379909,40.8871506045,40.8776729651,
+	40.868205053,40.8587468484,40.8492983317,40.8398594831,40.8304302833,
+	40.8210107125,40.8116007515,40.8022003807,40.792809581,40.7834283329,
+	40.7740566174,40.7646944152,40.7553417072,40.7459984744,40.7366646979,
+	40.7273403586,40.7180254378,40.7087199165,40.6994237762,40.6901369979,
+	40.6808595632,40.6715914533,40.6623326499,40.6530831343,40.6438428882,
+	40.6346118932,40.625390131,40.6161775833,40.6069742319,40.5977800587,
+	40.5885950455,40.5794191744,40.5702524272,40.5610947862,40.5519462333,
+	40.5428067507,40.5336763208,40.5245549257,40.5154425477,40.5063391692,
+	40.4972447727,40.4881593407,40.4790828555,40.4700152999,40.4609566565,
+	40.4519069079,40.4428660369,40.4338340262,40.4248108587,40.4157965172,
+	40.4067909847,40.3977942441,40.3888062786,40.3798270711,40.3708566047,
+	40.3618948628,40.3529418284,40.3439974848,40.3350618154,40.3261348035,
+	40.3172164326,40.3083066861,40.2994055475,40.2905130003,40.2816290283,
+	40.2727536149,40.2638867439,40.2550283991,40.2461785643,40.2373372232,
+	40.2285043598,40.219679958,40.2108640017,40.202056475,40.1932573619,
+	40.1844666466,40.1756843131,40.1669103458,40.1581447288,40.1493874464,
+	40.1406384829,40.1318978228,40.1231654504,40.1144413503,40.1057255068,
+	40.0970179046
+	}},
+	{ // Ri = 250k
+	-5,5,200,2001, {
+	239.919843376,239.854937108,239.789738489,239.724247218,239.658462996,
+	239.592385535,239.526014546,239.459349752,239.392390878,239.325137654,
+	239.257589818,239.189747112,239.121609284,239.053176087,238.984447281,
+	238.91542263,238.846101903,238.776484877,238.706571332,238.636361055,
+	238.565853836,238.495049475,238.423947772,238.352548536,238.280851579,
+	238.208856722,238.136563787,238.063972604,237.991083007,237.917894835,
+	237.844407935,237.770622155,237.696537352,237.622153385,237.54747012,
+	237.472487429,237.397205186,237.321623273,237.245741575,237.169559984,
+	237.093078396,237.016296711,236.939214835,236.86183268,236.78415016,
+	236.706167196,236.627883714,236.549299644,236.470414921,236.391229484,
+	236.311743279,236.231956253,236.151868362,236.071479563,235.99078982,
+	235.9097991,235.828507376,235.746914624,235.665020826,235.582825967,
+	235.500330038,235.417533033,235.334434951,235.251035796,235.167335575,
+	235.083334301,234.999031988,234.914428659,234.829524337,234.744319051,
+	234.658812834,234.573005723,234.48689776,234.400488988,234.313779459,
+	234.226769224,234.13945834,234.05184687,233.963934876,233.875722429,
+	233.7872096,233.698396466,233.609283107,233.519869606,233.430156051,
+	233.340142534,233.249829147,233.159215991,233.068303166,232.977090779,
+	232.885578937,232.793767753,232.701657342,232.609247824,232.516539321,
+	232.423531959,232.330225867,232.236621177,232.142718023,232.048516546,
+	231.954016887,231.85921919,231.764123605,231.66873028,231.573039372,
+	231.477051037,231.380765434,231.284182727,231.187303082,231.090126667,
+	230.992653654,230.894884217,230.796818534,230.698456783,230.599799147,
+	230.500845813,230.401596966,230.302052798,230.202213502,230.102079273,
+	230.001650309,229.900926811,229.799908981,229.698597024,229.596991149,
+	229.495091566,229.392898486,229.290412124,229.187632698,229.084560426,
+	228.98119553,228.877538233,228.77358876,228.66934734,228.564814202,
+	228.459989578,228.354873701,228.249466808,228.143769136,228.037780925,
+	227.931502416,227.824933853,227.718075481,227.610927548,227.503490301,
+	227.395763992,227.287748873,227.179445197,227.070853221,226.961973202,
+	226.852805398,226.743350071,226.633607482,226.523577894,226.413261574,
+	226.302658786,226.1917698,226.080594885,225.969134311,225.857388351,
+	225.745357278,225.633041366,225.520440893,225.407556135,225.294387371,
+	225.180934881,225.067198945,224.953179846,224.838877868,224.724293293,
+	224.609426409,224.494277501,224.378846857,224.263134765,224.147141516,
+	224.030867399,223.914312706,223.79747773,223.680362764,223.562968102,
+	223.445294038,223.32734087,223.209108892,223.090598404,222.971809703,
+	222.852743088,222.733398858,222.613777314,222.493878757,222.373703489,
+	222.253251812,222.132524028,222.011520442,221.890241357,221.768687078,
+	221.64685791,221.524754159,221.402376131,221.279724132,221.15679847,
+	221.033599452,220.910127386,220.78638258,220.662365343,220.538075983,
+	220.413514811,220.288682136,220.163578268,220.038203517,219.912558193,
+	219.786642608,219.660457072,219.534001897,219.407277394,219.280283874,
+	219.15302165,219.025491033,218.897692335,218.769625868,218.641291945,
+	218.512690877,218.383822977,218.254688558,218.125287932,217.995621411,
+	217.865689308,217.735491935,217.605029605,217.47430263,217.343311321,
+	217.212055993,217.080536955,216.948754521,216.816709003,216.684400712,
+	216.551829959,216.418997057,216.285902317,216.152546049,216.018928564,
+	215.885050174,215.750911189,215.616511919,215.481852673,215.346933762,
+	215.211755495,215.076318182,214.94062213,214.804667649,214.668455047,
+	214.531984632,214.395256711,214.258271591,214.121029579,213.983530982,
+	213.845776106,213.707765256,213.569498737,213.430976855,213.292199913,
+	213.153168215,213.013882066,212.874341767,212.734547621,212.594499931,
+	212.454198998,212.313645123,212.172838605,212.031779747,211.890468845,
+	211.748906201,211.607092111,211.465026874,211.322710786,211.180144146,
+	211.037327247,210.894260386,210.750943858,210.607377956,210.463562975,
+	210.319499207,210.175186945,210.03062648,209.885818102,209.740762104,
+	209.595458773,209.449908399,209.304111271,209.158067675,209.011777899,
+	208.865242229,208.71846095,208.571434346,208.424162703,208.276646303,
+	208.128885429,207.980880362,207.832631383,207.684138772,207.53540281,
+	207.386423774,207.237201943,207.087737593,206.938031001,206.788082442,
+	206.637892192,206.487460523,206.336787708,206.185874021,206.034719732,
+	205.883325112,205.73169043,205.579815956,205.427701956,205.2753487,
+	205.122756451,204.969925477,204.816856041,204.663548407,204.510002838,
+	204.356219596,204.202198941,204.047941133,203.893446432,203.738715096,
+	203.583747382,203.428543546,203.273103844,203.11742853,202.961517859,
+	202.805372081,202.64899145,202.492376216,202.335526629,202.178442938,
+	202.021125389,201.863574231,201.70578971,201.547772069,201.389521554,
+	201.231038407,201.072322871,200.913375185,200.754195591,200.594784328,
+	200.435141633,200.275267743,200.115162895,199.954827324,199.794261263,
+	199.633464946,199.472438604,199.31118247,199.149696771,198.987981739,
+	198.826037599,198.66386458,198.501462908,198.338832806,198.175974498,
+	198.012888208,197.849574157,197.686032566,197.522263653,197.358267639,
+	197.194044739,197.029595171,196.864919149,196.700016888,196.534888602,
+	196.369534501,196.203954798,196.038149702,195.872119422,195.705864166,
+	195.53938414,195.372679551,195.205750602,195.038597496,194.871220438,
+	194.703619627,194.535795263,194.367747547,194.199476675,194.030982844,
+	193.862266251,193.69332709,193.524165554,193.354781836,193.185176127,
+	193.015348617,192.845299495,192.675028949,192.504537166,192.333824332,
+	192.162890631,191.991736246,191.820361361,191.648766155,191.476950809,
+	191.304915502,191.132660411,190.960185714,190.787491586,190.6145782,
+	190.441445731,190.268094349,190.094524227,189.920735533,189.746728437,
+	189.572503106,189.398059705,189.223398401,189.048519357,188.873422736,
+	188.698108699,188.522577407,188.34682902,188.170863695,187.994681589,
+	187.818282858,187.641667658,187.46483614,187.287788459,187.110524763,
+	186.933045205,186.755349932,186.577439092,186.399312831,186.220971295,
+	186.042414627,185.863642971,185.684656468,185.505455258,185.326039482,
+	185.146409276,184.966564778,184.786506124,184.606233447,184.425746882,
+	184.245046561,184.064132614,183.883005171,183.70166436,183.52011031,
+	183.338343145,183.156362991,182.974169972,182.79176421,182.609145826,
+	182.426314941,182.243271672,182.060016139,181.876548456,181.69286874,
+	181.508977105,181.324873662,181.140558524,180.956031801,180.771293602,
+	180.586344035,180.401183206,180.215811221,180.030228184,179.844434198,
+	179.658429365,179.472213784,179.285787556,179.099150778,178.912303547,
+	178.725245958,178.537978106,178.350500084,178.162811983,177.974913895,
+	177.786805907,177.598488109,177.409960587,177.221223426,177.032276711,
+	176.843120525,176.653754949,176.464180064,176.274395949,176.084402683,
+	175.894200341,175.703788999,175.513168732,175.322339612,175.131301711,
+	174.940055099,174.748599845,174.556936017,174.365063682,174.172982904,
+	173.980693748,173.788196276,173.59549055,173.402576629,173.209454574,
+	173.01612444,172.822586284,172.628840161,172.434886125,172.240724228,
+	172.046354521,171.851777054,171.656991875,171.461999032,171.266798569,
+	171.071390532,170.875774963,170.679951906,170.483921399,170.287683483,
+	170.091238194,169.894585571,169.697725648,169.500658458,169.303384036,
+	169.105902411,168.908213614,168.710317673,168.512214616,168.313904469,
+	168.115387256,167.916663,167.717731724,167.518593448,167.31924819,
+	167.11969597,166.919936804,166.719970706,166.51979769,166.319417769,
+	166.118830954,165.918037255,165.71703668,165.515829236,165.314414928,
+	165.112793761,164.910965738,164.70893086,164.506689127,164.304240538,
+	164.10158509,163.898722779,163.6956536,163.492377545,163.288894608,
+	163.085204777,162.881308042,162.677204391,162.472893809,162.268376282,
+	162.063651792,161.858720322,161.653581853,161.448236362,161.242683829,
+	161.036924229,160.830957537,160.624783727,160.41840277,160.211814637,
+	160.005019298,159.79801672,159.590806869,159.38338971,159.175765206,
+	158.967933321,158.759894013,158.551647242,158.343192966,158.134531141,
+	157.925661722,157.716584662,157.507299912,157.297807424,157.088107145,
+	156.878199025,156.668083008,156.457759039,156.247227061,156.036487016,
+	155.825538844,155.614382484,155.403017872,155.191444946,154.979663638,
+	154.767673882,154.55547561,154.34306875,154.130453232,153.917628982,
+	153.704595926,153.491353989,153.277903091,153.064243155,152.850374101,
+	152.636295846,152.422008306,152.207511398,151.992805035,151.777889129,
+	151.562763591,151.347428331,151.131883256,150.916128273,150.700163287,
+	150.483988202,150.267602919,150.051007339,149.834201362,149.617184885,
+	149.399957805,149.182520017,148.964871415,148.74701189,148.528941333,
+	148.310659634,148.092166681,147.873462361,147.654546557,147.435419156,
+	147.216080038,146.996529086,146.776766179,146.556791196,146.336604013,
+	146.116204508,145.895592554,145.674768025,145.453730794,145.23248073,
+	145.011017705,144.789341586,144.56745224,144.345349535,144.123033334,
+	143.900503503,143.677759903,143.454802397,143.231630845,143.008245106,
+	142.784645041,142.560830506,142.336801358,142.112557454,141.888098647,
+	141.663424793,141.438535745,141.213431356,140.988111477,140.76257596,
+	140.536824656,140.310857414,140.084674085,139.858274517,139.631658559,
+	139.40482606,139.177776866,138.950510827,138.72302779,138.495327601,
+	138.267410109,138.039275161,137.810922605,137.582352287,137.353564057,
+	137.124557761,136.89533325,136.665890372,136.436228977,136.206348916,
+	135.976250041,135.745932202,135.515395255,135.284639054,135.053663455,
+	134.822468314,134.591053492,134.359418849,134.127564247,133.895489551,
+	133.663194629,133.430679348,133.197943581,132.964987203,132.73181009,
+	132.498412124,132.264793187,132.030953168,131.796891958,131.562609451,
+	131.328105548,131.093380151,130.85843317,130.623264518,130.387874115,
+	130.152261884,129.916427758,129.680371672,129.444093571,129.207593404,
+	128.970871129,128.733926713,128.496760129,128.259371358,128.021760393,
+	127.783927234,127.545871891,127.307594385,127.069094748,126.830373023,
+	126.591429265,126.352263542,126.112875935,125.873266537,125.633435457,
+	125.393382821,125.153108766,124.91261345,124.671897045,124.430959742,
+	124.189801752,123.948423304,123.706824648,123.465006057,123.222967823,
+	122.980710263,122.738233721,122.495538562,122.252625181,122.009493998,
+	121.766145463,121.522580057,121.278798292,121.034800711,120.790587894,
+	120.546160453,120.30151904,120.056664344,119.811597095,119.566318064,
+	119.320828067,119.075127963,118.82921866,118.583101115,118.336776335,
+	118.090245381,117.84350937,117.596569475,117.349426929,117.102083029,
+	116.854539134,116.606796673,116.358857143,116.110722114,115.862393231,
+	115.613872218,115.365160881,115.116261108,114.867174879,114.61790426,
+	114.368451414,114.118818604,113.86900819,113.619022642,113.368864537,
+	113.118536565,112.868041535,112.617382378,112.366562149,112.115584036,
+	111.864451361,111.613167587,111.361736321,111.11016132,110.858446499,
+	110.60659593,110.354613852,110.102504677,109.850272992,109.597923569,
+	109.345461366,109.09289154,108.840219447,108.587450649,108.334590925,
+	108.081646272,107.828622915,107.575527312,107.322366164,107.069146415,
+	106.815875267,106.562560181,106.309208889,106.055829395,105.802429989,
+	105.549019247,105.295606044,105.042199559,104.78880928,104.535445014,
+	104.282116893,104.028835379,103.775611272,103.522455718,103.26938021,
+	103.016396602,102.763517107,102.510754307,102.258121157,102.00563099,
+	101.75329752,101.501134848,101.249157464,100.997380252,100.74581849,
+	100.494487852,100.243404412,99.9925846399,99.7420454065,99.4918039784,
+	99.2418780182,98.992285581,98.7430451111,98.4941754376,98.2456957684,
+	97.9976256841,97.7499851301,97.5027944079,97.2560741654,97.0098453854,
+	96.764129374,96.5189477467,96.2743224139,96.030275565,95.7868296514,
+	95.5440073677,95.3018316327,95.0603255681,94.8195124769,94.5794158196,
+	94.3400591904,94.1014662917,93.8636609074,93.6266668754,93.3905080596,
+	93.1552083202,92.9207914838,92.687281313,92.4547014744,92.2230755076,
+	91.9924267924,91.7627785162,91.5341536421,91.3065748752,91.0800646308,
+	90.8546450013,90.6303377244,90.4071641513,90.1851452154,89.9643014023,
+	89.7446527197,89.5262186689,89.309018217,89.0930697707,88.8783911506,
+	88.6649995678,88.452911601,88.2421431758,88.0327095454,87.8246252726,
+	87.6179042144,87.4125595073,87.2086035549,87.0060480178,86.8049038042,
+	86.6051810635,86.4068891809,86.2100367742,86.0146316924,85.820681016,
+	85.6281910588,85.4371673718,85.2476147483,85.059537231,84.8729381203,
+	84.6878199835,84.5041846669,84.3220333071,84.1413663453,83.9621835415,
+	83.78448399,83.6082661365,83.4335277947,83.2602661648,83.088477852,
+	82.918158886,82.7493047404,82.581910353,82.4159701465,82.2514780484,
+	82.0884275127,81.9268115401,81.7666226995,81.6078531484,81.450494654,
+	81.2945386136,81.1399760753,80.9867977578,80.8349940706,80.6845551334,
+	80.5354707951,80.387730653,80.2413240706,80.0962401958,79.9524679782,
+	79.8099961858,79.668813422,79.5289081407,79.3902686621,79.2528831875,
+	79.1167398133,78.9818265451,78.8481313104,78.7156419717,78.5843463383,
+	78.4542321781,78.3252872283,78.1974992063,78.0708558196,77.9453447751,
+	77.8209537885,77.6976705926,77.5754829453,77.4543786377,77.3343455008,
+	77.2153714125,77.097444304,76.9805521656,76.8646830525,76.7498250897,
+	76.6359664772,76.5230954944,76.411200504,76.3002699564,76.1902923926,
+	76.081256448,75.9731508553,75.865964447,75.7596861581,75.6543050282,
+	75.5498102036,75.446190939,75.3434365993,75.2415366608,75.1404807122,
+	75.0402584562,74.94085971,74.8422744057,74.7444925918,74.6475044324,
+	74.5513002088,74.4558703183,74.3612052756,74.2672957116,74.1741323741,
+	74.0817061269,73.9900079501,73.8990289392,73.8087603045,73.7191933711,
+	73.630319578,73.542130477,73.4546177327,73.3677731209,73.2815885286,
+	73.1960559524,73.1111674979,73.0269153786,72.943291915,72.8602895336,
+	72.7779007657,72.6961182464,72.6149347136,72.5343430066,72.4543360653,
+	72.3749069287,72.296048734,72.2177547155,72.140018203,72.062832621,
+	71.9861914875,71.9100884125,71.834517097,71.7594713319,71.6849449967,
+	71.6109320582,71.5374265695,71.4644226687,71.3919145776,71.3198966008,
+	71.2483631244,71.1773086147,71.1067276173,71.0366147558,70.9669647305,
+	70.8977723176,70.829032368,70.7607398058,70.692889628,70.6254769025,
+	70.5584967677,70.491944431,70.4258151681,70.3601043217,70.2948073007,
+	70.2299195789,70.1654366943,70.1013542477,70.0376679022,69.974373382,
+	69.9114664714,69.848943014,69.7867989115,69.7250301233,69.663632665,
+	69.6026026079,69.5419360781,69.4816292553,69.4216783727,69.3620797151,
+	69.302829619,69.2439244713,69.1853607088,69.127134817,69.0692433298,
+	69.0116828285,68.9544499408,68.8975413407,68.8409537471,68.7846839236,
+	68.7287286773,68.6730848588,68.6177493608,68.5627191177,68.5079911053,
+	68.4535623394,68.399429876,68.3455908099,68.2920422747,68.238781442,
+	68.1858055204,68.1331117557,68.0806974294,68.0285598591,67.9766963971,
+	67.9251044304,67.8737813799,67.8227247,67.7719318779,67.7214004334,
+	67.671127918,67.6211119148,67.5713500377,67.521839931,67.4725792692,
+	67.4235657562,67.3747971248,67.3262711367,67.2779855816,67.2299382769,
+	67.1821270675,67.1345498251,67.0872044479,67.0400888603,66.9932010121,
+	66.9465388788,66.9001004606,66.8538837821,66.8078868926,66.7621078646,
+	66.7165447945,66.6711958016,66.626059028,66.5811326384,66.5364148192,
+	66.491903779,66.4475977476,66.4034949759,66.3595937358,66.3158923195,
+	66.2723890395,66.2290822282,66.1859702377,66.1430514394,66.1003242235,
+	66.0577869994,66.0154381946,65.9732762552,65.9312996451,65.8895068457,
+	65.8478963563,65.806466693,65.7652163892,65.7241439947,65.6832480761,
+	65.642527216,65.6019800131,65.5616050819,65.5214010526,65.4813665705,
+	65.4415002962,65.4018009052,65.3622670877,65.3228975484,65.2836910063,
+	65.2446461946,65.2057618602,65.1670367641,65.1284696804,65.0900593968,
+	65.0518047142,65.0137044463,64.9757574197,64.9379624738,64.9003184602,
+	64.8628242429,64.825478698,64.7882807137,64.7512291898,64.7143230378,
+	64.6775611809,64.6409425534,64.6044661009,64.5681307798,64.5319355578,
+	64.4958794131,64.4599613344,64.4241803212,64.388535383,64.3530255396,
+	64.317649821,64.282407267,64.2472969272,64.2123178609,64.1774691369,
+	64.1427498335,64.1081590383,64.0736958481,64.0393593686,64.0051487146,
+	63.9710630098,63.9371013865,63.9032629857,63.8695469568,63.8359524576,
+	63.8024786545,63.7691247216,63.7358898415,63.7027732045,63.669774009,
+	63.636891461,63.6041247743,63.5714731704,63.5389358781,63.5065121337,
+	63.4742011808,63.4420022703,63.4099146602,63.3779376154,63.3460704081,
+	63.3143123171,63.2826626281,63.2511206336,63.2196856325,63.1883569306,
+	63.1571338399,63.1260156789,63.0950017724,63.0640914515,63.0332840535,
+	63.0025789217,62.9719754055,62.9414728602,62.9110706472,62.8807681334,
+	62.8505646917,62.8204597006,62.7904525442,62.7605426122,62.7307292997,
+	62.7010120074,62.6713901411,62.6418631122,62.6124303372,62.5830912378,
+	62.5538452407,62.5246917779,62.4956302862,62.4666602075,62.4377809884,
+	62.4089920806,62.3802929404,62.3516830289,62.3231618119,62.2947287596,
+	62.2663833472,62.238125054,62.2099533641,62.1818677657,62.1538677518,
+	62.1259528192,62.0981224695,62.0703762081,62.0427135449,62.0151339937,
+	61.9876370727,61.9602223038,61.9328892131,61.9056373307,61.8784661904,
+	61.8513753301,61.8243642916,61.7974326202,61.7705798651,61.7438055793,
+	61.7171093194,61.6904906456,61.6639491218,61.6374843153,61.6110957971,
+	61.5847831416,61.5585459265,61.5323837333,61.5062961465,61.4802827541,
+	61.4543431474,61.4284769208,61.4026836724,61.376963003,61.3513145168,
+	61.3257378211,61.3002325264,61.2747982461,61.2494345967,61.2241411979,
+	61.1989176721,61.1737636448,61.1486787445,61.1236626024,61.0987148526,
+	61.0738351323,61.049023081,61.0242783416,60.9996005592,60.9749893819,
+	60.9504444605,60.9259654483,60.9015520014,60.8772037785,60.8529204409,
+	60.8287016523,60.8045470791,60.7804563903,60.7564292571,60.7324653534,
+	60.7085643554,60.6847259419,60.660949794,60.637235595,60.6135830308,
+	60.5899917896,60.5664615617,60.5429920399,60.5195829191,60.4962338965,
+	60.4729446717,60.4497149461,60.4265444237,60.4034328102,60.3803798139,
+	60.357385145,60.3344485156,60.3115696402,60.2887482352,60.2659840191,
+	60.2432767122,60.2206260372,60.1980317183,60.1754934821,60.1530110568,
+	60.1305841728,60.1082125622,60.0858959592,60.0636340995,60.041426721,
+	60.0192735634,59.9971743681,59.9751288783,59.9531368392,59.9311979974,
+	59.9093121016,59.8874789021,59.865698151,59.8439696018,59.8222930102,
+	59.8006681332,59.7790947295,59.7575725597,59.7361013857,59.7146809713,
+	59.6933110816,59.6719914837,59.6507219459,59.6295022382,59.6083321322,
+	59.587211401,59.5661398192,59.5451171629,59.5241432098,59.5032177389,
+	59.4823405308,59.4615113675,59.4407300325,59.4199963107,59.3993099884,
+	59.3786708534,59.3580786947,59.3375333029,59.3170344698,59.2965819887,
+	59.2761756541,59.2558152619,59.2355006095,59.2152314953,59.1950077192,
+	59.1748290824,59.1546953873,59.1346064375,59.1145620381,59.0945619952,
+	59.0746061163,59.05469421,59.0348260863,59.0150015562,58.9952204321,
+	58.9754825273,58.9557876566,58.9361356358,58.9165262819,58.896959413,
+	58.8774348483,58.8579524084,58.8385119146,58.8191131897,58.7997560573,
+	58.7804403424,58.7611658707,58.7419324694,58.7227399664,58.7035881909,
+	58.684476973,58.665406144,58.6463755361,58.6273849825,58.6084343176,
+	58.5895233766,58.5706519958,58.5518200125,58.533027265,58.5142735925,
+	58.4955588353,58.4768828345,58.4582454322,58.4396464715,58.4210857965,
+	58.402563252,58.384078684,58.3656319393,58.3472228655,58.3288513112,
+	58.310517126,58.2922201602,58.2739602651,58.2557372929,58.2375510965,
+	58.2194015299,58.2012884478,58.1832117056,58.16517116,58.1471666681,
+	58.129198088,58.1112652786,58.0933680997,58.0755064118,58.0576800761,
+	58.039888955,58.0221329113,58.0044118086,57.9867255116,57.9690738855,
+	57.9514567963,57.9338741109,57.9163256968,57.8988114223,57.8813311564,
+	57.8638847691,57.8464721308,57.8290931127,57.8117475869,57.7944354261,
+	57.7771565037,57.7599106939,57.7426978714,57.7255179118,57.7083706914,
+	57.691256087,57.6741739762,57.6571242374,57.6401067494,57.6231213918,
+	57.6061680451,57.58924659,57.5723569081,57.5554988818,57.5386723939,
+	57.5218773279,57.505113568,57.488380999,57.4716795062,57.4550089757,
+	57.4383692942,57.4217603489,57.4051820278,57.3886342192,57.3721168123,
+	57.3556296967,57.3391727627,57.3227459011,57.3063490034,57.2899819617,
+	57.2736446684,57.2573370167,57.2410589004,57.2248102138,57.2085908517,
+	57.1924007095,57.1762396831,57.1601076691,57.1440045645,57.127930267,
+	57.1118846745,57.0958676858,57.0798792,57.063919117,57.0479873368,
+	57.0320837602,57.0162082886,57.0003608236,56.9845412676,56.9687495233,
+	56.952985494,56.9372490836,56.9215401962,56.9058587367,56.8902046103,
+	56.8745777228,56.8589779803,56.8434052895,56.8278595578,56.8123406926,
+	56.796848602,56.7813831948,56.7659443798,56.7505320667,56.7351461652,
+	56.719786586,56.7044532397,56.6891460378,56.6738648919,56.6586097143,
+	56.6433804175,56.6281769146,56.6129991191,56.597846945,56.5827203065,
+	56.5676191185,56.5525432961,56.537492755,56.5224674112,56.507467181,
+	56.4924919814,56.4775417297,56.4626163434,56.4477157406,56.4328398399,
+	56.41798856,56.4031618202,56.3883595402,56.37358164,56.35882804,
+	56.3440986611,56.3293934243,56.3147122514,56.3000550642,56.2854217851,
+	56.2708123367,56.2562266421,56.2416646249,56.2271262086,56.2126113176,
+	56.1981198764,56.1836518097,56.1692070429,56.1547855016,56.1403871117,
+	56.1260117995,56.1116594916,56.097330115,56.0830235971,56.0687398656,
+	56.0544788483,56.0402404738,56.0260246706,56.0118313678,55.9976604948,
+	55.9835119812,55.969385757,55.9552817525,55.9411998985,55.9271401258,
+	55.9131023657,55.89908655,55.8850926104,55.8711204792,55.8571700891,
+	55.8432413727,55.8293342633,55.8154486945,55.8015845998,55.7877419134,
+	55.7739205698,55.7601205035,55.7463416495,55.7325839431,55.7188473199,
+	55.7051317156,55.6914370665,55.677763309,55.6641103798,55.6504782158,
+	55.6368667544,55.6232759331,55.6097056897,55.5961559624,55.5826266896,
+	55.5691178099,55.5556292623,55.542160986,55.5287129205,55.5152850055,
+	55.501877181,55.4884893873,55.475121565,55.4617736549,55.448445598,
+	55.4351373357,55.4218488095,55.4085799613,55.3953307332,55.3821010675,
+	55.3688909069,55.3557001941,55.3425288723,55.3293768848,55.3162441752,
+	55.3031306873,55.2900363653,55.2769611534,55.2639049962,55.2508678385,
+	55.2378496253,55.2248503018,55.2118698137,55.1989081067,55.1859651266,
+	55.1730408198,55.1601351326,55.1472480117,55.134379404,55.1215292566,
+	55.1086975168,55.0958841322,55.0830890507,55.0703122201,55.0575535887,
+	55.0448131049,55.0320907175,55.0193863752,55.0067000272,54.9940316227,
+	54.9813811114,54.9687484428,54.956133567,54.943536434,54.9309569943,
+	54.9183951983,54.9058509969,54.893324341,54.8808151818,54.8683234706,
+	54.8558491591,54.8433921989,54.8309525421,54.8185301409,54.8061249475,
+	54.7937369146,54.7813659949,54.7690121413,54.7566753071,54.7443554455,
+	54.73205251,54.7197664544,54.7074972325,54.6952447985,54.6830091066,
+	54.6707901112,54.6585877671,54.646402029,54.634232852,54.6220801911,
+	54.6099440019,54.5978242398,54.5857208606,54.5736338202,54.5615630746,
+	54.5495085801,54.5374702932,54.5254481704,54.5134421685,54.5014522444,
+	54.4894783554,54.4775204586,54.4655785116,54.4536524719,54.4417422974,
+	54.429847946,54.4179693758,54.4061065451,54.3942594124,54.3824279364,
+	54.3706120757,54.3588117893,54.3470270364,54.3352577761,54.323503968,
+	54.3117655715,54.3000425465,54.2883348527,54.2766424504,54.2649652996,
+	54.2533033607,54.2416565943,54.2300249609,54.2184084215,54.206806937,
+	54.1952204684,54.1836489771,54.1720924245,54.1605507722,54.1490239817,
+	54.1375120151,54.1260148343,54.1145324014,54.1030646788,54.0916116288,
+	54.0801732141,54.0687493974,54.0573401415,54.0459454094,54.0345651643,
+	54.0231993694,54.0118479883,54.0005109843,53.9891883213,53.977879963,
+	53.9665858734,53.9553060167,53.944040357,53.9327888587,53.9215514863,
+	53.9103282045,53.8991189781,53.8879237718,53.8767425508,53.8655752802,
+	53.8544219253,53.8432824515,53.8321568244,53.8210450096,53.8099469729,
+	53.7988626803,53.7877920977,53.7767351915,53.7656919278,53.7546622731,
+	53.7436461939,53.7326436569,53.721654629,53.7106790769,53.6997169678,
+	53.6887682688,53.6778329471,53.6669109702,53.6560023055,53.6451069207,
+	53.6342247836,53.6233558619,53.6125001237,53.6016575371,53.5908280702,
+	53.5800116914,53.5692083692,53.558418072,53.5476407686,53.5368764276,
+	53.5261250181,53.5153865089,53.5046608693,53.4939480683,53.4832480754,
+	53.47256086,53.4618863916,53.4512246399,53.4405755746,53.4299391657,
+	53.419315383,53.4087041967,53.398105577,53.3875194941,53.3769459184,
+	53.3663848205,53.355836171,53.3452999404,53.3347760998,53.3242646199,
+	53.3137654719,53.3032786267,53.2928040557,53.2823417301,53.2718916214,
+	53.261453701,53.2510279406,53.240614312,53.2302127868,53.2198233371,
+	53.2094459348,53.1990805521,53.1887271611,53.1783857341,53.1680562435,
+	53.1577386619,53.1474329617,53.1371391157,53.1268570966,53.1165868773,
+	53.1063284308,53.09608173,53.0858467482,53.0756234586,53.0654118344,
+	53.0552118491,53.0450234762,53.0348466893,53.0246814621,53.0145277683,
+	53.0043855819,52.9942548766,52.9841356267,52.9740278062,52.9639313893,
+	52.9538463503,52.9437726636,52.9337103037,52.9236592451,52.9136194624,
+	52.9035909305,52.8935736241,52.883567518,52.8735725874,52.8635888072,
+	52.8536161525,52.8436545987,52.833704121,52.8237646948,52.8138362956,
+	52.8039188989,52.7940124804,52.7841170158,52.7742324808,52.7643588514,
+	52.7544961035,52.7446442132,52.7348031565,52.7249729097,52.7151534489,
+	52.7053447507,52.6955467913,52.6857595473,52.6759829952,52.6662171118,
+	52.6564618738,52.6467172578,52.636983241,52.6272598001,52.6175469122,
+	52.6078445544,52.598152704,52.5884713381,52.5788004341,52.5691399694,
+	52.5594899214,52.5498502678,52.5402209861,52.5306020539,52.5209934492,
+	52.5113951496,52.5018071332,52.4922293778,52.4826618616,52.4731045626,
+	52.463557459,52.4540205291,52.4444937512,52.4349771037,52.425470565,
+	52.4159741138,52.4064877284,52.3970113878,52.3875450705,52.3780887554,
+	52.3686424213,52.3592060472,52.3497796121,52.340363095,52.3309564751,
+	52.3215597316,52.3121728436,52.3027957907,52.293428552,52.2840711072,
+	52.2747234357,52.2653855171,52.2560573311,52.2467388573,52.2374300756,
+	52.2281309658,52.2188415077,52.2095616814,52.2002914668,52.1910308441,
+	52.1817797934,52.1725382949,52.1633063289,52.1540838757,52.1448709156,
+	52.1356674293,52.1264733971,52.1172887997,52.1081136176,52.0989478315,
+	52.0897914223,52.0806443707,52.0715066576,52.0623782639,52.0532591707,
+	52.0441493588,52.0350488095,52.0259575039,52.0168754232,52.0078025486,
+	51.9987388616,51.9896843435,51.9806389757,51.9716027398,51.9625756172,
+	51.9535575896,51.9445486387,51.9355487462,51.9265578938,51.9175760635,
+	51.908603237,51.8996393962,51.8906845233,51.8817386003,51.8728016091,
+	51.8638735321,51.8549543514,51.8460440492,51.8371426079,51.8282500099,
+	51.8193662375,51.8104912732,51.8016250996,51.7927676992,51.7839190547,
+	51.7750791486,51.7662479639,51.7574254831,51.7486116892,51.7398065651,
+	51.7310100936,51.7222222578,51.7134430406,51.7046724253,51.6959103948,
+	51.6871569323,51.6784120212,51.6696756447,51.660947786,51.6522284287,
+	51.643517556,51.6348151515,51.6261211987,51.6174356812,51.6087585825,
+	51.6000898864,51.5914295766,51.5827776367,51.5741340507,51.5654988023,
+	51.5568718755,51.5482532542,51.5396429225,51.5310408642,51.5224470636,
+	51.5138615047,51.5052841718,51.496715049,51.4881541206,51.4796013709,
+	51.4710567843,51.4625203452,51.453992038,51.4454718472,51.4369597573,
+	51.428455753,51.4199598188,51.4114719394,51.4029920995,51.3945202839,
+	51.3860564773,51.3776006646,51.3691528308,51.3607129606,51.352281039,
+	51.3438570512,51.3354409821,51.3270328167,51.3186325404,51.3102401382,
+	51.3018555953,51.293478897,51.2851100286,51.2767489755,51.268395723,
+	51.2600502566,51.2517125617,51.2433826238,51.2350604285,51.2267459613,
+	51.218439208,51.210140154,51.2018487853,51.1935650874,51.1852890462,
+	51.1770206476,51.1687598773,51.1605067213,51.1522611655,51.1440231959,
+	51.1357927985,51.1275699594,51.1193546647,51.1111469005,51.1029466529,
+	51.0947539083,51.0865686527,51.0783908726,51.0702205543,51.062057684,
+	51.0539022483,51.0457542335,51.0376136261,51.0294804127,51.0213545797,
+	51.0132361137
+	}}
+};
diff --git a/examples/faust-tubes/valve/valve.h b/examples/faust-tubes/valve/valve.h
new file mode 100644
index 0000000..0acefe3
--- /dev/null
+++ b/examples/faust-tubes/valve/valve.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
+ * Copyright (C) 2011 Pete Shorthose
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * --------------------------------------------------------------------------
+ *
+ *
+ *    This file is part of the Faust Tube Library
+ *
+ *
+ * --------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#ifndef SRC_HEADERS_VALVE_H_
+#define SRC_HEADERS_VALVE_H_
+
+/****************************************************************
+ * 1-dimensional function tables for linear interpolation
+ *
+ * table1d and table1d_imp<size> must only differ in the last
+ * element, so that the typecast for tubetab below will work.
+ * Can't use inheritance because then C initializers will not
+ * work and initialization will be more awkward or less efficient.
+ */
+
+struct table1d { // 1-dimensional function table
+    float low;
+    float high;
+    float istep;
+    int size;
+    float data[];
+};
+
+template <int tab_size>
+struct table1d_imp {
+    float low;
+    float high;
+    float istep;
+    int size;
+    float data[tab_size];
+    operator table1d&() const { return *(table1d*)this; }
+};
+
+/*
+ * data tables 
+ */
+#include "12ax7.cc"
+#include "12AU7.cc"
+#include "12AT7.cc"
+#include "6V6.cc"
+#include "6DJ8.cc"
+#include "6C16.cc"
+
+enum {
+    TUBE_TABLE_12AX7_68k,
+    TUBE_TABLE_12AX7_250k,
+    TUBE_TABLE_6V6_68k,
+    TUBE_TABLE_6V6_250k,
+    TUBE_TABLE_12AU7_68k,
+    TUBE_TABLE_12AU7_250k,
+    TUBE_TABLE_6DJ8_68k,
+    TUBE_TABLE_6DJ8_250k,
+    TUBE_TABLE_12AT7_68k,
+    TUBE_TABLE_12AT7_250k,
+    TUBE_TABLE_6C16_68k,
+    TUBE_TABLE_6C16_250k,
+    TUBE_TABLE_SIZE
+};
+
+table1d *tubetab[TUBE_TABLE_SIZE] = {
+    &static_cast<table1d&>(tubetable_12AX7[0]),
+    &static_cast<table1d&>(tubetable_12AX7[1]),
+    &static_cast<table1d&>(tubetable_6V6[0]),
+    &static_cast<table1d&>(tubetable_6V6[1]),
+    &static_cast<table1d&>(tubetable_12AU7[0]),
+    &static_cast<table1d&>(tubetable_12AU7[1]),
+    &static_cast<table1d&>(tubetable_6DJ8[0]),
+    &static_cast<table1d&>(tubetable_6DJ8[1]),
+    &static_cast<table1d&>(tubetable_12AT7[0]),
+    &static_cast<table1d&>(tubetable_12AT7[1]),
+    &static_cast<table1d&>(tubetable_6C16[0]),
+    &static_cast<table1d&>(tubetable_6C16[1]),
+};
+
+/*
+ *  definitions for ffunction(float Ftube(int,float), "valve.h", "");
+ */
+
+static inline double Ftube(int table, double Vgk) {
+    const table1d& tab = *tubetab[table];
+    double f = (Vgk - tab.low) * tab.istep;
+    int i = static_cast<int>(f);
+    if (i < 0)
+        return tab.data[0];
+    if (i >= tab.size-1)
+        return tab.data[tab.size-1];
+    f -= i;
+    return tab.data[i]*(1-f) + tab.data[i+1]*f;
+}
+
+#endif  // SRC_HEADERS_VALVE_H_
diff --git a/examples/freeverb.dsp b/examples/freeverb.dsp
index 31114e1..37977bd 100644
--- a/examples/freeverb.dsp
+++ b/examples/freeverb.dsp
@@ -1,71 +1,66 @@
-declare name 		"freeverb";
-declare version 	"1.0";
-declare author 		"Grame";
-declare license 	"BSD";
-declare copyright 	"(c)GRAME 2006";
-declare reference 	"https://ccrma.stanford.edu/~jos/pasp/Freeverb.html";
+declare name        "freeverb";
+declare version     "1.0";
+declare author      "Grame";
+declare license     "BSD";
+declare copyright   "(c) GRAME 2006";
+declare reference   "https://ccrma.stanford.edu/~jos/pasp/Freeverb.html";
 
 //======================================================
 //
-//						Freeverb
-//		  Faster version using fixed delays (20% gain)
+//                      Freeverb
+//        Faster version using fixed delays (20% gain)
 //
 //======================================================
 
-
 // Constant Parameters
 //--------------------
 
-fixedgain	= 0.015;
-scalewet	= 3.0;
-scaledry	= 2.0;
-scaledamp	= 0.4;
-scaleroom	= 0.28;
-offsetroom	= 0.7;
-initialroom	= 0.5;
-initialdamp	= 0.5;
-initialwet	= 1.0/scalewet;
-initialdry	= 0;
+fixedgain   = 0.015; //value of the gain of fxctrl
+scalewet    = 3.0;
+scaledry    = 2.0;
+scaledamp   = 0.4;
+scaleroom   = 0.28;
+offsetroom  = 0.7;
+initialroom = 0.5;
+initialdamp = 0.5;
+initialwet  = 1.0/scalewet;
+initialdry  = 0;
 initialwidth= 1.0;
-initialmode	= 0.0;
-freezemode	= 0.5;
+initialmode = 0.0;
+freezemode  = 0.5;
 stereospread= 23;
-allpassfeed	= 0.5;
+allpassfeed = 0.5; //feedback of the delays used in allpass filters
 
 
-// Filter Parametres
+// Filter Parameters
 //------------------
 
-combtuningL1	= 1116;
-combtuningL2	= 1188;
-combtuningL3	= 1277;
-combtuningL4	= 1356;
-combtuningL5	= 1422;
-combtuningL6	= 1491;
-combtuningL7	= 1557;
-combtuningL8	= 1617;
+combtuningL1    = 1116;
+combtuningL2    = 1188;
+combtuningL3    = 1277;
+combtuningL4    = 1356;
+combtuningL5    = 1422;
+combtuningL6    = 1491;
+combtuningL7    = 1557;
+combtuningL8    = 1617;
 
-allpasstuningL1	= 556;
-allpasstuningL2	= 441;
-allpasstuningL3	= 341;
-allpasstuningL4	= 225;
+allpasstuningL1 = 556;
+allpasstuningL2 = 441;
+allpasstuningL3 = 341;
+allpasstuningL4 = 225;
 
 
 // Control Sliders
 //--------------------
-// Damp : filtrage des aigus des echos (surtout actif pour des grandes valeurs de RoomSize)
-// RoomSize : taille de la piece
-// Dry : signal original
-// Wet : signal avec reverbration
-
-dampSlider 		= hslider("Damp",0.5, 0, 1, 0.025)*scaledamp;
-roomsizeSlider 	= hslider("RoomSize", 0.8, 0, 1, 0.025)*scaleroom + offsetroom;
-wetSlider 		= hslider("Wet", 0.8, 0, 1, 0.025);
-drySlider 		= hslider("Dry", 0, 0, 1, 0.025);
-combfeed 		= roomsizeSlider;
-
-
+// Damp : filters the high frequencies of the echoes (especially active for great values of RoomSize)
+// RoomSize : size of the reverberation room
+// Dry : original signal
+// Wet : reverberated signal
 
+dampSlider      = hslider("Damp",0.5, 0, 1, 0.025)*scaledamp;
+roomsizeSlider  = hslider("RoomSize", 0.5, 0, 1, 0.025)*scaleroom + offsetroom;
+wetSlider       = hslider("Wet", 0.3333, 0, 1, 0.025);
+combfeed        = roomsizeSlider;
 
 
 // Comb and Allpass filters
@@ -80,23 +75,23 @@ comb(dt, fb, damp) = (+:@(dt)) ~ (*(1-damp) : (+ ~ *(damp)) : *(fb));
 //------------------
 
 monoReverb(fb1, fb2, damp, spread)
-	= _ <:	comb(combtuningL1+spread, fb1, damp),
-			comb(combtuningL2+spread, fb1, damp),
-			comb(combtuningL3+spread, fb1, damp),
-			comb(combtuningL4+spread, fb1, damp),
-			comb(combtuningL5+spread, fb1, damp),
-			comb(combtuningL6+spread, fb1, damp),
-			comb(combtuningL7+spread, fb1, damp),
-			comb(combtuningL8+spread, fb1, damp)
-		+>
-		 	allpass (allpasstuningL1+spread, fb2)
-		:	allpass (allpasstuningL2+spread, fb2)
-		:	allpass (allpasstuningL3+spread, fb2)
-		:	allpass (allpasstuningL4+spread, fb2)
-		;
+    = _ <:  comb(combtuningL1+spread, fb1, damp),
+            comb(combtuningL2+spread, fb1, damp),
+            comb(combtuningL3+spread, fb1, damp),
+            comb(combtuningL4+spread, fb1, damp),
+            comb(combtuningL5+spread, fb1, damp),
+            comb(combtuningL6+spread, fb1, damp),
+            comb(combtuningL7+spread, fb1, damp),
+            comb(combtuningL8+spread, fb1, damp)
+        +>
+            allpass (allpasstuningL1+spread, fb2)
+        :   allpass (allpasstuningL2+spread, fb2)
+        :   allpass (allpasstuningL3+spread, fb2)
+        :   allpass (allpasstuningL4+spread, fb2)
+        ;
 
 stereoReverb(fb1, fb2, damp, spread)
-	= + <: 	monoReverb(fb1, fb2, damp, 0), monoReverb(fb1, fb2, damp, spread);
+    = + <:  monoReverb(fb1, fb2, damp, 0), monoReverb(fb1, fb2, damp, spread);
 
 
 // fxctrl : add an input gain and a wet-dry control to a stereo FX
@@ -105,7 +100,6 @@ stereoReverb(fb1, fb2, damp, spread)
 fxctrl(g,w,Fx) =  _,_ <: (*(g),*(g) : Fx : *(w),*(w)), *(1-w), *(1-w) +> _,_;
 
 
-
 // Freeverb
 //---------
 
diff --git a/examples/gate_compressor.dsp b/examples/gate_compressor.dsp
index 87afeaf..72a24f2 100644
--- a/examples/gate_compressor.dsp
+++ b/examples/gate_compressor.dsp
@@ -1,3 +1,5 @@
+declare name 		"gate_compressor";
+
 ol = library("oscillator.lib");
 el = library("effect.lib");
 fl = library("filter.lib");
diff --git a/examples/graphic_eq.dsp b/examples/graphic_eq.dsp
index 7135600..eb8c6df 100644
--- a/examples/graphic_eq.dsp
+++ b/examples/graphic_eq.dsp
@@ -1,3 +1,6 @@
+
+declare name 		"graphic_eq";
+
 ol = library("oscillator.lib");
 fl = library("filter.lib");
 
diff --git a/examples/guitarix.dsp b/examples/guitarix.dsp
new file mode 100644
index 0000000..e18e7ee
--- /dev/null
+++ b/examples/guitarix.dsp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
+ * Copyright (C) 2011 Pete Shorthose
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * ----------------------------------------------------------------------------
+ * Adapted version from guitarixlite (v.0.28) using foreign functions 
+ * to this self-contained Faust version (v.0.29)
+ * Adapted by GRAME - 2014
+ * ----------------------------------------------------------------------------
+ */
+
+declare name        "Guitarix";
+declare version     "0.29";
+declare author   	"Guitarix project (http://guitarix.sourceforge.net/)";
+declare copyright 	"Guitarix project";
+declare license   	"LGPL";
+
+import("math.lib");
+import("filter.lib");
+import("tube.lib");
+import("tonestack.lib");
+
+process = preamp; 
+
+/****************************************************************
+ ** Tube Preamp Emulation with
+ *  tubescreamer -  tube stage 1 - 2 - tonestack - cabinet
+ */
+preamp = hgroup("Guitarix",
+         hgroup("[0]TubeScreamer",ts9sim) :
+         hgroup("[1]preamp: 12AX7", stage1 : stage2 ): 
+         hgroup("[2]tonestack: jcm2000", tstack) :
+         hgroup("[3]Cabinet", cab) )with {
+
+    stage1 = T1_12AX7 : *(preamp): lowpass(1,6531.0) : 
+    			T2_12AX7 : *(preamp) with {
+                preamp = vslider("[0] Pregain [style:knob]",-6,-20,20,0.1) : 
+                  db2linear : smooth(0.999);
+             };
+
+    stage2 = lowpass(1,6531.0) : T3_12AX7 : *(gain) with {
+                gain = vslider("[1] Gain [style:knob]",-6,-20.0,20.0,0.1) : 
+                  db2linear : smooth(0.999);
+             };
+
+    tstack = jcm2000(t, m, l) with {
+        t = vslider("[2] Treble [style:knob]",0.5,0,1,0.01);
+        m = vslider("[3] Middle [style:knob]",0.5,0,1,0.01);
+        l = vslider("[4] Bass [style:knob]",0.5,0,1,0.01);
+    };
+};
+
+/****************************************************************************************/
+
+//-- Rdtable from waveform
+rtable(table, r) = (table, int(r)):rdtable;
+
+// Change sign of input signal x;
+inverse(x) = abs(x) * invsign(x);
+
+//function that takes f value and x sign
+ccopysign(f, x) = abs(f)*sign(x);       
+
+//-- Get sign and reversed sign of a signal x
+sign (x) = x<0, 1, -1 : select2;  
+invsign (x) = x<0, -1, 1 : select2;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
+
+//-- Interpolate value between i and i+1 in table with coefficient f.
+interpolation (table, f, i) = rtable(table, i)*(1-f) + rtable(table,i+1)*f;
+
+//-- Bound Index with table boundaries
+boundIndex(size, index) = index : floor: min(size-1) : max(0);
+
+//-- Bound factor of interpolation : factor-index if still in the table boudaries, 0 otherwise
+boundFactor(size, factor, index) = 0<index<size-1, factor - index, 0 : select2;  
+
+/****************************************************************************************
+ * 1-dimensional function tables for linear interpolation
+****************************************************************************************/
+
+// Linear interpolation of x value in table
+tubeF(table, low, high, step, size, x) = interpolation(
+											table, 
+											getFactor(low, step, size, x),
+											linindex(low, step, x) : boundIndex(size));
+
+//--Get interpolation factor
+getFactor(low, step, size, x) = boundFactor(size, linindex(low, step, x), linindex(low, step, x) : boundIndex(size));
+
+//-- Calculate linear index
+linindex(low, step, x) = (x - low) * step;
+
+/****************************************************************************************
+ * 1-dimensional function tables for nonlinear interpolation
+****************************************************************************************/
+nonlininterpolation(table, low, high, step, size, x) = ts9(low, step, size, table, x) , inverse(x) : ccopysign;
+
+//-- Interpolate value from table
+ts9 (low, step, size, table, x) = interpolation(
+										table, 
+										getCoef(low, step, size, x), 
+										nonlinindex(low, step, x) : boundIndex(size));
+
+//-- Calculate non linear index
+nonlinindex(low, step, x) = (abs(x)/(3.0 + abs(x)) - low) * step;
+
+//--Get interpolation factor
+getCoef(low, step, size, x) = boundFactor(size, nonlinindex(low, step, x), nonlinindex(low, step, x) : boundIndex(size));
+
+/********* Faust Version of ts9nonlin.cc, generated by tools/ts9sim.py ****************/
+
+ts9comp = nonlininterpolation(ts9table, low, high, step, size) with{
+
+// Characteristics of the wavetable
+	low = 0.0;
+	high = 0.970874;
+	step = 101.97;
+	size = 100;
+	
+ts9table = waveform{0.0,-0.0296990148227,-0.0599780676992,-0.0908231643281,-0.122163239629,
+	-0.15376009788,-0.184938007182,-0.214177260107,-0.239335434213,-0.259232575019,
+	-0.274433909887,-0.286183308354,-0.29553854444,-0.303222323477,-0.309706249977,
+	-0.315301338712,-0.320218440785,-0.324604982281,-0.328567120703,-0.332183356975,
+	-0.335513124719,-0.33860236542,-0.34148724693,-0.344196707008,-0.346754233717,
+	-0.34917913798,-0.351487480543,-0.35369275887,-0.355806424152,-0.357838275995,
+	-0.359796767655,-0.361689244919,-0.363522135105,-0.365301098113,-0.367031148289,
+	-0.368716753588,-0.370361916943,-0.371970243537,-0.373544996828,-0.375089145544,
+	-0.376605403346,-0.378096262548,-0.379564022938,-0.381010816596,-0.382438629377,
+	-0.383849319643,-0.385244634694,-0.386626225283,-0.387995658543,-0.389354429565,
+	-0.39070397188,-0.392045667012,-0.393380853288,-0.39471083403,-0.396036885269,
+	-0.397360263098,-0.398682210753,-0.400003965547,-0.401326765733,-0.402651857394,
+	-0.403980501471,-0.405313980999,-0.406653608692,-0.40800073496,-0.409356756504,
+	-0.410723125631,-0.412101360439,-0.413493056085,-0.414899897347,-0.416323672745,
+	-0.417766290556,-0.419229797097,-0.420716397759,-0.422228481377,-0.423768648654,
+	-0.425339745558,-0.426944902828,-0.428587583057,-0.430271637224,-0.432001373102,
+	-0.433781638746,-0.435617925286,-0.437516494692,-0.439484540257,-0.441530390423,
+	-0.443663770898,-0.445896146322,-0.448241172434,-0.450715304661,-0.453338632988,
+	-0.45613605235,-0.45913894467,-0.46238766699,-0.465935359011,-0.469854010456,
+	-0.474244617411,-0.479255257451,-0.48511588606,-0.492212726244,-0.501272723631
+	};
+};
+/****************************************************************************************/
+
+/****************************************************************************************
+*	declare id 		"ts9sim";
+*	declare name            "Tube Screamer";
+*	declare category        "Distortion";
+*
+** 		based on a circuit diagram of the Ibanez TS-9 and
+** 		a mathematical analysis published by Tamás Kenéz
+****************************************************************************************/
+
+smoothi(c) = *(1-c) : +~*(c);
+
+ts9sim = ts9nonlin : lowpassfilter : *(gain) with {
+
+    R1 = 4700;
+    R2 = 51000 + 500000 * vslider("drive[name:Drive][style:knob]", 0.5, 0, 1, 0.01);
+    C = 0.047 * 1e-6;
+    a1 = (R1 + R2) * C * 2 * SR;
+    a2 = R1 * C * 2 * SR;
+    B0 = (1 + a1) / (1 + a2);
+    B1 = (1 - a1) / (1 + a2);
+    A1 = (1 - a2) / (1 + a2);
+    X2 = tf1(B0, B1, A1);
+
+    ts9nonlin = _ <: _ ,(X2,_ : - : ts9comp) : - :> _;
+    
+    fc = vslider("tone[log][name:Tone][style:knob]", 400, 100, 1000, 1.03);
+    lowpassfilter = lowpass(1,fc);
+    gain = vslider("level[name:Level][style:knob]", -16, -20, 4, 0.1) : component("music.lib").db2linear : smoothi(0.999);
+};
+
+
+/****************************************************************************************
+*	declare name            "cabinet";
+*
+** 		based on a circuit diagram of the Ibanez TS-9 and
+** 		a mathematical analysis published by Tamás Kenéz
+****************************************************************************************/
+
+wetdry = vslider("[5] amount[style:knob]",  100, 0, 100, 1) : /(100);
+dry = 1 - wetdry;
+
+cab = _<:(*(dry):_), (*(wetdry):conv((0.000488281, -0.0020752, 0.000561523, -0.00231934, 0.000634766, -0.00247803, 0.000512695, -0.00247803, 0.000146484, -0.00219727, -0.000622559, -0.00145264, -0.00202637, 
+    -2.44141e-05, -0.00438232, 0.00247803, -0.00822754, 0.00706787, -0.0159546, 0.0202148, -0.0471558, 0.0953003, -0.208582, 0.312427, 0.75, -0.26803, 
+    0.399963, 0.200696, -0.146655, -0.29303, -0.222168, -0.113098, 0.0267334, 0.0312134, 0.164685, 0.0443481, 0.186621, 0.0540039, 0.123303, 
+    0.0805054, 0.0739868, 0.0591797, 0.0661743, 0.0400391, 0.0429932, 0.0339844, 0.0320557, 0.02323, 0.0217285, 0.0182007, 0.0157227, 0.0130005, 
+    0.0103882, 0.00942383, 0.00718994, 0.0067749, 0.00458984, 0.00455322, 0.00272217, 0.00294189, 0.00140381, 0.00170898, 0.000402832, 0.000720215, -0.000354004, 
+    -2.44141e-05, -0.000915527, -0.000610352, -0.00134277, -0.0010498, -0.00166016, -0.0013916, -0.0019043, -0.00166016, -0.0020874, -0.00187988, -0.00224609, -0.00203857, 
+    -0.00235596, -0.00217285, -0.0024292, -0.0022583, -0.00247803, -0.00233154, -0.00252686, -0.00238037, -0.00256348, -0.0024292, 0.75, -0.00246582, -0.0026001, 
+    -0.00247803, -0.0026001, -0.00249023, -0.0026001, -0.00250244, -0.0026001, -0.00251465, -0.0026001, -0.00251465, -0.0026001, -0.00251465, -0.0026001, -0.00252686, 
+    -0.00258789, -0.00252686, -0.00258789, -0.00251465, -0.00257568, -0.00251465, -0.00256348, -0.00251465, -0.00256348, -0.00251465, -0.00256348, -0.00251465, -0.00256348, 
+    -0.00251465, -0.00256348, -0.00251465, -0.00256348, -0.00252686, -0.00256348, -0.00252686, -0.00255127, -0.00252686, -0.00255127, -0.00252686, -0.00255127, -0.00252686, 
+    -0.00255127, -0.00252686, -0.00256348
+     ))):>_;
diff --git a/examples/harpe.dsp b/examples/harpe.dsp
new file mode 100644
index 0000000..ddf6e22
--- /dev/null
+++ b/examples/harpe.dsp
@@ -0,0 +1,55 @@
+//-----------------------------------------------
+// 		Basic harpe simulation with OSC control
+//		(based on Karplus-Strong)
+//
+//-----------------------------------------------
+
+declare name  	"Harpe";
+declare author  "Grame";
+
+process = harpe(11); 	// an 11 strings harpe
+
+
+//-----------------------------------------------
+// 		whoite noise generator
+//-----------------------------------------------
+noise 	= random / RANDMAX
+	with {
+		random 		= +(12345) ~ *(1103515245);
+		RANDMAX		= 2147483647.0;
+	};
+
+
+//-----------------------------------------------
+// 		String simulation
+//-----------------------------------------------
+string(freq, att, level, trig) = noise*level
+							: *(trig : trigger(freq2samples(freq)))
+							: resonator(freq2samples(freq), att)
+	with {
+		resonator(d, a) = (+ : @(d-1)) ~ (average : *(1.0-a));
+		average(x)	= (x+x')/2;
+		trigger(n) 	= upfront : + ~ decay(n) : >(0.0);
+		upfront(x) 	= (x-x') > 0.0;
+		decay(n,x)	= x - (x>0.0)/n;
+		freq2samples(f) = 44100.0/f;
+	};
+
+
+//-----------------------------------------------
+// 		Build a N strings harpe
+//		Each string is triggered by a specific
+//		position [0..1] of the "hand"
+//-----------------------------------------------
+harpe(N) = 	hand <: par(i, N, position((i+0.5)/N)
+							: string( 440 * 2.0^(i/5.0), att, lvl)
+							: pan((i+0.5)/N) )
+				 :> _,_
+	with {
+		lvl  = hslider("level [unit:f][osc:/accxyz/0 -10 10]", 0.5, 0, 1, 0.01)^2;
+		att  = hslider("attenuation [osc:/1/fader3]", 0.005, 0, 0.01, 0.001);
+		hand = hslider("hand[osc:/accxyz/1 -10 10]", 0, 0, 1, 0.01):smooth(0.9);
+		pan(p) = _ <: *(sqrt(1-p)), *(sqrt(p));
+		position(a,x) = (min(x,x') < a) & (a < max(x, x'));
+		smooth(c) = *(1.0-c) : + ~ *(c);
+	};
diff --git a/examples/karplus.dsp b/examples/karplus.dsp
index d6c86c5..f0407a5 100644
--- a/examples/karplus.dsp
+++ b/examples/karplus.dsp
@@ -32,6 +32,6 @@ average(x)	= (x+x')/2;
 
 resonator(d, a) = (+ : delay(4096, d-1.5)) ~ (average : *(1.0-a)) ;
 
-process = noise * hslider("level", 0.5, 0, 1, 0.1)
+process = noise * hslider("level", 0.5, 0, 1, 0.01)
 		: vgroup("excitator", *(button("play"): trigger(size)))
 		: vgroup("resonator", resonator(dur, att));
diff --git a/examples/reverb_designer.dsp b/examples/reverb_designer.dsp
index 4e36a66..c442898 100644
--- a/examples/reverb_designer.dsp
+++ b/examples/reverb_designer.dsp
@@ -1,7 +1,7 @@
-import("effect.lib");
+el = library("effect.lib");
 
   N = 16; // Feedback Delay Network (FDN) order (power of 2, 2 to 16)
  NB =  5; // Number of T60-controlled frequency-bands (3 or more)
 BSO =  3; // Order of each lowpass/highpass bandsplit (odd positive integer)
 
-process = fdnrev0_demo(N,NB,BSO);
+process = el.fdnrev0_demo(N,NB,BSO);
diff --git a/examples/spectral_level.dsp b/examples/spectral_level.dsp
index eaeec98..d3c8c15 100644
--- a/examples/spectral_level.dsp
+++ b/examples/spectral_level.dsp
@@ -1,5 +1,8 @@
 // Spectrum analyzer
 
+
+declare name 		"spectrum_level";
+
 fl = library("filter.lib");
 
 BandsPerOctave = 3; // third-octave filter bank
diff --git a/examples/tester2.dsp b/examples/tester2.dsp
new file mode 100644
index 0000000..c538d42
--- /dev/null
+++ b/examples/tester2.dsp
@@ -0,0 +1,36 @@
+declare name 		"StereoAudioTester";
+declare version 	"1.0";
+declare author 		"Grame";
+declare license 	"BSD";
+declare copyright 	"(c)GRAME 2014";
+
+//-----------------------------------------------
+// Stereo Audio Tester : send a test signal (sine, 
+// noise, pink) on a stereo channel
+//-----------------------------------------------
+
+import("music.lib");
+
+pink	= f : (+ ~ g) with {
+	f(x) = 0.04957526213389*x - 0.06305581334498*x' + 0.01483220320740*x'';
+	g(x) = 1.80116083982126*x - 0.80257737639225*x';
+};
+
+
+// User interface
+//----------------
+smooth(c)	= *(1-c) : +~*(c);
+transition(n) = \(old,new).(if(old<new, min(old+1.0/n,new), max(old-1.0/n,new))) ~ _;
+
+vol  = hslider("[2] volume [unit:dB]", -96, -96, 0, 1): db2linear : smooth(0.999);
+freq = hslider("[1] freq [unit:Hz][scale:log]", 440, 40, 20000, 1);
+wave = vslider("[3] signal [style:menu{'white noise':0;'pink noise':1;'sine':2}]", 0, 0, 2, 1) : int;
+dest = hslider("[4] channel [style:radio{'none':0;'left':1;'right':2;'both':3}]", 0, 0, 3, 1) : int;
+
+testsignal	= noise, pink(noise), osci(freq): select3(wave);
+
+process 	= vgroup( "Stereo Audio Tester", 
+				testsignal*vol 
+				<: par(i, 2, *((dest & (i+1)) != 0 : transition(4410))) 
+			);
+
diff --git a/examples/virtual_analog_oscillators.dsp b/examples/virtual_analog_oscillators.dsp
new file mode 100644
index 0000000..18c1d06
--- /dev/null
+++ b/examples/virtual_analog_oscillators.dsp
@@ -0,0 +1,9 @@
+ol = library("oscillator.lib");
+fl = library("filter.lib");
+el = library("effect.lib");
+
+process = 
+ vgroup("[1]", ol.virtual_analog_oscillator_demo) : 
+ vgroup("[2]", el.moog_vcf_demo) : 
+ vgroup("[3]", fl.spectral_level_demo) <:
+  _,_;
diff --git a/examples/vumeter.dsp b/examples/vumeter.dsp
index b839fb1..cfd3417 100644
--- a/examples/vumeter.dsp
+++ b/examples/vumeter.dsp
@@ -17,4 +17,4 @@ hmeter(x)		= attach(x, envelop(x) : hbargraph("[2][unit:dB]", -70, +5));
 
 envelop         = abs : max ~ -(1.0/SR) : max(db2linear(-70)) : linear2db;
 
-process 		= vmeter;
+process 		= hmeter,hmeter;
diff --git a/examples/zita_rev1.dsp b/examples/zita_rev1.dsp
index 95a8bf1..6ae7af4 100644
--- a/examples/zita_rev1.dsp
+++ b/examples/zita_rev1.dsp
@@ -1,2 +1,5 @@
+
+declare name 		"zita_rev1";
+
 process = component("effect.lib").zita_rev1;
 // For test inputs, see ./reverb_tester.dsp
diff --git a/syntax-highlighting/Faust.plist b/syntax-highlighting/Faust.plist
index 3f8b340..cb214f1 100644
--- a/syntax-highlighting/Faust.plist
+++ b/syntax-highlighting/Faust.plist
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
 	<key>BBEditDocumentType</key>
@@ -12,17 +12,16 @@
 	<array>
 		<string>process</string>
 		<string>declare</string>
-        <string>with</string>
-        <string>component</string>
-        <string>library</string>
-        <string>environment</string>
-        <string>case</string>
-        <string>seq</string>
-        <string>par</string>
-        <string>sum</string>
-        <string>prod</string>
-        <string>import</string>
-        
+		<string>with</string>
+		<string>component</string>
+		<string>library</string>
+		<string>environment</string>
+		<string>case</string>
+		<string>seq</string>
+		<string>par</string>
+		<string>sum</string>
+		<string>prod</string>
+		<string>import</string>
 		<string>mem</string>
 		<string>prefix</string>
 		<string>int</string>
@@ -32,9 +31,9 @@
 		<string>select2</string>
 		<string>select3</string>
 		<string>ffunction</string>
-        <string>fconstant</string>
-        <string>fvariable</string>
-        <string>button</string>
+		<string>fconstant</string>
+		<string>fvariable</string>
+		<string>button</string>
 		<string>checkbox</string>
 		<string>vslider</string>
 		<string>hslider</string>
@@ -76,6 +75,10 @@
 	<array>
 		<dict>
 			<key>BBLMLanguageSuffix</key>
+			<string>.lib</string>
+		</dict>
+		<dict>
+			<key>BBLMLanguageSuffix</key>
 			<string>.dsp</string>
 		</dict>
 	</array>
@@ -88,7 +91,7 @@
 		<key>Close Statement Blocks</key>
 		<string>}</string>
 		<key>Close Strings 1</key>
-		<string>"</string>
+		<string>"</string>
 		<key>Close Strings 2</key>
 		<string></string>
 		<key>End-of-line Ends Strings 1</key>
@@ -110,7 +113,7 @@
 		<key>Open Statement Blocks</key>
 		<string>{</string>
 		<key>Open Strings 1</key>
-		<string>"</string>
+		<string>"</string>
 		<key>Open Strings 2</key>
 		<string></string>
 		<key>Prefix for Functions</key>
diff --git a/syntax-highlighting/README b/syntax-highlighting/README
index c9eac98..fa49aa1 100644
--- a/syntax-highlighting/README
+++ b/syntax-highlighting/README
@@ -37,3 +37,14 @@ faust filetype file
 6) EMACS
 An EMACS Faust mode is provided by Juan Gabriel Alzate Romero at https://github.com/rukano/emacs-faust-mode
 
+
+7) NANO
+copy file faust.nanorc into folder /usr/share/nano/
+
+add lines 
+	set tabsize 4
+	include "/usr/share/nano/faust.nanorc"
+to file /etc/nanorc
+
+8) ATOM
+Place the directory 'language-faust/' into '~/.atom/packages/'. 
diff --git a/syntax-highlighting/atom/README.md b/syntax-highlighting/atom/README.md
new file mode 100644
index 0000000..6d8a765
--- /dev/null
+++ b/syntax-highlighting/atom/README.md
@@ -0,0 +1,4 @@
+# faust language support in Atom
+
+Adds syntax highlighting and snippets to faust files in Atom.
+Place the directory 'language-faust/' into '~/.atom/packages/'.
diff --git a/syntax-highlighting/atom/language-faust/CONTRIBUTING.md b/syntax-highlighting/atom/language-faust/CONTRIBUTING.md
new file mode 100644
index 0000000..e70782f
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/CONTRIBUTING.md
@@ -0,0 +1 @@
+See the [Atom contributing guide](https://atom.io/docs/latest/contributing)
diff --git a/syntax-highlighting/atom/language-faust/LICENSE.md b/syntax-highlighting/atom/language-faust/LICENSE.md
new file mode 100644
index 0000000..51be247
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/LICENSE.md
@@ -0,0 +1,46 @@
+Copyright (c) 2014 GitHub Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+--------------------------------------------------------------------
+
+This package was derived from a TextMate bundle located at
+https://github.com/rsms/faust.tmbundle and distributed under the following
+license, located in `LICENSE`:
+
+Copyright (c) 2009 Rasmus Andersson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/syntax-highlighting/atom/language-faust/README.md b/syntax-highlighting/atom/language-faust/README.md
new file mode 100644
index 0000000..cbd0d70
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/README.md
@@ -0,0 +1,3 @@
+# faust language support in Atom
+
+Adds syntax highlighting and snippets to faust files in Atom.
diff --git a/syntax-highlighting/atom/language-faust/grammars/faust.cson b/syntax-highlighting/atom/language-faust/grammars/faust.cson
new file mode 100644
index 0000000..706b6a0
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/grammars/faust.cson
@@ -0,0 +1,112 @@
+'comment': 'faust language'
+'fileTypes': [
+  'dsp'
+]
+'foldingStartMarker': '({|\\()\\s*$'
+'foldingStopMarker': '(}|\\))\\s*$'
+'keyEquivalent': '^~G'
+'name': 'faust'
+'patterns': [
+  {
+    'begin': '/\\*'
+    'captures':
+      '0':
+        'name': 'punctuation.definition.comment.faust'
+    'end': '\\*/'
+    'name': 'comment.block.faust'
+  }
+  {
+    'captures':
+      '1':
+        'name': 'punctuation.definition.comment.faust'
+    'match': '(//).*$\\n?'
+    'name': 'comment.line.double-slash.faust'
+  }
+
+  {
+    'name': 'constant.numeric.faust'
+    'match': '(\\.\\d+([Ee][\-\+]\\d+)?i?)\\b'
+  }
+  {
+    'name': 'constant.numeric.faust'
+    'match': '\\b\\d+\\.\\d*(([Ee][\-\+]\\d+)?i?\\b)?'
+  }
+  {
+    'name': 'constant.numeric.faust'
+    'match': '\\b((0x[0-9a-fA-F]+)|(0[0-7]+i?)|(\\d+([Ee]\\d+)?i?)|(\\d+[Ee][\-\+]\\d+i?))\\b'
+  }
+  {
+    'name': 'constant.symbol.faust'
+    'match': '\\b(mem|prefix|int|float|rdtable|rwtable|select2|select3| ffunction|fconstant|fvariable|button|checkbox|vslider|hslider|nentry|vgroup|hgroup|tgroup|vbargraph|hbargraph|attach|acos|asin|atan|atan2|cos|sin|tan|exp|log|log10|pow|sqrt|abs|min|max|fmod|remainder|floor|ceil|rint)\\b'
+  }
+  {
+    'name': 'keyword.control.faust'
+    'match': '\\b(import|component|library|environment|with|process)\\b'
+  }
+  {
+    'name': 'keyword.algebra.faust'
+    'match': '(,|:>|<:|:|~)'
+  }
+  {
+    'name': 'constant.numeric.faust'
+    'match': '(;|=)'
+  }
+  {
+    'include': '#string_escaped_char'
+  }
+  {
+    'include': '#strings'
+  }
+  {
+    'include': '#operators'
+  }
+]
+'repository':
+  'string_escaped_char':
+    'patterns': [
+      {
+        'match': '\\\\([0-7]{3}|[abfnrtv\\\\\'"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})'
+        'name': 'constant.character.escape.faust'
+      }
+      {
+        'match': '\\\\[^0-7xuUabfnrtv\\\'"]'
+        'name': 'invalid.illegal.unknown-escape.faust'
+      }
+    ]
+  'operators':
+    'patterns': [
+      {
+        'name': 'keyword.operator.faust'
+        'match': '(\\+|&|==|!=|\\(|\\)|\\-|\\||\\-=|\\|=|\\|\\||<|<=|\\[|\\]|\\*|\\^|\\*=|\\^=|<\\-|>|>=|\\{|\\}|/|<<|/=|<<=|\\+\\+|=|:=|,|;|%|>>|%=|>>=|\\-\\-|!|\\.\\.\\.|\\.|:|&\\^|&\\^=)'
+      }
+    ]
+  'printf_verbs':
+    'patterns': [
+      {
+        'match': '%(\\[\\d+\\])?([\\+#\\-0\\x20]{,2}((\\d+|\\*)?(\\.?(\\d+|\\*|(\\[\\d+\\])\\*?)?(\\[\\d+\\])?)?))?[vT%tbcdoqxXUbeEfFgGsp]'
+        'name': 'constant.escape.format-verb.faust'
+      }
+    ]
+  'strings':
+    'patterns': [
+      {
+        'begin': '"'
+        'beginCaptures':
+          '0':
+            'name': 'punctuation.definition.string.begin.faust'
+        'end': '"'
+        'endCaptures':
+          '0':
+            'name': 'punctuation.definition.string.end.faust'
+        'name': 'string.quoted.double.faust'
+        'patterns': [
+          {
+            'include': '#string_escaped_char'
+          }
+          {
+            'include': '#printf_verbs'
+          }
+        ]
+      }
+    ]
+'scopeName': 'source.faust'
diff --git a/syntax-highlighting/atom/language-faust/package.json b/syntax-highlighting/atom/language-faust/package.json
new file mode 100644
index 0000000..cce37de
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/package.json
@@ -0,0 +1,26 @@
+{
+  "name": "language-faust",
+  "description": "faust language support in Atom",
+  "version": "0.1.0",
+  "license": "MIT",
+  "engines": {
+    "atom": "*",
+    "node": "*"
+  },
+  "homepage": "http://atom.github.io/language-faust",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/atom/language-faust.git"
+  },
+  "bugs": {
+    "url": "https://github.com/atom/language-faust/issues"
+  },
+  "readme": "# faust language support in Atom\n\nAdds syntax highlighting and snippets to faust files in Atom.\n",
+  "readmeFilename": "README.md",
+  "_id": "language-faust at 0.1.0",
+  "dist": {
+    "shasum": "264db63fab8c2b6cf8c1e439f5bc83d479a2397e"
+  },
+  "_resolved": "/var/folders/cs/hjtd49ys4xz5jlr8t2mqbkk00000gn/T/d-114431-26663-1ston5p/package.tgz",
+  "_from": "/var/folders/cs/hjtd49ys4xz5jlr8t2mqbkk00000gn/T/d-114431-26663-1ston5p/package.tgz"
+}
diff --git a/syntax-highlighting/atom/language-faust/settings/language-faust.cson b/syntax-highlighting/atom/language-faust/settings/language-faust.cson
new file mode 100644
index 0000000..5969bfe
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/settings/language-faust.cson
@@ -0,0 +1,3 @@
+'.source.faust':
+  'editor':
+    'commentStart': '// '
diff --git a/syntax-highlighting/atom/language-faust/snippets/language-faust.cson b/syntax-highlighting/atom/language-faust/snippets/language-faust.cson
new file mode 100644
index 0000000..4c0fd74
--- /dev/null
+++ b/syntax-highlighting/atom/language-faust/snippets/language-faust.cson
@@ -0,0 +1,58 @@
+'.source.faust':
+  'import':
+    'prefix': 'import'
+    'body': 'import("${1:filter}.lib");'
+  'library':
+    'prefix': 'library'
+    'body': 'library("${1:filter}.lib")'
+  'component':
+    'prefix': 'component'
+    'body': 'component("${1:filter}.lib")'
+  'process':
+    'prefix': 'process'
+    'body': "process = ${1:expression};$2"
+  'definition':
+    'prefix': 'def'
+    'body': "${1:name} = ${2:expression};$3"
+  'hslider':
+    'prefix': 'hslider'
+    'body': 'hslider("${1:volume}",0,0,1,0.01)'
+  'vslider':
+    'prefix': 'vslider'
+    'body': 'vslider("${1:volume}",0,0,1,0.01)'
+  'button':
+    'prefix': 'button'
+    'body': 'button("${1:play}")'
+  'checkbox':
+    'prefix': 'checkbox'
+    'body': 'checkbox("${1:mute}")'
+  'hbargraph':
+    'prefix': 'hbargraph'
+    'body': 'hbargraph("${1:vumeter}",0,1)'
+  'vbargraph':
+    'prefix': 'vbargraph'
+    'body': 'vbargraph("${1:vumeter}",0,1)'
+  'environment':
+    'prefix': 'environment'
+    'body': 'environment {${1:definition};}'
+  'with':
+    'prefix': 'with'
+    'body': """
+    	with {
+    		${1:name} = ${2:definition};$3
+    	}
+    """
+  'doc':
+    'prefix': 'doc'
+    'body':"""
+        //--------------- ${1:func} ----------------
+        // ${2:presentation}
+        //
+        // ### Usage:
+        //    `${3:example}`
+        //
+        // #### Where:
+        // + ${4:arg1} = ${5:role and value}
+        //
+        //------------------------------------------
+    """
diff --git a/syntax-highlighting/codepress/faust.css b/syntax-highlighting/codepress/faust.css
old mode 100755
new mode 100644
diff --git a/syntax-highlighting/codepress/faust.js b/syntax-highlighting/codepress/faust.js
old mode 100755
new mode 100644
diff --git a/syntax-highlighting/faust.nanorc b/syntax-highlighting/faust.nanorc
new file mode 100644
index 0000000..613172f
--- /dev/null
+++ b/syntax-highlighting/faust.nanorc
@@ -0,0 +1,20 @@
+##Here is an exemple for highlighting Faust code
+##Lionel Rascle leyoy at free.fr for Grame
+#
+
+syntax "faust" "\.dsp$"
+
+
+
+color brightmagenta "(min|max|cos|sin|floor|abs|sqrt)"
+color brightmagenta "(vbargraph|hbargraph|button|attach|checkbox|library|par|vgroup|hgroup|tgroup|pow|tan|ffunction|rdtable|hslider|vslider|nentry)"
+color brightred "(<:|:>|~|:|,)"
+color brightblue "(process|with|case|seq|par|sum|prod|import|component|library|environment|declare)"
+
+## String highlighting.
+color brightyellow "<[^= 	]*>" ""(\\.|[^"])*""
+
+## Comment highlighting
+color cyan "//.*"
+color cyan start="/\*" end="\*/"
+
diff --git a/tests/faust2appls-tests/kisana.dsp b/tests/faust2appls-tests/kisana.dsp
new file mode 100644
index 0000000..f3eafa3
--- /dev/null
+++ b/tests/faust2appls-tests/kisana.dsp
@@ -0,0 +1,104 @@
+//-----------------------------------------------
+// 		Kisana : 3-loops string instrument
+//		(based on Karplus-Strong)
+//
+//-----------------------------------------------
+
+declare name  	"Kisana";
+declare author  "Yann Orlarey";
+
+import("music.lib"); 
+
+
+
+KEY = 60;	// basic midi key
+NCY = 15; 	// note cycle length
+CCY = 15;	// control cycle length
+BPS = 360;	// general tempo (beat per sec)
+
+
+process = kisana;    
+
+
+//-------------------------------kisana----------------------------------
+// USAGE:  kisana : _,_;
+// 		3-loops string instrument
+//-----------------------------------------------------------------------
+
+kisana = hgroup("Loops", harpe(C,11,48), harpe(C,11,60), (harpe(C,11,72) : *(1.5), *(1.5))) 
+	:> 	*(l),*(l)
+	with {
+		l = hslider("[1]master",-20, -60, 0, 0.01) : db2linear;
+		C = hslider("../[2]timbre",0, 0, 1, 0.01) : automat(BPS, CCY, 0.0);
+	};
+ 
+
+
+//----------------------------------Harpe--------------------------------
+// USAGE:  harpe(C,10,60) : _,_;
+//		C is the filter coefficient 0..1
+// 		Build a N (10) strings harpe using a pentatonic scale 
+//		based on midi key b (60)
+//		Each string is triggered by a specific
+//		position of the "hand"
+//-----------------------------------------------------------------------
+harpe(C,N,b) = 	hand <: par(i, N, position(i+1)
+							: string(C,Penta(b).degree2Hz(i), att, lvl)
+							: pan((i+0.5)/N) )
+				 	:> _,_
+	with {
+		att  = 4; 
+		hand = vgroup("loop%b", vslider("[1]note", 0, 0, N, 1) : int : automat(BPS, NCY, 0.0));
+		lvl  = vslider("v:loop/level", 0, 0, 6, 1) : int : automat(BPS, CCY, 0.0) : -(6) : db2linear; 
+		pan(p) = _ <: *(sqrt(1-p)), *(sqrt(p));
+		position(a,x) = abs(x - a) < 0.5;
+		db2linear(x)	= pow(10, x/20.0);
+
+	};
+
+
+//----------------------------------Penta-------------------------------
+// Pentatonic scale with degree to midi and degree to Hz conversion
+// USAGE: Penta(60).degree2midi(3) ==> 67 midikey
+//        Penta(60).degree2Hz(4)   ==> 440 Hz
+//-----------------------------------------------------------------------
+
+Penta(key) = environment {
+
+	A4Hz = 440; 
+	
+	degree2midi(0) = key+0;
+	degree2midi(1) = key+2;
+	degree2midi(2) = key+4;
+	degree2midi(3) = key+7;
+	degree2midi(4) = key+9;
+	degree2midi(d) = degree2midi(d-5)+12;
+	
+	degree2Hz(d) = A4Hz*semiton(degree2midi(d)-69) with { semiton(n) = 2.0^(n/12.0); };
+
+}; 
+ 
+
+//----------------------------------String-------------------------------
+// A karplus-strong string.
+//
+// USAGE: string(440Hz, 4s, 1.0, button("play"))
+// or	  button("play") : string(440Hz, 4s, 1.0)
+//-----------------------------------------------------------------------
+
+string(coef, freq, t60, level, trig) = noise*level
+							: *(trig : trigger(freq2samples(freq)))
+							: resonator(freq2samples(freq), att)
+	with {
+		resonator(d,a)	= (+ : @(d-1)) ~ (average : *(a));
+		average(x)		= (x*(1+coef)+x'*(1-coef))/2;
+		trigger(n) 		= upfront : + ~ decay(n) : >(0.0);
+		upfront(x) 		= (x-x') > 0.0;
+		decay(n,x)		= x - (x>0.0)/n;
+		freq2samples(f) = 44100.0/f;
+		att 			= pow(0.001,1.0/(freq*t60)); // attenuation coefficient
+		random  		= +(12345)~*(1103515245);
+		noise   		= random/2147483647.0;
+	};
+
+   
diff --git a/tests/faust2appls-tests/test b/tests/faust2appls-tests/test
new file mode 100755
index 0000000..12465ca
--- /dev/null
+++ b/tests/faust2appls-tests/test
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# message colors
+red='\e[1;31m'
+green='\e[1;32m'
+NC='\e[0m' # No Color
+
+OPTIONS="$1 $2"
+
+SCRIPTS=../../tools/faust2appls/faust2*
+rm -rf sandbox
+rm -f LOG
+for f in *.dsp; do
+	echo "test file $f"
+	for s in $SCRIPTS; do
+		echo -n "compile $f with script $s $OPTIONS  : "
+		(($s $OPTIONS $f  >> ../LOG 2>&1) && echo -e "${green}PASSED${NC}" ) || echo -e "${red}FAILED${NC}"
+	done
+done
+		
+		
diff --git a/tests/mathdoc/Makefile b/tests/mathdoc/Makefile
new file mode 100644
index 0000000..1a620f4
--- /dev/null
+++ b/tests/mathdoc/Makefile
@@ -0,0 +1,47 @@
+# This Makefile is mostly intended to gather all resulting faust2mathdoc pdf files into the single directory "allmathpdfs".
+# GRAME 2009
+# Karim Barkati
+
+
+DSP = $(wildcard *.dsp)
+TEX = $(wildcard *-mdoc/tex/*.tex)
+PDF = $(wildcard *-mdoc/pdf/*.pdf)
+
+all : mathdoc copy
+
+
+.PHONY: all clean compile copy install mathdoc help
+
+
+compile :
+	$(MAKE) -C ../../compiler -f Makefile.unix
+
+install :
+	sudo $(MAKE) -C ../.. install
+	sudo $(MAKE) -C ../../tools/faust2appls install
+
+mathdoc :
+	faust2mathdoc *.dsp
+
+copy :
+	mkdir -p allmathdsps
+	mkdir -p allmathtexs
+	mkdir -p allmathpdfs
+	cp $(DSP) allmathdsps/
+	cp $(TEX) allmathtexs/
+	cp $(PDF) allmathpdfs/
+
+help :
+	@echo "make or make all : compile math documentation of all examples, then copy resulting pdf files into \"allmathpdfs\" directory."
+	@echo "make clean   : remove \"*-mdoc\" and \"allmath*\" directories."
+	@echo "make compile : compile the faust compiler."
+	@echo "make install : install the faust compiler and faust2appls scripts."
+	@echo "make mathdoc    : generate math documentation of all examples (with faust2mathdoc)."
+	@echo "make copy    : copy dsp, pdf, and tex files into \"allmathdsps\", \"allmathpdfs\", and \"allmathtexs\" directories."
+	@echo "make total   : clean, compile faust, install faust and faust2appls, compile math docs, and copy files."
+
+clean :
+	rm -rf *-mdoc
+	rm -rf allmath*
+
+total : clean compile install mathdoc copy
\ No newline at end of file
diff --git a/tests/mathdoc/prefix.dsp b/tests/mathdoc/prefix.dsp
new file mode 100644
index 0000000..da04d48
--- /dev/null
+++ b/tests/mathdoc/prefix.dsp
@@ -0,0 +1,13 @@
+declare name 		"prefix";
+declare version 	"1.0";
+declare author 		"Grame";
+declare license 	"BSD";
+declare copyright 	"(c)GRAME 2009";
+
+//-------------------------------------------------
+// Simple prefix test for documentator
+//-------------------------------------------------
+
+
+process = prefix (3,*(7));
+
diff --git a/tests/mathdoc/rms.dsp b/tests/mathdoc/rms.dsp
new file mode 100644
index 0000000..2f93f38
--- /dev/null
+++ b/tests/mathdoc/rms.dsp
@@ -0,0 +1,27 @@
+declare name 		"rms";
+declare version 	"1.0";
+declare author 		"Grame";
+declare license 	"BSD";
+declare copyright 	"(c)GRAME 2009";
+
+
+// Root Mean Square of n consecutive samples
+RMS(n) = square : mean(n) : sqrt ;
+
+// the square of a signal
+square(x) = x * x ;
+
+// the mean of n consecutive samples of a signal
+// uses fixpoint to avoid the accumulation of
+// rounding errors 
+mean(n) = float2fix : integrate(n) : fix2float : /(n); 
+
+// the sliding sum of n consecutive samples of a signal
+integrate(n,x) = x - x at n : +~_ ;
+
+// convertion between float and fix point
+float2fix(x) = int(x*(1<<20));      
+fix2float(x) = float(x)/(1<<20);    
+
+// Root Mean Square of 1000 consecutive samples
+process = RMS(1000) ;
diff --git a/tests/mathdoc/select2.dsp b/tests/mathdoc/select2.dsp
new file mode 100644
index 0000000..66a52f2
--- /dev/null
+++ b/tests/mathdoc/select2.dsp
@@ -0,0 +1,18 @@
+declare name 		"select2";
+declare version 	"0.1";
+declare author 		"Grame";
+declare license 	"BSD";
+declare copyright 	"(c)GRAME 2009";
+
+//-----------------------------------------------
+// Two noises compared
+//-----------------------------------------------
+
+
+RANDMAX = 2147483647;
+random1 = ffunction(int random (), <stdlib.h>, "");
+noise1 = (random1 << 1) * (1.0/RANDMAX);
+random2 = (*(1103515245)+12345) ~ _ ; 
+noise2 = random2 * (1.0/RANDMAX);
+
+process = select2(button("Switch"), noise1, noise2) * hslider("Volume", 0, 0, 1, 0.01) <: _,_ ;
diff --git a/tests/mathdoc/select3.dsp b/tests/mathdoc/select3.dsp
new file mode 100644
index 0000000..5505c6a
--- /dev/null
+++ b/tests/mathdoc/select3.dsp
@@ -0,0 +1,19 @@
+declare name 		"select3";
+declare version 	"0.1";
+declare author 		"Grame";
+declare license 	"BSD";
+declare copyright 	"(c)GRAME 2009";
+
+//-----------------------------------------------
+// Three noises compared
+//-----------------------------------------------
+
+
+RANDMAX = 2147483647;
+random1 = ffunction(int random (), <stdlib.h>, "");
+noise1 = (random1 << 1) * (1.0/RANDMAX);
+random2 = (*(1103515245)+12345) ~ _ ; 
+noise2 = random2 * (1.0/RANDMAX);
+noise3 = 0;
+
+process = select3(button("Switch"), noise1, noise2, noise3) * hslider("volume", 0, 0, 1, 0.01) <: _,_ ;
diff --git a/tools/README b/tools/README
index c1c1bcb..8086f25 100644
--- a/tools/README
+++ b/tools/README
@@ -1,9 +1,8 @@
-	 		Additional tools for Faust
-			==========================
-	 Grame, Centre National de Creation Musicale
-	 			 http://www.grame.fr
-
+	 	Additional tools for Faust
+		==========================
 
+	 Grame, Centre National de Creation Musicale
+	 	http://www.grame.fr
 
 
 These additional tools are provided by various contributors to help 
@@ -21,7 +20,7 @@ Currently the following tools are available :
   Haskell and SuperCollider).
 
 - faust2pd is a Q program used to generate a user interface patch to
-  use in conjuction with a Faust generated pd plugin.
+  use in conjunction with a Faust generated pd plugin.
 
 - scbuilder is a Ruby/Python/SCons script for building SuperCollider
   plugins, either from C++ sources or from Faust specifications.
@@ -32,3 +31,8 @@ Currently the following tools are available :
 
 - faust2flash allows to convert Faust programs into Flash .swf files
   that can be published in web pages.
+
+- sound2faust allows to convert audio files in Faust 'waveforms'. The output file contains:
+	- an interleaved version (all audio channels are generated in a same 'waveform')
+	- several 'waveforms' for separated mono channels
+	- a resulting 'processor' that simply output all mono 'waveforms' 
diff --git a/tools/faust2appls/Makefile b/tools/faust2appls/Makefile
index e5adf8b..6187f79 100644
--- a/tools/faust2appls/Makefile
+++ b/tools/faust2appls/Makefile
@@ -12,8 +12,12 @@ help:
 	@echo Call 'make install DESTDIR=/your/install/dir' to install to another location.
 
 install:
+	mkdir -p $(dest)
+	install faustpath $(dest)
+	install faustoptflags $(dest)
 	install faust2alqt $(dest)
 	install faust2alsa $(dest)
+	install faust2au $(dest)
 	install faust2caqt $(dest)
 	install faust2csound $(dest)
 	install faust2ladspa $(dest)
@@ -23,16 +27,22 @@ install:
 	install faust2jack $(dest)
 	install faust2jackinternal $(dest)
 	install faust2jackserver $(dest)
+	install faust2jackconsole $(dest)
 	install faust2jaqt $(dest)
 	install faust2mathdoc $(dest)
 	install faust2mathviewer $(dest)
 	install faust2msp $(dest)
+	install faust2w32msp $(dest)
+	install faust2max6 $(dest)
 	install faust2octave $(dest)
 	install faust2paqt $(dest)
 	install faust2pdf $(dest)
 	install faust2plot $(dest)
 	install faust2png $(dest)
 	install faust2puredata $(dest)
+	install faust2w32puredata $(dest)
+	install faust2ros $(dest)
+	install faust2rosgtk $(dest)
 	install faust2svg $(dest)
 	install faust2supercollider $(dest)
 	install ../faust2sc-1.0.0/faust2sc $(dest)
@@ -40,4 +50,83 @@ install:
 	install faust2graphviewer $(dest)
 	install faust2sig $(dest)
 	install faust2sigviewer $(dest)
+	install faust2netjackqt $(dest)
+	install faust2netjackconsole $(dest)
+	install faust2vst $(dest)
+	install faust2vsti $(dest)
+	install faust2w32vst $(dest)
+	install faust2ios $(dest)
+	install faust2lv2 $(dest)
+	install faust2lv2synth $(dest)
+	install faust2alsaconsole $(dest)
+	install faust2rpialsaconsole $(dest)
+	install faust2rpinetjackconsole $(dest)
+	install faust2android $(dest)
+	install faust2owl $(dest)
+	install faust2webaudioasm $(dest)
+	install faust2asmjs $(dest)
+	install faust2api $(dest)
+	install faust2raqt $(dest)
+	install faust2md $(dest)
+	
+
+uninstall:
+	rm -f $(dest)/faustpath
+	rm -f $(dest)/faustoptflags
+	rm -f $(dest)/faust2alqt
+	rm -f $(dest)/faust2alsa
+	rm -f $(dest)/faust2au
+	rm -f $(dest)/faust2ausynth
+	rm -f $(dest)/faust2caqt
+	rm -f $(dest)/faust2csound
+	rm -f $(dest)/faust2ladspa
+	rm -f $(dest)/faust2dssi
+	rm -f $(dest)/faust2eps
+	rm -f $(dest)/faust2firefox
+	rm -f $(dest)/faust2jack
+	rm -f $(dest)/faust2jackinternal
+	rm -f $(dest)/faust2jackserver
+	rm -f $(dest)/faust2jackconsole
+	rm -f $(dest)/faust2jaqt
+	rm -f $(dest)/faust2mathdoc
+	rm -f $(dest)/faust2mathviewer
+	rm -f $(dest)/faust2msp
+	rm -f $(dest)/faust2w32msp
+	rm -f $(dest)/faust2max6
+	rm -f $(dest)/faust2octave
+	rm -f $(dest)/faust2paqt
+	rm -f $(dest)/faust2pdf
+	rm -f $(dest)/faust2plot
+	rm -f $(dest)/faust2png
+	rm -f $(dest)/faust2puredata
+	rm -f $(dest)/faust2w32puredata
+	rm -f $(dest)/faust2ros
+	rm -f $(dest)/faust2rosgtk
+	rm -f $(dest)/faust2svg
+	rm -f $(dest)/faust2supercollider
+	rm -f $(dest)/faust2sc
+	rm -f $(dest)/faust2graph
+	rm -f $(dest)/faust2graphviewer
+	rm -f $(dest)/faust2sig
+	rm -f $(dest)/faust2sigviewer
+	rm -f $(dest)/faust2netjackqt
+	rm -f $(dest)/faust2netjackconsole
+	rm -f $(dest)/faust2vst
+	rm -f $(dest)/faust2vsti
+	rm -f $(dest)/faust2w32vst
+	rm -f $(dest)/faust2ios
+	rm -f $(dest)/faust2lv2
+	rm -f $(dest)/faust2lv2synth
+	rm -f $(dest)/faust2alsaconsole
+	rm -f $(dest)/faust2rpialsaconsole
+	rm -f $(dest)/faust2rpinetjackconsole
+	rm -f $(dest)/faust2android
+	rm -f $(dest)/faust2owl
+	rm -f $(dest)/faust2webaudioasm
+	rm -f $(dest)/faust2asmjs
+	rm -f $(dest)/faust2api
+	rm -f $(dest)/faust2raqt
+	rm -f $(dest)/faust2md
+	
+
 
diff --git a/tools/faust2appls/README b/tools/faust2appls/README
index 383f748..c6e27c3 100644
--- a/tools/faust2appls/README
+++ b/tools/faust2appls/README
@@ -2,17 +2,49 @@ This folder contains useful scripts that combines faust and g++ to generates exe
 You can use 'sudo make install' to install them. 
 
 
-1) The following scripts generate audio applications
+1) The following scripts generate audio application
 
-faust2jack <file1.dsp>...       : create jack-gtk  applications for each input file
+faust2alqt <file.dsp>...       	: create ALSA/QT application for each input file
 
-faust2jaqt <file.dsp>...        : create jack-qt applications for each input file
+faust2alsa <file.dsp>...       	: create ALSA/GTKk application for each input file
 
-faust2alsa <file1.dsp>...       : create alsa-gtk applications for each input file
+faust2au <file.dsp>...		      : create Audio Unit Effect for each input file
 
-faust2plot  <file1.dsp>...      : create a matplot application for each input file
+faust2ausynth <file.dsp>...           : create Audio Unit Synth for each input file
 
-faust2coreaudio  <file1.dsp>... : create a coreaudio-qt application for each input file
+faust2caqt  <file.dsp>... 		: create a CoreAudio/QT application for each input file
+
+faust2csound <file.dsp>...     	: create a CSOUND plugin for each input file
+
+faust2dssi <file.dsp>...       	: create a DSSI plugin for each input file
+
+faust2jack <file.dsp>...       	: create JACK/GTK application for each input file
+
+faust2jaqt <file.dsp>...       	: create JACK/QT application for each input file
+
+faust2ladspa  <file.dsp>...    	: create a LADSPA plugin for each input file
+
+faust2max6  <file.dsp>...		: create a Max/MSP 6 plugin (64 bits samples) for each input file
+
+faust2msp  <file.dsp>...      		: create a Max/MSP 4 or 5 plugin (32 bits samples) for each input file
+
+faust2paqt  <file.dsp>...      	: create a PortAudio/QT application for each input file
+
+faust2netjackqt  <file.dsp>...  	: create a NetJack/QT application for each input file
+
+faust2netjackconsole  <file.dsp>...   : create a NetJack/console application for each input file
+	
+faust2puredata  <file.dsp>...  	: create a PureData 4 or 5 plugin for each input file
+
+faust2supercollider <file.dsp>... 	: create a SuperCollider plugin for each input file
+
+faust2vst  <file.dsp>...  		: create a VST plugin for each input file
+
+faust2webaudio  <file.dsp>...       : create a HTML/WebAudioAPI (with JavaScript code) application for each input file
+
+faust2asmjs  <file.dsp>...          : using Emscripten compiler, create a WebAudioAPI node for each input file
+
+faust2webaudioasm  <file.dsp>...   	: using Emscripten compiler, create a HTML/WebAudioAPI (with asm.js code) application for each input file
 
 
 2) The following scripts can be used to generate block diagrams
@@ -29,3 +61,9 @@ faust2eps  <file1.dsp>...       : create svg block-diagrams for each input file
 faust2firefox  <file1.dsp>...   : faust2svg with visualization using firefox
 
 faust2octave <file.dsp>         : faust2plot with visualization using octave   
+
+4) the following scripts can be used to generate documentation
+
+faust2mathdoc <file.dsp>        : generate mathematical documentation 
+
+faust2md <file.dsp> > file.md   : generate markdown documentation from the comments in the code
diff --git a/tools/faust2appls/faust2alqt b/tools/faust2appls/faust2alqt
index 3781411..1274781 100755
--- a/tools/faust2appls/faust2alqt
+++ b/tools/faust2appls/faust2alqt
@@ -2,14 +2,23 @@
 
 #####################################################################
 #                                                                   #
-#               Compiles Faust programs to jack-qt                  #
+#               Compiles Faust programs to alsa-qt                  #
 #               (c) Grame, 2009                                     #
 #                                                                   #
 #####################################################################
 
-OSCINC=""
-QTDEFS=""
-OSCLIB=""
+. faustpath
+. faustoptflags
+
+CXXFLAGS=$MYGCCFLAGS
+
+ARCHFILE="alsa-qt.cpp"
+ARCHLIB="-lasound"
+
+#-------------------------------------------------------------------------------
+# Search for qmake or qmake-qt4
+
+QMAKE=$(which qmake-qt4 || echo qmake) 
 
 
 #-------------------------------------------------------------------
@@ -23,12 +32,19 @@ OSCLIB=""
 # without having to configure CXX and CXXFLAGS
 for p in $@; do
 	if [ "$p" = -icc ]; then
-		CXX=icpc
-		CXXFLAGS='-O3 -xHost -ftz -fno-alias -fp-model fast=2'
+		# we ignore -icc when compiling for QT
+		TOTO=""
+		#CXX=icpc
+		#CXXFLAGS='-Wfatal-errors -O3 -xT -ftz -fno-alias -fp-model fast=2'
     fi
 done
 
 #PHASE 2 : dispatch command arguments
+
+OSCINC=""
+QTDEFS=""
+OSCLIB=""
+
 for p in $@; do
     if [ "$p" = -omp ]; then
         if [[ $CXX == "icpc" ]]; then
@@ -41,12 +57,16 @@ for p in $@; do
     if [ "$p" = -icc ]; then
     	ignore=" "
     elif [ $p = "-osc" ]; then
-		 OSCINC="INCLUDEPATH+=/usr/local/lib/faust/osclib"
-		 QTDEFS="DEFINES += OSCCTRL"
-		 OSCLIB="-L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+		 OSCDEFS="DEFINES += OSCCTRL"
+		 OSCLIBS="-lOSCFaust"
+	elif [ "$p" = "-httpd" ]; then
+		HTTPDEFS="DEFINES += HTTPCTRL"
+		HTTPLIBS="-lHTTPDFaust -lmicrohttpd -lqrencode"
+	elif [ "$p" = "-qrcode" ]; then # requires -httpd
+		QRDEFS="DEFINES += QRCODECTRL"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -78,13 +98,13 @@ for p in $FILES; do
     mkdir "$TMP"
 
     # compile faust to c++
-	faust -a alsa-qt.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+	faust -i -a $ARCHFILE $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
 
     # compile c++ to binary
     (
 	    cd "$TMP"
-        qmake -project "INCLUDEPATH+=$CUR" "INCLUDEPATH+=/usr/local/lib/faust/" "$OSCINC" "LIBS+=-lasound $OSCLIB" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" "$QTDEFS"
-	    qmake $SPEC
+       	$QMAKE -project "QT += widgets printsupport network" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=$FAUSTINC" "QMAKE_CXXFLAGS=$CXXFLAGS -Wno-unused-parameter $FAUSTTOOLSFLAGS" "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "HEADERS+=$FAUSTINC/faust/gui/faustqt.h" "RESOURCES+= $FAUSTINC/faust/gui/Styles/Grey.qrc" "$OSCDEFS" "$HTTPDEFS" "$QRDEFS"  
+	    $QMAKE $SPEC
         make
     ) > /dev/null
 
diff --git a/tools/faust2appls/faust2alsa b/tools/faust2appls/faust2alsa
index faba0c1..027dc52 100755
--- a/tools/faust2appls/faust2alsa
+++ b/tools/faust2appls/faust2alsa
@@ -4,16 +4,15 @@ OSCDEFS=""
 #####################################################################
 #                                                                   #
 #               Compiles Faust programs to alsa-gtk                 #
-#               (c) Grame, 2009-2011                                #
+#               (c) Grame, 2009-2013                                #
 #                                                                   #
 #####################################################################
 
+. faustpath
 
-#-------------------------------------------------------------------
-# Default compilation flags for gcc and icc :
-#
-MYGCCFLAGS="-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
-MYICCFLAGS="-O3 -xHost -ftz -fno-alias -fp-model fast=2"
+. faustoptflags
+
+CXXFLAGS=$MYGCCFLAGS
 
 
 #-------------------------------------------------------------------
@@ -26,7 +25,6 @@ MYICCFLAGS="-O3 -xHost -ftz -fno-alias -fp-model fast=2"
 # PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
 # without having to configure CXX and CXXFLAGS
 CXX=g++
-CXXFLAGS=$MYGCCFLAGS
 for p in $@; do
 	if [ "$p" = -icc ]; then
 		CXX=icpc
@@ -47,10 +45,16 @@ for p in $@; do
     if [ "$p" = -icc ]; then
     	ignore=" "
     elif [ $p = "-osc" ]; then
-		 OSCDEFS="-I/usr/local/lib/faust/osclib -DOSCCTRL -L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+	 OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -66,15 +70,15 @@ done
 for f in $FILES; do
 	
 	# compile faust to c++
-	faust -a alsa-gtk.cpp $OPTIONS "$f" -o "$f.cpp"
+	faust -i -a alsa-gtk.cpp $OPTIONS "$f" -o "$f.cpp"
 
 	# compile c++ to binary
 	(
-		$CXX $CXXFLAGS $OMP -I/usr/local/lib/faust "$f.cpp" `pkg-config --cflags --libs alsa gtk+-2.0` $OSCDEFS -o "${f%.dsp}"
+		$CXX $CXXFLAGS $FAUSTTOOLSFLAGS $OMP "$f.cpp" `pkg-config --cflags --libs alsa gtk+-2.0` $PROCARCH $OSCDEFS $HTTPDEFS -o "${f%.dsp}"
 	) > /dev/null
 	rm "$f.cpp"
 
-	# collect binary file name for FaustGIDE
+	# collect binary file name for FaustWorks
 	BINARIES="$BINARIES${f%.dsp};"
 done
 
diff --git a/tools/faust2appls/faust2alsaconsole b/tools/faust2appls/faust2alsaconsole
new file mode 100755
index 0000000..18004d4
--- /dev/null
+++ b/tools/faust2appls/faust2alsaconsole
@@ -0,0 +1,99 @@
+#!/bin/bash
+
+OSCDEFS=""
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to alsa-gtk                 #
+#               (c) Grame, 2009-2011                                #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+. faustoptflags
+
+CXXFLAGS=$MYGCCFLAGS
+
+#-------------------------------------------------------------------
+# Default compilation flags for gcc and icc :
+#
+if [[ $(uname -m) == armv6l ]]; then
+	MYGCCFLAGS="-O3 -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -ffast-math -ftree-vectorize"
+else
+	MYGCCFLAGS="-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
+fi
+MYICCFLAGS="-O3 -xHost -ftz -fno-alias -fp-model fast=2"
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+CXX=g++
+CXXFLAGS=$MYGCCFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		CXX=icpc
+		CXXFLAGS=$MYICCFLAGS
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+	
+#-------------------------------------------------------------------
+# compile the *.dsp files using ALSA and GTK on linux
+#
+for f in $FILES; do
+	
+	# compile faust to c++
+	faust -i -a alsa-console.cpp $OPTIONS "$f" -o "$f.cpp"
+
+	# compile c++ to binary
+	(
+		$CXX $CXXFLAGS $FAUSTTOOLSFLAGS $OMP "$f.cpp" `pkg-config --cflags --libs alsa` $PROCARCH $OSCDEFS $HTTPDEFS -lpthread -o "${f%.dsp}"
+	) > /dev/null
+	rm "$f.cpp"
+
+	# collect binary file name for FaustWorks
+	BINARIES="$BINARIES${f%.dsp};"
+done
+
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2android b/tools/faust2appls/faust2android
new file mode 100755
index 0000000..b432694
--- /dev/null
+++ b/tools/faust2appls/faust2android
@@ -0,0 +1,156 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Compile a Faust program to an android app           #
+#               (c) Romain Michon CCRMA and Grame, 2014             #
+#               (c) Yann Orlarey Grame, 2015             			#
+#                                                                   #
+#####################################################################
+
+# change if you want to get the log of what's happening
+LOG="/dev/null"
+
+# exit if a command fails
+set -e
+
+# Global variables for file and options
+FILE=
+INSTALL=0
+SOURCE=0
+SWIG=0
+FAUST=0
+KEYBOARD=0
+REUSE=0
+
+# PHASE 2 : dispatch command arguments
+for p in $@; do
+	if [ $p = "-swig" ]; then
+		SWIG=1
+	fi
+	if [[ -f "$p" ]]; then
+	    FILE="$p"
+	elif [ $p = "-install" ]; then
+		INSTALL=1
+	elif [ $p = "-source" ]; then
+		SOURCE=1
+	elif [ $p = "-faust" ]; then
+		FAUST=1
+	elif [ $p = "-reuse" ]; then
+		REUSE=1
+	elif [ $p = "-keyboard" ]; then
+		KEYBOARD=1
+	elif [ $p = "-debug" ]; then
+		LOG="/dev/stdout"
+    elif [ ${p:0:1} = "-" ]; then
+        OPTIONS="$OPTIONS $p"
+	elif [ $p = "-h" ]; then
+		echo "Usage: faust2android faustFile.dsp"
+		echo "OPTIONS:"
+		echo "-install: once compilation is over, installs the generated app on the Android device connected to the computer."
+		echo "-source: creates an eclipse project of the app in the current directory."
+		echo "Any other options are considered as Faust options. To get a list of the Faust options type: faust -h."
+		echo "-swig: regenerate the C++ and the JAVA interface for the native portion of the app."
+		echo "-faust: only carries out the faust compilation and install the generated C++ file in the JNI folder."
+		echo "-reuse: keep build directory and reuse it to speedup compilation."
+		echo "-debug: verbose output."
+		exit 1
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+# only carry out the faust compilation 
+if [ $FAUST -eq 1 ]; then
+	faust -i -a android-sp.cpp $OPTIONS "$FILE" -o "app/src/main/jni/dsp_faust.cpp"
+	exit 1
+fi
+ 
+# Create the temporary directory where compilation will take place
+
+APPNAME=$(basename "$FILE")
+APPNAME="${APPNAME%.dsp}"
+BUILDDIR="faustandro.$APPNAME"
+APPFOLDER="$BUILDDIR/app/src/main"
+JNIFOLDER="$APPFOLDER/jni"
+
+if [ $REUSE -eq 0 ]; then
+	if [ -d "$BUILDDIR" ]; then
+		echo "Delete existing Android project $BUILDDIR" > $LOG
+		rm -rf "$BUILDDIR"
+	fi
+fi
+		
+if [ ! -d "$BUILDDIR" ]; then
+  	echo "Creating new Android project $BUILDDIR"  > $LOG
+  	
+  	mkdir -p "$BUILDDIR"
+	cp -r /usr/local/lib/faust/android/*  "$BUILDDIR"
+	# Copy include files *.h if any (ignore any error here)
+	(cp *.h $JNIFOLDER 2> $LOG) || true
+	
+	# change 'faust' with real *APPNAME
+	PLATFORM=$(uname)
+
+	if [ $PLATFORM = "Darwin" ]; then
+		sed -i '' 's,com.faust,com.'$APPNAME',g' $BUILDDIR/app/build.gradle
+		sed -i '' 's,com.faust,com.'$APPNAME',g' $APPFOLDER/java/com/faust/*
+		sed -i '' 's,com.faust,com.'$APPNAME',g' $APPFOLDER/java/com/triggertrap/seekarc/*
+		sed -i '' 's,com.faust,com.'$APPNAME',g' $APPFOLDER/AndroidManifest.xml
+		sed -i '' 's,com.faust,com.'$APPNAME',g' $APPFOLDER/res/layout/*
+		sed -i '' 's,1,'$APPNAME',g' $APPFOLDER/res/values/strings.xml
+	else
+		sed -i 's,com.faust,com.'$APPNAME',g' $BUILDDIR/app/build.gradle
+		sed -i 's,com.faust,com.'$APPNAME',g' $APPFOLDER/java/com/faust/*
+		sed -i 's,com.faust,com.'$APPNAME',g' $APPFOLDER/java/com/triggertrap/seekarc/*
+		sed -i 's,com.faust,com.'$APPNAME',g' $APPFOLDER/AndroidManifest.xml
+		sed -i 's,com.faust,com.'$APPNAME',g' $APPFOLDER/res/layout/*
+		sed -i 's,1,'$APPNAME',g' $APPFOLDER/res/values/strings.xml
+	fi
+	
+	mv $APPFOLDER/java/com/faust $APPFOLDER/java/com/$APPNAME
+
+	# TODO wrong: should be checked
+	if [ $SWIG -eq 1 ]; then
+		rm -rf $APPFOLDER/java/com/dsp_faust || true
+		mkdir -p $APPFOLDER/java/com/dsp_faust
+		swig -java -package com.dsp_faust -includeall -verbose -outdir $APPFOLDER/java/com/dsp_faust -c++ -I/usr/local/include -I/System/Library/Frameworks/JavaVM.framework/Headers -I$JNIFOLDER -o $JNIFOLDER/java_interface_wrap.cpp $BUILDDIR/dsp_faust_interface.i
+	fi
+else
+	echo "Reusing existing Android project $BUILDDIR" > $LOG
+fi
+
+
+# Compile the Faust code for the NDK
+faust -i -a android-sp.cpp $OPTIONS "$FILE" -o "$JNIFOLDER/dsp_faust.cpp"
+
+
+# Run Gradle
+cd $BUILDDIR
+./gradlew assembleRelease > $LOG
+cd ..
+
+cp -r $BUILDDIR/app/build/outputs/apk/app-release.apk $APPNAME.apk
+
+# ****************
+# TREAT OPTIONS
+# ****************
+
+if [ $INSTALL -eq 1 ]; then
+	adb install -r $APPNAME.apk
+fi
+
+if [ $SOURCE -eq 1 ]; then
+	rm -rf faustApp
+	mv $BUILDDIR faustApp
+	echo "An Android studio project named faustApp was created." > $LOG
+else
+	if [ $REUSE -eq 0 ]; then
+		echo "Delete Android project $BUILDDIR" > $LOG
+		rm -rf $BUILDDIR
+	fi
+fi
+
+echo "$APPNAME.apk;"
+
+
diff --git a/tools/faust2appls/faust2api b/tools/faust2appls/faust2api
new file mode 100755
index 0000000..b1221f7
--- /dev/null
+++ b/tools/faust2appls/faust2api
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#    Generates an API for Android or iOS based on a Faust object    #
+#               (c) Romain Michon CCRMA and Grame, 2014             #
+#                                                                   #
+#####################################################################
+
+# change if you want to get the log of what's happening
+LOG="/dev/null"
+#LOG="log"
+
+# exit if a command fails
+set -e
+
+# global option variables
+ANDROID=0
+IOS=0
+
+# dispatch command arguments
+for p in $@; do
+	if [[ -f "$p" ]]; then
+	    FILE="$p"
+	elif [ $p = "-android" ]; then
+		ANDROID=1
+	elif [ $p = "-ios" ]; then
+		IOS=1
+	elif [ $p = "-h" ]; then
+		echo "TODO doc"
+		exit
+	fi
+done
+
+if [ -z $FILE ]; then
+	echo "Please, provide a Faust file to process"
+	exit
+fi
+
+if [ $ANDROID -eq 1 ]; then
+	APIFOLDER="dsp-faust"
+	rm -r "$APIFOLDER" > /dev/null || true
+	mkdir "$APIFOLDER"
+	cp -r /usr/local/lib/faust/android/app/src/main/java/com/grame/dsp_faust $APIFOLDER
+	cp -r /usr/local/lib/faust/android/app/src/main/jni $APIFOLDER
+	faust -i -a android.cpp "$FILE" -o "$APIFOLDER/jni/dsp_faust.cpp"
+	echo "Your faust-dsp API package for Android was created"
+elif [ $IOS -eq 1 ]; then
+	faust -i -a ios-coreaudio-api.cpp "$FILE" -o dsp-faust.h
+	echo "Your dsp-faust.h C++ API for IOS was created"
+else
+	echo "Please specify an architecture or a platform:"
+	echo "-android"
+	echo "-ios"
+	echo "For more informations, visit http://ccrma.stanford.edu/~rmichon/mobileFaust"
+fi
diff --git a/tools/faust2appls/faust2asmjs b/tools/faust2appls/faust2asmjs
new file mode 100755
index 0000000..f30381f
--- /dev/null
+++ b/tools/faust2appls/faust2asmjs
@@ -0,0 +1,134 @@
+#!/bin/bash
+
+#-------------------------------------------------------------------
+# Wrapping resources
+
+CPP_WRAPPER=webaudio-asm.cpp
+JS_WRAPPER=webaudio-asm-emcc.js
+COMB="false"
+COMB_SRC=
+COMB_EXPORTED=
+COMB_WRAPPED=
+COMB_WRAPPED_FILES=
+COMB_SEP=
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust/
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust/
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# existing *.dsp files          -> FILES
+#
+
+for p in $@; do
+    if [ $p = "-help" ] || [ $p = "-h" ]; then
+        echo "faust2asmjs [-poly] [-comb] <file.dsp>"
+        echo "Use '-poly' to produce a polyphonic DSP, ready to be used with MIDI events"
+        echo "Use '-comb' to combine several DSP in a unique resulting 'comb.js' file, sharing the same Emcripten runtime"
+    elif [ $p = "-comb" ]; then
+        COMB="true"
+    elif [ $p = "-poly" ]; then
+        CPP_WRAPPER=webaudio-asm-poly.cpp
+        JS_WRAPPER=webaudio-asm-poly-emcc.js
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -e "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+BINARIES=""
+
+if [ $COMB = "false" ]; then
+
+for f in $FILES; do
+    name=${f%.dsp}
+    
+    # compile the C++ code
+    faust -a $FAUSTLIB/webaudio/$CPP_WRAPPER -i -uim -cn $name $OPTIONS $f -o $name.cpp
+    
+    if [ $CPP_WRAPPER = webaudio-asm.cpp ]; then
+        EXPORTED="['_"$name"_constructor','_"$name"_destructor','_"$name"_compute','_"$name"_getNumInputs','_"$name"_getNumOutputs','_"$name"_setValue','_"$name"_getValue','_"$name"_getJSON']"
+    else
+        EXPORTED="['_"$name"_poly_constructor','_"$name"_poly_destructor','_"$name"_poly_compute','_"$name"_poly_getNumInputs','_"$name"_poly_getNumOutputs','_"$name"_poly_setValue','_"$name"_poly_getValue','_"$name"_poly_getJSON','_"$name"_poly_keyOn','_"$name"_poly_keyOff','_"$name"_poly_allNotesOff','_"$name"_poly_ctrlChange','_"$name"_poly_pitchWheel','_"$name"_poly_pitchBend']"       
+	fi
+    
+    # compile the C++ code to asm.js
+    emcc -O2 --memory-init-file 0 $name.cpp -s TOTAL_MEMORY=100663296 --post-js $FAUSTLIB/webaudio/$JS_WRAPPER -o $name-temp.js \
+        -s EXPORTED_FUNCTIONS=$EXPORTED
+   
+    # compose the asm.js code
+    sed -e "s/DSP/"$name"/g" $name-temp.js > $name.js
+    
+    rm $name-temp.js
+    rm $name.cpp
+
+	# collect binary file name for FaustWorks
+	BINARIES="$BINARIES$name.js;"
+
+done
+
+else
+
+for f in $FILES; do
+    name=${f%.dsp}
+    
+    # compile the C++ code
+    faust -a $FAUSTLIB/webaudio/$CPP_WRAPPER -i -uim -cn $name $OPTIONS $f -o $name.cpp
+    
+    if [ $CPP_WRAPPER = webaudio-asm.cpp ]; then
+        EXPORTED="'_"$name"_constructor','_"$name"_destructor','_"$name"_compute','_"$name"_getNumInputs','_"$name"_getNumOutputs','_"$name"_setValue','_"$name"_getValue','_"$name"_getJSON'"
+    else
+        EXPORTED="'_"$name"_poly_constructor','_"$name"_poly_destructor','_"$name"_poly_compute','_"$name"_poly_getNumInputs','_"$name"_poly_getNumOutputs','_"$name"_poly_setValue','_"$name"_poly_getValue','_"$name"_poly_getJSON','_"$name"_poly_keyOn','_"$name"_poly_keyOff','_"$name"_poly_allNotesOff','_"$name"_poly_ctrlChange','_"$name"_poly_pitchWheel','_"$name"_poly_pitchBend'"       
+	fi
+    
+    # compose the asm.js code
+    sed -e "s/DSP/"$name"/g" $FAUSTLIB/webaudio/$JS_WRAPPER > $name-wrapper.js
+    
+    COMB_SRC+=$name.cpp
+    COMB_SRC+=" "
+    
+    COMB_EXPORTED+=$COMB_SEP$EXPORTED
+    COMB_SEP=","
+    
+    COMB_WRAPPED_FILES+=$name-wrapper.js
+    COMB_WRAPPED_FILES+=" "
+    
+    COMB_WRAPPED+=" --post-js "
+    COMB_WRAPPED+=$name-wrapper.js
+  	
+done
+
+# compile final file
+emcc -O2 --memory-init-file 0 $COMB_SRC -s TOTAL_STACK=20971520 -s TOTAL_MEMORY=41943040 $COMB_WRAPPED -o comb.js \
+    -s EXPORTED_FUNCTIONS="["$COMB_EXPORTED"]"
+
+# collect binary file name for FaustWorks
+BINARIES="comb.js;"
+
+rm $COMB_SRC
+rm $COMB_WRAPPED_FILES
+
+fi
+
+echo $BINARIES
diff --git a/tools/faust2appls/faust2au b/tools/faust2appls/faust2au
new file mode 100755
index 0000000..b526a7d
--- /dev/null
+++ b/tools/faust2appls/faust2au
@@ -0,0 +1,278 @@
+#!/bin/sh
+
+#####################################################################
+#
+#               Compiles Faust programs to Audio Unit
+#               (c) Grame 2013
+#
+#####################################################################
+
+PATH=$PATH:/usr/local/bin
+
+#-------------------------------------------------------------------------------
+# Search where Faust is installed. Store '.../lib/faust/' in $FLIB
+# and '.../include/(faust)' in $FINC
+
+FLIB=""; FINC="";
+FPATH="$FAUST_INSTALL /usr/local /usr /opt /opt/local"; # <- where to search
+for f in $FPATH; do
+if [ -e $f/lib/faust ]; 	then FLIB=$f/lib/faust;	fi
+if [ -e $f/include/faust ];	then FINC=$f/include/; fi
+done
+if [ -z "$FLIB" -o -z "$FINC" ]; then
+echo "ERROR : $0 cannot find Faust directories (normally /usr/local/include/faust and /usr/local/lib/faust)";
+exit 1;
+fi
+
+#-------------------------------------------------------------------------------
+#PHASE 1 : collects files and options from the command line
+
+DEBUG=0
+if [ $DEBUG -eq 1 ]; then
+PRINTDEV=/dev/tty
+else
+PRINTDEV=/dev/null
+fi
+
+for p in $@; do
+if [ "$p" = -omp ]; then
+if [[ $CXX == "icpc" ]]; then
+OMP="-openmp"
+else
+OMP="-fopenmp"
+fi
+fi
+
+if [ "$p" = -debug ]; then
+DEBUG=1
+elif [ "$p" = -icc ]; then
+ignore=" "
+elif [ $p = "-osc" ]; then
+OSCDEFS="DEFINES += OSCCTRL"
+OSCLIBS="-lOSCFaust"
+elif [ "$p" = "-httpd" ]; then
+HTTPDEFS="DEFINES += HTTPCTRL"
+HTTPLIBS="-lHTTPDFaust -lmicrohttpd"
+elif [ ${p:0:1} = "-" ]; then
+OPTIONS="$OPTIONS $p"
+elif [[ -f "$p" ]]; then
+FILES="$FILES $p"
+else
+OPTIONS="$OPTIONS $p"
+fi
+done
+
+#-------------------------------------------------------------------------------
+
+#PHASE 2 : compile the *.dsp file
+
+for f in $FILES; do
+
+# could use FILES for handling multiple dap files, while other AU args like manufacturer and subtype should be handled in a way
+
+# Get the number of inputs of the Faust code:
+NINPUTS=$(faust "$f" | grep getNumInputs | awk '{ printf "%d", $6}')
+# echo "Number of Faust module inputs = $NINPUTS"
+
+if [ $NINPUTS -gt 0 ]; then
+    echo "Generating an AU Effect plugin..."
+    ARCHFILE="au-effect.cpp"
+    AUTYPE=aufx
+    FAUSTAU_CLASS=FaustAUEffect
+    COMPTYPE=kAudioUnitType_Effect
+else
+    echo "Generating an AU Instrument plugin..."
+    ARCHFILE="au-instrument.cpp"
+    AUTYPE=aumu
+    FAUSTAU_CLASS=FaustAUInstrument
+    COMPTYPE=kAudioUnitType_MusicDevice
+fi
+
+export ARCHFILE
+export AUTYPE
+export FAUSTAU_CLASS
+export COMPTYPE
+
+#echo $ARCHFILE
+#echo $AUTYPE
+#echo $FAUSTAU_CLASS
+#echo $COMPTYPE
+
+FAUST_DIR=$FLIB
+AU_DIR=$HOME/Library/Audio/Plug-Ins/Components
+TEMP_DIR=./faust.XXX
+
+if [ $# -lt 1 ]
+then
+echo FAUST dsp file not specified
+exit
+fi
+
+if [ ! -f $f ]
+then
+echo Input file does not exist
+exit
+fi
+
+if [ -d $TEMP_DIR ]
+then
+rm -r $TEMP_DIR
+fi
+mkdir $TEMP_DIR
+cp -r /usr/local/lib/faust/AU/* $TEMP_DIR
+cp $f $TEMP_DIR
+cp *.dsp $TEMP_DIR >& $PRINTDEV
+cp *.lib $TEMP_DIR >& $PRINTDEV
+cd $TEMP_DIR
+mkdir Source >& $PRINTDEV
+
+FULL_FILE_NAME=$f
+
+FILE_NAME=$(BASENAME "$FULL_FILE_NAME")
+EXTENSION="${FILE_NAME##*.}"
+FILE_NAME="${FILE_NAME%.*}"
+
+cp $FAUST_DIR/$ARCHFILE au-arch-temp.cpp
+perl -pi -e 's/FaustAU_CustomViewFactory/'FaustAU_"$FILE_NAME"CustomViewFactory'/g' au-arch-temp.cpp
+perl -pi -e 's/FaustAU_CustomViewFactory/'FaustAU_"$FILE_NAME"CustomViewFactory'/g' FaustAUCustomView.plist
+
+
+faust $OPTIONS -a au-arch-temp.cpp $f -o Source/au-output.cpp
+
+rm au-arch-temp.cpp
+
+faust $OPTIONS -xml $f > $PRINTDEV
+mv $f.xml Source/au-output.xml
+
+if [ ! -f Source/au-output.cpp ]
+then
+echo FAUST could not generate cpp file
+cd ..
+rm -r $TEMP_DIR
+exit
+fi
+
+if [ $# -lt 2 ]
+then
+MANUFACTURER="Grame"
+else
+MANUFACTURER=$2
+fi
+
+NAME=$MANUFACTURER:' '"$FILE_NAME"
+
+if [ $# -lt 3 ]
+then
+STR=${FILE_NAME:0:4}
+SUB_TYPE=$(echo $STR | tr [[:lower:]] [[:upper:]])
+else
+SUB_TYPE=$3
+fi
+
+if [ $# -lt 4 ]
+then
+MANF=${MANUFACTURER:0:4}
+else
+MANF=$4
+fi
+
+perl -pi -e 's/_NAME_/'"$NAME"'/g' Info.plist
+perl -pi -e 's/_DESC_/'"$NAME"'/g' Info.plist
+perl -pi -e 's/_STYP_/'"$SUB_TYPE"'/g'  Info.plist
+perl -pi -e 's/_MANF_/'"$MANF"'/g' Info.plist
+perl -pi -e 's/_BUNDLE_ID_/'"$FILE_NAME"'/g' Info.plist
+perl -pi -e 's/_TYPE_/'"$AUTYPE"'/g' Info.plist
+
+perl -pi -e 's/_BUNDLE_NAME_/'"$FILE_NAME"'/g' English.lproj/InfoPlist.strings
+perl -pi -e 's/_BUNDLE_INFO_/'"$NAME"'/g' English.lproj/InfoPlist.strings
+
+perl -pi -e 's/_NAME_/'"$NAME"'/g' Source/AUSource/FaustAU.r
+perl -pi -e 's/_DESC_/'"$NAME"'/g' Source/AUSource/FaustAU.r
+perl -pi -e 's/_COMPTYPE_/'"$COMPTYPE"'/g' Source/AUSource/FaustAU.r
+
+perl -pi -e 's/_FaustAUClass_/'"$FAUSTAU_CLASS"'/g' Source/AUSource/FaustAU.h
+
+perl -pi -e 's/_STYP_/'"$SUB_TYPE"'/g' Source/AUSource/FaustAUVersion.h
+perl -pi -e 's/_MANF_/'"$MANF"'/g' Source/AUSource/FaustAUVersion.h
+
+perl -pi -e 's/_FILENAME_/'"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomView.m
+
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomView.h
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomView.m
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomViewFactory.h
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomViewFactory.m
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Bargraph.h
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Bargraph.m
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Button.h
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Button.m
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Knob.h
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Knob.m
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Slider.h
+perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Slider.m
+
+perl -pi -e 's/FaustAU_CustomView.h/'FaustAU_"$FILE_NAME"CustomView.h'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_CustomView.m/'FaustAU_"$FILE_NAME"CustomView.m'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_CustomViewFactory.h/'FaustAU_"$FILE_NAME"CustomViewFactory.h'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_CustomViewFactory.m/'FaustAU_"$FILE_NAME"CustomViewFactory.m'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Knob.h/'FaustAU_"$FILE_NAME"Knob.h'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Knob.m/'FaustAU_"$FILE_NAME"Knob.m'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Button.h/'FaustAU_"$FILE_NAME"Button.h'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Button.m/'FaustAU_"$FILE_NAME"Button.m'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Slider.h/'FaustAU_"$FILE_NAME"Slider.h'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Slider.m/'FaustAU_"$FILE_NAME"Slider.m'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Bargraph.h/'FaustAU_"$FILE_NAME"Bargraph.h'/g' FaustAU.xcodeproj/project.pbxproj
+perl -pi -e 's/FaustAU_Bargraph.m/'FaustAU_"$FILE_NAME"Bargraph.m'/g' FaustAU.xcodeproj/project.pbxproj
+
+
+mv Source/CocoaUI/FaustAU_CustomView.h Source/CocoaUI/FaustAU_"$FILE_NAME"CustomView.h
+mv Source/CocoaUI/FaustAU_CustomView.m Source/CocoaUI/FaustAU_"$FILE_NAME"CustomView.m
+mv Source/CocoaUI/FaustAU_CustomViewFactory.h Source/CocoaUI/FaustAU_"$FILE_NAME"CustomViewFactory.h
+mv Source/CocoaUI/FaustAU_CustomViewFactory.m Source/CocoaUI/FaustAU_"$FILE_NAME"CustomViewFactory.m
+mv Source/CocoaUI/FaustAU_Bargraph.h Source/CocoaUI/FaustAU_"$FILE_NAME"Bargraph.h
+mv Source/CocoaUI/FaustAU_Bargraph.m Source/CocoaUI/FaustAU_"$FILE_NAME"Bargraph.m
+mv Source/CocoaUI/FaustAU_Button.h Source/CocoaUI/FaustAU_"$FILE_NAME"Button.h
+mv Source/CocoaUI/FaustAU_Button.m Source/CocoaUI/FaustAU_"$FILE_NAME"Button.m
+mv Source/CocoaUI/FaustAU_Knob.h Source/CocoaUI/FaustAU_"$FILE_NAME"Knob.h
+mv Source/CocoaUI/FaustAU_Knob.m Source/CocoaUI/FaustAU_"$FILE_NAME"Knob.m
+mv Source/CocoaUI/FaustAU_Slider.h Source/CocoaUI/FaustAU_"$FILE_NAME"Slider.h
+mv Source/CocoaUI/FaustAU_Slider.m Source/CocoaUI/FaustAU_"$FILE_NAME"Slider.m
+
+
+xcodebuild ARCHS="i386 x86_64" HEADER_SEARCH_PATHS=$FINC CONFIGURATION_BUILD_DIR=$HOME/Library/Audio/Plug-Ins/Components > $PRINTDEV > ./build_errors.log
+
+if [ ! -d $AU_DIR/FaustAU.component/ ]
+then
+echo Unable to generate Audio Unit
+	cd ..
+	if [ $DEBUG -eq 0 ]; then
+	  rm -r $TEMP_DIR
+	fi
+	exit
+fi
+
+if [ -d $AU_DIR/"$FILE_NAME".component/ ]
+then
+    if [ $DEBUG -eq 0 ]; then
+	rm -r  $AU_DIR/"$FILE_NAME".component/
+    fi
+fi
+
+mv $AU_DIR/FaustAU.component $AU_DIR/"$FILE_NAME".component
+
+if [ -d $AU_DIR/FaustAUCustomView.bundle/ ]
+then
+    rm -r  $AU_DIR/FaustAUCustomView.bundle/
+fi
+
+cd ..
+if [ $DEBUG -eq 0 ]; then
+rm -r $TEMP_DIR
+fi
+
+echo "'$NAME'" Audio Unit generated and installed successfully
+
+if [ $DEBUG -eq 1 ]; then
+    echo "See $TEMP_DIR for build products"
+fi
+
+done
diff --git a/tools/faust2appls/faust2caqt b/tools/faust2appls/faust2caqt
index c14ebaf..3c0efdc 100755
--- a/tools/faust2appls/faust2caqt
+++ b/tools/faust2appls/faust2caqt
@@ -2,16 +2,18 @@
 
 #####################################################################
 #                                                                   #
-#               Compiles Faust programs to jack-qt                  #
-#               (c) Grame, 2009                                     #
+#               Compiles Faust programs to core audio-qt            #
+#               (c) Grame, 2012                                     #
 #                                                                   #
 #####################################################################
-PATH=$PATH:/usr/local/bin
-FAUST=faust
 
-OSCINC=""
-QTDEFS=""
-OSCLIB=""
+. faustpath
+. faustoptflags
+CXXFLAGS=$MYGCCFLAGS
+
+ARCHFILE="ca-qt.cpp"
+ARCHLIB="-L/usr/local/lib -L/opt/local/lib -framework CoreAudio -framework AudioUnit -framework CoreServices -framework CoreMIDI -framework CoreFoundation"
+PATH=$PATH:/usr/local/bin
 
 
 #-------------------------------------------------------------------
@@ -24,29 +26,55 @@ OSCLIB=""
 # PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
 # without having to configure CXX and CXXFLAGS
 for p in $@; do
-	if [ "$p" = "-icc" ]; then
-		CXX=icpc
-		CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2'
+	if [ "$p" = -icc ]; then
+		# we ignore -icc when compiling for QT
+		TOTO=""
+		#CXX=icpc
+		#CXXFLAGS='-Wfatal-errors -O3 -xT -ftz -fno-alias -fp-model fast=2'
     fi
 done
 
 #PHASE 2 : dispatch command arguments
+
+OSCINC=""
+QTDEFS=""
+OSCLIB=""
+
 for p in $@; do
+    if [ $p = "-help" ] || [ $p = "-h" ]; then
+        echo "faust2jaqt [-osc] [-http] [-poly] <file.dsp>"
+        echo "Use '-poly' to produce a polyphonic DSP, ready to be used with MIDI events"
+        echo "Use '-midi' to activate MIDI control"
+        echo "Use '-osc' to activate OSC control"
+        echo "Use '-http' to activate HTTP control"
+        echo "Use '-qrcode' to activate QR code generation"
+    fi
+    
     if [ "$p" = -omp ]; then
         if [[ $CXX == "icpc" ]]; then
             OMP="-openmp"
         else
             OMP="-fopenmp"
         fi
-    elif [ "$p" = -icc ]; then
+    fi
+  
+    if [ "$p" = -icc ]; then
     	ignore=" "
-	elif [ "$p" = "-osc" ]; then
-		OSCINC="INCLUDEPATH+=/usr/local/lib/faust/osclib"
-		QTDEFS="DEFINES += OSCCTRL"
-		OSCLIB="-L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+    elif [ $p = "-poly" ]; then
+        POLYDEFS="DEFINES += POLY"
+    elif [ $p = "-midi" ]; then
+        MIDIDEFS="DEFINES += MIDICTRL"
+    elif [ $p = "-osc" ]; then
+		 OSCDEFS="DEFINES += OSCCTRL"
+		 OSCLIBS="-lOSCFaust"
+	elif [ "$p" = "-httpd" ]; then
+		HTTPDEFS="DEFINES += HTTPCTRL"
+		HTTPLIBS="-lHTTPDFaust -lmicrohttpd -lqrencode"
+	elif [ "$p" = "-qrcode" ]; then # requires -httpd
+		QRDEFS="DEFINES += QRCODECTRL"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -59,7 +87,16 @@ done
 # Check darwin specifics
 #
 if [[ $(uname) == Darwin ]]; then
-    SPEC="-spec macx-g++ -Wnone"
+    SYS_VERSION=$(uname -v | cut -d : -f1 | cut -d. -f1 | cut -d' ' -f4)
+    CXXFLAGS+=" -D__MACOSX_CORE__"
+	if [ $SYS_VERSION -gt 12 ]
+	then
+	    SPEC="-spec macx-clang"
+	    CLANGOPT="CONFIG+=c++11"
+	else
+	    SPEC="-spec macx-g++"
+	    CLANGOPT=""
+	fi
     EXT=".app"
 fi
 
@@ -78,15 +115,15 @@ for p in $FILES; do
     mkdir "$TMP"
 
     # compile faust to c++
-	$FAUST -a ca-qt.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+	faust -i -a $ARCHFILE $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
 
     # compile c++ to binary
     (
 	    cd "$TMP"
-		qmake -project "INCLUDEPATH+=$CUR" "INCLUDEPATH+=/usr/local/lib/faust/" "$OSCINC" "LIBS+=-framework CoreAudio -framework AudioUnit -framework CoreServices $OSCLIB" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" "$QTDEFS"
-		qmake $SPEC
+	    qmake -project "QT += widgets printsupport network" "CONFIG+=warn_off" "$CLANGOPT" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=$FAUSTINC /opt/local/include" "QMAKE_CXXFLAGS= $CXXFLAGS -Wno-unused-parameter $FAUSTTOOLSFLAGS" "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "HEADERS+=$FAUSTINC/faust/gui/faustqt.h" "RESOURCES+= $FAUSTINC/faust/gui/Styles/Grey.qrc" "$OSCDEFS" "$HTTPDEFS" "$QRDEFS" "$POLYDEFS" "$MIDIDEFS" 
+	    qmake $SPEC
         make
-    ) > /dev/null #2>/dev/null
+    ) > /dev/null
 
     rm -rf "$SRCDIR/${f%.dsp}$EXT"
     cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
diff --git a/tools/faust2appls/faust2csound b/tools/faust2appls/faust2csound
index ffc3b5f..164165f 100755
--- a/tools/faust2appls/faust2csound
+++ b/tools/faust2appls/faust2csound
@@ -17,6 +17,18 @@
 
 # PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
 # without having to configure CXX and CXXFLAGS
+
+PATH=$PATH:/usr/local/bin
+
+if [[ $(uname) == Darwin ]]; then
+    LIB="-I/Library/Frameworks/CsoundLib64.framework/Headers -I/usr/local/include -framework CsoundLib64 -L/usr/local/lib -dynamiclib"
+    EXT=".dylib"
+else
+    LIB="-I/usr/include/csound -shared -fPIC"
+    EXT=".so"
+fi
+
+
 for p in $@; do
 	if [ "$p" = -icc ]; then
 		CXX=icpc
@@ -36,9 +48,13 @@ for p in $@; do
   
     if [ "$p" = -icc ]; then
     	ignore=" "
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -51,11 +67,12 @@ done
 #
 for SRC in $FILES; do
 	opname=`basename ${SRC%.dsp}`
-    faust  -uim -double -a csound.cpp $OPTIONS "$SRC" -o "$SRC.cpp"
-    ${CXX=g++} ${CXXFLAGS=-O3} $OMP -I/usr/include/csound -shared -fPIC -DOPCODE_NAME=$opname "$SRC.cpp" -o "${SRC%.dsp}.dylib"
+    faust  -i -uim -double -a csound.cpp $OPTIONS "$SRC" -o "$SRC.cpp"
+    ${CXX=g++} ${CXXFLAGS=-O3} $FAUSTTOOLSFLAGS  $OMP $LIB -DOPCODE_NAME=$opname "$SRC.cpp" -o "${SRC%.dsp}""$EXT"
     rm "$SRC.cpp"
-    BINARIES="$BINARIES${SRC%.dsp}.dylib;"
+    BINARIES="$BINARIES${SRC%.dsp}""$EXT;"
 done
 
 # return the binaries names
 echo "$BINARIES"
+
diff --git a/tools/faust2appls/faust2dssi b/tools/faust2appls/faust2dssi
index 6bb87ad..f6bb1d1 100755
--- a/tools/faust2appls/faust2dssi
+++ b/tools/faust2appls/faust2dssi
@@ -16,6 +16,8 @@ OSCDEFS=""
 # existing *.dsp files          -> FILES
 #
 
+CXXFLAGS="-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
+
 # PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
 # without having to configure CXX and CXXFLAGS
 for p in $@; do
@@ -37,12 +39,16 @@ for p in $@; do
   
     if [ "$p" = -icc ]; then
     	ignore=" "
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ $p = "-osc" ]; then
     	#option ignored for dssi plugins
-		 OSCDEFS="-I/usr/local/lib/faust/osclib -DOSCCTRL -L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+		 OSCDEFS="-DOSCCTRL -lOSCFaust"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -72,11 +78,11 @@ for f in $FILES; do
 	dst="${f%.dsp}.so"
 	
 	# compile faust to c++
-	faust -a dssi.cpp $OPTIONS "$f" -o "$f.cpp"
+	faust -i -a dssi.cpp $OPTIONS "$f" -o "$f.cpp"
 
 	# compile c++ to binary
 	(
-		${CXX=g++} -I. -Wall -O2 -fPIC -DPIC $SPEC $CXXFLAGS "$f.cpp" -o $dst
+		${CXX=g++} $FAUSTTOOLSFLAGS  -I. -Wall -O2 -fPIC -DPIC $PROCARCH $SPEC $CXXFLAGS "$f.cpp" -o $dst
 	) > /dev/null
 	rm "$f.cpp"
 
diff --git a/tools/faust2appls/faust2graph b/tools/faust2appls/faust2graph
index 19f2575..6bea4fe 100755
--- a/tools/faust2appls/faust2graph
+++ b/tools/faust2appls/faust2graph
@@ -1,7 +1,26 @@
-#!/bin/bash
-for f in $@; do
+#! /bin/bash -e
+
+#  usage : faust2sig foo.dsp        -> foo-sig.pdf
+#  usage : faust2sig -svg foo.dsp   -> foo-sig.svg
+
+FILES=""
+IGNORE=""
+FORMAT="pdf"
+
+# Analyze command line
+for p in $@; do
+    if [ "$p" = -svg ]; then
+        FORMAT="svg"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    IGNORE="$IGNORE $p"
+	fi
+done
+
+
+for f in $FILES; do
     faust -vec -tg $f -o /dev/null
-	dot -Tpdf $f.dot -o $f.graph.pdf
+	dot -T$FORMAT $f.dot -o $f.graph.$FORMAT
 	rm $f.dot
 done
-
diff --git a/tools/faust2appls/faust2ios b/tools/faust2appls/faust2ios
new file mode 100755
index 0000000..e288b79
--- /dev/null
+++ b/tools/faust2appls/faust2ios
@@ -0,0 +1,112 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to iOS applications         #
+#               (c) Grame, 2012-2013                                #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+#PHASE 1 : collects files and options from the command line
+
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+
+    if [ "$p" = -icc ]; then
+        ignore=" "
+    elif [ $p = "-osc" ]; then
+        OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ "$p" = "-httpd" ]; then
+        HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ "$p" = "-jack" ]; then
+        JACK="1"
+    elif [ "$p" = "-xcode" ]; then
+        XCODE="1"
+    elif [ "$p" = "-all" ]; then
+        ALL="1"
+    elif [ "$p" = "-noagc" ]; then
+        NOAGC="1"
+    elif [ ${p:0:1} = "-" ]; then
+        OPTIONS="$OPTIONS $p"
+    elif [[ -f "$p" ]]; then
+        FILES="$FILES $p"
+    else
+        OPTIONS="$OPTIONS $p"
+    fi
+done
+
+
+#PHASE 2 : compile all files
+
+for p in $FILES; do
+	S=$(dirname "$p")
+	F=$(basename "$p")
+	P=${F%.dsp}
+
+	T=$(mktemp -d faust.XXX)
+	cp -r /usr/local/lib/faust/iOS/* $T
+	cp -r /usr/local/include/faust $T
+
+	if [ "$JACK" = "1" ]; then
+	   #echo "Compile with JACK/CoreAudio support"
+	   faust -i $OPTIONS -a ios-coreaudio-jack.cpp "$p" -o "$T/ios-faust.h"
+	   (
+		xcodebuild -project "$T/iOS.xcodeproj" -target Template_Jack PRODUCT_NAME=$P
+        cd "$T" && xcodebuild -scheme Template_Jack archive PRODUCT_NAME=$P
+	   ) > /dev/null
+    elif [ "$NOAGC" = "1" ]; then
+        if [ "$ALL" = "1" ]; then
+            echo "Compile with CoreAudio support in 64/32 bits and no AGC"
+            faust -i $OPTIONS -a ios-coreaudio.cpp "$p" -o "$T/ios-faust.h"
+            (
+                xcodebuild GCC_PREPROCESSOR_DEFINITIONS='${inherited} DISABLE_AGC=1' -project "$T/iOS.xcodeproj" -target Template_CoreAudio PRODUCT_NAME=$P
+                cd "$T" && xcodebuild -scheme Template_CoreAudio archive PRODUCT_NAME=$P
+            ) > /dev/null
+        else
+            echo "Compile with CoreAudio support in 32 bits and no AGC"
+            faust -i $OPTIONS -a ios-coreaudio.cpp "$p" -o "$T/ios-faust.h"
+            (
+                xcodebuild GCC_PREPROCESSOR_DEFINITIONS='${inherited} DISABLE_AGC=1' -project "$T/iOS.xcodeproj" -target Template_CoreAudio_32bits PRODUCT_NAME=$P
+                cd "$T" && xcodebuild -scheme Template_CoreAudio_32bits archive PRODUCT_NAME=$P
+            ) > /dev/null
+        fi
+    else
+        if [ "$ALL" = "1" ]; then
+            echo "Compile with CoreAudio support in 64/32 bits and AGC"
+            faust -i $OPTIONS -a ios-coreaudio.cpp "$p" -o "$T/ios-faust.h"
+            (
+                xcodebuild  -project "$T/iOS.xcodeproj" -target Template_CoreAudio PRODUCT_NAME=$P
+                cd "$T" && xcodebuild -scheme Template_CoreAudio archive PRODUCT_NAME=$P
+            ) > /dev/null
+        else
+            echo "Compile with CoreAudio support in 32 bits and AGC"
+            faust -i $OPTIONS -a ios-coreaudio.cpp "$p" -o "$T/ios-faust.h"
+            (
+                xcodebuild -project "$T/iOS.xcodeproj" -target Template_CoreAudio_32bits PRODUCT_NAME=$P
+                cd "$T" && xcodebuild -scheme Template_CoreAudio_32bits archive PRODUCT_NAME=$P
+            ) > /dev/null
+        fi
+	fi
+    
+    # move generated app to source directory
+    rm -rf "$S/$P.app"
+    mv "$T/build/Release-iphoneos/$P.app" "$S/"
+    if [ "$XCODE" != "1" ]; then
+        rm -rf "$T"
+    else
+        echo "Keep Xcode project"
+    fi
+        
+	# collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$S/$P.app;"
+done
+
+echo $BINARIES
diff --git a/tools/faust2appls/faust2jack b/tools/faust2appls/faust2jack
index b1358b7..1359f68 100755
--- a/tools/faust2appls/faust2jack
+++ b/tools/faust2appls/faust2jack
@@ -9,6 +9,23 @@ OSCDEFS=""
 #####################################################################
 
 #-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust/
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust/
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+
+#-------------------------------------------------------------------
 # Check darwin specifics
 #
 if [[ $(uname) == Darwin ]]; then
@@ -41,7 +58,7 @@ for p in $@; do
 		CXXFLAGS=$MYICCFLAGS
     fi
 done
-
+	
 
 #PHASE 2 : dispatch command arguments
 for p in $@; do
@@ -56,10 +73,19 @@ for p in $@; do
     if [ "$p" = -icc ]; then
     	ignore=" "
     elif [ $p = "-osc" ]; then
-		 OSCDEFS="-I/usr/local/lib/faust/osclib -DOSCCTRL -L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+	 OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+	elif [ $p = "-ocv" ]; then
+	 OCVDEFS="-DOCVCTRL -lpthread"
+	 OCVLIBS="opencv"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -67,19 +93,17 @@ for p in $@; do
 done
 
 
-
-	
 #-------------------------------------------------------------------
 # compile the *.dsp files using JACK-GTK on linux
 #
 for f in $FILES; do
 	
 	# compile faust to c++
-	faust -a jack-gtk.cpp $OPTIONS "$f" -o "$f.cpp"
+	faust -i -a jack-gtk.cpp $OPTIONS "$f" -o "$f.cpp"
 
 	# compile c++ to binary
 	(
-		$CXX $CXXFLAGS $OMP -I/usr/local/lib/faust "$f.cpp" `pkg-config --cflags --libs jack gtk+-2.0` $OSCDEFS -o "${f%.dsp}"
+		$CXX $CXXFLAGS $FAUSTTOOLSFLAGS $OMP "$f.cpp" `pkg-config --cflags --libs jack $OCVLIBS gtk+-2.0` $PROCARCH $OSCDEFS $HTTPDEFS $OCVDEFS -o "${f%.dsp}"
 	) > /dev/null
 	rm "$f.cpp"
 
diff --git a/tools/faust2appls/faust2jackconsole b/tools/faust2appls/faust2jackconsole
new file mode 100755
index 0000000..f845d20
--- /dev/null
+++ b/tools/faust2appls/faust2jackconsole
@@ -0,0 +1,87 @@
+#!/bin/bash
+
+OSCDEFS=""
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to alsa-gtk                 #
+#               (c) Grame, 2009-2011                                #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+. faustoptflags
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+CXX=g++
+CXXFLAGS=$MYGCCFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		CXX=icpc
+		CXXFLAGS=$MYICCFLAGS
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -lOSCFaust -lpthread"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+	
+#-------------------------------------------------------------------
+# compile the *.dsp files using ALSA and GTK on linux
+#
+for f in $FILES; do
+	
+	# compile faust to c++
+	faust -i -a jack-console.cpp $OPTIONS "$f" -o "$f.cpp"
+
+	# compile c++ to binary
+	(
+		$CXX $CXXFLAGS $FAUSTTOOLSFLAGS $OMP "$f.cpp" -I/usr/local/include -L/usr/local/lib -ljack $PROCARCH $OSCDEFS $HTTPDEFS -o "${f%.dsp}"
+	) > /dev/null
+	rm "$f.cpp"
+
+	# collect binary file name for FaustWorks
+	BINARIES="$BINARIES${f%.dsp};"
+done
+
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2jackinternal b/tools/faust2appls/faust2jackinternal
index 0dfee28..fe058c0 100755
--- a/tools/faust2appls/faust2jackinternal
+++ b/tools/faust2appls/faust2jackinternal
@@ -3,15 +3,15 @@
 if [[ $(uname) == Darwin ]]; then
 	#On Darwin build a Jack internal client
 	for f in $@; do
-		faust -a jack-internal.cpp $f -o $f.cpp
-		${CXX=g++} ${CXXFLAGS=-O3} `pkg-config --cflags jack` $f.cpp -ljackserver -fPIC -bundle -o ${f%.dsp}.so
+		faust -i -a jack-internal.cpp $f -o $f.cpp
+		${CXX=g++} ${CXXFLAGS=-O3} $FAUSTTOOLSFLAGS `pkg-config --cflags jack` $f.cpp -I/usr/local/include -L/usr/local/lib -ljackserver -fPIC -bundle -o ${f%.dsp}.so
 	done
 
 else
 	#On Linux build a Jack internal client 
 	for f in $@; do
-		faust -a jack-gtk.cpp $f -o $f.cpp
-		${CXX=g++} ${CXXFLAGS=-O3} `pkg-config --cflags jack` $f.cpp  -ljackserver -fPIC -shared -o ${f%.dsp}.so
+		faust -i -a jack-internal.cpp $f -o $f.cpp
+		${CXX=g++} ${CXXFLAGS=-O3} $FAUSTTOOLSFLAGS `pkg-config --cflags jack` $f.cpp  -ljackserver -fPIC -shared -o ${f%.dsp}.so
 	done
 
 fi
diff --git a/tools/faust2appls/faust2jackserver b/tools/faust2appls/faust2jackserver
index fdf1fdd..08da49d 100755
--- a/tools/faust2appls/faust2jackserver
+++ b/tools/faust2appls/faust2jackserver
@@ -1,34 +1,120 @@
 #!/bin/bash
 
-if [[ $(uname) == Darwin ]]; then
-	#On Darwin build a Jack QT4 application using xcode
-	for f in $@; do
-	
-		CUR=$(pwd)
-		TMP=/var/tmp/${f%.dsp}
-	
-		rm -rf $TMP
-		install -d $TMP
-		
-		faust -a jack-qt.cpp $f -o $TMP/${f%.dsp}.cpp
-		
-		cd $TMP; qmake -project "INCLUDEPATH+=$CUR" "INCLUDEPATH+=/usr/local/lib/faust/" "LIBS+=-ljackserver" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" 
-		cd $TMP; qmake
-		echo toto
-		cd $TMP; xcodebuild -project ${f%.dsp}.xcodeproj
-		echo titi
-		cd $CUR; rm -rf ${f%.dsp}.app
-		cd $CUR; mv $TMP/build/Default/${f%.dsp}.app ${f%.dsp}.app
-		rm -rf $TMP
-		
-	done
-
-
-else
-	#On Linux (default) build a jack gtk application
-	for f in $@; do
-		faust -a jack-gtk.cpp $f -o $f.cpp
-		${CXX=g++} ${CXXFLAGS=-O3} `pkg-config --cflags --libs jack gtk+-2.0` $f.cpp -o ${f%.dsp}
-	done
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to jack-qt  (server mode)   #
+#               (c) Grame, 2014                                     #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+ARCHFILE="jack-qt.cpp"
+ARCHLIB="-L/usr/local/lib -ljackserver"
+PATH=$PATH:/usr/local/bin
+
+#-------------------------------------------------------------------------------
+# Search for qmake or qmake-qt4
+
+QMAKE=$(which qmake-qt4 || echo qmake) 
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+CXXFLAGS='-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math'
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		# we ignore -icc when compiling for QT
+		TOTO=""
+		#CXX=icpc
+		#CXXFLAGS='-Wfatal-errors -O3 -xT -ftz -fno-alias -fp-model fast=2'
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+
+OSCINC=""
+QTDEFS=""
+OSCLIB=""
+
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+		 OSCDEFS="DEFINES += OSCCTRL"
+		 OSCLIBS="-lOSCFaust"
+	elif [ "$p" = "-httpd" ]; then
+		HTTPDEFS="DEFINES += HTTPCTRL"
+		HTTPLIBS="-lHTTPDFaust -lmicrohttpd -lqrencode"
+	elif [ "$p" = "-qrcode" ]; then # requires -httpd
+		QRDEFS="DEFINES += QRCODECTRL"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
 
+
+#-------------------------------------------------------------------
+# Check darwin specifics
+#
+if [[ $(uname) == Darwin ]]; then
+    SPEC="-spec macx-g++"
+    EXT=".app"
 fi
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+	faust -i -a $ARCHFILE $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+	    cd "$TMP"
+	    $QMAKE -project "QT += widgets printsupport network" "CONFIG+=warn_off" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=$FAUSTINC" "QMAKE_CXXFLAGS=$CXXFLAGS -Wno-unused-parameter $FAUSTTOOLSFLAGS" "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "HEADERS+=$FAUSTINC/faust/gui/faustqt.h" "$OSCDEFS" "$HTTPDEFS" "$QRDEFS"   
+	    $QMAKE $SPEC
+        make
+    ) > /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+    cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2jaqt b/tools/faust2appls/faust2jaqt
index 2163e60..edac4b6 100755
--- a/tools/faust2appls/faust2jaqt
+++ b/tools/faust2appls/faust2jaqt
@@ -7,10 +7,16 @@
 #                                                                   #
 #####################################################################
 
-OSCINC=""
-QTDEFS=""
-OSCLIB=""
+. faustpath
+
+ARCHFILE="jack-qt.cpp"
+ARCHLIB="-L/usr/local/lib -ljack"
+PATH=$PATH:/usr/local/bin
+
+#-------------------------------------------------------------------------------
+# Search for qmake or qmake-qt4
 
+QMAKE=$(which qmake-qt4 || echo qmake) 
 
 #-------------------------------------------------------------------
 # Analyze command arguments :
@@ -19,17 +25,35 @@ OSCLIB=""
 # existing *.dsp files          -> FILES
 #
 
+CXXFLAGS='-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math'
+
 # PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
 # without having to configure CXX and CXXFLAGS
 for p in $@; do
 	if [ "$p" = -icc ]; then
-		CXX=icpc
-		CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2'
+		# we ignore -icc when compiling for QT
+		TOTO=""
+		#CXX=icpc
+		#CXXFLAGS='-Wfatal-errors -O3 -xT -ftz -fno-alias -fp-model fast=2'
     fi
 done
 
 #PHASE 2 : dispatch command arguments
+
+OSCINC=""
+QTDEFS=""
+OSCLIB=""
+
 for p in $@; do
+    if [ $p = "-help" ] || [ $p = "-h" ]; then
+        echo "faust2jaqt [-osc] [-http] [-poly] <file.dsp>"
+        echo "Use '-poly' to produce a polyphonic DSP, ready to be used with MIDI events"
+        echo "Use '-midi' to activate MIDI control"
+        echo "Use '-osc' to activate OSC control"
+        echo "Use '-http' to activate HTTP control"
+        echo "Use '-qrcode' to activate QR code generation"
+    fi
+    
     if [ "$p" = -omp ]; then
         if [[ $CXX == "icpc" ]]; then
             OMP="-openmp"
@@ -40,26 +64,42 @@ for p in $@; do
   
     if [ "$p" = -icc ]; then
     	ignore=" "
+    elif [ $p = "-poly" ]; then
+        POLYDEFS="DEFINES += POLY"
+    elif [ $p = "-midi" ]; then
+        MIDIDEFS="DEFINES += MIDICTRL"
     elif [ $p = "-osc" ]; then
-		 OSCINC="INCLUDEPATH+=/usr/local/lib/faust/osclib"
-		 QTDEFS="DEFINES += OSCCTRL"
-		 OSCLIB="-L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+        OSCDEFS="DEFINES += OSCCTRL"
+        OSCLIBS="-lOSCFaust"
+	elif [ "$p" = "-httpd" ]; then
+		HTTPDEFS="DEFINES += HTTPCTRL"
+		HTTPLIBS="-lHTTPDFaust -lmicrohttpd -lqrencode"
+	elif [ "$p" = "-qrcode" ]; then # requires -httpd
+		QRDEFS="DEFINES += QRCODECTRL"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
-	else
+    else
 	    OPTIONS="$OPTIONS $p"        
 	fi
 done
 
-
-
 #-------------------------------------------------------------------
 # Check darwin specifics
 #
 if [[ $(uname) == Darwin ]]; then
-    SPEC="-spec macx-g++"
+    ARCHLIB+=" -framework CoreMIDI -framework CoreFoundation -framework CoreAudio"
+    CXXFLAGS+=" -D__MACOSX_CORE__"
+    SYS_VERSION=$(uname -v | cut -d : -f1 | cut -d. -f1 | cut -d' ' -f4)
+	if [ $SYS_VERSION -gt 12 ]
+	then
+	    SPEC="-spec macx-clang"
+	    CLANGOPT="CONFIG+=c++11"
+	else
+	    SPEC="-spec macx-g++"
+	    CLANGOPT=""
+	fi
     EXT=".app"
 fi
 
@@ -78,13 +118,13 @@ for p in $FILES; do
     mkdir "$TMP"
 
     # compile faust to c++
-	faust -a jack-qt.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
-
+ 	faust -i -a $ARCHFILE $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+  
     # compile c++ to binary
     (
 	    cd "$TMP"
-        qmake -project "INCLUDEPATH+=$CUR" "INCLUDEPATH+=/usr/local/lib/faust/" "$OSCINC" "LIBS+=-ljack $OSCLIB" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" "$QTDEFS"
-	    qmake $SPEC
+	    $QMAKE -project "QT += widgets printsupport network" "CONFIG+=warn_off" "$CLANGOPT" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=$FAUSTINC" "QMAKE_CXXFLAGS=$CXXFLAGS -Wno-unused-parameter $FAUSTTOOLSFLAGS" "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "HEADERS+=$FAUSTINC/faust/gui/faustqt.h" "RESOURCES+= $FAUSTINC/faust/gui/Styles/Grey.qrc"  "$OSCDEFS" "$HTTPDEFS" "$QRDEFS" "$POLYDEFS" "$MIDIDEFS" 
+	    $QMAKE $SPEC
         make
     ) > /dev/null
 
diff --git a/tools/faust2appls/faust2ladspa b/tools/faust2appls/faust2ladspa
index 3c4bab0..610d2ce 100755
--- a/tools/faust2appls/faust2ladspa
+++ b/tools/faust2appls/faust2ladspa
@@ -29,7 +29,7 @@ fi
 # PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
 # without having to configure CXX and CXXFLAGS
 
-CXXFLAGS='-O3 $MARCH -mfpmath=sse -msse -msse2 -msse3 -ffast-math' 
+CXXFLAGS="-O3 $MARCH -mfpmath=sse -msse -msse2 -msse3 -ffast-math" 
 
 for p in $@; do
 	if [ "$p" = -icc ]; then
@@ -50,12 +50,13 @@ for p in $@; do
   
     if [ "$p" = -icc ]; then
     	ignore=" "
-    elif [ $p = "-osc" ]; then
-    	#option ignored for plugins
-		OSCDEFS="-I/usr/local/lib/faust/osclib -DOSCCTRL -L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -86,13 +87,13 @@ for f in $FILES; do
 	module=`basename $f .dsp`
 	
 	# compile faust to c++
-	faust -a ladspa.cpp $OPTIONS "$f" -o "$f.cpp"
+	faust -i -a ladspa.cpp $OPTIONS "$f" -o "$f.cpp"
 
 	# compile c++ to binary
 	(
-		${CXX=g++} $CXXFLAGS $SPEC -Dmydsp=$module -I/usr/local/lib/faust "$f.cpp" -o $dst
-	) #> /dev/null
-	#rm "$f.cpp"
+		${CXX=g++} $CXXFLAGS $FAUSTTOOLSFLAGS $PROCARCH $SPEC -Dmydsp=$module -I/usr/local/lib/faust "$f.cpp" -o $dst
+	) > /dev/null
+	rm "$f.cpp"
 
 	# collect binary file name for FaustGIDE
 	BINARIES="$BINARIES$dst;"
diff --git a/tools/faust2appls/faust2lv2 b/tools/faust2appls/faust2lv2
new file mode 100755
index 0000000..ff46916
--- /dev/null
+++ b/tools/faust2appls/faust2lv2
@@ -0,0 +1,163 @@
+#! /bin/bash
+
+#set -x
+
+# defaults (these can be changed with the options listed below)
+URI_PREFIX=http://faust-lv2.googlecode.com
+FAUST_META=1
+FAUST_MIDICC=1
+
+PROCARCH="-fPIC"
+CXXFLAGS="-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
+
+# We recognize the following special options here:
+# -nometa: ignore metadata (author information etc.) from the Faust source
+# -nomidicc: plugin doesn't process MIDI control data
+# -dyn-manifest: use dynamic manifests (requires LV2 host support)
+# -uri-prefix URI: URI prefix of plugin (arg must be a valid URI)
+
+for ((i=1;i<$#+1;i++)); do
+    p=${!i}
+    if [ $p = "-omp" ]; then
+    	: ignore
+    elif [ $p = "-icc" ]; then
+	CXX=icpc
+    	CXXFLAGS="-O3 -xHost -ftz -fno-alias -fp-model fast=2"
+    elif [ $p = "-osc" ]; then
+    	: ignore
+    elif [ $p = "-httpd" ]; then
+    	: ignore
+    elif [ $p = "-nometa" ]; then
+    	FAUST_META=0
+    elif [ $p = "-nomidicc" ]; then
+    	FAUST_MIDICC=0
+    elif [ $p = "-dyn-manifest" ]; then
+    	dyn_manifest=yes
+    elif [ $p = "-uri-prefix" ]; then
+	(( i++ ))
+    	URI_PREFIX=${!i}
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64 -fPIC"
+    elif [ ${p:0:1} = "-" ]; then
+	OPTIONS="$OPTIONS $p"
+    elif [[ -f "$p" ]]; then
+	FILES="$FILES $p"
+    else
+	OPTIONS="$OPTIONS $p"
+    fi
+done
+
+FILES=( $FILES )
+if [ ${#FILES[@]} = 0 ]; then
+    echo "$0: no filename specified" >&2
+    exit 1
+elif [ ${#FILES[@]} -gt 1 ]; then
+    echo "$0: multiple filenames specified" >&2
+    exit 1
+fi
+
+arch=lv2.cpp
+dspname=${FILES[0]}
+SRCDIR=$(dirname "$dspname")
+
+clsname=`basename "$dspname" .dsp`
+cppname="$clsname.cpp"
+soname="$clsname.so"
+lv2name="$clsname.lv2"
+tmpdir=`mktemp -d`
+
+CXX=g++
+CPPFLAGS="-DPLUGIN_URI=\"$URI_PREFIX/$clsname\" -DFAUST_META=$FAUST_META -DFAUST_MIDICC=$FAUST_MIDICC"
+
+# Create the temp directory and the bundle directory inside it.
+mkdir -p $tmpdir/$lv2name
+# Compile the Faust module.
+faust -i -a $arch -cn "$clsname" $OPTIONS "$dspname" -o "$tmpdir/$cppname"
+$CXX -shared $CXXFLAGS $PROCARCH $CPPFLAGS  $FAUSTTOOLSFLAGS "$tmpdir/$cppname" -o "$tmpdir/$lv2name/$soname"
+# Generate the manifest.
+if [ -n "$dyn_manifest" ]; then
+# Use a dynamic manifest.
+sed -e"s?@name@?$clsname?g" -e"s?@uri@?$URI_PREFIX/$clsname?g" -e"s?@dllext@?.so?g" > "$tmpdir/$lv2name/manifest.ttl" <<EOF
+
+########## @uri@ ##########
+
+ at prefix doap: <http://usefulinc.com/ns/doap#> .
+ at prefix foaf: <http://xmlns.com/foaf/0.1/> .
+ at prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+ at prefix dman: <http://lv2plug.in/ns/ext/dynmanifest#> .
+
+<@uri@/manifest>
+    lv2:binary <@name@@dllext@> ;
+    a dman:DynManifest .
+
+# Here's how you can declare the category of the plugin. (For lv2synth.cpp
+# instances, the lv2:InstrumentPlugin type will be added automatically.) See
+# http://lv2plug.in/ns/lv2core/ for a list of known plugin classes.
+
+# <@uri@> a lv2:FilterPlugin .
+
+# You might also want to set the license and author information below.
+# NOTE: This isn't normally necessary if you declared the corresponding
+# information as metadata in the Faust source of the plugin. The standard
+# author, license and description fields in the Faust source are automagically
+# included in the generated LV2 manifest.
+
+# <@uri@>
+#     doap:license <http://opensource.org/licenses/isc> ;
+#     doap:maintainer [
+#         foaf:name "Your Name Here" ;
+#         foaf:homepage <http://somewhere.org/> ;
+#         foaf:mbox <mailto:your at mail.here> ;
+#     ] .
+EOF
+else
+# Use a static manifest.
+sed -e"s?@name@?$clsname?g" -e"s?@uri@?$URI_PREFIX/$clsname?g" -e"s?@dllext@?.so?g" > "$tmpdir/$lv2name/manifest.ttl" <<EOF
+
+########## @uri@ ##########
+
+ at prefix doap: <http://usefulinc.com/ns/doap#> .
+ at prefix foaf: <http://xmlns.com/foaf/0.1/> .
+ at prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+ at prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<@uri@>
+    a lv2:Plugin ;
+    lv2:binary <@name@@dllext@> ;
+    rdfs:seeAlso <@name at .ttl> .
+
+# Here's how you can declare the category of the plugin. (For lv2synth.cpp
+# instances, the lv2:InstrumentPlugin type will be added automatically.) See
+# http://lv2plug.in/ns/lv2core/ for a list of known plugin classes.
+
+# <@uri@> a lv2:FilterPlugin .
+
+# You might also want to set the license and author information below.
+# NOTE: This isn't normally necessary if you declared the corresponding
+# information as metadata in the Faust source of the plugin. The standard
+# author, license and description fields in the Faust source are automagically
+# included in the generated LV2 manifest.
+
+# <@uri@>
+#     doap:license <http://opensource.org/licenses/isc> ;
+#     doap:maintainer [
+#         foaf:name "Your Name Here" ;
+#         foaf:homepage <http://somewhere.org/> ;
+#         foaf:mbox <mailto:your at mail.here> ;
+#     ] .
+EOF
+# This compiles the plugin to an executable which is run to generate the
+# plugin-specific part of the manifest.
+$CXX $CXXFLAGS $CPPFLAGS  $FAUSTTOOLSFLAGS "$tmpdir/$cppname" -o "$tmpdir/$clsname"
+"$tmpdir/$clsname" > "$tmpdir/$lv2name/$clsname.ttl"
+rm -f "$tmpdir/$clsname"
+fi
+# copy down the bundle
+rm -rf "$SRCDIR/$lv2name"
+cp -r "$tmpdir/$lv2name" "$SRCDIR"
+# Clean up.
+rm -rf $tmpdir
+# Print the name of the generated bundle zip file.
+echo "$SRCDIR/$lv2name;"
diff --git a/tools/faust2appls/faust2lv2synth b/tools/faust2appls/faust2lv2synth
new file mode 100755
index 0000000..6b98e24
--- /dev/null
+++ b/tools/faust2appls/faust2lv2synth
@@ -0,0 +1,170 @@
+#! /bin/bash
+
+#set -x
+
+# defaults (these can be changed with the options listed below)
+URI_PREFIX=http://faust-lv2.googlecode.com
+FAUST_META=1
+FAUST_MIDICC=1
+NVOICES=16
+
+PROCARCH="-fPIC"
+CXXFLAGS="-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
+
+# We recognize the following special options here:
+# -nometa: ignore metadata (author information etc.) from the Faust source
+# -nomidicc: plugin doesn't process MIDI control data
+# -nvoices N: number of synth voices of the plugin (arg must be an integer)
+# -dyn-manifest: use dynamic manifests (requires LV2 host support)
+# -uri-prefix URI: URI prefix of plugin (arg must be a valid URI)
+
+for ((i=1;i<$#+1;i++)); do
+    p=${!i}
+    if [ $p = "-omp" ]; then
+    	: ignore
+    elif [ $p = "-icc" ]; then
+	CXX=icpc
+    	CXXFLAGS="-O3 -xHost -ftz -fno-alias -fp-model fast=2"
+    elif [ $p = "-osc" ]; then
+    	: ignore
+    elif [ $p = "-httpd" ]; then
+    	: ignore
+    elif [ $p = "-nometa" ]; then
+    	FAUST_META=0
+    elif [ $p = "-nomidicc" ]; then
+    	FAUST_MIDICC=0
+    elif [ $p = "-dyn-manifest" ]; then
+    	dyn_manifest=yes
+    elif [ $p = "-uri-prefix" ]; then
+	(( i++ ))
+    	URI_PREFIX=${!i}
+    elif [ $p = "-nvoices" ]; then
+	(( i++ ))
+    	NVOICES=${!i}
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64 -fPIC"
+    elif [ ${p:0:1} = "-" ]; then
+	OPTIONS="$OPTIONS $p"
+    elif [[ -f "$p" ]]; then
+	FILES="$FILES $p"
+    else
+	OPTIONS="$OPTIONS $p"
+    fi
+done
+
+FILES=( $FILES )
+if [ ${#FILES[@]} = 0 ]; then
+    echo "$0: no filename specified" >&2
+    exit 1
+elif [ ${#FILES[@]} -gt 1 ]; then
+    echo "$0: multiple filenames specified" >&2
+    exit 1
+fi
+
+arch=lv2synth.cpp
+dspname=${FILES[0]}
+SRCDIR=$(dirname "$dspname")
+
+clsname=`basename "$dspname" .dsp`
+cppname="$clsname.cpp"
+soname="$clsname.so"
+lv2name="$clsname.lv2"
+tmpdir=`mktemp -d`
+
+CXX=g++
+CPPFLAGS="-DPLUGIN_URI=\"$URI_PREFIX/$clsname\" -DFAUST_META=$FAUST_META -DFAUST_MIDICC=$FAUST_MIDICC -DNVOICES=$NVOICES"
+
+# Create the temp directory and the bundle directory inside it.
+mkdir -p $tmpdir/$lv2name
+# Compile the Faust module.
+faust -i -a $arch -cn "$clsname" $OPTIONS "$dspname" -o "$tmpdir/$cppname"
+$CXX -shared $CXXFLAGS $FAUSTTOOLSFLAGS $PROCARCH $CPPFLAGS "$tmpdir/$cppname" -o "$tmpdir/$lv2name/$soname"
+# Generate the manifest.
+if [ -n "$dyn_manifest" ]; then
+# Use a dynamic manifest.
+sed -e"s?@name@?$clsname?g" -e"s?@uri@?$URI_PREFIX/$clsname?g" -e"s?@dllext@?.so?g" > "$tmpdir/$lv2name/manifest.ttl" <<EOF
+
+########## @uri@ ##########
+
+ at prefix doap: <http://usefulinc.com/ns/doap#> .
+ at prefix foaf: <http://xmlns.com/foaf/0.1/> .
+ at prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+ at prefix dman: <http://lv2plug.in/ns/ext/dynmanifest#> .
+
+<@uri@/manifest>
+    lv2:binary <@name@@dllext@> ;
+    a dman:DynManifest .
+
+# Here's how you can declare the category of the plugin. (For lv2synth.cpp
+# instances, the lv2:InstrumentPlugin type will be added automatically.) See
+# http://lv2plug.in/ns/lv2core/ for a list of known plugin classes.
+
+# <@uri@> a lv2:FilterPlugin .
+
+# You might also want to set the license and author information below.
+# NOTE: This isn't normally necessary if you declared the corresponding
+# information as metadata in the Faust source of the plugin. The standard
+# author, license and description fields in the Faust source are automagically
+# included in the generated LV2 manifest.
+
+# <@uri@>
+#     doap:license <http://opensource.org/licenses/isc> ;
+#     doap:maintainer [
+#         foaf:name "Your Name Here" ;
+#         foaf:homepage <http://somewhere.org/> ;
+#         foaf:mbox <mailto:your at mail.here> ;
+#     ] .
+EOF
+else
+# Use a static manifest.
+sed -e"s?@name@?$clsname?g" -e"s?@uri@?$URI_PREFIX/$clsname?g" -e"s?@dllext@?.so?g" > "$tmpdir/$lv2name/manifest.ttl" <<EOF
+
+########## @uri@ ##########
+
+ at prefix doap: <http://usefulinc.com/ns/doap#> .
+ at prefix foaf: <http://xmlns.com/foaf/0.1/> .
+ at prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+ at prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<@uri@>
+    a lv2:Plugin ;
+    lv2:binary <@name@@dllext@> ;
+    rdfs:seeAlso <@name at .ttl> .
+
+# Here's how you can declare the category of the plugin. (For lv2synth.cpp
+# instances, the lv2:InstrumentPlugin type will be added automatically.) See
+# http://lv2plug.in/ns/lv2core/ for a list of known plugin classes.
+
+# <@uri@> a lv2:FilterPlugin .
+
+# You might also want to set the license and author information below.
+# NOTE: This isn't normally necessary if you declared the corresponding
+# information as metadata in the Faust source of the plugin. The standard
+# author, license and description fields in the Faust source are automagically
+# included in the generated LV2 manifest.
+
+# <@uri@>
+#     doap:license <http://opensource.org/licenses/isc> ;
+#     doap:maintainer [
+#         foaf:name "Your Name Here" ;
+#         foaf:homepage <http://somewhere.org/> ;
+#         foaf:mbox <mailto:your at mail.here> ;
+#     ] .
+EOF
+# This compiles the plugin to an executable which is run to generate the
+# plugin-specific part of the manifest.
+$CXX $CXXFLAGS $FAUSTTOOLSFLAGS $CPPFLAGS "$tmpdir/$cppname" -o "$tmpdir/$clsname"
+"$tmpdir/$clsname" > "$tmpdir/$lv2name/$clsname.ttl"
+rm -f "$tmpdir/$clsname"
+fi
+
+
+# copy down the bundle
+rm -rf "$SRCDIR/$lv2name"
+cp -r "$tmpdir/$lv2name" "$SRCDIR"
+# Clean up.
+rm -rf $tmpdir
+# Print the name of the generated bundle zip file.
+echo "$SRCDIR/$lv2name;"
diff --git a/tools/faust2appls/faust2mathdoc b/tools/faust2appls/faust2mathdoc
index a67c306..b247cf2 100755
--- a/tools/faust2appls/faust2mathdoc
+++ b/tools/faust2appls/faust2mathdoc
@@ -92,7 +92,7 @@ then
 fi
 
 CONVERT=""
-if [ $1 = "-utf8" ] || [ $1 = "--utf8" ]
+if [ "$1" = "-utf8" ] || [ "$1" = "--utf8" ]
 then
     CONVERT="utf8"
     shift 1
@@ -115,7 +115,7 @@ for FILEPATH in $@ ; do
 	FILENAME=`basename $FILEPATH` &&
 	case $FILENAME in
 	    *.dsp )  
-	    if [ $CONVERT = "utf8" ] 
+	    if [ "$CONVERT" = "utf8" ] 
 	    then
 	    	recode2utf8 $FILENAME
 	    fi
diff --git a/tools/faust2appls/faust2max6 b/tools/faust2appls/faust2max6
new file mode 100755
index 0000000..1c542ad
--- /dev/null
+++ b/tools/faust2appls/faust2max6
@@ -0,0 +1,153 @@
+#! /bin/bash -e
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to Max6 externals			#
+#				using double precision samples						#
+#               (c) Grame, 2012                                     #
+#                                                                   #
+#####################################################################
+
+# path to max SDK
+
+SDK=/usr/local/include/c74support/
+MAXINC=$SDK/max-includes
+MSPINC=$SDK/msp-includes
+
+createInfoPList() {
+	(
+	echo '<?xml version="1.0" encoding="UTF-8"?>'
+	echo '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
+	echo '<plist version="1.0">'
+	echo '<dict>'
+	echo '	<key>CFBundleExecutable</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundleName</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundlePackageType</key>'
+	echo '	<string>iLaX</string>'
+	echo '</dict>'
+	echo '</plist>'
+	) > "$2"
+}
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust
+  JSFILE_PATH="\/usr\/local\/lib\/faust\/max-msp\/ui.js"
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust
+  JSFILE_PATH="\/usr\/lib\/faust\/max-msp\/ui.js"
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		CXX=icpc
+		CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2'
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+#-------------------------------------------------------------------
+# Check darwin specifics
+#
+if [[ $(uname) == Darwin ]]; then
+    SPEC="-spec macx-g++"
+    EXT="~.mxo"
+fi
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+PATH=$PATH:/usr/local/bin
+
+for p in $FILES; do
+
+    CC=g++
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+	faust -i -double -a $FAUSTLIB/max-msp/max-msp64.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+	cd "$TMP"
+	install -d "${f%.dsp}$EXT/Contents/MacOS"
+
+	$CC  -Wfatal-errors -framework Carbon -I ../../ -I$MAXINC -I$MSPINC $FAUSTTOOLSFLAGS -F$MAXINC -F$MSPINC -framework MaxAPI -framework MaxAudioAPI -arch i386 -arch x86_64  -Wl,-U,_object_new_imp -Wl,-U,_object_method_imp -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -Wl,-Y,1455 -bundle "${f%.dsp}.cpp" -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}~"
+    ) > /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+
+    # Keep .dsp and .cpp files in the plug-in
+    cp "$TMP/${f%.dsp}.cpp" "$TMP/${f%.dsp}$EXT"   
+    cp "$SRCDIR/$f" "$TMP/${f%.dsp}$EXT"
+
+    cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+    
+    # create Max patch
+    cat $FAUSTLIB/max-msp/wrapper.maxpat > ${f%.dsp}-temp1.maxpat
+    sed -e "s/DSP_NAME/"${f%.dsp}"~/g" ${f%.dsp}-temp1.maxpat >> ${f%.dsp}-temp2.maxpat
+    sed -e "s/UI_FILE/"$JSFILE_PATH"/g" ${f%.dsp}-temp2.maxpat > ${f%.dsp}.maxpat
+    
+    rm ${f%.dsp}-temp1.maxpat
+    rm ${f%.dsp}-temp2.maxpat
+    
+done
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2md b/tools/faust2appls/faust2md
new file mode 100755
index 0000000..c8731d4
--- /dev/null
+++ b/tools/faust2appls/faust2md
@@ -0,0 +1,151 @@
+#!/usr/bin/python
+
+#---------------------- faust2md -----------------------
+# Usage: `faust2md [-t 4] [-c] [-f] foo.dsp > foo.md`
+#
+# Ultra simple automatic documentation system for Faust.
+# Creates a markdown file by extracting the comments from
+# a faust file. The option -t n can be used to change the
+# default (4) tab setting. The option -c can be used to
+# include the faust code itself into the generated doc.
+# And the option -f can be used to include a YAML front
+# matter with the name of the file and the date.
+#
+# The format of a comment is :
+#	//------------ foo(x,y) ----------------
+#	//  markdown text....
+#	//  markdown text....
+#	//---------------------------------------
+# everything else is considered faust code.
+# The translation is the following:
+#   # foo(x,y)
+#	markdown text....
+#	markdown text....
+#--------------------------------------------------------
+
+
+import sys, re, datetime, string, getopt
+
+# Outdent a comment line by n characters in
+# order to remove the prefix "//   "
+def outdent(line, n):
+	if len(line) <= n:
+		return "\n"
+	else:
+		return line[n:]
+
+# Match the first line of a comment
+# of type "//--- foo(x,y) ----"
+# at least 3 - are needed
+def matchBeginComment(line):
+	return re.search(r'^\s*//-{3,}\s*([^-]+)-{3,}', line)
+
+# Match the last line of a comment
+# of type "//-----------------"
+# or a blank line
+def matchEndComment(line):
+	return re.search(r'^\s*((//-{3,})|(\s*))$', line)
+
+# Compute the indentation of a line,
+# that is the position of the first word character
+# after "//   "
+def indentation(line):
+	match = re.search(r'(^\s*//\s*\w)', line)
+	if match:
+		return len(match.group(1))-1
+	else:
+		return 0
+
+# Indicates if a line is a comment
+def isComment(line):
+	match = re.search(r'^\s*//', line)
+	if match:
+		return 1
+	else:
+		return 0
+
+# Measure the indentation of a md-comment line
+# that is the len of the prefix '//   '
+def indentation(line):
+	match = re.search(r'(^\s*//\s*\w)', line)
+	if match:
+		return len(match.group(1))-1
+	else:
+		return 0
+
+# Print the front matter of the file
+def frontMatter(file):
+	print '---'
+	print 'file:', file
+	print 'date:', datetime.date.today()
+	print '---'
+	print ''
+
+#
+# THE PROGRAM STARTS HERE
+#
+
+tabsize 	= 4		# tabsize used for expanding tabs
+codeflag	= 0		# 0: no source code; 1: print also source code
+frontflag	= 0		# 0: no front matter; 1: print front matter
+mode 		= 0		# 0: in code; 1: in md-comment
+idt 		= 0		# indentation retained to outdent comment lines
+
+# Analyze command line arguments
+try:
+	opts, args = getopt.getopt(sys.argv[1:], "t:cf")
+	if not args:
+		raise getopt.error, "At least one file argument required"
+except getopt.error, msg:
+	print msg
+	print "usage:", sys.argv[0], "[-t tabsize] [-c] [-f] file ..."
+	sys.exit(1)
+
+for optname, optvalue in opts:
+	if optname == '-t':
+		tabsize = int(optvalue)
+	if optname == '-c':
+		codeflag = 1
+	if optname == '-f':
+		frontflag = 1
+
+# Process all the files and print the documentation on the standard output
+for file in args:
+	with open(file) as f:
+		if frontflag: frontMatter(file)
+		for text in f:
+			line = string.expandtabs(text, tabsize)
+			if isComment(line)==0:
+				if mode==1:
+					# we are closing a md-comment
+					print ''
+					mode = 0
+				if codeflag:
+					print '\t',line,
+			else:
+				if mode==0:	# we are in code
+					match = matchBeginComment(line)
+					if match:
+						mode=1	# we just started a md-comment
+						idt = 0	# we have to measure the indentation
+						print ''
+						print '#', match.group(1)
+					else:
+						# it is a comment but not a md-comment
+						# therefore it is part of the code
+						if codeflag:
+							print '\t',line,
+				else:
+					# we are in a md-comment
+					if idt==0:
+						# we have to measure the indentation
+						idt = indentation(line)
+					# check end of md-comment
+					match = matchEndComment(line)
+					if match:
+						# end of md-comment switch back to mode O
+						mode = 0
+					else:
+						# lien of content of md-comment
+						# we print it unindented
+						print outdent(line,idt),
diff --git a/tools/faust2appls/faust2msp b/tools/faust2appls/faust2msp
index a35787b..7b36fc2 100755
--- a/tools/faust2appls/faust2msp
+++ b/tools/faust2appls/faust2msp
@@ -2,11 +2,18 @@
 
 #####################################################################
 #                                                                   #
-#               Compiles Faust programs to Max/MSP                  #
-#               (c) Grame, 2010                                     #
+#               Compiles Faust programs to Max externals			#
+#				using single precision samples						#
+#               (c) Grame, 2012                                     #
 #                                                                   #
 #####################################################################
 
+# path to max SDK
+
+SDK=/usr/local/include/c74support/
+MAXINC=$SDK/max-includes
+MSPINC=$SDK/msp-includes
+
 createInfoPList() {
 	(
 	echo '<?xml version="1.0" encoding="UTF-8"?>'
@@ -26,6 +33,23 @@ createInfoPList() {
 
 
 #-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+
+#-------------------------------------------------------------------
 # Analyze command arguments :
 # faust options                 -> OPTIONS
 # if -omp : -openmp or -fopenmp -> OPENMP
@@ -55,7 +79,7 @@ for p in $@; do
     	ignore=" "
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -68,7 +92,6 @@ done
 # Check darwin specifics
 #
 if [[ $(uname) == Darwin ]]; then
-    SPEC="-spec macx-g++"
     EXT="~.mxo"
 fi
 
@@ -79,7 +102,6 @@ PATH=$PATH:/usr/local/bin
 
 for p in $FILES; do
 
-    #INC=-I/usr/local/include/c74support/max-includes -I/usr/local/include/c74support/msp-includes
     CC=g++
 
     CUR=$(pwd)
@@ -92,21 +114,15 @@ for p in $FILES; do
     mkdir "$TMP"
 
     # compile faust to c++
-	faust -a max-msp.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+	faust -i -a $FAUSTLIB/max-msp/max-msp.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
 
     # compile c++ to binary
     (
 	cd "$TMP"
 	install -d "${f%.dsp}$EXT/Contents/MacOS"
-	$CC -arch i386 -fpascal-strings -fasm-blocks -g -O3 -I/usr/local/lib/faust -I/usr/local/include/c74support/max-includes -I/usr/local/include/c74support/msp-includes -c "${f%.dsp}.cpp" -o "${f%.dsp}.i386.o"
-	$CC -framework MaxAPI -framework Carbon -framework MaxAudioAPI -arch i386 -Wl,-Y,1455 -bundle "${f%.dsp}.i386.o" -o "${f%.dsp}.i386~"
-	#$CC -arch ppc -fpascal-strings -fasm-blocks -g -O3 -I/usr/local/lib/faust -I/usr/local/include/c74support/max-includes -I/usr/local/include/c74support/msp-includes -c "${f%.dsp}.cpp" -o "${f%.dsp}.ppc.o"
-	#$CC -framework Carbon -framework MaxAPI -framework MaxAudioAPI -arch ppc -Wl,-Y,1455 -bundle "${f%.dsp}.ppc.o"  -o "${f%.dsp}.ppc~"
-	createInfoPList "${f%.dsp}~" "${f%.dsp}$EXT/Contents/Info.plist"
-	#lipo -create "${f%.dsp}.i386~" "${f%.dsp}.ppc~"  -output "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}~"
-	lipo -create "${f%.dsp}.i386~" -output "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}~"
 
-    ) > /dev/null
+	$CC  -Wfatal-errors -framework Carbon -I ../../ -I$MAXINC -I$MSPINC $FAUSTTOOLSFLAGS -F$MAXINC -F$MSPINC -framework MaxAPI -framework MaxAudioAPI -arch i386 -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -Wl,-Y,1455 -bundle "${f%.dsp}.cpp" -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}~"
+    ) 
 
     rm -rf "$SRCDIR/${f%.dsp}$EXT"
 
@@ -117,8 +133,9 @@ for p in $FILES; do
     cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
     rm -rf "$TDR"
 
-    # collect binary file name for FaustGIDE
+    # collect binary file name for FaustWorks
     BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+    
 done
 
 echo $BINARIES
diff --git a/tools/faust2appls/faust2netjackconsole b/tools/faust2appls/faust2netjackconsole
new file mode 100755
index 0000000..4ddd876
--- /dev/null
+++ b/tools/faust2appls/faust2netjackconsole
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust/
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust/
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# existing *.dsp files          -> FILES
+#
+
+for p in $@; do
+    if [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"
+	fi
+done
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+for f in $FILES; do
+    faust -i -a netjack-console.cpp $OPTIONS $f -o $f.cpp
+    g++  $f.cpp $FAUSTTOOLSFLAGS -I/usr/local/include -L/usr/local/lib -ljacknet $OSCDEFS $HTTPDEFS -o  ${f%.dsp} 
+    rm $f.cpp
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
+
diff --git a/tools/faust2appls/faust2netjackqt b/tools/faust2appls/faust2netjackqt
new file mode 100755
index 0000000..7c984f8
--- /dev/null
+++ b/tools/faust2appls/faust2netjackqt
@@ -0,0 +1,132 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to netjack-qt               #
+#               (c) Grame, 2009                                     #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+. faustoptflags
+
+CXXFLAGS=$MYCXXFLAGS
+
+ARCHFILE="netjack-qt.cpp"
+ARCHLIB="-L/usr/local/lib -ljacknet"
+
+#-------------------------------------------------------------------------------
+# Search for qmake or qmake-qt4
+
+QMAKE=$(which qmake-qt4 || echo qmake) 
+
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		# we ignore -icc when compiling for QT
+		TOTO=""
+		#CXX=icpc
+		#CXXFLAGS='-Wfatal-errors -O3 -xT -ftz -fno-alias -fp-model fast=2'
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+
+OSCINC=""
+QTDEFS=""
+OSCLIB=""
+
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+		 OSCDEFS="DEFINES += OSCCTRL"
+		 OSCLIBS="-lOSCFaust"
+	elif [ "$p" = "-httpd" ]; then
+		HTTPDEFS="DEFINES += HTTPCTRL"
+		HTTPLIBS="-lHTTPDFaust -lmicrohttpd"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+
+#-------------------------------------------------------------------
+# Check darwin specifics
+#
+if [[ $(uname) == Darwin ]]; then
+    SYS_VERSION=$(uname -v | cut -d : -f1 | cut -d. -f1 | cut -d' ' -f4)
+	if [ $SYS_VERSION -gt 12 ]
+	then
+	    SPEC="-spec macx-clang"
+	    CLANGOPT="CONFIG+=c++11"
+	else
+	    SPEC="-spec macx-g++"
+	    CLANGOPT=""
+	fi
+    EXT=".app"
+fi
+
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+	faust -i -a $ARCHFILE $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+	    cd "$TMP"
+       	$QMAKE -project "QT += widgets printsupport network" "CONFIG+=warn_off" "$CLANGOPT" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=$FAUSTINC" "QMAKE_CXXFLAGS=$CXXFLAGS -Wno-unused-parameter $FAUSTTOOLSFLAGS" "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "HEADERS+=$FAUSTINC/faust/gui/faustqt.h" "RESOURCES+= $FAUSTINC/faust/gui/Styles/Grey.qrc"  "$OSCDEFS" "$HTTPDEFS"
+	    $QMAKE $SPEC
+        make
+    ) > /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+    cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2octave b/tools/faust2appls/faust2octave
index f633d12..a4944b3 100755
--- a/tools/faust2appls/faust2octave
+++ b/tools/faust2appls/faust2octave
@@ -38,7 +38,7 @@ for p in $@; do
     	ignore=" "
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -52,7 +52,7 @@ done
 for f in $FILES; do
 	
 	# compile faust to c++
-    faust -a matlabplot.cpp $OPTIONS "$f" -o "$f.cpp"
+    faust -i -a matlabplot.cpp $OPTIONS "$f" -o "$f.cpp"
 
 	# compile c++ to binary
 	(
diff --git a/tools/faust2appls/faust2owl b/tools/faust2appls/faust2owl
new file mode 100755
index 0000000..57e088b
--- /dev/null
+++ b/tools/faust2appls/faust2owl
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+FILENAME=$1
+CLASSNAME=`basename $FILENAME .dsp`
+PATCHNAME=$CLASSNAME"Patch"
+PATCHFILE=$PATCHNAME".hpp"
+
+#echo $FILENAME $CLASSNAME $PATCHNAME $PATCHFILE
+
+faust -i -inpl -a owl.cpp -cn $CLASSNAME $FILENAME | sed -e "s/FaustPatch/$PATCHNAME/g" > $PATCHFILE
+echo ""         
+echo "           Instructions to add $PATCHFILE to your owl pedal"
+echo ""         
+echo ""
+echo "Copy file [[ $PATCHFILE ]] to OwlWare/Libraries/OwlPatches directory"
+echo ""
+echo "Add line [[ #include \"$PATCHFILE\" ]] to OwlWare/Libraries/OwlPatches/includes.h file"
+echo ""
+echo "Add line [[ REGISTER_PATCH($PATCHNAME, \"$PATCHNAME\", 2, 2); ]] to OwlWare/Libraries/OwlPatches/patches.cpp file"
+echo ""
+echo "Rebuild the firmware using the command make in OwlWare directory"
+echo ""
+echo "Upload the resulting firmware OwlWare/build/OwlWare.bin to the pedal using the OwlNest software."
+echo ""
+
+
+
+
diff --git a/tools/faust2appls/faust2paqt b/tools/faust2appls/faust2paqt
index 939e5ed..e4aa095 100755
--- a/tools/faust2appls/faust2paqt
+++ b/tools/faust2appls/faust2paqt
@@ -11,6 +11,11 @@ OSCINC=""
 QTDEFS=""
 OSCLIB=""
 
+#-------------------------------------------------------------------------------
+# Search for qmake or qmake-qt4
+
+QMAKE=$(which qmake-qt4 || echo qmake) 
+
 
 #-------------------------------------------------------------------
 # Analyze command arguments :
@@ -41,12 +46,12 @@ for p in $@; do
     if [ "$p" = -icc ]; then
     	ignore=" "
     elif [ $p = "-osc" ]; then
-		 OSCINC="INCLUDEPATH+=/usr/local/lib/faust/osclib"
+		 OSCINC="INCLUDEPATH+=/usr/local/include/faust/osclib"
 		 QTDEFS="DEFINES += OSCCTRL"
-		 OSCLIB="-L/usr/local/lib/faust/osclib -lOSCFaust -loscpack"
+		 OSCLIB="-lOSCFaust"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -78,13 +83,13 @@ for p in $FILES; do
     mkdir "$TMP"
 
     # compile faust to c++
-	faust -a pa-qt.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+	faust -i -a pa-qt.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
 
     # compile c++ to binary
     (
 	    cd "$TMP"
-        qmake -project "INCLUDEPATH+=$CUR" "INCLUDEPATH+=/usr/local/lib/faust/" "$OSCINC" "LIBS+=-lportaudio $OSCLIB" "HEADERS+=/usr/local/lib/faust/gui/faustqt.h" "$QTDEFS"
-	    qmake $SPEC
+        $QMAKE -project "QT += widgets printsupport" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=/usr/local/include/faust/" "$OSCINC" "LIBS+=-lportaudio $OSCLIB" "HEADERS+=/usr/local/include/faust/gui/faustqt.h" "RESOURCES+= /usr/local/include/faust/gui/Styles/Grey.qrc" "$QTDEFS"
+	    $QMAKE $SPEC
         make
     ) > /dev/null
 
diff --git a/tools/faust2appls/faust2plot b/tools/faust2appls/faust2plot
index 27057ce..77d1cca 100755
--- a/tools/faust2appls/faust2plot
+++ b/tools/faust2appls/faust2plot
@@ -52,9 +52,13 @@ for p in $@; do
   
     if [ "$p" = -icc ]; then
     	ignore=" "
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -67,11 +71,11 @@ done
 for f in $FILES; do
 	
 	# compile faust to c++
-    faust -a matlabplot.cpp $OPTIONS "$f" -o "$f.cpp"
+    faust -i -a matlabplot.cpp $OPTIONS "$f" -o "$f.cpp"
 
 	# compile c++ to binary
 	(
-		${CXX=g++} ${CXXFLAGS=-O3} $OMP "$f.cpp" -o "${f%.dsp}"
+		${CXX=g++} ${CXXFLAGS=-O3} $PROCARCH $OMP "$f.cpp" -o "${f%.dsp}"
 	) > /dev/null
 	rm "$f.cpp"
 
diff --git a/tools/faust2appls/faust2puredata b/tools/faust2appls/faust2puredata
index 085d0e7..aa1daff 100755
--- a/tools/faust2appls/faust2puredata
+++ b/tools/faust2appls/faust2puredata
@@ -3,7 +3,7 @@
 #####################################################################
 #                                                                   #
 #               Compiles Faust programs to puredata                 #
-#               (c) Grame, 2009                                     #
+#               (c) Grame, 2009-2014                                #
 #                                                                   #
 #####################################################################
 
@@ -36,9 +36,15 @@ for p in $@; do
   
     if [ "$p" = -icc ]; then
     	ignore=" "
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-poly" ]; then
+	F2PDPOLY="-n 8"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
 	    OPTIONS="$OPTIONS $p"        
@@ -51,11 +57,11 @@ done
 #
 if [[ $(uname) == Darwin ]]; then
     CXXFLAGS="-O3 -mfpmath=sse -msse -ffast-math"
-    LIB="-I/Applications/Pd-extended.app/Contents/Resources/include/ -bundle -undefined suppress -flat_namespace"    
+    LIB="-I/Applications/Pd-extended.app/Contents/Resources/include/ -I. -bundle -undefined suppress -flat_namespace"    
     EXT="~.pd_darwin"
 else
     CXXFLAGS="-O3 -march=native -mfpmath=sse -msse -ffast-math"
-    LIB="-I/usr/include/pd -I/usr/include/pdextended -fPIC -shared"
+    LIB="-I/usr/include/pd -I/usr/include/pdextended -I. -fPIC -shared"
     EXT="~.pd_linux"
 fi
 
@@ -72,32 +78,38 @@ for p in $FILES; do
     SRCDIR=$(dirname "$p")
 
     # creates a temporary dir 
-    TDR=$(mktemp -d faust.XXX)
+    TDR=$(mktemp -d faust.XXXXXX)
     TMP=$TDR/${f%.dsp}
     mkdir "$TMP"
+    
+    # case where a foreign C++ function is called in the Faust code (TODO: this is only a quick fix!)
+    count=`ls -1 *.h 2>/dev/null | wc -l`
+    if [ $count != 0 ]; then
+    	cp *.h $TMP
+    fi
 
     # compile faust to c++ and xml
     faust -xml "$SRCDIR/$f" -o /dev/null;
     mv "$SRCDIR/$f.xml" $TMP/
-    faust -a puredata.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+    faust -i -a puredata.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
 
     # compile c++ to binary
     (
         cd "$TMP"
 		if [[ $(uname) == Darwin ]]; then
 			# On Darwin we build 32-bits and 64-bits plugins combined with lipo
-			${CXX=g++}  -arch i386 $CXXFLAGS $OMP $LIB -Dmydsp=${f%.dsp} -o ${f%.dsp}.i386 ${f%.dsp}.cpp
-			${CXX=g++}  -arch x86_64 $CXXFLAGS $OMP $LIB -Dmydsp=${f%.dsp} -o ${f%.dsp}.x86_64 ${f%.dsp}.cpp
+			${CXX=g++}  -arch i386 $CXXFLAGS  $FAUSTTOOLSFLAGS $OMP $LIB -Dmydsp=${f%.dsp} -o ${f%.dsp}.i386 ${f%.dsp}.cpp
+			${CXX=g++}  -arch x86_64 $CXXFLAGS $FAUSTTOOLSFLAGS $OMP $LIB -Dmydsp=${f%.dsp} -o ${f%.dsp}.x86_64 ${f%.dsp}.cpp
 			lipo -create "${f%.dsp}.i386" "${f%.dsp}.x86_64"  -output "${f%.dsp}$EXT"
 		else
-			${CXX=g++} $CXXFLAGS $OMP $LIB -Dmydsp=${f%.dsp} -o ${f%.dsp}$EXT ${f%.dsp}.cpp
+			${CXX=g++} $CXXFLAGS $FAUSTTOOLSFLAGS $PROCARCH $OMP $LIB -Dmydsp=${f%.dsp} -o ${f%.dsp}$EXT ${f%.dsp}.cpp
 		fi		
         if [ $(which faust2pd) ]; then
-        	faust2pd -s $f.xml
+        	faust2pd -s $F2PDPOLY $f.xml
         fi
     ) > /dev/null
 
-    ##rm -rf "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
     cp "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
     # collects all the files produced
     BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
diff --git a/tools/faust2appls/faust2raqt b/tools/faust2appls/faust2raqt
new file mode 100755
index 0000000..252f7ac
--- /dev/null
+++ b/tools/faust2appls/faust2raqt
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to RtAudio-qt               #
+#               (c) Grame, 2015                                     #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+ARCHFILE="ra-qt.cpp"
+ARCHLIB="-L/usr/local/lib -lrtaudio"
+PATH=$PATH:/usr/local/bin
+
+#-------------------------------------------------------------------------------
+# Search for qmake or qmake-qt4
+
+QMAKE=$(which qmake-qt4 || echo qmake) 
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+CXXFLAGS='-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math'
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		# we ignore -icc when compiling for QT
+		TOTO=""
+		#CXX=icpc
+		#CXXFLAGS='-Wfatal-errors -O3 -xT -ftz -fno-alias -fp-model fast=2'
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+
+OSCINC=""
+QTDEFS=""
+OSCLIB=""
+
+for p in $@; do
+    if [ $p = "-help" ] || [ $p = "-h" ]; then
+        echo "faust2raqt [-osc] [-http] [-poly] <file.dsp>"
+        echo "Use '-poly' to produce a polyphonic DSP, ready to be used with MIDI events"
+        echo "Use '-midi' to activate MIDI control"
+        echo "Use '-osc' to activate OSC control"
+        echo "Use '-http' to activate HTTP control"
+        echo "Use '-qrcode' to activate QR code generation"
+    fi
+    
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-poly" ]; then
+        POLYDEFS="DEFINES += POLY"
+    elif [ $p = "-midi" ]; then
+        MIDIDEFS="DEFINES += MIDICTRL"
+    elif [ $p = "-osc" ]; then
+        OSCDEFS="DEFINES += OSCCTRL"
+        OSCLIBS="-lOSCFaust"
+	elif [ "$p" = "-httpd" ]; then
+		HTTPDEFS="DEFINES += HTTPCTRL"
+		HTTPLIBS="-lHTTPDFaust -lmicrohttpd -lqrencode"
+	elif [ "$p" = "-qrcode" ]; then # requires -httpd
+		QRDEFS="DEFINES += QRCODECTRL"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+    else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+#-------------------------------------------------------------------
+# Check darwin specifics
+#
+if [[ $(uname) == Darwin ]]; then
+    ARCHLIB+=" -framework CoreMIDI -framework CoreFoundation -framework CoreAudio"
+    CXXFLAGS+=" -D__MACOSX_CORE__"
+    SYS_VERSION=$(uname -v | cut -d : -f1 | cut -d. -f1 | cut -d' ' -f4)
+	if [ $SYS_VERSION -gt 12 ]
+	then
+	    SPEC="-spec macx-clang"
+	    CLANGOPT="CONFIG+=c++11"
+	else
+	    SPEC="-spec macx-g++"
+	    CLANGOPT=""
+	fi
+    EXT=".app"
+fi
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+ 	faust -i -a $ARCHFILE $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+  
+    # compile c++ to binary
+    (
+	    cd "$TMP"
+	    $QMAKE -project "QT += widgets printsupport network" "CONFIG+=warn_off" "$CLANGOPT" "INCLUDEPATH+=$CUR" "INCLUDEPATH+=$FAUSTINC" "QMAKE_CXXFLAGS=$CXXFLAGS -Wno-unused-parameter $FAUSTTOOLSFLAGS" "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "HEADERS+=$FAUSTINC/faust/gui/faustqt.h" "RESOURCES+= $FAUSTINC/faust/gui/Styles/Grey.qrc"  "$OSCDEFS" "$HTTPDEFS" "$QRDEFS" "$POLYDEFS" "$MIDIDEFS" 
+	    $QMAKE $SPEC
+        make
+    ) > /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+    cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2ros b/tools/faust2appls/faust2ros
new file mode 100755
index 0000000..7cc3b88
--- /dev/null
+++ b/tools/faust2appls/faust2ros
@@ -0,0 +1,264 @@
+#! /bin/bash -e
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to ROS packages             #
+#               (c) Grame, 2014                                     #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+ARCHFILE="jack-ros.cpp"
+path=$(pwd)
+CURRENT_DIR=$(pwd)
+
+# Dispatch command arguments
+WORKSPACES=''
+NEW_NAMES=''
+
+params=("$@")
+n=0
+for p in $@; do
+	n=$(($n+1))
+	# install option, get workspace's name
+    if [ "$p" = "-install" ]; then
+	WORKSPACES="$WORKSPACES ${params[$n]}"
+	
+	# o option, get the new application's name	
+    elif [ "$p" = "-o" ]; then
+	NEW_NAMES="$NEW_NAMES ${params[$n]}"
+	
+	elif [ "$p" = "--help" ] || [ "$p" = "-h" ] ; then
+	HELP=true
+	
+    elif [ ${p:0:1} = "-" ]; then
+	OPTIONS="$OPTIONS $p ${params[$n]}"
+	
+    elif [[ -f "$p" ]]; then
+	FILES="$FILES $p"
+	 
+    fi
+done
+
+# Puts option parameters in tables
+NEW_NAMES=($NEW_NAMES)
+WORKSPACES=($WORKSPACES)
+
+
+# Get parameters tables size 
+NAMES_LENGTH=${#NEW_NAMES[@]}
+WS_LENGTH=${#WORKSPACES[@]}
+
+if [ $HELP ]
+then
+############ BEGIN HELP MESSAGE ############
+echo -e "####################################################################################################
+######################################## FAUST2ROS HELP ############################################
+####################################################################################################
+
+################################################################################################
+		This command allows you to compile a FAUST DSP file into a ROS package, 
+			compressed or ready to be used in a workspace.
+################################################################################################
+USAGE:
+faust2ros ~/path/to/mydsp.dsp
+Output : mydsp.zip, a compressed package
+
+OPTIONS :
+	-install
+		faust2ros -install ~/path/to/my/workspace ~/other/path/to/mydsp.dsp
+		Output : mydsp.cpp, a C++ file in a package, in a workspace,
+							ready to be run
+	-o 
+		faust2ros -o mynewname ~/path/to/mydsp.dsp
+		Output : mynewname.zip
+	
+For more options and informations, type faust -h or faust --help
+
+####################################################################################################
+"
+############ END HELP MESSAGE ############
+else
+
+	# Check if packages exist ; if not, create them
+	i=0
+	for (( i = 0 ; i < $WS_LENGTH ; i=$i+1 ))
+	do  
+	    if [ ! -d ${WORKSPACES[${i}]} ]
+	    then
+	        mkdir -p ${WORKSPACES[${i}]}/src
+	    else 
+	        cd ${WORKSPACES[${i}]}
+	        if [ ! -d src ]
+	        then
+	        	mkdir src
+	        fi
+	    fi
+	    cd ${WORKSPACES[${i}]}/src
+	    if [ !  CMakeLists.txt ] || [ -w CMakeLists.txt ] 
+	    then
+	    	
+	    rm -f CMakeLists.txt
+	    	
+	    catkin_init_workspace > /dev/null
+	    fi
+	
+	done
+
+	# if there is only one workspace specified, no need to run a loop
+	if [ $WS_LENGTH = 1 ]   
+	then WORKSPACE_PATH="${WORKSPACES[$1]}"/src
+	fi
+
+	#-------------------------------------------------------------------
+	# compile the *.dsp files
+	#
+	i=0
+	   
+	    for p in $FILES
+	    do 
+
+		# Check .dsp path ; if there is no path, file should be in current directory
+		temp=$(basename "$p")
+		temp_path=$(dirname ${p})
+
+		if [ ! $temp_path = '.' ]
+		then
+		    p=$temp
+		    path=$temp_path
+		fi
+		
+		# Create dsp package depending on options
+		if [ "$NEW_NAMES" = "" ]
+		then
+		    f=$(basename "$p")
+		    name="${f%.dsp}"
+		else
+		    name="${NEW_NAMES[${i}]}"
+		fi
+			# zip file
+	    	if [ $WS_LENGTH = 0 ] 
+	    	then
+		    cd $CURRENT_DIR
+		    	
+			temp_dir=$(mktemp -d ROS.XXXXXX)
+			cd $temp_dir
+				mkdir src
+			    cd src
+			    	catkin_create_pkg $name roscpp std_msgs > /dev/null
+
+			PACKAGE_PATH=$CURRENT_DIR/$temp_dir/src/$name
+		else
+			# install in workspace
+		    if [ $WS_LENGTH = 1 ]
+		    then
+			cd $WORKSPACE_PATH
+	    	    if [[ -d $WORKSPACE_PATH/$name ]]
+			    then
+					rm -r $WORKSPACE_PATH/$name
+			    fi
+	    
+			    catkin_create_pkg $name roscpp std_msgs > /dev/null
+			    
+				PACKAGE_PATH=$WORKSPACE_PATH/$name
+		    
+		    else 
+	    
+			WORKSPACE_PATH="${WORKSPACES[${i}]}"/src
+			cd $WORKSPACE_PATH
+	    	    if [ -d $WORKSPACE_PATH/$name ]
+			    then		    	
+			    	rm - r $WORKSPACE_PATH/$name
+			    fi
+		    
+			    catkin_create_pkg $name roscpp std_msgs > /dev/null
+		    
+				PACKAGE_PATH=$WORKSPACE_PATH/$name
+		    fi
+		fi
+		cd $PACKAGE_PATH
+
+# Set CMakeLists.txt to fit to the faust package	
+############## CMAKELISTS ############################
+echo -e "cmake_minimum_required(VERSION 2.8.3)
+project($name)
+
+SET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math\")
+
+include_directories(\${catkin_INCLUDE_DIRS})
+
+catkin_package()
+find_package(catkin REQUIRED COMPONENTS
+  roscpp
+  std_msgs
+)
+
+add_executable(\${PROJECT_NAME} src/\${PROJECT_NAME}.cpp)
+
+target_link_libraries(\${PROJECT_NAME} jack \${catkin_LIBRARIES})" > CMakeLists.txt
+############# END CMAKELISTS #########################
+	    
+		# double compilation
+		cd src
+			faust -i -a ros-callbacks.cpp -o "$PACKAGE_PATH/src/$name.cpp" $path/$p
+			g++ $name.cpp -o $name
+	    	faust -i -a $ARCHFILE $OPTIONS "$path/$p" -o "$PACKAGE_PATH/src/$name.cpp" $path/$p	> /dev/null	
+	    	./$name		# adds the callbacks declaration to the generated c++ file
+	    	rm $name
+		# zip file
+		if [ $WS_LENGTH = 0 ]
+		then
+			cd $CURRENT_DIR/$temp_dir/src/$name
+############ BEGIN README ###########################
+echo -e "			README : Using Faust with ROS
+		Grame, Centre National de Creation Musicale
+		###########################################
+
+This file was automatically generated with faust2ros or faust2rosgtk
+
+To run your new application : 
+	1) unzip this package into a ROS workspace.
+	2) source this workspace :
+		a) go in your workspace's root
+		b) type 'source devel/setup.bash'
+	3) run with 'rosrun myapp myapp'
+
+For more informations, check the documentation :
+https://sourceforge.net/p/faudiostream/code/ci/master/tree/documentation" > README.txt
+############ END README #############################
+	  		cd $CURRENT_DIR/$temp_dir/src
+	    	zip -r $name.zip $name > /dev/null
+	    	cd $CURRENT_DIR
+	    	cp $temp_dir/src/$name.zip $CURRENT_DIR
+	    	rm -r $temp_dir
+	    	OUTPUT="$OUTPUT $name.zip;"
+		# package installation
+		else
+		    cd ${WORKSPACES[${i}]}
+############ BEGIN README ###########################	    
+echo -e "			README : Using Faust with ROS
+		Grame, Centre National de Creation Musicale
+		###########################################
+
+This file was automatically generated with faust2ros or faust2rosgtk
+
+To run your new application : 
+	1) source this workspace :
+		a) go in your workspace's root
+		b) type 'source devel/setup.bash'
+	3) run with 'rosrun myapp myapp'
+
+For more informations, check the documentation :
+https://sourceforge.net/p/faudiostream/code/ci/master/tree/documentation" > README.txt
+############ END README #############################	    
+	    		catkin_make > /dev/null
+	   			OUTPUT="$OUTPUT $name.cpp;"
+		fi 
+
+    	i=$((i+1))
+
+    	done
+
+	echo $OUTPUT
+fi
diff --git a/tools/faust2appls/faust2rosgtk b/tools/faust2appls/faust2rosgtk
new file mode 100755
index 0000000..585ff2a
--- /dev/null
+++ b/tools/faust2appls/faust2rosgtk
@@ -0,0 +1,254 @@
+#! /bin/bash -e
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to ROS packages             #
+#               with a GTK interface                                #
+#               (c) Grame, 2014                                     #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+ARCHFILE="jack-gtk-ros.cpp"
+
+path=$(pwd)
+CURRENT_DIR=$(pwd)
+
+# Dispatch command arguments
+WORKSPACES=''
+NEW_NAMES=''
+params=("$@")
+n=0
+for p in $@; do
+	n=$(($n+1))
+	
+	# install option, get workspace's name
+    if [ "$p" = "-install" ]; then
+	WORKSPACES="$WORKSPACES ${params[$n]}"
+	
+	# o option, get the new application's name	
+    elif [ "$p" = "-o" ]; then
+	NEW_NAMES="$NEW_NAMES ${params[$n]}"
+	
+	elif [ "$p" = "--help" ] || [ "$p" = "-h" ] ; then
+	HELP=true
+
+    elif [ ${p:0:1} = "-" ]; then
+    	OPTIONS="$OPTIONS $p ${params[$n]}"
+	
+    elif [[ -f "$p" ]]; then
+	FILES="$FILES $p"
+       
+    fi
+done
+
+# Puts option parameters in tables
+NEW_NAMES=($NEW_NAMES)
+WORKSPACES=($WORKSPACES)
+
+
+# Get parameters tables size 
+NAMES_LENGTH=${#NEW_NAMES[@]}
+WS_LENGTH=${#WORKSPACES[@]}
+
+if [ $HELP ]
+then
+############ BEGIN HELP MESSAGE ############
+echo -e "####################################################################################################
+######################################## FAUST2ROS HELP ############################################
+####################################################################################################
+
+################################################################################################
+		This command allows you to compile a FAUST DSP file into a ROS package, 
+			compressed or ready to be used in a workspace.
+################################################################################################
+USAGE:
+faust2rosgtk ~/path/to/mydsp.dsp
+Output : mydsp.zip, a compressed package
+
+OPTIONS :
+	-install
+		faust2rosgtk -install ~/path/to/my/workspace ~/other/path/to/mydsp.dsp
+		Output : mydsp.cpp, a C++ file in a package, in a workspace,
+							ready to be run
+	-o 
+		faust2rosgtk -o mynewname ~/path/to/mydsp.dsp
+		Output : mynewname.zip
+	
+For more options and informations, type faust -h or faust --help
+
+####################################################################################################
+"
+############ END HELP MESSAGE ############
+else
+	# Check if packages exist ; if not, create them
+	i=0
+	for (( i = 0 ; i < $WS_LENGTH ; i=$i+1 ))
+	do  
+	    if [ ! -d ${WORKSPACES[${i}]} ]
+	    then
+	        mkdir -p ${WORKSPACES[${i}]}/src
+	    else 
+	        cd ${WORKSPACES[${i}]}
+		        if [ ! -d src ]
+    		    then mkdir src
+        		fi
+    	fi
+    	cd ${WORKSPACES[${i}]}/src
+    		if [ !  CMakeLists.txt ] || [ -w CMakeLists.txt ] 
+    		then	
+    			rm -f CMakeLists.txt
+    			catkin_init_workspace > /dev/null
+    		fi
+	done
+
+	# if there is only one workspace specified, no need to run a loop
+	if [ $WS_LENGTH = 1 ]   
+	then WORKSPACE_PATH="${WORKSPACES[$1]}"/src
+	fi
+
+	#-------------------------------------------------------------------
+	# compile the *.dsp files
+	#
+	i=0
+	   
+	    for p in $FILES
+	    do 
+	
+			# Check .dsp path ; if there is no path, file should be in curent directory
+			temp=$(basename "$p")
+			temp_path=$(dirname ${p})
+
+			if [ ! $temp_path = '.' ]
+			then
+	    		p=$temp
+	    		path=$temp_path
+			fi
+	
+			# Create dsp package depending on options
+			if [ "$NEW_NAMES" = "" ]
+			then
+	    		f=$(basename "$p")
+	    		name="${f%.dsp}"
+			else
+			    name="${NEW_NAMES[${i}]}"
+			fi
+			name=$name"_gtk"
+			# zip file
+    		if [ $WS_LENGTH = 0 ] 
+    		then
+				cd $CURRENT_DIR	
+					temp_dir=$(mktemp -d ROS.XXXXXX)
+				cd $temp_dir
+					mkdir src
+		    	cd src
+		    		catkin_create_pkg $name roscpp std_msgs > /dev/null
+					PACKAGE_PATH=$CURRENT_DIR/$temp_dir/src/$name
+			else
+	    	# install in workspace
+	    		if [ $WS_LENGTH = 1 ]
+	    		then
+					cd $WORKSPACE_PATH
+	    	    		if [[ -d $WORKSPACE_PATH/$name ]]
+		    			then
+							rm -r $WORKSPACE_PATH/$name
+						fi
+		    			catkin_create_pkg $name roscpp std_msgs > /dev/null
+		    			PACKAGE_PATH=$WORKSPACE_PATH/$name
+	   			else 
+					WORKSPACE_PATH="${WORKSPACES[${i}]}"/src
+					cd $WORKSPACE_PATH
+	    	    		if [ -d $WORKSPACE_PATH/$name ]
+		    			then
+		        			rm -r $WORKSPACE_PATH/$name	
+						fi
+						catkin_create_pkg $name roscpp std_msgs > /dev/null
+						PACKAGE_PATH=$WORKSPACE_PATH/$name
+	    		fi
+			fi
+			cd $PACKAGE_PATH
+
+# Set CMakeLists.txt to fit to the faust package
+############## CMAKELISTS ############################	
+echo -e "cmake_minimum_required(VERSION 2.8.3) 
+project($name)
+
+SET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math\")
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK2 REQUIRED gtk+-2.0)
+include_directories(\${catkin_INCLUDE_DIRS} \${GTK2_INCLUDE_DIRS})
+link_directories(\${GTK2_LIBRARY_DIRS})
+catkin_package()
+find_package(catkin REQUIRED COMPONENTS
+  roscpp
+  std_msgs
+)
+
+add_executable(\${PROJECT_NAME} src/\${PROJECT_NAME}.cpp)
+
+target_link_libraries(\${PROJECT_NAME} \${GTK2_LIBRARIES} jack \${catkin_LIBRARIES})" > CMakeLists.txt
+############# END CMAKELISTS #########################
+	    
+			# Double compilation
+			cd src
+				faust -i -a ros-callbacks.cpp -o "$PACKAGE_PATH/src/$name.cpp" $path/$p
+				g++ $name.cpp -o $name
+				faust -i -a $ARCHFILE $OPTIONS "$path/$p" -o "$PACKAGE_PATH/src/$name.cpp" $path/$p	> /dev/null
+				./$name		# adds the callbacks declaration to the generated c++ file
+    			rm $name 
+	
+				# zip file
+				if [ $WS_LENGTH = 0 ]
+				then
+	   				cd $CURRENT_DIR/$temp_dir/src/$name
+############ BEGIN README ############
+echo -e "			README : Using Faust with ROS
+		Grame, Centre National de Creation Musicale
+		###########################################
+
+This file was automatically generated with faust2ros or faust2rosgtk
+
+To run your new application : 
+	1) unzip this package into a ROS workspace.
+	2) source this workspace :
+		a) go in your workspace's root
+		b) type 'source devel/setup.bash'
+	3) run with 'rosrun myapp myapp'
+
+For more informations, check the documentation :
+https://sourceforge.net/p/faudiostream/code/ci/master/tree/documentation" > README.txt
+############ END README ############
+					cd $CURRENT_DIR/$temp_dir/src
+					    zip -r $name.zip $name > /dev/null
+	    			cd $CURRENT_DIR
+	    				cp $temp_dir/src/$name.zip $CURRENT_DIR
+	    				rm -r $temp_dir
+	    				OUTPUT="$OUTPUT $name.zip;"
+					# package installation
+				else
+				    cd ${WORKSPACES[${i}]}
+############ BEGIN README ############
+echo -e "			README : Using Faust with ROS
+		Grame, Centre National de Creation Musicale
+		###########################################
+
+This file was automatically generated with faust2ros or faust2rosgtk
+
+To run your new application : 
+	1) source this workspace :
+		a) go in your workspace's root
+		b) type 'source devel/setup.bash'
+	3) run with 'rosrun myapp myapp'
+
+For more informations, check the documentation :
+https://sourceforge.net/p/faudiostream/code/ci/master/tree/documentation" > README.txt
+############ END README ############
+						catkin_make > /dev/null
+	    				OUTPUT="$OUTPUT $name.cpp;"
+				fi 
+			    i=$((i+1))
+	    done	
+	echo $OUTPUT
+fi	
diff --git a/tools/faust2appls/faust2rpialsaconsole b/tools/faust2appls/faust2rpialsaconsole
new file mode 100755
index 0000000..44d0573
--- /dev/null
+++ b/tools/faust2appls/faust2rpialsaconsole
@@ -0,0 +1,104 @@
+#!/bin/bash
+
+OSCDEFS=""
+#####################################################################
+#                                                                   #
+#               Crosscompiles Faust programs to RaspberryPi 		#
+#				alsa-console architecture     						#
+#               Author : Pilar de la Cruz                           #
+#               (c) Grame, 2009-2013                                #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+# base directory for tools
+
+BASE_DIR="/opt/rpicrosstool"
+
+#-------------------------------------------------------------------
+# Default compilation flags for gcc and icc :
+#
+
+#CXXFLAGS="-Wall -g -D_debug_ -D_DEBUG_"
+CXXFLAGS="-O3 -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -ffast-math -ftree-vectorize"
+#-------------------------------------------------------------------
+# Kernel Sources Dir
+
+LINUX_KERNEL_INSTALL_DIR="$BASE_DIR/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/"
+
+
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# Toolchain cross-compilation for Raspberry Pi
+
+CXX=$BASE_DIR"/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-c++"
+
+
+# Librairies and includes directories for Rapsberry Pi
+
+
+LD_LIBRARY_PATHS="-L$LINUX_KERNEL_INSTALL_DIR/lib -lasound"
+INCLUDES_DIR="-L$LINUX_KERNEL_INSTALL_DIR_INCLUDE/include/"
+
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -L$LINUX_KERNEL_INSTALL_DIR/lib/ -lOSCFaust -loscpack"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -L$LINUX_KERNEL_INSTALL_DIR/lib -lHTTPDFaust -lmicrohttpd"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+#-------------------------------------------------------------------
+# compile the *.dsp files using ALSA and GTK on linux
+#
+for f in $FILES; do
+	
+	# compile faust to c++
+	faust -i -a alsa-console.cpp $OPTIONS "$f" -o "$f.cpp"
+
+	# compile c++ to binary
+	(
+		$CXX $CXXFLAGS $OMP "$f.cpp" $INCLUDES_DIR $LD_LIBRARY_PATHS $PROCARCH $OSCDEFS $HTTPDEFS -o "${f%.dsp}"
+	) > /dev/null
+	rm "$f.cpp"
+
+	# collect binary file name for FaustWorks
+	BINARIES="$BINARIES${f%.dsp};"
+done
+
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2rpinetjackconsole b/tools/faust2appls/faust2rpinetjackconsole
new file mode 100755
index 0000000..1829af2
--- /dev/null
+++ b/tools/faust2appls/faust2rpinetjackconsole
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+OSCDEFS=""
+#####################################################################
+#                                                                   #
+#               Crosscompiles Faust programs to RaspberryPi 		#
+#				netjack-console architecture     					#
+#               Author : Pilar de la Cruz                           #
+#               (c) Grame, 2009-2013                                #
+#                                                                   #
+#####################################################################
+
+. faustpath
+
+# base directory for tools
+
+BASE_DIR="/opt/rpicrosstool"
+
+#-------------------------------------------------------------------
+# Default compilation flags for gcc and icc :
+#
+
+#CXXFLAGS="-Wall -g -D_debug_ -D_DEBUG_"
+CXXFLAGS="-O3 -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -ffast-math -ftree-vectorize"
+#-------------------------------------------------------------------
+# Kernel Sources Dir
+
+LINUX_KERNEL_INSTALL_DIR="$BASE_DIR/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi"
+
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# Toolchain cross-compilation for Raspberry Pi
+
+CXX=$BASE_DIR"/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-c++"
+
+
+# Librairies and includes directories for Rapsberry Pi
+
+
+LD_LIBRARY_PATHS="-L$LINUX_KERNEL_INSTALL_DIR/lib/ -lasound -ljacknet"
+INCLUDES_DIR="-I$LINUX_KERNEL_INSTALL_DIR/include/"
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# existing *.dsp files          -> FILES
+#
+
+for p in $@; do
+    if [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -L$LINUX_KERNEL_INSTALL_DIR/lib/ -lOSCFaust -loscpack"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -L$LINUX_KERNEL_INSTALL_DIR/lib/ -lHTTPDFaust -lmicrohttpd"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"
+	fi
+done
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+for f in $FILES; do
+    faust -i -a netjack-console.cpp $OPTIONS $f -o $f.cpp
+    $CXX $CXXFLAGS $OMP "$f.cpp" $LD_LIBRARY_PATHS $INCLUDES_DIR $PROCARCH $OSCDEFS $HTTPDEFS -o "${f%.dsp}" 
+    rm $f.cpp
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
+
diff --git a/tools/faust2appls/faust2sig b/tools/faust2appls/faust2sig
index 3bca44c..cb1f423 100755
--- a/tools/faust2appls/faust2sig
+++ b/tools/faust2appls/faust2sig
@@ -1,7 +1,26 @@
-#!/bin/bash
-for f in $@; do
+#! /bin/bash -e
+
+#  usage : faust2sig foo.dsp        -> foo-sig.pdf
+#  usage : faust2sig -svg foo.dsp   -> foo-sig.svg
+
+FILES=""
+IGNORE=""
+FORMAT="pdf"
+
+# Analyze command line
+for p in $@; do
+    if [ "$p" = -svg ]; then
+        FORMAT="svg"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    IGNORE="$IGNORE $p"
+	fi
+done
+
+
+for f in $FILES; do
     faust -sg $f -o /dev/null
-	dot -Tpdf $f-sig.dot -o $f-sig.pdf
+	dot -T$FORMAT $f-sig.dot -o $f.sig.$FORMAT
 	rm $f-sig.dot
 done
-
diff --git a/tools/faust2appls/faust2supercollider b/tools/faust2appls/faust2supercollider
index b2eeca3..11251f3 100755
--- a/tools/faust2appls/faust2supercollider
+++ b/tools/faust2appls/faust2supercollider
@@ -13,6 +13,27 @@
 
 # Possible path
 
+PATH=$PATH:/usr/local/bin
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust/
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust/
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+#-------------------------------------------------------------------
+# Need SuperCollider 'plugin_interface' include path to compile UGens:
+
 SC0=$SUPERCOLLIDER_HEADERS
 SC1="/usr/local/include/SuperCollider"
 SC2="/usr/local/include/supercollider"
@@ -35,8 +56,9 @@ else
 	echo "Can't find SuperCollider headers"
 	exit 1
 fi 
+###echo Using SC Headers in $SC
 
-INCLUDE="-I$SC/plugin_interface/ -I$SC/common/ -I$SC/server/"
+INCLUDE="-I$SC/plugin_interface/ -I$SC/common/ -I$SC/server/ -I$FAUSTLIB"
 
 if [ $# = 0 ]; then
     echo USAGE:
@@ -82,10 +104,9 @@ for p in $@; do
     	ignore=" "
     elif [ ${p:0:1} = "-" ]; then
 	    OPTIONS="$OPTIONS $p"
-	elif [[ -e "$p" ]]; then
+	elif [[ -f "$p" ]]; then
 	    FILES="$FILES $p"
 	else
-	    echo "*** Faust source-file '$p' not found"
 	    OPTIONS="$OPTIONS $p"
 	fi
 done
@@ -135,13 +156,13 @@ for p in $FILES; do
     # compile the .dsp file to c++ and xml
     faust -xml "$SRCDIR/$f" -o /dev/null;
     mv "$SRCDIR/$f.xml" $TMP/
-    faust -a supercollider.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+    faust -i -a supercollider.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
 
     # compile c++ to binary; --prefix should be same as in ../../examples/Makefile.sccompile
     (
         cd "$TMP"
         faust2sc --prefix=Faust $SYNTHDEF $f.xml > "${f%.dsp}.sc" 2>$OUTDEV
-        ${CXX=g++}  -O3 $SCFLAGS -I$CUR $INCLUDE $CXXFLAGS $OMP -Dmydsp=${f%.dsp} -o ${f%.dsp}.$EXT ${f%.dsp}.cpp
+        ${CXX=g++}  -O3 $FAUSTTOOLSFLAGS $SCFLAGS -I$CUR $INCLUDE $CXXFLAGS $OMP -Dmydsp=${f%.dsp} -o ${f%.dsp}.$EXT ${f%.dsp}.cpp
     )> $OUTDEV
 
     ## move the produced files from tmp to source dir
diff --git a/tools/faust2appls/faust2svg b/tools/faust2appls/faust2svg
index 3ed167e..9bf20a7 100755
--- a/tools/faust2appls/faust2svg
+++ b/tools/faust2appls/faust2svg
@@ -1,5 +1,6 @@
 #!/bin/bash
+
 for f in $@; do
-    faust -svg $f -o /dev/null
+    faust -t 0 -svg $f -o /dev/null
 done
 
diff --git a/tools/faust2appls/faust2vst b/tools/faust2appls/faust2vst
new file mode 100755
index 0000000..ade8d92
--- /dev/null
+++ b/tools/faust2appls/faust2vst
@@ -0,0 +1,147 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to VST (OSX version)		#
+#               (c) Grame, 2012                                     #
+#                                                                   #
+#####################################################################
+
+# VST specific sdk files
+#------------------------
+VSTSDK="/usr/local/include/vstsdk2.4"
+EXT=".vst"
+
+INCLUDES="-I$VSTSDK/ -I$VSTSDK/public.sdk/source/vst2.x/"
+
+LIBS=" -framework Carbon -framework CoreServices"
+
+SOURCES=" $VSTSDK/public.sdk/source/vst2.x/audioeffect.cpp $VSTSDK/public.sdk/source/vst2.x/audioeffectx.cpp $VSTSDK/public.sdk/source/vst2.x/vstplugmain.cpp"
+
+CXXFLAGS='-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math'
+
+
+
+createInfoPList() {
+	(
+	echo '<?xml version="1.0" encoding="UTF-8"?>' > info.plist
+	echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
+	echo '<plist version="1.0">'
+	echo '<dict>'
+	echo '	<key>CFBundleDevelopmentRegion</key>'
+	echo '	<string>English</string>'
+	echo '	<key>CFBundleExecutable</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundleIdentifier</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundleInfoDictionaryVersion</key>'
+	echo '	<string>6.0</string>'
+	echo '	<key>CFBundleName</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundlePackageType</key>'
+	echo '	<string>BNDL</string>'
+	echo '	<key>CFBundleShortVersionString</key>'
+	echo '	<string>2.4</string>'
+	echo '	<key>CFBundleSignature</key>'
+	echo '	<string>????</string>'
+	echo '	<key>CFBundleVersion</key>'
+	echo '	<string>2.4</string>'
+	echo '	<key>CSResourcesFileMapped</key>'
+	echo '	<true/>'
+	echo '</dict>'
+	echo '</plist>'
+	) > "$2"
+}
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+for p in $@; do
+	if [ "$p" = -icc ]; then
+		CXX=icpc
+		CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2'
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+PATH=$PATH:/usr/local/bin
+
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TMP=$(mktemp -d faust.XXX)
+
+    # compile faust to c++
+	faust -i -a vst.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+	cd "$TMP"
+	install -d "${f%.dsp}$EXT/Contents/MacOS"
+	if [[ $(uname) == "Darwin" ]]; then
+		g++ -arch i386 $CXXFLAGS $FAUSTTOOLSFLAGS $INCLUDES -bundle $PROCARCH -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.i386" "${f%.dsp}.cpp" $SOURCES
+		g++ -arch x86_64 $CXXFLAGS $FAUSTTOOLSFLAGS $INCLUDES -bundle $PROCARCH -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.x86_64" "${f%.dsp}.cpp" $SOURCES
+		lipo -create "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.i386" "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.x86_64" -output "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}"
+	else
+		g++ -arch i386 $CXXFLAGS $FAUSTTOOLSFLAGS $INCLUDES -bundle $PROCARCH -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}" "${f%.dsp}.cpp" $SOURCES
+	fi
+	createInfoPList "${f%.dsp}" "${f%.dsp}$EXT/Contents/Info.plist"
+	echo "BNDL????" > "${f%.dsp}$EXT/Contents/PkgInfo"
+    )> /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+
+    cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$TMP"
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
+
+
diff --git a/tools/faust2appls/faust2vsti b/tools/faust2appls/faust2vsti
new file mode 100755
index 0000000..486108d
--- /dev/null
+++ b/tools/faust2appls/faust2vsti
@@ -0,0 +1,143 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Compiles Faust programs to VST (OSX version)		#
+#               (c) Grame, 2012                                     #
+#                                                                   #
+#####################################################################
+
+# VST specific sdk files
+#------------------------
+VSTSDK="/usr/local/include/vstsdk2.4"
+EXT=".vst"
+
+INCLUDES="-I$VSTSDK/ -I$VSTSDK/public.sdk/source/vst2.x/"
+
+LIBS=" -framework Carbon -framework CoreServices"
+
+SOURCES=" $VSTSDK/public.sdk/source/vst2.x/audioeffect.cpp $VSTSDK/public.sdk/source/vst2.x/audioeffectx.cpp $VSTSDK/public.sdk/source/vst2.x/vstplugmain.cpp"
+
+CXXFLAGS='-Wfatal-errors -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math'
+
+
+
+createInfoPList() {
+	(
+	echo '<?xml version="1.0" encoding="UTF-8"?>' > info.plist
+	echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
+	echo '<plist version="1.0">'
+	echo '<dict>'
+	echo '	<key>CFBundleDevelopmentRegion</key>'
+	echo '	<string>English</string>'
+	echo '	<key>CFBundleExecutable</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundleIdentifier</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundleInfoDictionaryVersion</key>'
+	echo '	<string>6.0</string>'
+	echo '	<key>CFBundleName</key>'
+	echo "	<string>$1</string>"
+	echo '	<key>CFBundlePackageType</key>'
+	echo '	<string>BNDL</string>'
+	echo '	<key>CFBundleShortVersionString</key>'
+	echo '	<string>2.4</string>'
+	echo '	<key>CFBundleSignature</key>'
+	echo '	<string>????</string>'
+	echo '	<key>CFBundleVersion</key>'
+	echo '	<string>2.4</string>'
+	echo '	<key>CSResourcesFileMapped</key>'
+	echo '	<true/>'
+	echo '</dict>'
+	echo '</plist>'
+	) > "$2"
+}
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+# PHASE 1 : Look for -icc option to force use of intel icc (actually icpc)
+# without having to configure CXX and CXXFLAGS
+for p in $@; do
+    if [ "$p" = -icc ]; then
+	CXX=icpc
+	CXXFLAGS='-O3 -xT -ftz -fno-alias -fp-model fast=2'
+    fi
+done
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-osc" ]; then
+	 OSCDEFS="-DOSCCTRL -lOSCFaust"
+    elif [ $p = "-httpd" ]; then
+	 HTTPDEFS="-DHTTPCTRL -lHTTPDFaust -lmicrohttpd"
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+PATH=$PATH:/usr/local/bin
+
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TMP=$(mktemp -d faust.XXX)
+
+    # compile faust to c++
+	faust -i -a vst.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+	cd "$TMP"
+	install -d "${f%.dsp}$EXT/Contents/MacOS"
+	if [[ $(uname) == "Darwin" ]]; then
+		g++ -arch i386 $CXXFLAGS $FAUSTTOOLSFLAGS $INCLUDES -bundle $PROCARCH -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.i386" "${f%.dsp}.cpp" $SOURCES
+		g++ -arch x86_64 $CXXFLAGS $FAUSTTOOLSFLAGS $INCLUDES -bundle $PROCARCH -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.x86_64" "${f%.dsp}.cpp" $SOURCES
+		lipo -create "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.i386" "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}.x86_64" -output "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}"
+	else
+		g++ -arch i386 $CXXFLAGS $FAUSTTOOLSFLAGS $INCLUDES -bundle $PROCARCH -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}" "${f%.dsp}.cpp" $SOURCES
+	fi
+	createInfoPList "${f%.dsp}" "${f%.dsp}$EXT/Contents/Info.plist"
+	echo "BNDL????" > "${f%.dsp}$EXT/Contents/PkgInfo"
+    )> /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+
+    cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    rm -rf "$TMP"
+
+    # collect binary file name for FaustGIDE
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo $BINARIES
diff --git a/tools/faust2appls/faust2w32max6 b/tools/faust2appls/faust2w32max6
new file mode 100755
index 0000000..4c23eda
--- /dev/null
+++ b/tools/faust2appls/faust2w32max6
@@ -0,0 +1,121 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Cross-compiles Faust programs to Max/MSP            #
+#					form 	: Linux or OSX							#
+#					to		: Windows 32							#
+#               (c) Grame, 2011                                     #
+#                                                                   #
+#####################################################################
+
+#------------------------------------------------------------------------------
+# 1/ MAX/MSP SDK Should be installed somewhere
+MAXSDK=/usr/local/include/c74support
+EXT="~.mxe"
+
+#------------------------------------------------------------------------------
+# 2/ mingw crosscompiler should be installed ('mingw32' package on Ubuntu)
+# It must be in the PATH and the exact prefix should be specified in
+# the environment variable MINGWPREFIX
+
+: ${MINGWPREFIX="i686-w64-mingw32-"}
+CXX="${MINGWPREFIX}g++"
+(which "$CXX" >/dev/null) || (echo "MingW compiler $CXX not found"; exit 1)
+DLLWRAP="${MINGWPREFIX}dllwrap --target=i386-mingw32"
+STRIP="${MINGWPREFIX}strip"
+
+
+#-----------------------------------------------------------------------------
+# Compilation flags
+LIBS="$MAXSDK/max-includes/MaxAPI.lib  $MAXSDK/msp-includes/MaxAudio.lib"
+CXXINCS="-I$MAXSDK/max-includes -I$MAXSDK/msp-includes "
+CXXFLAGS="-DWIN_VERSION -DWIN_EXT_VERSION"
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -e "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"
+	fi
+done
+
+BINARIES=""
+
+#PHASE 3 : Compile each dsp files in $FILES
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+	faust -i -double -a $FAUSTLIB/max-msp/max-msp64.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+		cd "$TMP"
+		echo "TMP=$TMP"
+
+		# we need to create the .def file needed to generate the .dll
+		echo "LIBRARY     ${f%.dsp}~" 						 > ${f%.dsp}.def
+		echo "DESCRIPTION 'Faust generated MAX plugin'" 	>> ${f%.dsp}.def
+		echo "EXPORTS     main" 							>> ${f%.dsp}.def
+
+		$CXX $CXXINCS $CXXFLAGS -c "${f%.dsp}.cpp" -o "${f%.dsp}.o"
+		$DLLWRAP --driver-name $CXX --def ${f%.dsp}.def *.o  $LIBS -o "${f%.dsp}$EXT"
+		$STRIP "${f%.dsp}$EXT"
+    ) > /dev/null
+
+	cp "$TMP/${f%.dsp}$EXT" "$SRCDIR"
+
+    # remove temporary directory
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustWorks
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo "$BINARIES"
diff --git a/tools/faust2appls/faust2w32msp b/tools/faust2appls/faust2w32msp
new file mode 100755
index 0000000..92ab506
--- /dev/null
+++ b/tools/faust2appls/faust2w32msp
@@ -0,0 +1,121 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Cross-compiles Faust programs to Max/MSP            #
+#					form 	: Linux or OSX							#
+#					to		: Windows 32							#
+#               (c) Grame, 2011                                     #
+#                                                                   #
+#####################################################################
+
+#------------------------------------------------------------------------------
+# 1/ MAX/MSP SDK Should be installed somewhere
+MAXSDK=/usr/local/include/c74support
+EXT="~.mxe"
+
+#------------------------------------------------------------------------------
+# 2/ mingw crosscompiler should be installed ('mingw32' package on Ubuntu)
+# It must be in the PATH and the exact prefix should be specified in
+# the environment variable MINGWPREFIX
+
+: ${MINGWPREFIX="i686-w64-mingw32-"}
+CXX="${MINGWPREFIX}g++"
+(which "$CXX" >/dev/null) || (echo "MingW compiler $CXX not found"; exit 1)
+DLLWRAP="${MINGWPREFIX}dllwrap --target=i386-mingw32"
+STRIP="${MINGWPREFIX}strip"
+
+
+#-----------------------------------------------------------------------------
+# Compilation flags
+LIBS="$MAXSDK/max-includes/MaxAPI.lib  $MAXSDK/msp-includes/MaxAudio.lib"
+CXXINCS="-I$MAXSDK/max-includes -I$MAXSDK/msp-includes "
+CXXFLAGS="-DWIN_VERSION -DWIN_EXT_VERSION"
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -e "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"
+	fi
+done
+
+BINARIES=""
+
+#PHASE 3 : Compile each dsp files in $FILES
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+	faust -i -a $FAUSTLIB/max-msp/max-msp.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+		cd "$TMP"
+		echo "TMP=$TMP"
+
+		# we need to create the .def file needed to generate the .dll
+		echo "LIBRARY     ${f%.dsp}~" 						 > ${f%.dsp}.def
+		echo "DESCRIPTION 'Faust generated MAX plugin'" 	>> ${f%.dsp}.def
+		echo "EXPORTS     main" 							>> ${f%.dsp}.def
+
+		$CXX $CXXINCS $CXXFLAGS -c "${f%.dsp}.cpp" -o "${f%.dsp}.o"
+		$DLLWRAP --driver-name $CXX --def ${f%.dsp}.def *.o  $LIBS -static-libstdc++ -static-libgcc -o "${f%.dsp}$EXT"
+		$STRIP "${f%.dsp}$EXT"
+    ) > /dev/null
+
+	cp "$TMP/${f%.dsp}$EXT" "$SRCDIR"
+
+    # remove temporary directory
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustWorks
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo "$BINARIES"
diff --git a/tools/faust2appls/faust2w32puredata b/tools/faust2appls/faust2w32puredata
new file mode 100755
index 0000000..cb0b85d
--- /dev/null
+++ b/tools/faust2appls/faust2w32puredata
@@ -0,0 +1,115 @@
+#! /bin/bash -e
+
+#####################################################################
+#                                                                   #
+#               Cross-compiles Faust programs to puredata           #
+#					form 	: Linux									#
+#					to		: Windows 32							#
+#               (c) Grame, 2014                                     #
+#                                                                   #
+#####################################################################
+
+#------------------------------------------------------------------------------
+# mingw crosscompiler should be installed ('mingw32' package on Ubuntu)
+# the exact prefix should be specified in the environment variable MINGW
+
+: ${MINGWPREFIX="i686-w64-mingw32-"}
+CXX="${MINGWPREFIX}g++"
+(which "$CXX" >/dev/null) || (echo "MingW compiler $CXX not found"; exit 1)
+
+
+#-------------------------------------------------------------------
+# Compiler settings
+
+CXXFLAGS="-O3 -mfpmath=sse -msse -ffast-math -Wl,--enable-auto-import"
+LIB="-I/usr/include/pd -shared /usr/include/pd/pd.dll"
+EXT="~.dll"
+
+
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+    	OMP="-fopenmp"
+    fi
+  
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ $p = "-arch32" ]; then
+	PROCARCH="-m32 -L/usr/lib32"
+    elif [ $p = "-arch64" ]; then
+	PROCARCH="-m64"
+    elif [ $p = "-poly" ]; then
+	F2PDPOLY="-n 8"
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -f "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+
+
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+    SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir 
+    TDR=$(mktemp -d faust.XXXXXX)
+    TMP=$TDR/${f%.dsp}
+    mkdir "$TMP"
+    
+    # case where a foreign C++ function is called in the Faust code (TODO: this is only a quick fix!)
+    count=`ls -1 *.h 2>/dev/null | wc -l`
+    if [ $count != 0 ]; then
+    	cp *.h $TMP
+    fi
+
+    # compile faust to c++ and xml
+    faust -xml "$SRCDIR/$f" -o /dev/null;
+    mv "$SRCDIR/$f.xml" $TMP/
+    faust -i -a puredata.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+        cd "$TMP"
+		$CXX $CXXFLAGS $FAUSTTOOLSFLAGS $PROCARCH $OMP $LIB -static-libstdc++ -static-libgcc -Dmydsp=${f%.dsp} -o ${f%.dsp}$EXT ${f%.dsp}.cpp
+
+        if [ $(which faust2pd) ]; then
+        	faust2pd -s $F2PDPOLY $f.xml
+        fi
+    ) > /dev/null
+
+    rm -rf "$SRCDIR/${f%.dsp}$EXT"
+    cp "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT"
+    
+    # collects all the files produced
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+    if [ $(which faust2pd)  ]; then
+    	cp "$TMP/${f%.dsp}.pd" "$SRCDIR/${f%.dsp}.pd"
+    	BINARIES="$BINARIES$SRCDIR/${f%.dsp}.pd;"
+    fi
+    rm -rf "$TDR"
+
+
+done
+
+# return the binaries names
+echo "$BINARIES"
+
+
diff --git a/tools/faust2appls/faust2w32vst b/tools/faust2appls/faust2w32vst
new file mode 100755
index 0000000..64dec80
--- /dev/null
+++ b/tools/faust2appls/faust2w32vst
@@ -0,0 +1,110 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Cross-compiles Faust programs to VST plugins        #
+#					form 	: Linux									#
+#					to		: Windows 32							#
+#               (c) Grame, 2014                                     #
+#                                                                   #
+#####################################################################
+
+#------------------------------------------------------------------------------
+# 1/ VST SDK Should be installed somewhere
+VST=/usr/local/include/vstsdk2.4
+
+# these cpp files have to be compiled too
+VSTSRC="$VST/public.sdk/source/vst2.x/audioeffect.cpp $VST/public.sdk/source/vst2.x/audioeffectx.cpp $VST/public.sdk/source/vst2.x/vstplugmain.cpp "
+
+#------------------------------------------------------------------------------
+# mingw crosscompiler should be installed ('mingw32' package on Ubuntu)
+# It must be in the PATH and the exact prefix should be specified in
+# the environment variable MINGWPREFIX
+
+: ${MINGWPREFIX="i686-w64-mingw32-"}
+CXX="${MINGWPREFIX}g++"
+(which "$CXX" >/dev/null) || (echo "MingW compiler $CXX not found"; exit 1)
+DLLWRAP="${MINGWPREFIX}dllwrap --target=i386-mingw32"
+STRIP="${MINGWPREFIX}strip"
+
+
+#-----------------------------------------------------------------------------
+# Compilation flags
+CXXFLAGS="-O3 -mfpmath=sse -msse -ffast-math -DBUILDING_DLL -Wno-multichar -Wno-write-strings"
+CXXINCS=" -I$VST -I$VST/public.sdk/source/vst2.x"
+EXT=".dll"
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# if -omp : -openmp or -fopenmp -> OPENMP
+# existing *.dsp files          -> FILES
+#
+
+
+#PHASE 2 : dispatch command arguments
+for p in $@; do
+    if [ "$p" = -omp ]; then
+        if [[ $CXX == "icpc" ]]; then
+            OMP="-openmp"
+        else
+            OMP="-fopenmp"
+        fi
+    fi
+
+    if [ "$p" = -icc ]; then
+    	ignore=" "
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -e "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"
+	fi
+done
+
+BINARIES=""
+
+#PHASE 3 : Compile each dsp files in $FILES
+for p in $FILES; do
+
+    CUR=$(pwd)
+    f=$(basename "$p")
+	SRCDIR=$(dirname "$p")
+
+    # creates a temporary dir
+    TDR=$(mktemp -d faust.XXX)
+	TMP="$TDR/${f%.dsp}"
+    mkdir "$TMP"
+
+    # compile faust to c++
+	faust -i -a vst.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp"
+
+    # compile c++ to binary
+    (
+		cd "$TMP"
+
+		# we need to create the .def file needed to generate the .dll
+		echo "LIBRARY     ${f%.dsp}" 						 > ${f%.dsp}.def
+		echo "DESCRIPTION 'Faust generated VST plugin'" 	>> ${f%.dsp}.def
+		echo "EXPORTS     VSTPluginMain" 					>> ${f%.dsp}.def
+
+		$CXX $CXXINCS $CXXFLAGS -c "$VST/public.sdk/source/vst2.x/audioeffect.cpp" -o audioeffect.o
+		$CXX $CXXINCS $CXXFLAGS -c "$VST/public.sdk/source/vst2.x/audioeffectx.cpp" -o audioeffectx.o
+		$CXX $CXXINCS $CXXFLAGS -c "$VST/public.sdk/source/vst2.x/vstplugmain.cpp" -o vstplugmain.o
+		$CXX $CXXINCS $CXXFLAGS -c "${f%.dsp}.cpp" -o "${f%.dsp}.o"
+
+		$DLLWRAP --driver-name $CXX --def ${f%.dsp}.def *.o  $LIBS -static-libstdc++ -static-libgcc -o "${f%.dsp}$EXT"
+		$STRIP "${f%.dsp}$EXT"
+    ) #> /dev/null
+
+	cp "$TMP/${f%.dsp}$EXT" "$SRCDIR"
+
+    # remove temporary directory
+    rm -rf "$TDR"
+
+    # collect binary file name for FaustWorks
+    BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;"
+done
+
+echo "$BINARIES"
diff --git a/tools/faust2appls/faust2webaudioasm b/tools/faust2appls/faust2webaudioasm
new file mode 100755
index 0000000..9446bd8
--- /dev/null
+++ b/tools/faust2appls/faust2webaudioasm
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+#-------------------------------------------------------------------
+# Wrapping resources
+
+EXPORT_FOOTER=""
+HTML_FOOTER=webaudio-asm-footer.html
+CPP_WRAPPER=webaudio-asm.cpp
+JS_WRAPPER=webaudio-asm-emcc.js
+LINKS=""
+SVG=""
+EXPORT="false"
+
+#-------------------------------------------------------------------
+# Set Faust include path
+
+if [ -f $FAUST_LIB_PATH/music.lib ]
+then
+  FAUSTLIB=$FAUST_LIB_PATH
+elif [ -f /usr/local/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/local/lib/faust/
+elif [ -f /usr/lib/faust/music.lib ]
+then
+  FAUSTLIB=/usr/lib/faust/
+else
+  error "$0: Cannot find Faust library dir (usually /usr/local/lib/faust)"
+fi
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# faust options                 -> OPTIONS
+# existing *.dsp files          -> FILES
+#
+
+for p in $@; do
+    if [ $p = "-help" ] || [ $p = "-h" ]; then
+        echo "faust2webaudioasm [-poly] [-links] <file.dsp>"
+        echo "Use '-poly' to produce a polyphonic DSP, ready to be used with MIDI events"
+        echo "Use '-links' to add links to source code and SVG diagrams in the generated HTML file"
+    elif [ $p = "-links" ]; then
+        SVG="-svg"
+        LINKS="<div style=\"text-align:center;height:20px\"> 
+                <style>
+				a:link {font-family:Arial; font-size:12px; color:#3D3C3A; text-decoration:none}
+				a:visited {font-family:Arial; font-size:12px; color:#3D3C3A; text-decoration:none}
+				a:hover {font-family:Arial; font-size:12px; color:white; text-decoration:none}
+                </style>
+            <a href=\"DSP.dsp\" target=\"_blank\">source</a> 
+            <a href=\"DSP-svg/process.svg\" target=\"_blank\">diagram</a>
+            </div>"
+        EXPORT="true"
+        EXPORT_FOOTER=export-wrapper.html
+    elif [ $p = "-poly" ]; then
+        HTML_FOOTER=webaudio-asm-poly-footer.html
+        CPP_WRAPPER=webaudio-asm-poly.cpp
+        JS_WRAPPER=webaudio-asm-poly-emcc.js
+    elif [ ${p:0:1} = "-" ]; then
+	    OPTIONS="$OPTIONS $p"
+	elif [[ -e "$p" ]]; then
+	    FILES="$FILES $p"
+	else
+	    OPTIONS="$OPTIONS $p"        
+	fi
+done
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+BINARIES=""
+
+for f in $FILES; do
+    name=${f%.dsp}
+    
+    # compile the Faust DSP to C++ code
+    faust $SVG -a $FAUSTLIB/webaudio/$CPP_WRAPPER -i -uim -cn $name $OPTIONS $f -o $name.cpp
+    
+    if [ $HTML_FOOTER = webaudio-asm-footer.html ]; then
+        EXPORTED="['_"$name"_constructor','_"$name"_destructor','_"$name"_compute','_"$name"_getNumInputs','_"$name"_getNumOutputs','_"$name"_setValue','_"$name"_getValue','_"$name"_getJSON']"
+     else
+	    EXPORTED="['_"$name"_poly_constructor','_"$name"_poly_destructor','_"$name"_poly_compute','_"$name"_poly_getNumInputs','_"$name"_poly_getNumOutputs','_"$name"_poly_setValue','_"$name"_poly_getValue','_"$name"_poly_getJSON','_"$name"_poly_keyOn','_"$name"_poly_keyOff','_"$name"_poly_allNotesOff','_"$name"_poly_ctrlChange','_"$name"_poly_pitchWheel','_"$name"_poly_pitchBend']"       
+	fi
+     
+    # compile the C++ code to asm.js
+    emcc -O2 --memory-init-file 0 $name.cpp -s TOTAL_MEMORY=100663296 --pre-js $FAUSTLIB/js/jsscripts.js --post-js $FAUSTLIB/webaudio/$JS_WRAPPER -o $name-temp1.js \
+        -s EXPORTED_FUNCTIONS=$EXPORTED
+          
+    # compose the self-contained HTML page
+    echo "<html>" > $name-temp2.html
+    echo "<head>" >> $name-temp2.html
+    echo "<meta charset=\"UTF-8\">" >> $name-temp2.html
+    echo "<style type=\"text/css\">" >> $name-temp2.html
+    cat $FAUSTLIB/js/stylesheet.js >> $name-temp2.html
+    echo "</style>" >> $name-temp2.html
+    echo "<script type=\"text/javascript\">" >> $name-temp2.html
+    cat $FAUSTLIB/js/jsscripts.js >> $name-temp2.html
+    cat $FAUSTLIB/webaudio/WebMIDIAPI.js >> $name-temp2.html
+    sed -e "s/DSP/"$name"/g" $name-temp1.js >> $name-temp2.html
+    echo "</script>" >> $name-temp2.html 
+    echo "</head>" >> $name-temp2.html
+    echo "<body>" >> $name-temp2.html
+    echo $LINKS >> $name-temp2.html
+    cat $FAUSTLIB/webaudio/$HTML_FOOTER >> $name-temp2.html
+    if [ $EXPORT = "true" ] ; then
+        cat $FAUSTLIB/webaudio/$EXPORT_FOOTER >> $name-temp2.html
+    fi
+    echo "</body>" >> $name-temp2.html
+    echo "</html>" >> $name-temp2.html
+    sed -e "s/DSP/"$name"/g" $name-temp2.html > $name.html
+    
+    rm $name-temp1.js
+    rm $name-temp2.html
+    rm $name.cpp
+
+	BINARIES="$BINARIES$name.html;"
+
+done
+
+echo $BINARIES
diff --git a/tools/faust2appls/faustoptflags b/tools/faust2appls/faustoptflags
new file mode 100755
index 0000000..1fee17d
--- /dev/null
+++ b/tools/faust2appls/faustoptflags
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Defines the best optimisation flags to use          #
+#				on the various platforms. This file is called		#
+#				by the faust2xxx scripts. It sets two variables		#
+#				$MYGCCFLAGS and $MYICCFLAGS							#
+#               (c) Grame, 2013                                		#
+#                                                                   #
+#####################################################################
+
+#-------------------------------------------------------------------
+# Default compilation flags for gcc and icc :
+#
+if [[ $(uname -m) == armv6l ]]; then		# for Raspberry PI
+	MYGCCFLAGS="-O3 -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -ffast-math -ftree-vectorize"
+elif [[ $(uname -s) == Darwin ]]; then		# for MacOSX (intel)
+	MYGCCFLAGS="-O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
+else 										# for Linux (intel)
+	MYGCCFLAGS="-O3 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize"
+fi
+
+# for Linux (intel) with icc
+MYICCFLAGS="-O3 -xHost -ftz -fno-alias -fp-model fast=2"
+
diff --git a/tools/faust2appls/faustpath b/tools/faust2appls/faustpath
new file mode 100644
index 0000000..138033d
--- /dev/null
+++ b/tools/faust2appls/faustpath
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+#####################################################################
+#                                                                   #
+#               Search where Faust is installed and defines   		#
+#				$FAUSTLIB and $FAUSTINC so that we can use			#
+#				-L$FAUSTLIB and -I$FAUSTINC where needed.			#
+#               (c) Grame, 20013                                    #
+#                                                                   #
+#####################################################################
+
+#-------------------------------------------------------------------------------
+# Search where Faust is installed. Store '.../lib/faust/' in $FAUSTLIB
+# and '.../include/(faust)' in $FAUSTINC 
+#
+# USAGE :
+# add line << . faustpath >> to your script
+# and use -L$FAUSTLIB and -I$FAUSTINC where needed
+
+
+FAUSTLIB=""; FAUSTINC=""; 
+FPATH="$FAUST_INSTALL /usr/local /usr /opt /opt/local"; # <- where to search
+for f in $FPATH; do
+	if [ -e $f/lib/faust ]; 	then FAUSTLIB=$f/lib/faust;	fi
+	if [ -e $f/include/faust ];	then FAUSTINC=$f/include/; fi
+done
+for f in $FPATH; do
+	if [ -e $f/lib/libmicrohttpd.a ]; 	then HTTPLIB=$f/lib/faust;	fi
+done
+if [ -z "$FAUSTLIB" -o -z "$FAUSTINC" ]; then 
+	echo "ERROR : $0 cannot find Faust directories (normally /usr/local/include/faust and /usr/local/lib/faust)"; 
+	exit 1;
+fi
diff --git a/tools/faust2flash_v0.1/Step_2_FlashBuilder_project/html-template/playerProductInstall.swf b/tools/faust2flash_v0.1/Step_2_FlashBuilder_project/html-template/playerProductInstall.swf
deleted file mode 100644
index bdc3437..0000000
Binary files a/tools/faust2flash_v0.1/Step_2_FlashBuilder_project/html-template/playerProductInstall.swf and /dev/null differ
diff --git a/tools/faust2pd/ChangeLog b/tools/faust2pd/ChangeLog
index c75ea77..c1d4645 100644
--- a/tools/faust2pd/ChangeLog
+++ b/tools/faust2pd/ChangeLog
@@ -1,3 +1,11 @@
+2014-09-17  Albert Graef  <aggraef at gmail.com>
+
+	+ Release 2.8
+
+	* Pass the -mcpu=generic option to llc when batch-compiling Pure
+	scripts, to prevent illegal instructions depending on the build
+	host's cpu type.
+
 2009-08-08  Albert Graef  <Dr.Graef at t-online.de>
 
 	+ Release 2.2
diff --git a/tools/faust2pd/Makefile b/tools/faust2pd/Makefile
index 6957fb0..bd6bbed 100644
--- a/tools/faust2pd/Makefile
+++ b/tools/faust2pd/Makefile
@@ -1,7 +1,7 @@
 
 # Package name and version number:
 dist = faust2pd-$(version)
-version = 2.5
+version = 2.9
 
 # Default installation prefix:
 prefix = /usr/local
@@ -27,7 +27,7 @@ endif
 
 DESTDIR=
 
-DISTFILES = Makefile COPYING ChangeLog README config.guess *.pure *.pd examples/README examples/*/Makefile examples/*/*.dsp examples/*/*.syn examples/*/*.pd examples/*/*.pure examples/*/*.xml
+DISTFILES = Makefile COPYING ChangeLog README config.guess *.pure *.pd examples/README debian/* examples/*/Makefile examples/*/*.cpp examples/*/*.dsp examples/*/*.syn examples/*/*.pd examples/*/*.pure examples/*/*.xml pd/*.h
 SEDFILES = README
 
 .PHONY: all examples clean distclean realclean install uninstall
@@ -52,7 +52,7 @@ realclean:
 # as of pure-0.21, we can compile the script to an executable
 faust2pd$(EXE): faust2pd.pure faustxml.pure
 	sed -e 's?@version@?$(version)?' < $< > xx$<
-	pure -c xx$< -o $@
+	pure $(PUREC_FLAGS) -I. -c xx$< -o $@
 	rm -f xx$<
 
 # install faust2pd
@@ -87,7 +87,7 @@ datesubst = sed -e "s?@version@?$(version)?g" -e "s?|today|?$(date)?g" < $(1) >
 
 dist:
 	rm -rf $(dist)
-	mkdir $(dist) && mkdir $(dist)/examples
+	mkdir $(dist) && mkdir $(dist)/debian && mkdir $(dist)/pd && mkdir $(dist)/examples
 	for x in basic faust seqdemo synth; do mkdir $(dist)/examples/$$x; done
 	for x in $(DISTFILES); do ln -sf $$PWD/$$x $(dist)/$$x; done
 	for x in $(SEDFILES); do rm -f $(dist)/$$x; $(call datesubst,$$PWD/$$x,$(dist)/$$x); done
@@ -100,6 +100,18 @@ distcheck: dist
 	cd $(dist) && make all examples && make install install-pd DESTDIR=./BUILD
 	rm -rf $(dist)
 
+# Debian packaging
+
+debsrc = $(shell echo $(dist) | sed -e 's/-$(version)/_$(version)/').orig.tar.gz
+
+deb: $(debsrc) dist
+	tar xfz $(dist).tar.gz
+	cd $(dist) && debuild $(DEBUILD_FLAGS)
+	rm -rf $(dist)
+
+$(debsrc):
+	wget -nv https://bitbucket.org/purelang/pure-lang/downloads/$(dist).tar.gz -O $@
+
 # Generate the documentation.
 
 sources = faustxml.pure
diff --git a/tools/faust2pd/README b/tools/faust2pd/README
index 832df70..5ae05b2 100644
--- a/tools/faust2pd/README
+++ b/tools/faust2pd/README
@@ -3,9 +3,9 @@
 faust2pd: Pd Patch Generator for Faust
 ======================================
 
-Version 2.5, October 20, 2011
+Version @version@, |today|
 
-Albert Graef <Dr.Graef at t-online.de>
+Albert Graef <aggraef at gmail.com>
 
 This package contains software which makes it easier to use Faust DSPs with Pd
 and the Pure programming language. The main component is the faust2pd script
@@ -33,7 +33,7 @@ As of version 2.1, the faust2pd script is now compiled to a native executable
 before installation. This makes the program start up much faster, which is a
 big advantage because most xml files don't take long to be processed.
 
-.. _Pure: http://pure-lang.googlecode.com
+.. _Pure: http://purelang.bitbucket.org
 
 .. contents::
 .. sectnum::
@@ -41,7 +41,7 @@ big advantage because most xml files don't take long to be processed.
 Copying
 =======
 
-Copyright (c) 2009-2011 by Albert Graef.
+Copyright (c) 2009-2014 by Albert Graef.
 
 faust2pd 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
@@ -84,7 +84,7 @@ Installation
 ============
 
 Get the latest source from
-http://pure-lang.googlecode.com/files/faust2pd-2.5.tar.gz.
+https://bitbucket.org/purelang/pure-lang/downloads/faust2pd-@version@.tar.gz.
 
 Run ``make`` and ``make install`` to compile and install the faust2pd program
 on your system. You can set the installation prefix by running make as ``make
@@ -291,7 +291,7 @@ patches illustrating how Faust units are used in Pd.
   multitimbral synth, built with Faust units, in an automatic fashion using a
   pattern sequencer programmed in Pure. This example requires the Pure
   interpreter as well as the pd-pure plugin available from
-  http://pure-lang.googlecode.com.
+  http://purelang.bitbucket.org.
 
 Wrapping DSPs with faust2pd
 ===========================
@@ -356,7 +356,7 @@ work around these limitations.
   milliseconds to the ``faust-delay`` receiver. If you need interactive
   control over the switching time then it is better to use checkboxes instead,
   or you can have faust2pd automatically substitute checkboxes for all buttons
-  in a patch by invoking it with the -f a.k.a. --fake-buttons option.
+  in a patch by invoking it with the -b a.k.a. --fake-buttons option.
 
 - Sliders in Pd do not display their value in numeric form so it may be hard
   to figure out what the current value is. Therefore faust2pd has an option -s
diff --git a/tools/faust2pd/config.guess b/tools/faust2pd/config.guess
index 6cc26cd..e61a66b 100755
--- a/tools/faust2pd/config.guess
+++ b/tools/faust2pd/config.guess
@@ -1,14 +1,14 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-#   Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011, 2012, 2013 Free Software Foundation, Inc.
 
-timestamp='2007-01-15'
+timestamp='2013-08-17'
 
 # This file 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
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -17,26 +17,22 @@ timestamp='2007-01-15'
 # 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., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per at bothner.com>.
-# Please send patches to <config-patches at gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner. 
 #
-# This script attempts to guess a canonical system name similar to
-# config.sub.  If it succeeds, it prints the system name on stdout, and
-# exits with 0.  Otherwise, it exits with 1.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 #
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
+
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -56,8 +52,9 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+2012, 2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -144,7 +141,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
 	# NetBSD (nbsd) targets should (where applicable) match one or
-	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
 	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
 	# switched to ELF, *-*-netbsd* would select the old
 	# object file format.  This provides both forward
@@ -170,7 +167,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-			| grep __ELF__ >/dev/null
+			| grep -q __ELF__
 		then
 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
 		    # Return netbsd for either.  FIX?
@@ -180,7 +177,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		fi
 		;;
 	    *)
-	        os=netbsd
+		os=netbsd
 		;;
 	esac
 	# The OS release
@@ -201,6 +198,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 	echo "${machine}-${os}${release}"
 	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
     *:OpenBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -223,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
 		;;
 	*5.*)
-	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
 		;;
 	esac
 	# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -269,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
 	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	exit ;;
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
     Alpha\ *:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# Should we change UNAME_MACHINE based on the output of uname instead
@@ -295,12 +299,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	echo s390-ibm-zvmoe
 	exit ;;
     *:OS400:*:*)
-        echo powerpc-ibm-os400
+	echo powerpc-ibm-os400
 	exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 	echo arm-acorn-riscix${UNAME_RELEASE}
 	exit ;;
-    arm:riscos:*:*|arm:RISCOS:*:*)
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
 	echo arm-unknown-riscos
 	exit ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -324,14 +328,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	case `/usr/bin/uname -p` in
 	    sparc) echo sparc-icl-nx7; exit ;;
 	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
     sun4H:SunOS:5.*:*)
 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit ;;
-    i86pc:SunOS:5.*:*)
-	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
@@ -375,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+	echo m68k-atari-mint${UNAME_RELEASE}
 	exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
 	echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
+	exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+	echo m68k-atari-mint${UNAME_RELEASE}
 	exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
     m68k:machten:*:*)
 	echo m68k-apple-machten${UNAME_RELEASE}
 	exit ;;
@@ -461,8 +484,8 @@ EOF
 	echo m88k-motorola-sysv3
 	exit ;;
     AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
 	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
 	then
 	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -475,7 +498,7 @@ EOF
 	else
 	    echo i586-dg-dgux${UNAME_RELEASE}
 	fi
- 	exit ;;
+	exit ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
 	echo m88k-dolphin-sysv3
 	exit ;;
@@ -532,7 +555,7 @@ EOF
 		echo rs6000-ibm-aix3.2
 	fi
 	exit ;;
-    *:AIX:*:[45])
+    *:AIX:*:[4567])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
@@ -575,52 +598,52 @@ EOF
 	    9000/[678][0-9][0-9])
 		if [ -x /usr/bin/getconf ]; then
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                    case "${sc_cpu_version}" in
-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
-                      532)                      # CPU_PA_RISC2_0
-                        case "${sc_kernel_bits}" in
-                          32) HP_ARCH="hppa2.0n" ;;
-                          64) HP_ARCH="hppa2.0w" ;;
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
 			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
-                        esac ;;
-                    esac
+			esac ;;
+		    esac
 		fi
 		if [ "${HP_ARCH}" = "" ]; then
 		    eval $set_cc_for_build
-		    sed 's/^              //' << EOF >$dummy.c
+		    sed 's/^		//' << EOF >$dummy.c
 
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
 
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
 
-                  switch (cpu)
-              	{
-              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-              	case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-              	    switch (bits)
-              		{
-              		case 64: puts ("hppa2.0w"); break;
-              		case 32: puts ("hppa2.0n"); break;
-              		default: puts ("hppa2.0"); break;
-              		} break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-              	    puts ("hppa2.0"); break;
-              #endif
-              	default: puts ("hppa1.0"); break;
-              	}
-                  exit (0);
-              }
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
 EOF
 		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -640,7 +663,7 @@ EOF
 	    # => hppa64-hp-hpux11.23
 
 	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
-		grep __LP64__ >/dev/null
+		grep -q __LP64__
 	    then
 		HP_ARCH="hppa2.0w"
 	    else
@@ -711,22 +734,22 @@ EOF
 	exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 	echo c1-convex-bsd
-        exit ;;
+	exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-        exit ;;
+	exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
 	echo c34-convex-bsd
-        exit ;;
+	exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
 	echo c38-convex-bsd
-        exit ;;
+	exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 	echo c4-convex-bsd
-        exit ;;
+	exit ;;
     CRAY*Y-MP:*:*:*)
 	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
@@ -750,14 +773,14 @@ EOF
 	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
 	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit ;;
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
     5000:UNIX_System_V:4.*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -769,37 +792,96 @@ EOF
 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
 	exit ;;
     *:FreeBSD:*:*)
-	case ${UNAME_MACHINE} in
-	    pc98)
-		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
 	    amd64)
 		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 	    *)
-		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 	esac
 	exit ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
 	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
     *:MINGW*:*)
-	echo ${UNAME_MACHINE}-pc-mingw32
+	#echo ${UNAME_MACHINE}-pc-mingw32
+	#exit ;;
+
+	# 2013-8-17 ag: Patch to properly detect the target architecture on
+	# MSYS/MinGW(64) systems. For various reasons this isn't in the
+	# original config.guess, but it suits our purposes. See
+	# http://lists.gnu.org/archive/html/config-patches/2013-03/msg00000.html
+
+        # This uname only tells us that MSYS is in MinGW mode.
+        # The toolchain used might be i686-pc-mingw32
+        # or x86_64-w64-mingw32 - MSYS can't know.
+        # Try cc test.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <stdio.h>
+	__MINGW32__
+	__MINGW64__
+	__MINGW64_VERSION_MAJOR
+EOF
+	if $CC_FOR_BUILD -E $dummy.c 2>/dev/null | \
+	  grep -q __MINGW32__ >/dev/null
+	then
+	    # __MINGW32__ is not defined - this isn't MinGW at all.
+	    :
+	else
+            if $CC_FOR_BUILD -E $dummy.c 2>/dev/null | \
+		grep -q __MINGW64__ >/dev/null
+            then
+        	# 32-bit mingw
+	  	machine=i686
+            else
+        	# 64-bit mingw
+		machine=x86_64
+	    fi
+
+	    if $CC_FOR_BUILD -E $dummy.c 2>/dev/null | \
+		grep -q __MINGW64_VERSION_MAJOR >/dev/null
+	    then
+		# mingw.org toolchain
+    		echo ${machine}-pc-mingw32
+	    else
+		# mingw-w64 toolchain
+    		echo ${machine}-w64-mingw32
+	    fi
+	    exit
+	fi
+	;;
+    i*:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
-    	# uname -m includes "-pc" on this system.
-    	echo ${UNAME_MACHINE}-mingw32
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
 	exit ;;
     i*:PW*:*)
 	echo ${UNAME_MACHINE}-pc-pw32
 	exit ;;
-    x86:Interix*:[3456]*)
-	echo i586-pc-interix${UNAME_RELEASE}
-	exit ;;
-    EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*)
-	echo x86_64-unknown-interix${UNAME_RELEASE}
-	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
     [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
 	echo i${UNAME_MACHINE}-pc-mks
 	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -829,20 +911,68 @@ EOF
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
 	exit ;;
-    arm*:Linux:*:*)
+    aarch64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+	    fi
+	fi
+	exit ;;
     avr32*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
     cris:Linux:*:*)
-	echo cris-axis-linux-gnu
+	echo ${UNAME_MACHINE}-axis-linux-gnu
 	exit ;;
     crisv32:Linux:*:*)
-	echo crisv32-axis-linux-gnu
+	echo ${UNAME_MACHINE}-axis-linux-gnu
 	exit ;;
     frv:Linux:*:*)
-    	echo frv-unknown-linux-gnu
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
 	exit ;;
     ia64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -853,74 +983,33 @@ EOF
     m68*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
-    mips:Linux:*:*)
+    mips:Linux:*:* | mips64:Linux:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 	#undef CPU
-	#undef mips
-	#undef mipsel
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mipsel
+	CPU=${UNAME_MACHINE}el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips
+	CPU=${UNAME_MACHINE}
 	#else
 	CPU=
 	#endif
 	#endif
 EOF
-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-	    /^CPU/{
-		s: ::g
-		p
-	    }'`"
-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
-	;;
-    mips64:Linux:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#undef CPU
-	#undef mips64
-	#undef mips64el
-	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mips64el
-	#else
-	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips64
-	#else
-	CPU=
-	#endif
-	#endif
-EOF
-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-	    /^CPU/{
-		s: ::g
-		p
-	    }'`"
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
 	;;
     or32:Linux:*:*)
-	echo or32-unknown-linux-gnu
-	exit ;;
-    ppc:Linux:*:*)
-	echo powerpc-unknown-linux-gnu
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
-    ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-gnu
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
 	exit ;;
-    alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
-	  EV5)   UNAME_MACHINE=alphaev5 ;;
-	  EV56)  UNAME_MACHINE=alphaev56 ;;
-	  PCA56) UNAME_MACHINE=alphapca56 ;;
-	  PCA57) UNAME_MACHINE=alphapca56 ;;
-	  EV6)   UNAME_MACHINE=alphaev6 ;;
-	  EV67)  UNAME_MACHINE=alphaev67 ;;
-	  EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
-	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
 	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
@@ -930,14 +1019,17 @@ EOF
 	  *)    echo hppa-unknown-linux-gnu ;;
 	esac
 	exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-gnu
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
 	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux
 	exit ;;
     sh64*:Linux:*:*)
-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
     sh*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -945,78 +1037,18 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
     vax:Linux:*:*)
 	echo ${UNAME_MACHINE}-dec-linux-gnu
 	exit ;;
     x86_64:Linux:*:*)
-	echo x86_64-unknown-linux-gnu
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
-    xtensa:Linux:*:*)
-    	echo xtensa-unknown-linux-gnu
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
-    i*86:Linux:*:*)
-	# The BFD linker knows what the default object file format is, so
-	# first see if it will tell us. cd to the root directory to prevent
-	# problems with other programs or directories called `ld' in the path.
-	# Set LC_ALL=C to ensure ld outputs messages in English.
-	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
-			 | sed -ne '/supported targets:/!d
-				    s/[ 	][ 	]*/ /g
-				    s/.*supported targets: *//
-				    s/ .*//
-				    p'`
-        case "$ld_supported_targets" in
-	  elf32-i386)
-		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
-		;;
-	  a.out-i386-linux)
-		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-		exit ;;
-	  coff-i386)
-		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-		exit ;;
-	  "")
-		# Either a pre-BFD a.out linker (linux-gnuoldld) or
-		# one that does not give us useful --help.
-		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
-		exit ;;
-	esac
-	# Determine whether the default compiler is a.out or elf
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#include <features.h>
-	#ifdef __ELF__
-	# ifdef __GLIBC__
-	#  if __GLIBC__ >= 2
-	LIBC=gnu
-	#  else
-	LIBC=gnulibc1
-	#  endif
-	# else
-	LIBC=gnulibc1
-	# endif
-	#else
-	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-	LIBC=gnu
-	#else
-	LIBC=gnuaout
-	#endif
-	#endif
-	#ifdef __dietlibc__
-	LIBC=dietlibc
-	#endif
-EOF
-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-	    /^LIBC/{
-		s: ::g
-		p
-	    }'`"
-	test x"${LIBC}" != x && {
-		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
-		exit
-	}
-	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
-	;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 	# earlier versions are messed up and put the nodename in both
@@ -1024,11 +1056,11 @@ EOF
 	echo i386-sequent-sysv4
 	exit ;;
     i*86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
 	# I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
+	# Use sysv4.2uw... so that sysv4* matches it.
 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
 	exit ;;
     i*86:OS/2:*:*)
@@ -1045,7 +1077,7 @@ EOF
     i*86:syllable:*:*)
 	echo ${UNAME_MACHINE}-pc-syllable
 	exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
 	echo i386-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
     i*86:*DOS:*:*)
@@ -1060,7 +1092,7 @@ EOF
 	fi
 	exit ;;
     i*86:*:5:[678]*)
-    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 	case `/bin/uname -X | grep "^Machine"` in
 	    *486*)	     UNAME_MACHINE=i486 ;;
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
@@ -1088,10 +1120,13 @@ EOF
 	exit ;;
     pc:*:*:*)
 	# Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i386.
-	echo i386-pc-msdosdjgpp
-        exit ;;
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
     Intel:Mach:3*:*)
 	echo i386-pc-mach3
 	exit ;;
@@ -1126,8 +1161,18 @@ EOF
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
 	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && { echo i486-ncr-sysv4; exit; } ;;
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 	echo m68k-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
@@ -1140,7 +1185,7 @@ EOF
     rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
 	echo powerpc-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
     SM[BE]S:UNIX_SV:*:*)
@@ -1160,10 +1205,10 @@ EOF
 		echo ns32k-sni-sysv
 	fi
 	exit ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <Richard.M.Bartel at ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel at ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes at openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
@@ -1189,11 +1234,11 @@ EOF
 	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 	if [ -d /usr/nec ]; then
-	        echo mips-nec-sysv${UNAME_RELEASE}
+		echo mips-nec-sysv${UNAME_RELEASE}
 	else
-	        echo mips-unknown-sysv${UNAME_RELEASE}
+		echo mips-unknown-sysv${UNAME_RELEASE}
 	fi
-        exit ;;
+	exit ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
 	echo powerpc-be-beos
 	exit ;;
@@ -1203,6 +1248,12 @@ EOF
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
 	echo i586-pc-beos
 	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
 	exit ;;
@@ -1230,6 +1281,16 @@ EOF
     *:Darwin:*:*)
 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
 	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
 	    unknown) UNAME_PROCESSOR=powerpc ;;
 	esac
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1245,7 +1306,10 @@ EOF
     *:QNX:*:4*)
 	echo i386-pc-qnx
 	exit ;;
-    NSE-?:NONSTOP_KERNEL:*:*)
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
 	echo nse-tandem-nsk${UNAME_RELEASE}
 	exit ;;
     NSR-?:NONSTOP_KERNEL:*:*)
@@ -1290,13 +1354,13 @@ EOF
 	echo pdp10-unknown-its
 	exit ;;
     SEI:*:*:SEIUX)
-        echo mips-sei-seiux${UNAME_RELEASE}
+	echo mips-sei-seiux${UNAME_RELEASE}
 	exit ;;
     *:DragonFly:*:*)
 	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
 	exit ;;
     *:*VMS:*:*)
-    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
 	case "${UNAME_MACHINE}" in
 	    A*) echo alpha-dec-vms ; exit ;;
 	    I*) echo ia64-dec-vms ; exit ;;
@@ -1311,11 +1375,14 @@ EOF
     i*86:rdos:*:*)
 	echo ${UNAME_MACHINE}-pc-rdos
 	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
 esac
 
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
 eval $set_cc_for_build
 cat >$dummy.c <<EOF
 #ifdef _SEQUENT_
@@ -1333,11 +1400,11 @@ main ()
 #include <sys/param.h>
   printf ("m68k-sony-newsos%s\n",
 #ifdef NEWSOS4
-          "4"
+	"4"
 #else
-	  ""
+	""
 #endif
-         ); exit (0);
+	); exit (0);
 #endif
 #endif
 
@@ -1471,9 +1538,9 @@ This script, last modified $timestamp, has failed to recognize
 the operating system you are using. It is advised that you
 download the most up to date version of the config scripts from
 
-  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 and
-  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
 
 If the version you run ($0) is already up to date, please
 send the following data and any information you think might be
diff --git a/tools/faust2pd/examples/README b/tools/faust2pd/examples/README
index 7f3f975..39adae7 100644
--- a/tools/faust2pd/examples/README
+++ b/tools/faust2pd/examples/README
@@ -9,4 +9,4 @@
 
 - seqdemo/seqdemo.pd: A step sequencer example. The sound generation is done
   with Faust dsps, the sequencer is implemented in Pure. (This needs pd-pure
-  to run, get it at http://pure-lang.googlecode.com/.)
+  to run, get it at http://purelang.bitbucket.org/.)
diff --git a/tools/faust2pd/examples/basic/Makefile b/tools/faust2pd/examples/basic/Makefile
index 0bb0c69..75339ae 100644
--- a/tools/faust2pd/examples/basic/Makefile
+++ b/tools/faust2pd/examples/basic/Makefile
@@ -8,6 +8,11 @@ ifneq "$(findstring -mingw,$(host))" ""
 DLL = .dll
 PDLIB = -Wl,--enable-auto-import -lpd
 endif
+ifneq "$(findstring -darwin,$(host))" ""
+# OSX
+DLL = .pd_darwin
+shared = -dynamiclib -Wl,-undefined -Wl,dynamic_lookup
+endif
 ifneq "$(findstring x86_64-,$(host))" ""
 # 64 bit, needs -fPIC flag
 EXTRA_CFLAGS += -fPIC
@@ -17,13 +22,7 @@ ifneq "$(findstring x86,$(host))" ""
 EXTRA_CFLAGS += -msse -ffast-math
 endif
 
-# Try to figure out the Pd include directory.
-pdincdir = $(strip $(shell pkg-config pd --cflags-only-I 2>/dev/null))
-ifeq "$(pdincdir)" ""
-# Try some common locations.
-pdincdir = $(addprefix -I,$(shell ls -d /usr/local/include/pdextended /usr/local/include/pd /usr/include/pdextended /usr/include/pd 2>/dev/null))
-endif
-EXTRA_CFLAGS += $(pdincdir)
+EXTRA_CFLAGS += -I ../../pd
 
 dspsrc  := $(wildcard *.dsp)
 cppsrc  := $(dspsrc:.dsp=.cpp)
diff --git a/tools/faust2pd/examples/basic/puredata.cpp b/tools/faust2pd/examples/basic/puredata.cpp
new file mode 100644
index 0000000..0e9ff9f
--- /dev/null
+++ b/tools/faust2pd/examples/basic/puredata.cpp
@@ -0,0 +1,636 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2006-2011 Albert Graef <Dr.Graef at t-online.de>
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as 
+	published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+ 	License along with the GNU C Library; if not, write to the Free
+  	Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  	02111-1307 USA. 
+ ************************************************************************
+ ************************************************************************/
+
+/* Pd architecture file, written by Albert Graef <Dr.Graef at t-online.de>.
+   This was derived from minimal.cpp included in the Faust distribution.
+   Please note that this is to be compiled as a shared library, which is
+   then loaded dynamically by Pd as an external. */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string>
+
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/gui/meta.h"
+#include "faust/audio/dsp.h"
+
+//using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/***************************************************************************
+   Pd UI interface
+ ***************************************************************************/
+
+enum ui_elem_type_t {
+  UI_BUTTON, UI_CHECK_BUTTON,
+  UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
+  UI_V_BARGRAPH, UI_H_BARGRAPH,
+  UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
+};
+
+struct ui_elem_t {
+  ui_elem_type_t type;
+  char *label;
+  float *zone;
+  float init, min, max, step;
+};
+
+class PdUI : public UI
+{
+public:
+  const char *name;
+  int nelems, level;
+  ui_elem_t *elems;
+		
+  PdUI();
+  PdUI(const char *nm, const char *s);
+  virtual ~PdUI();
+
+protected:
+  std::string path;
+  void add_elem(ui_elem_type_t type, const char *label = NULL);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float init, float min, float max, float step);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float min, float max);
+
+public:
+  virtual void addButton(const char* label, float* zone);
+  virtual void addCheckButton(const char* label, float* zone);
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+  
+  virtual void openTabBox(const char* label);
+  virtual void openHorizontalBox(const char* label);
+  virtual void openVerticalBox(const char* label);
+  virtual void closeBox();
+	
+  virtual void run();
+};
+
+static std::string mangle(const char *name, int level, const char *s)
+{
+  const char *s0 = s;
+  std::string t = "";
+  if (!s) return t;
+  // Get rid of bogus "0x00" labels in recent Faust revisions. Also, for
+  // backward compatibility with old Faust versions, make sure that default
+  // toplevel groups and explicit toplevel groups with an empty label are
+  // treated alike (these both return "0x00" labels in the latest Faust, but
+  // would be treated inconsistently in earlier versions).
+  if (!*s || strcmp(s, "0x00") == 0) {
+    if (level == 0)
+      // toplevel group with empty label, map to dsp name
+      s = name;
+    else
+      // empty label
+      s = "";
+  }
+  while (*s)
+    if (isalnum(*s))
+      t += *(s++);
+    else {
+      const char *s1 = s;
+      while (*s && !isalnum(*s)) ++s;
+      if (s1 != s0 && *s) t += "-";
+    }
+  return t;
+}
+
+static std::string normpath(std::string path)
+{
+  path = std::string("/")+path;
+  int pos = path.find("//");
+  while (pos >= 0) {
+    path.erase(pos, 1);
+    pos = path.find("//");
+  }
+  size_t len = path.length();
+  if (len > 1 && path[len-1] == '/')
+    path.erase(len-1, 1);
+  return path;
+}
+
+static std::string pathcat(std::string path, std::string label)
+{
+  if (path.empty())
+    return normpath(label);
+  else if (label.empty())
+    return normpath(path);
+  else
+    return normpath(path+"/"+label);
+}
+
+PdUI::PdUI()
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = "";
+  path = "";
+}
+
+PdUI::PdUI(const char *nm, const char *s)
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = nm?nm:"";
+  path = s?s:"";
+}
+
+PdUI::~PdUI()
+{
+  if (elems) {
+    for (int i = 0; i < nelems; i++)
+      if (elems[i].label)
+	free(elems[i].label);
+    free(elems);
+  }
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 1.0;
+  elems[nelems].step = 1.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float init, float min, float max, float step)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = init;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = step;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float min, float max)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+void PdUI::addButton(const char* label, float* zone)
+{ add_elem(UI_BUTTON, label, zone); }
+void PdUI::addCheckButton(const char* label, float* zone)
+{ add_elem(UI_CHECK_BUTTON, label, zone); }
+void PdUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
+
+void PdUI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_H_BARGRAPH, label, zone, min, max); }
+void PdUI::addVerticalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_V_BARGRAPH, label, zone, min, max); }
+
+void PdUI::openTabBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openHorizontalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openVerticalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::closeBox()
+{
+  int pos = path.rfind("/");
+  if (pos < 0) pos = 0;
+  path.erase(pos);
+  level--;
+}
+
+void PdUI::run() {}
+
+/******************************************************************************
+*******************************************************************************
+
+			    FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+		
+<<includeclass>>
+
+#include <stdio.h>
+#include <string>
+#include "m_pd.h"
+
+#define sym(name) xsym(name)
+#define xsym(name) #name
+#define faust_setup(name) xfaust_setup(name)
+#define xfaust_setup(name) name ## _tilde_setup(void)
+
+// time for "active" toggle xfades in secs
+#define XFADE_TIME 0.1f
+
+static t_class *faust_class;
+
+struct t_faust {
+  t_object x_obj;
+#ifdef __MINGW32__
+  /* This seems to be necessary as some as yet undetermined Pd routine seems
+     to write past the end of x_obj on Windows. */
+  int fence; /* dummy field (not used) */
+#endif
+  mydsp *dsp;
+  PdUI *ui;
+  std::string *label;
+  int active, xfade, n_xfade, rate, n_in, n_out;
+  t_sample **inputs, **outputs, **buf;
+  t_outlet *out;
+  t_sample f;
+};
+
+static t_symbol *s_button, *s_checkbox, *s_vslider, *s_hslider, *s_nentry,
+  *s_vbargraph, *s_hbargraph;
+
+static inline void zero_samples(int k, int n, t_sample **out)
+{
+  for (int i = 0; i < k; i++)
+#ifdef __STDC_IEC_559__
+    /* IEC 559 a.k.a. IEEE 754 floats can be initialized faster like this */
+    memset(out[i], 0, n*sizeof(t_sample));
+#else
+    for (int j = 0; j < n; j++)
+      out[i][j] = 0.0f;
+#endif
+}
+
+static inline void copy_samples(int k, int n, t_sample **out, t_sample **in)
+{
+  for (int i = 0; i < k; i++)
+    memcpy(out[i], in[i], n*sizeof(t_sample));
+}
+
+static t_int *faust_perform(t_int *w)
+{
+  t_faust *x = (t_faust *)(w[1]);
+  int n = (int)(w[2]);
+  if (!x->dsp || !x->buf) return (w+3);
+  AVOIDDENORMALS;
+  if (x->xfade > 0) {
+    float d = 1.0f/x->n_xfade, f = (x->xfade--)*d;
+    d = d/n;
+    x->dsp->compute(n, x->inputs, x->buf);
+    if (x->active)
+      if (x->n_in == x->n_out)
+	/* xfade inputs -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->inputs[i][j]+(1.0f-f)*x->buf[i][j];
+      else
+	/* xfade 0 -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = (1.0f-f)*x->buf[i][j];
+    else
+      if (x->n_in == x->n_out)
+	/* xfade buf -> inputs */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j]+(1.0f-f)*x->inputs[i][j];
+      else
+	/* xfade buf -> 0 */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j];
+  } else if (x->active) {
+    x->dsp->compute(n, x->inputs, x->buf);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else if (x->n_in == x->n_out) {
+    copy_samples(x->n_out, n, x->buf, x->inputs);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else
+    zero_samples(x->n_out, n, x->outputs);
+  return (w+3);
+}
+
+static void faust_dsp(t_faust *x, t_signal **sp)
+{
+  int n = sp[0]->s_n, sr = (int)sp[0]->s_sr;
+  if (x->rate <= 0) {
+    /* default sample rate is whatever Pd tells us */
+    PdUI *ui = x->ui;
+    float *z = NULL;
+    if (ui->nelems > 0 &&
+	(z = (float*)malloc(ui->nelems*sizeof(float)))) {
+      /* save the current control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  z[i] = *ui->elems[i].zone;
+    }
+    /* set the proper sample rate; this requires reinitializing the dsp */
+    x->rate = sr;
+    x->dsp->init(sr);
+    if (z) {
+      /* restore previous control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  *ui->elems[i].zone = z[i];
+      free(z);
+    }
+  }
+  if (n > 0)
+    x->n_xfade = (int)(x->rate*XFADE_TIME/n);
+  dsp_add(faust_perform, 2, x, n);
+  for (int i = 0; i < x->n_in; i++)
+    x->inputs[i] = sp[i+1]->s_vec;
+  for (int i = 0; i < x->n_out; i++)
+    x->outputs[i] = sp[x->n_in+i+1]->s_vec;
+  if (x->buf != NULL)
+    for (int i = 0; i < x->n_out; i++) {
+      x->buf[i] = (t_sample*)malloc(n*sizeof(t_sample));
+      if (x->buf[i] == NULL) {
+	for (int j = 0; j < i; j++)
+	  free(x->buf[j]);
+	free(x->buf);
+	x->buf = NULL;
+	break;
+      }
+    }
+}
+
+static int pathcmp(const char *s, const char *t)
+{
+  int n = strlen(s), m = strlen(t);
+  if (n == 0 || m == 0)
+    return 0;
+  else if (t[0] == '/')
+    return strcmp(s, t);
+  else if (n <= m || s[n-m-1] != '/')
+    return strcmp(s+1, t);
+  else
+    return strcmp(s+n-m, t);
+}
+
+static void faust_any(t_faust *x, t_symbol *s, int argc, t_atom *argv)
+{
+  if (!x->dsp) return;
+  PdUI *ui = x->ui;
+  if (s == &s_bang) {
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label && ui->elems[i].zone) {
+	t_atom args[6];
+	t_symbol *_s;
+	switch (ui->elems[i].type) {
+	case UI_BUTTON:
+	  _s = s_button;
+	  break;
+	case UI_CHECK_BUTTON:
+	  _s = s_checkbox;
+	  break;
+	case UI_V_SLIDER:
+	  _s = s_vslider;
+	  break;
+	case UI_H_SLIDER:
+	  _s = s_hslider;
+	  break;
+	case UI_NUM_ENTRY:
+	  _s = s_nentry;
+	  break;
+	case UI_V_BARGRAPH:
+	  _s = s_vbargraph;
+	  break;
+	case UI_H_BARGRAPH:
+	  _s = s_hbargraph;
+	  break;
+	default:
+	  continue;
+	}
+	SETSYMBOL(&args[0], gensym(ui->elems[i].label));
+	SETFLOAT(&args[1], *ui->elems[i].zone);
+	SETFLOAT(&args[2], ui->elems[i].init);
+	SETFLOAT(&args[3], ui->elems[i].min);
+	SETFLOAT(&args[4], ui->elems[i].max);
+	SETFLOAT(&args[5], ui->elems[i].step);
+	outlet_anything(x->out, _s, 6, args);
+      }
+  } else {
+    const char *label = s->s_name;
+    int count = 0;
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label &&
+	  pathcmp(ui->elems[i].label, label) == 0) {
+	if (argc == 0) {
+	  if (ui->elems[i].zone) {
+	    t_atom arg;
+	    SETFLOAT(&arg, *ui->elems[i].zone);
+	    outlet_anything(x->out, gensym(ui->elems[i].label), 1, &arg);
+	  }
+	  ++count;
+	} else if (argc == 1 &&
+		   (argv[0].a_type == A_FLOAT ||
+		    argv[0].a_type == A_DEFFLOAT) &&
+		   ui->elems[i].zone) {
+	  float f = atom_getfloat(argv);
+	  *ui->elems[i].zone = f;
+	  ++count;
+	} else
+	  pd_error(x, "[faust] %s: bad control argument: %s",
+		   x->label->c_str(), label);
+      }
+    if (count == 0 && strcmp(label, "active") == 0) {
+      if (argc == 0) {
+	t_atom arg;
+	SETFLOAT(&arg, (float)x->active);
+	outlet_anything(x->out, gensym((char*)"active"), 1, &arg);
+      } else if (argc == 1 &&
+		 (argv[0].a_type == A_FLOAT ||
+		  argv[0].a_type == A_DEFFLOAT)) {
+	float f = atom_getfloat(argv);
+	x->active = (int)f;
+	x->xfade = x->n_xfade;
+      }
+    }
+  }
+}
+
+static void faust_free(t_faust *x)
+{
+  if (x->label) delete x->label;
+  if (x->dsp) delete x->dsp;
+  if (x->ui) delete x->ui;
+  if (x->inputs) free(x->inputs);
+  if (x->outputs) free(x->outputs);
+  if (x->buf) {
+    for (int i = 0; i < x->n_out; i++)
+      if (x->buf[i]) free(x->buf[i]);
+    free(x->buf);
+  }
+}
+
+static void *faust_new(t_symbol *s, int argc, t_atom *argv)
+{
+  t_faust *x = (t_faust*)pd_new(faust_class);
+  int sr = -1;
+  t_symbol *id = NULL;
+  x->active = 1;
+  for (int i = 0; i < argc; i++)
+    if (argv[i].a_type == A_FLOAT || argv[i].a_type == A_DEFFLOAT)
+      sr = (int)argv[i].a_w.w_float;
+    else if (argv[i].a_type == A_SYMBOL || argv[i].a_type == A_DEFSYMBOL)
+      id = argv[i].a_w.w_symbol;
+  x->rate = sr;
+  if (sr <= 0) sr = 44100;
+  x->xfade = 0; x->n_xfade = (int)(sr*XFADE_TIME/64);
+  x->inputs = x->outputs = x->buf = NULL;
+    x->label = new std::string(sym(mydsp) "~");
+  x->dsp = new mydsp();
+  x->ui = new PdUI(sym(mydsp), id?id->s_name:NULL);
+  if (!x->dsp || !x->ui || !x->label) goto error;
+  if (id) {
+    *x->label += " ";
+    *x->label += id->s_name;
+  }
+  x->n_in = x->dsp->getNumInputs();
+  x->n_out = x->dsp->getNumOutputs();
+  if (x->n_in > 0)
+    x->inputs = (t_sample**)malloc(x->n_in*sizeof(t_sample*));
+  if (x->n_out > 0) {
+    x->outputs = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+    x->buf = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+  }
+  if ((x->n_in > 0 && x->inputs == NULL) ||
+      (x->n_out > 0 && (x->outputs == NULL || x->buf == NULL)))
+    goto error;
+  for (int i = 0; i < x->n_out; i++)
+    x->buf[i] = NULL;
+  x->dsp->init(sr);
+  x->dsp->buildUserInterface(x->ui);
+  for (int i = 0; i < x->n_in; i++)
+    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+  x->out = outlet_new(&x->x_obj, 0);
+  for (int i = 0; i < x->n_out; i++)
+    outlet_new(&x->x_obj, &s_signal);
+  return (void *)x;
+ error:
+  faust_free(x);
+  x->dsp = NULL; x->ui = NULL;
+  x->inputs = x->outputs = x->buf = NULL;
+  return (void *)x;
+}
+
+extern "C" void faust_setup(mydsp)
+{
+  t_symbol *s = gensym(sym(mydsp) "~");
+  faust_class =
+    class_new(s, (t_newmethod)faust_new, (t_method)faust_free,
+	      sizeof(t_faust), CLASS_DEFAULT,
+	      A_GIMME, A_NULL);
+  class_addmethod(faust_class, (t_method)faust_dsp, gensym((char*)"dsp"), A_NULL);
+  class_addanything(faust_class, faust_any);
+  class_addmethod(faust_class, nullfn, &s_signal, A_NULL);
+  s_button = gensym((char*)"button");
+  s_checkbox = gensym((char*)"checkbox");
+  s_vslider = gensym((char*)"vslider");
+  s_hslider = gensym((char*)"hslider");
+  s_nentry = gensym((char*)"nentry");
+  s_vbargraph = gensym((char*)"vbargraph");
+  s_hbargraph = gensym((char*)"hbargraph");
+  /* give some indication that we're loaded and ready to go */
+  mydsp dsp = mydsp();
+  post("[faust] %s: %d inputs, %d outputs", sym(mydsp) "~",
+       dsp.getNumInputs(), dsp.getNumOutputs());
+}
diff --git a/tools/faust2pd/examples/faust/Makefile b/tools/faust2pd/examples/faust/Makefile
index 17c12a3..e96df3e 100644
--- a/tools/faust2pd/examples/faust/Makefile
+++ b/tools/faust2pd/examples/faust/Makefile
@@ -8,6 +8,11 @@ ifneq "$(findstring -mingw,$(host))" ""
 DLL = .dll
 PDLIB = -Wl,--enable-auto-import -lpd
 endif
+ifneq "$(findstring -darwin,$(host))" ""
+# OSX
+DLL = .pd_darwin
+shared = -dynamiclib -Wl,-undefined -Wl,dynamic_lookup
+endif
 ifneq "$(findstring x86_64-,$(host))" ""
 # 64 bit, needs -fPIC flag
 EXTRA_CFLAGS += -fPIC
@@ -17,13 +22,7 @@ ifneq "$(findstring x86,$(host))" ""
 EXTRA_CFLAGS += -msse -ffast-math
 endif
 
-# Try to figure out the Pd include directory.
-pdincdir = $(strip $(shell pkg-config pd --cflags-only-I 2>/dev/null))
-ifeq "$(pdincdir)" ""
-# Try some common locations.
-pdincdir = $(addprefix -I,$(shell ls -d /usr/local/include/pdextended /usr/local/include/pd /usr/include/pdextended /usr/include/pd 2>/dev/null))
-endif
-EXTRA_CFLAGS += $(pdincdir)
+EXTRA_CFLAGS += -I ../../pd
 
 dspsrc  := $(wildcard *.dsp)
 cppsrc  := $(dspsrc:.dsp=.cpp)
diff --git a/tools/faust2pd/examples/faust/puredata.cpp b/tools/faust2pd/examples/faust/puredata.cpp
new file mode 100644
index 0000000..0e9ff9f
--- /dev/null
+++ b/tools/faust2pd/examples/faust/puredata.cpp
@@ -0,0 +1,636 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2006-2011 Albert Graef <Dr.Graef at t-online.de>
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as 
+	published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+ 	License along with the GNU C Library; if not, write to the Free
+  	Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  	02111-1307 USA. 
+ ************************************************************************
+ ************************************************************************/
+
+/* Pd architecture file, written by Albert Graef <Dr.Graef at t-online.de>.
+   This was derived from minimal.cpp included in the Faust distribution.
+   Please note that this is to be compiled as a shared library, which is
+   then loaded dynamically by Pd as an external. */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string>
+
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/gui/meta.h"
+#include "faust/audio/dsp.h"
+
+//using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/***************************************************************************
+   Pd UI interface
+ ***************************************************************************/
+
+enum ui_elem_type_t {
+  UI_BUTTON, UI_CHECK_BUTTON,
+  UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
+  UI_V_BARGRAPH, UI_H_BARGRAPH,
+  UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
+};
+
+struct ui_elem_t {
+  ui_elem_type_t type;
+  char *label;
+  float *zone;
+  float init, min, max, step;
+};
+
+class PdUI : public UI
+{
+public:
+  const char *name;
+  int nelems, level;
+  ui_elem_t *elems;
+		
+  PdUI();
+  PdUI(const char *nm, const char *s);
+  virtual ~PdUI();
+
+protected:
+  std::string path;
+  void add_elem(ui_elem_type_t type, const char *label = NULL);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float init, float min, float max, float step);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float min, float max);
+
+public:
+  virtual void addButton(const char* label, float* zone);
+  virtual void addCheckButton(const char* label, float* zone);
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+  
+  virtual void openTabBox(const char* label);
+  virtual void openHorizontalBox(const char* label);
+  virtual void openVerticalBox(const char* label);
+  virtual void closeBox();
+	
+  virtual void run();
+};
+
+static std::string mangle(const char *name, int level, const char *s)
+{
+  const char *s0 = s;
+  std::string t = "";
+  if (!s) return t;
+  // Get rid of bogus "0x00" labels in recent Faust revisions. Also, for
+  // backward compatibility with old Faust versions, make sure that default
+  // toplevel groups and explicit toplevel groups with an empty label are
+  // treated alike (these both return "0x00" labels in the latest Faust, but
+  // would be treated inconsistently in earlier versions).
+  if (!*s || strcmp(s, "0x00") == 0) {
+    if (level == 0)
+      // toplevel group with empty label, map to dsp name
+      s = name;
+    else
+      // empty label
+      s = "";
+  }
+  while (*s)
+    if (isalnum(*s))
+      t += *(s++);
+    else {
+      const char *s1 = s;
+      while (*s && !isalnum(*s)) ++s;
+      if (s1 != s0 && *s) t += "-";
+    }
+  return t;
+}
+
+static std::string normpath(std::string path)
+{
+  path = std::string("/")+path;
+  int pos = path.find("//");
+  while (pos >= 0) {
+    path.erase(pos, 1);
+    pos = path.find("//");
+  }
+  size_t len = path.length();
+  if (len > 1 && path[len-1] == '/')
+    path.erase(len-1, 1);
+  return path;
+}
+
+static std::string pathcat(std::string path, std::string label)
+{
+  if (path.empty())
+    return normpath(label);
+  else if (label.empty())
+    return normpath(path);
+  else
+    return normpath(path+"/"+label);
+}
+
+PdUI::PdUI()
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = "";
+  path = "";
+}
+
+PdUI::PdUI(const char *nm, const char *s)
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = nm?nm:"";
+  path = s?s:"";
+}
+
+PdUI::~PdUI()
+{
+  if (elems) {
+    for (int i = 0; i < nelems; i++)
+      if (elems[i].label)
+	free(elems[i].label);
+    free(elems);
+  }
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 1.0;
+  elems[nelems].step = 1.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float init, float min, float max, float step)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = init;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = step;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float min, float max)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+void PdUI::addButton(const char* label, float* zone)
+{ add_elem(UI_BUTTON, label, zone); }
+void PdUI::addCheckButton(const char* label, float* zone)
+{ add_elem(UI_CHECK_BUTTON, label, zone); }
+void PdUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
+
+void PdUI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_H_BARGRAPH, label, zone, min, max); }
+void PdUI::addVerticalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_V_BARGRAPH, label, zone, min, max); }
+
+void PdUI::openTabBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openHorizontalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openVerticalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::closeBox()
+{
+  int pos = path.rfind("/");
+  if (pos < 0) pos = 0;
+  path.erase(pos);
+  level--;
+}
+
+void PdUI::run() {}
+
+/******************************************************************************
+*******************************************************************************
+
+			    FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+		
+<<includeclass>>
+
+#include <stdio.h>
+#include <string>
+#include "m_pd.h"
+
+#define sym(name) xsym(name)
+#define xsym(name) #name
+#define faust_setup(name) xfaust_setup(name)
+#define xfaust_setup(name) name ## _tilde_setup(void)
+
+// time for "active" toggle xfades in secs
+#define XFADE_TIME 0.1f
+
+static t_class *faust_class;
+
+struct t_faust {
+  t_object x_obj;
+#ifdef __MINGW32__
+  /* This seems to be necessary as some as yet undetermined Pd routine seems
+     to write past the end of x_obj on Windows. */
+  int fence; /* dummy field (not used) */
+#endif
+  mydsp *dsp;
+  PdUI *ui;
+  std::string *label;
+  int active, xfade, n_xfade, rate, n_in, n_out;
+  t_sample **inputs, **outputs, **buf;
+  t_outlet *out;
+  t_sample f;
+};
+
+static t_symbol *s_button, *s_checkbox, *s_vslider, *s_hslider, *s_nentry,
+  *s_vbargraph, *s_hbargraph;
+
+static inline void zero_samples(int k, int n, t_sample **out)
+{
+  for (int i = 0; i < k; i++)
+#ifdef __STDC_IEC_559__
+    /* IEC 559 a.k.a. IEEE 754 floats can be initialized faster like this */
+    memset(out[i], 0, n*sizeof(t_sample));
+#else
+    for (int j = 0; j < n; j++)
+      out[i][j] = 0.0f;
+#endif
+}
+
+static inline void copy_samples(int k, int n, t_sample **out, t_sample **in)
+{
+  for (int i = 0; i < k; i++)
+    memcpy(out[i], in[i], n*sizeof(t_sample));
+}
+
+static t_int *faust_perform(t_int *w)
+{
+  t_faust *x = (t_faust *)(w[1]);
+  int n = (int)(w[2]);
+  if (!x->dsp || !x->buf) return (w+3);
+  AVOIDDENORMALS;
+  if (x->xfade > 0) {
+    float d = 1.0f/x->n_xfade, f = (x->xfade--)*d;
+    d = d/n;
+    x->dsp->compute(n, x->inputs, x->buf);
+    if (x->active)
+      if (x->n_in == x->n_out)
+	/* xfade inputs -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->inputs[i][j]+(1.0f-f)*x->buf[i][j];
+      else
+	/* xfade 0 -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = (1.0f-f)*x->buf[i][j];
+    else
+      if (x->n_in == x->n_out)
+	/* xfade buf -> inputs */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j]+(1.0f-f)*x->inputs[i][j];
+      else
+	/* xfade buf -> 0 */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j];
+  } else if (x->active) {
+    x->dsp->compute(n, x->inputs, x->buf);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else if (x->n_in == x->n_out) {
+    copy_samples(x->n_out, n, x->buf, x->inputs);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else
+    zero_samples(x->n_out, n, x->outputs);
+  return (w+3);
+}
+
+static void faust_dsp(t_faust *x, t_signal **sp)
+{
+  int n = sp[0]->s_n, sr = (int)sp[0]->s_sr;
+  if (x->rate <= 0) {
+    /* default sample rate is whatever Pd tells us */
+    PdUI *ui = x->ui;
+    float *z = NULL;
+    if (ui->nelems > 0 &&
+	(z = (float*)malloc(ui->nelems*sizeof(float)))) {
+      /* save the current control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  z[i] = *ui->elems[i].zone;
+    }
+    /* set the proper sample rate; this requires reinitializing the dsp */
+    x->rate = sr;
+    x->dsp->init(sr);
+    if (z) {
+      /* restore previous control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  *ui->elems[i].zone = z[i];
+      free(z);
+    }
+  }
+  if (n > 0)
+    x->n_xfade = (int)(x->rate*XFADE_TIME/n);
+  dsp_add(faust_perform, 2, x, n);
+  for (int i = 0; i < x->n_in; i++)
+    x->inputs[i] = sp[i+1]->s_vec;
+  for (int i = 0; i < x->n_out; i++)
+    x->outputs[i] = sp[x->n_in+i+1]->s_vec;
+  if (x->buf != NULL)
+    for (int i = 0; i < x->n_out; i++) {
+      x->buf[i] = (t_sample*)malloc(n*sizeof(t_sample));
+      if (x->buf[i] == NULL) {
+	for (int j = 0; j < i; j++)
+	  free(x->buf[j]);
+	free(x->buf);
+	x->buf = NULL;
+	break;
+      }
+    }
+}
+
+static int pathcmp(const char *s, const char *t)
+{
+  int n = strlen(s), m = strlen(t);
+  if (n == 0 || m == 0)
+    return 0;
+  else if (t[0] == '/')
+    return strcmp(s, t);
+  else if (n <= m || s[n-m-1] != '/')
+    return strcmp(s+1, t);
+  else
+    return strcmp(s+n-m, t);
+}
+
+static void faust_any(t_faust *x, t_symbol *s, int argc, t_atom *argv)
+{
+  if (!x->dsp) return;
+  PdUI *ui = x->ui;
+  if (s == &s_bang) {
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label && ui->elems[i].zone) {
+	t_atom args[6];
+	t_symbol *_s;
+	switch (ui->elems[i].type) {
+	case UI_BUTTON:
+	  _s = s_button;
+	  break;
+	case UI_CHECK_BUTTON:
+	  _s = s_checkbox;
+	  break;
+	case UI_V_SLIDER:
+	  _s = s_vslider;
+	  break;
+	case UI_H_SLIDER:
+	  _s = s_hslider;
+	  break;
+	case UI_NUM_ENTRY:
+	  _s = s_nentry;
+	  break;
+	case UI_V_BARGRAPH:
+	  _s = s_vbargraph;
+	  break;
+	case UI_H_BARGRAPH:
+	  _s = s_hbargraph;
+	  break;
+	default:
+	  continue;
+	}
+	SETSYMBOL(&args[0], gensym(ui->elems[i].label));
+	SETFLOAT(&args[1], *ui->elems[i].zone);
+	SETFLOAT(&args[2], ui->elems[i].init);
+	SETFLOAT(&args[3], ui->elems[i].min);
+	SETFLOAT(&args[4], ui->elems[i].max);
+	SETFLOAT(&args[5], ui->elems[i].step);
+	outlet_anything(x->out, _s, 6, args);
+      }
+  } else {
+    const char *label = s->s_name;
+    int count = 0;
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label &&
+	  pathcmp(ui->elems[i].label, label) == 0) {
+	if (argc == 0) {
+	  if (ui->elems[i].zone) {
+	    t_atom arg;
+	    SETFLOAT(&arg, *ui->elems[i].zone);
+	    outlet_anything(x->out, gensym(ui->elems[i].label), 1, &arg);
+	  }
+	  ++count;
+	} else if (argc == 1 &&
+		   (argv[0].a_type == A_FLOAT ||
+		    argv[0].a_type == A_DEFFLOAT) &&
+		   ui->elems[i].zone) {
+	  float f = atom_getfloat(argv);
+	  *ui->elems[i].zone = f;
+	  ++count;
+	} else
+	  pd_error(x, "[faust] %s: bad control argument: %s",
+		   x->label->c_str(), label);
+      }
+    if (count == 0 && strcmp(label, "active") == 0) {
+      if (argc == 0) {
+	t_atom arg;
+	SETFLOAT(&arg, (float)x->active);
+	outlet_anything(x->out, gensym((char*)"active"), 1, &arg);
+      } else if (argc == 1 &&
+		 (argv[0].a_type == A_FLOAT ||
+		  argv[0].a_type == A_DEFFLOAT)) {
+	float f = atom_getfloat(argv);
+	x->active = (int)f;
+	x->xfade = x->n_xfade;
+      }
+    }
+  }
+}
+
+static void faust_free(t_faust *x)
+{
+  if (x->label) delete x->label;
+  if (x->dsp) delete x->dsp;
+  if (x->ui) delete x->ui;
+  if (x->inputs) free(x->inputs);
+  if (x->outputs) free(x->outputs);
+  if (x->buf) {
+    for (int i = 0; i < x->n_out; i++)
+      if (x->buf[i]) free(x->buf[i]);
+    free(x->buf);
+  }
+}
+
+static void *faust_new(t_symbol *s, int argc, t_atom *argv)
+{
+  t_faust *x = (t_faust*)pd_new(faust_class);
+  int sr = -1;
+  t_symbol *id = NULL;
+  x->active = 1;
+  for (int i = 0; i < argc; i++)
+    if (argv[i].a_type == A_FLOAT || argv[i].a_type == A_DEFFLOAT)
+      sr = (int)argv[i].a_w.w_float;
+    else if (argv[i].a_type == A_SYMBOL || argv[i].a_type == A_DEFSYMBOL)
+      id = argv[i].a_w.w_symbol;
+  x->rate = sr;
+  if (sr <= 0) sr = 44100;
+  x->xfade = 0; x->n_xfade = (int)(sr*XFADE_TIME/64);
+  x->inputs = x->outputs = x->buf = NULL;
+    x->label = new std::string(sym(mydsp) "~");
+  x->dsp = new mydsp();
+  x->ui = new PdUI(sym(mydsp), id?id->s_name:NULL);
+  if (!x->dsp || !x->ui || !x->label) goto error;
+  if (id) {
+    *x->label += " ";
+    *x->label += id->s_name;
+  }
+  x->n_in = x->dsp->getNumInputs();
+  x->n_out = x->dsp->getNumOutputs();
+  if (x->n_in > 0)
+    x->inputs = (t_sample**)malloc(x->n_in*sizeof(t_sample*));
+  if (x->n_out > 0) {
+    x->outputs = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+    x->buf = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+  }
+  if ((x->n_in > 0 && x->inputs == NULL) ||
+      (x->n_out > 0 && (x->outputs == NULL || x->buf == NULL)))
+    goto error;
+  for (int i = 0; i < x->n_out; i++)
+    x->buf[i] = NULL;
+  x->dsp->init(sr);
+  x->dsp->buildUserInterface(x->ui);
+  for (int i = 0; i < x->n_in; i++)
+    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+  x->out = outlet_new(&x->x_obj, 0);
+  for (int i = 0; i < x->n_out; i++)
+    outlet_new(&x->x_obj, &s_signal);
+  return (void *)x;
+ error:
+  faust_free(x);
+  x->dsp = NULL; x->ui = NULL;
+  x->inputs = x->outputs = x->buf = NULL;
+  return (void *)x;
+}
+
+extern "C" void faust_setup(mydsp)
+{
+  t_symbol *s = gensym(sym(mydsp) "~");
+  faust_class =
+    class_new(s, (t_newmethod)faust_new, (t_method)faust_free,
+	      sizeof(t_faust), CLASS_DEFAULT,
+	      A_GIMME, A_NULL);
+  class_addmethod(faust_class, (t_method)faust_dsp, gensym((char*)"dsp"), A_NULL);
+  class_addanything(faust_class, faust_any);
+  class_addmethod(faust_class, nullfn, &s_signal, A_NULL);
+  s_button = gensym((char*)"button");
+  s_checkbox = gensym((char*)"checkbox");
+  s_vslider = gensym((char*)"vslider");
+  s_hslider = gensym((char*)"hslider");
+  s_nentry = gensym((char*)"nentry");
+  s_vbargraph = gensym((char*)"vbargraph");
+  s_hbargraph = gensym((char*)"hbargraph");
+  /* give some indication that we're loaded and ready to go */
+  mydsp dsp = mydsp();
+  post("[faust] %s: %d inputs, %d outputs", sym(mydsp) "~",
+       dsp.getNumInputs(), dsp.getNumOutputs());
+}
diff --git a/tools/faust2pd/examples/seqdemo/Makefile b/tools/faust2pd/examples/seqdemo/Makefile
index b58f8fc..64ae2e5 100644
--- a/tools/faust2pd/examples/seqdemo/Makefile
+++ b/tools/faust2pd/examples/seqdemo/Makefile
@@ -8,6 +8,11 @@ ifneq "$(findstring -mingw,$(host))" ""
 DLL = .dll
 PDLIB = -Wl,--enable-auto-import -lpd
 endif
+ifneq "$(findstring -darwin,$(host))" ""
+# OSX
+DLL = .pd_darwin
+shared = -dynamiclib -Wl,-undefined -Wl,dynamic_lookup
+endif
 ifneq "$(findstring x86_64-,$(host))" ""
 # 64 bit, needs -fPIC flag
 EXTRA_CFLAGS += -fPIC
@@ -17,13 +22,7 @@ ifneq "$(findstring x86,$(host))" ""
 EXTRA_CFLAGS += -msse -ffast-math
 endif
 
-# Try to figure out the Pd include directory.
-pdincdir = $(strip $(shell pkg-config pd --cflags-only-I 2>/dev/null))
-ifeq "$(pdincdir)" ""
-# Try some common locations.
-pdincdir = $(addprefix -I,$(shell ls -d /usr/local/include/pdextended /usr/local/include/pd /usr/include/pdextended /usr/include/pd 2>/dev/null))
-endif
-EXTRA_CFLAGS += $(pdincdir)
+EXTRA_CFLAGS += -I ../../pd
 
 dspsrc  := $(wildcard *.dsp)
 cppsrc  := $(dspsrc:.dsp=.cpp)
diff --git a/tools/faust2pd/examples/seqdemo/chorus.dsp b/tools/faust2pd/examples/seqdemo/chorus.dsp
index 96873bd..1f8fc90 100644
--- a/tools/faust2pd/examples/seqdemo/chorus.dsp
+++ b/tools/faust2pd/examples/seqdemo/chorus.dsp
@@ -12,10 +12,10 @@ freq	= hslider("freq", 2, 0, 10, 0.01);
 dtime	= hslider("delay", 0.025, 0, 0.2, 0.001);
 depth	= hslider("depth", 0.02, 0, 1, 0.001);
 
-tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,waveform,i&(n-1)) +
-			  d*rdtable(n,waveform,(i+1)&(n-1))
+tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,wave,i&(n-1)) +
+			  d*rdtable(n,wave,(i+1)&(n-1))
 with {
-	waveform 	= time*(2.0*PI)/n : f;
+	wave	 	= time*(2.0*PI)/n : f;
 	phase		= freq/SR : (+ : decimal) ~ _;
 	modphase	= decimal(phase+mod/(2*PI))*n;
 	i		= int(floor(modphase));
diff --git a/tools/faust2pd/examples/seqdemo/puredata.cpp b/tools/faust2pd/examples/seqdemo/puredata.cpp
new file mode 100644
index 0000000..0e9ff9f
--- /dev/null
+++ b/tools/faust2pd/examples/seqdemo/puredata.cpp
@@ -0,0 +1,636 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2006-2011 Albert Graef <Dr.Graef at t-online.de>
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as 
+	published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+ 	License along with the GNU C Library; if not, write to the Free
+  	Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  	02111-1307 USA. 
+ ************************************************************************
+ ************************************************************************/
+
+/* Pd architecture file, written by Albert Graef <Dr.Graef at t-online.de>.
+   This was derived from minimal.cpp included in the Faust distribution.
+   Please note that this is to be compiled as a shared library, which is
+   then loaded dynamically by Pd as an external. */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string>
+
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/gui/meta.h"
+#include "faust/audio/dsp.h"
+
+//using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/***************************************************************************
+   Pd UI interface
+ ***************************************************************************/
+
+enum ui_elem_type_t {
+  UI_BUTTON, UI_CHECK_BUTTON,
+  UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
+  UI_V_BARGRAPH, UI_H_BARGRAPH,
+  UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
+};
+
+struct ui_elem_t {
+  ui_elem_type_t type;
+  char *label;
+  float *zone;
+  float init, min, max, step;
+};
+
+class PdUI : public UI
+{
+public:
+  const char *name;
+  int nelems, level;
+  ui_elem_t *elems;
+		
+  PdUI();
+  PdUI(const char *nm, const char *s);
+  virtual ~PdUI();
+
+protected:
+  std::string path;
+  void add_elem(ui_elem_type_t type, const char *label = NULL);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float init, float min, float max, float step);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float min, float max);
+
+public:
+  virtual void addButton(const char* label, float* zone);
+  virtual void addCheckButton(const char* label, float* zone);
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+  
+  virtual void openTabBox(const char* label);
+  virtual void openHorizontalBox(const char* label);
+  virtual void openVerticalBox(const char* label);
+  virtual void closeBox();
+	
+  virtual void run();
+};
+
+static std::string mangle(const char *name, int level, const char *s)
+{
+  const char *s0 = s;
+  std::string t = "";
+  if (!s) return t;
+  // Get rid of bogus "0x00" labels in recent Faust revisions. Also, for
+  // backward compatibility with old Faust versions, make sure that default
+  // toplevel groups and explicit toplevel groups with an empty label are
+  // treated alike (these both return "0x00" labels in the latest Faust, but
+  // would be treated inconsistently in earlier versions).
+  if (!*s || strcmp(s, "0x00") == 0) {
+    if (level == 0)
+      // toplevel group with empty label, map to dsp name
+      s = name;
+    else
+      // empty label
+      s = "";
+  }
+  while (*s)
+    if (isalnum(*s))
+      t += *(s++);
+    else {
+      const char *s1 = s;
+      while (*s && !isalnum(*s)) ++s;
+      if (s1 != s0 && *s) t += "-";
+    }
+  return t;
+}
+
+static std::string normpath(std::string path)
+{
+  path = std::string("/")+path;
+  int pos = path.find("//");
+  while (pos >= 0) {
+    path.erase(pos, 1);
+    pos = path.find("//");
+  }
+  size_t len = path.length();
+  if (len > 1 && path[len-1] == '/')
+    path.erase(len-1, 1);
+  return path;
+}
+
+static std::string pathcat(std::string path, std::string label)
+{
+  if (path.empty())
+    return normpath(label);
+  else if (label.empty())
+    return normpath(path);
+  else
+    return normpath(path+"/"+label);
+}
+
+PdUI::PdUI()
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = "";
+  path = "";
+}
+
+PdUI::PdUI(const char *nm, const char *s)
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = nm?nm:"";
+  path = s?s:"";
+}
+
+PdUI::~PdUI()
+{
+  if (elems) {
+    for (int i = 0; i < nelems; i++)
+      if (elems[i].label)
+	free(elems[i].label);
+    free(elems);
+  }
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 1.0;
+  elems[nelems].step = 1.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float init, float min, float max, float step)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = init;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = step;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float min, float max)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+void PdUI::addButton(const char* label, float* zone)
+{ add_elem(UI_BUTTON, label, zone); }
+void PdUI::addCheckButton(const char* label, float* zone)
+{ add_elem(UI_CHECK_BUTTON, label, zone); }
+void PdUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
+
+void PdUI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_H_BARGRAPH, label, zone, min, max); }
+void PdUI::addVerticalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_V_BARGRAPH, label, zone, min, max); }
+
+void PdUI::openTabBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openHorizontalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openVerticalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::closeBox()
+{
+  int pos = path.rfind("/");
+  if (pos < 0) pos = 0;
+  path.erase(pos);
+  level--;
+}
+
+void PdUI::run() {}
+
+/******************************************************************************
+*******************************************************************************
+
+			    FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+		
+<<includeclass>>
+
+#include <stdio.h>
+#include <string>
+#include "m_pd.h"
+
+#define sym(name) xsym(name)
+#define xsym(name) #name
+#define faust_setup(name) xfaust_setup(name)
+#define xfaust_setup(name) name ## _tilde_setup(void)
+
+// time for "active" toggle xfades in secs
+#define XFADE_TIME 0.1f
+
+static t_class *faust_class;
+
+struct t_faust {
+  t_object x_obj;
+#ifdef __MINGW32__
+  /* This seems to be necessary as some as yet undetermined Pd routine seems
+     to write past the end of x_obj on Windows. */
+  int fence; /* dummy field (not used) */
+#endif
+  mydsp *dsp;
+  PdUI *ui;
+  std::string *label;
+  int active, xfade, n_xfade, rate, n_in, n_out;
+  t_sample **inputs, **outputs, **buf;
+  t_outlet *out;
+  t_sample f;
+};
+
+static t_symbol *s_button, *s_checkbox, *s_vslider, *s_hslider, *s_nentry,
+  *s_vbargraph, *s_hbargraph;
+
+static inline void zero_samples(int k, int n, t_sample **out)
+{
+  for (int i = 0; i < k; i++)
+#ifdef __STDC_IEC_559__
+    /* IEC 559 a.k.a. IEEE 754 floats can be initialized faster like this */
+    memset(out[i], 0, n*sizeof(t_sample));
+#else
+    for (int j = 0; j < n; j++)
+      out[i][j] = 0.0f;
+#endif
+}
+
+static inline void copy_samples(int k, int n, t_sample **out, t_sample **in)
+{
+  for (int i = 0; i < k; i++)
+    memcpy(out[i], in[i], n*sizeof(t_sample));
+}
+
+static t_int *faust_perform(t_int *w)
+{
+  t_faust *x = (t_faust *)(w[1]);
+  int n = (int)(w[2]);
+  if (!x->dsp || !x->buf) return (w+3);
+  AVOIDDENORMALS;
+  if (x->xfade > 0) {
+    float d = 1.0f/x->n_xfade, f = (x->xfade--)*d;
+    d = d/n;
+    x->dsp->compute(n, x->inputs, x->buf);
+    if (x->active)
+      if (x->n_in == x->n_out)
+	/* xfade inputs -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->inputs[i][j]+(1.0f-f)*x->buf[i][j];
+      else
+	/* xfade 0 -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = (1.0f-f)*x->buf[i][j];
+    else
+      if (x->n_in == x->n_out)
+	/* xfade buf -> inputs */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j]+(1.0f-f)*x->inputs[i][j];
+      else
+	/* xfade buf -> 0 */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j];
+  } else if (x->active) {
+    x->dsp->compute(n, x->inputs, x->buf);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else if (x->n_in == x->n_out) {
+    copy_samples(x->n_out, n, x->buf, x->inputs);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else
+    zero_samples(x->n_out, n, x->outputs);
+  return (w+3);
+}
+
+static void faust_dsp(t_faust *x, t_signal **sp)
+{
+  int n = sp[0]->s_n, sr = (int)sp[0]->s_sr;
+  if (x->rate <= 0) {
+    /* default sample rate is whatever Pd tells us */
+    PdUI *ui = x->ui;
+    float *z = NULL;
+    if (ui->nelems > 0 &&
+	(z = (float*)malloc(ui->nelems*sizeof(float)))) {
+      /* save the current control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  z[i] = *ui->elems[i].zone;
+    }
+    /* set the proper sample rate; this requires reinitializing the dsp */
+    x->rate = sr;
+    x->dsp->init(sr);
+    if (z) {
+      /* restore previous control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  *ui->elems[i].zone = z[i];
+      free(z);
+    }
+  }
+  if (n > 0)
+    x->n_xfade = (int)(x->rate*XFADE_TIME/n);
+  dsp_add(faust_perform, 2, x, n);
+  for (int i = 0; i < x->n_in; i++)
+    x->inputs[i] = sp[i+1]->s_vec;
+  for (int i = 0; i < x->n_out; i++)
+    x->outputs[i] = sp[x->n_in+i+1]->s_vec;
+  if (x->buf != NULL)
+    for (int i = 0; i < x->n_out; i++) {
+      x->buf[i] = (t_sample*)malloc(n*sizeof(t_sample));
+      if (x->buf[i] == NULL) {
+	for (int j = 0; j < i; j++)
+	  free(x->buf[j]);
+	free(x->buf);
+	x->buf = NULL;
+	break;
+      }
+    }
+}
+
+static int pathcmp(const char *s, const char *t)
+{
+  int n = strlen(s), m = strlen(t);
+  if (n == 0 || m == 0)
+    return 0;
+  else if (t[0] == '/')
+    return strcmp(s, t);
+  else if (n <= m || s[n-m-1] != '/')
+    return strcmp(s+1, t);
+  else
+    return strcmp(s+n-m, t);
+}
+
+static void faust_any(t_faust *x, t_symbol *s, int argc, t_atom *argv)
+{
+  if (!x->dsp) return;
+  PdUI *ui = x->ui;
+  if (s == &s_bang) {
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label && ui->elems[i].zone) {
+	t_atom args[6];
+	t_symbol *_s;
+	switch (ui->elems[i].type) {
+	case UI_BUTTON:
+	  _s = s_button;
+	  break;
+	case UI_CHECK_BUTTON:
+	  _s = s_checkbox;
+	  break;
+	case UI_V_SLIDER:
+	  _s = s_vslider;
+	  break;
+	case UI_H_SLIDER:
+	  _s = s_hslider;
+	  break;
+	case UI_NUM_ENTRY:
+	  _s = s_nentry;
+	  break;
+	case UI_V_BARGRAPH:
+	  _s = s_vbargraph;
+	  break;
+	case UI_H_BARGRAPH:
+	  _s = s_hbargraph;
+	  break;
+	default:
+	  continue;
+	}
+	SETSYMBOL(&args[0], gensym(ui->elems[i].label));
+	SETFLOAT(&args[1], *ui->elems[i].zone);
+	SETFLOAT(&args[2], ui->elems[i].init);
+	SETFLOAT(&args[3], ui->elems[i].min);
+	SETFLOAT(&args[4], ui->elems[i].max);
+	SETFLOAT(&args[5], ui->elems[i].step);
+	outlet_anything(x->out, _s, 6, args);
+      }
+  } else {
+    const char *label = s->s_name;
+    int count = 0;
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label &&
+	  pathcmp(ui->elems[i].label, label) == 0) {
+	if (argc == 0) {
+	  if (ui->elems[i].zone) {
+	    t_atom arg;
+	    SETFLOAT(&arg, *ui->elems[i].zone);
+	    outlet_anything(x->out, gensym(ui->elems[i].label), 1, &arg);
+	  }
+	  ++count;
+	} else if (argc == 1 &&
+		   (argv[0].a_type == A_FLOAT ||
+		    argv[0].a_type == A_DEFFLOAT) &&
+		   ui->elems[i].zone) {
+	  float f = atom_getfloat(argv);
+	  *ui->elems[i].zone = f;
+	  ++count;
+	} else
+	  pd_error(x, "[faust] %s: bad control argument: %s",
+		   x->label->c_str(), label);
+      }
+    if (count == 0 && strcmp(label, "active") == 0) {
+      if (argc == 0) {
+	t_atom arg;
+	SETFLOAT(&arg, (float)x->active);
+	outlet_anything(x->out, gensym((char*)"active"), 1, &arg);
+      } else if (argc == 1 &&
+		 (argv[0].a_type == A_FLOAT ||
+		  argv[0].a_type == A_DEFFLOAT)) {
+	float f = atom_getfloat(argv);
+	x->active = (int)f;
+	x->xfade = x->n_xfade;
+      }
+    }
+  }
+}
+
+static void faust_free(t_faust *x)
+{
+  if (x->label) delete x->label;
+  if (x->dsp) delete x->dsp;
+  if (x->ui) delete x->ui;
+  if (x->inputs) free(x->inputs);
+  if (x->outputs) free(x->outputs);
+  if (x->buf) {
+    for (int i = 0; i < x->n_out; i++)
+      if (x->buf[i]) free(x->buf[i]);
+    free(x->buf);
+  }
+}
+
+static void *faust_new(t_symbol *s, int argc, t_atom *argv)
+{
+  t_faust *x = (t_faust*)pd_new(faust_class);
+  int sr = -1;
+  t_symbol *id = NULL;
+  x->active = 1;
+  for (int i = 0; i < argc; i++)
+    if (argv[i].a_type == A_FLOAT || argv[i].a_type == A_DEFFLOAT)
+      sr = (int)argv[i].a_w.w_float;
+    else if (argv[i].a_type == A_SYMBOL || argv[i].a_type == A_DEFSYMBOL)
+      id = argv[i].a_w.w_symbol;
+  x->rate = sr;
+  if (sr <= 0) sr = 44100;
+  x->xfade = 0; x->n_xfade = (int)(sr*XFADE_TIME/64);
+  x->inputs = x->outputs = x->buf = NULL;
+    x->label = new std::string(sym(mydsp) "~");
+  x->dsp = new mydsp();
+  x->ui = new PdUI(sym(mydsp), id?id->s_name:NULL);
+  if (!x->dsp || !x->ui || !x->label) goto error;
+  if (id) {
+    *x->label += " ";
+    *x->label += id->s_name;
+  }
+  x->n_in = x->dsp->getNumInputs();
+  x->n_out = x->dsp->getNumOutputs();
+  if (x->n_in > 0)
+    x->inputs = (t_sample**)malloc(x->n_in*sizeof(t_sample*));
+  if (x->n_out > 0) {
+    x->outputs = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+    x->buf = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+  }
+  if ((x->n_in > 0 && x->inputs == NULL) ||
+      (x->n_out > 0 && (x->outputs == NULL || x->buf == NULL)))
+    goto error;
+  for (int i = 0; i < x->n_out; i++)
+    x->buf[i] = NULL;
+  x->dsp->init(sr);
+  x->dsp->buildUserInterface(x->ui);
+  for (int i = 0; i < x->n_in; i++)
+    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+  x->out = outlet_new(&x->x_obj, 0);
+  for (int i = 0; i < x->n_out; i++)
+    outlet_new(&x->x_obj, &s_signal);
+  return (void *)x;
+ error:
+  faust_free(x);
+  x->dsp = NULL; x->ui = NULL;
+  x->inputs = x->outputs = x->buf = NULL;
+  return (void *)x;
+}
+
+extern "C" void faust_setup(mydsp)
+{
+  t_symbol *s = gensym(sym(mydsp) "~");
+  faust_class =
+    class_new(s, (t_newmethod)faust_new, (t_method)faust_free,
+	      sizeof(t_faust), CLASS_DEFAULT,
+	      A_GIMME, A_NULL);
+  class_addmethod(faust_class, (t_method)faust_dsp, gensym((char*)"dsp"), A_NULL);
+  class_addanything(faust_class, faust_any);
+  class_addmethod(faust_class, nullfn, &s_signal, A_NULL);
+  s_button = gensym((char*)"button");
+  s_checkbox = gensym((char*)"checkbox");
+  s_vslider = gensym((char*)"vslider");
+  s_hslider = gensym((char*)"hslider");
+  s_nentry = gensym((char*)"nentry");
+  s_vbargraph = gensym((char*)"vbargraph");
+  s_hbargraph = gensym((char*)"hbargraph");
+  /* give some indication that we're loaded and ready to go */
+  mydsp dsp = mydsp();
+  post("[faust] %s: %d inputs, %d outputs", sym(mydsp) "~",
+       dsp.getNumInputs(), dsp.getNumOutputs());
+}
diff --git a/tools/faust2pd/examples/seqdemo/sequ.pd b/tools/faust2pd/examples/seqdemo/sequ.pd
new file mode 100644
index 0000000..d06067e
--- /dev/null
+++ b/tools/faust2pd/examples/seqdemo/sequ.pd
@@ -0,0 +1,160 @@
+#N canvas 546 331 537 528 10;
+#X obj 178 425 route 1 2 3;
+#X obj 130 253 list split 3;
+#X obj 144 364 list;
+#X obj 178 394 list;
+#X msg 130 282 \$2 \$3 \$1;
+#X obj 130 309 unpack f s f;
+#X obj 130 334 pack f s;
+#X obj 21 124 inlet;
+#X obj 182 3 tgl 15 0 \$0-toggle \$0-toggle empty 0 -6 0 8 -262144
+-1 -1 1 1;
+#X obj 339 196 loadbang;
+#X msg 339 223 1;
+#X obj 339 249 s \$0-toggle;
+#X obj 87 125 r \$0-toggle;
+#X obj 21 156 spigot;
+#X obj 182 32 bng 15 50 50 0 \$0-blink \$0-blink empty 0 -6 0 8 -262144
+-260818 -1;
+#N canvas 255 528 450 300 part 0;
+#X obj 97 49 route note;
+#X obj 48 81 unpack f f f f;
+#X obj 48 106 pipe f f f 500;
+#X obj 162 105 pipe s f 500;
+#X obj 162 80 unpack s f f;
+#X obj 97 21 inlet;
+#X obj 128 194 outlet;
+#X text 18 227 decode and schedule note and control messages for a
+single part;
+#X msg 48 158 note \$1 \$2 \$3;
+#X obj 48 133 pack f f f;
+#X obj 162 132 pack s f;
+#X msg 162 159 \$1 \$2;
+#X connect 0 0 1 0;
+#X connect 0 1 4 0;
+#X connect 1 0 2 0;
+#X connect 1 1 2 1;
+#X connect 1 2 2 2;
+#X connect 1 3 2 3;
+#X connect 2 0 9 0;
+#X connect 2 1 9 1;
+#X connect 2 2 9 2;
+#X connect 3 0 10 0;
+#X connect 3 1 10 1;
+#X connect 4 0 3 0;
+#X connect 4 1 3 1;
+#X connect 4 2 3 2;
+#X connect 5 0 0 0;
+#X connect 8 0 6 0;
+#X connect 9 0 8 0;
+#X connect 10 0 11 0;
+#X connect 11 0 6 0;
+#X restore 199 455 pd part;
+#X obj 199 485 outlet;
+#X obj 118 185 s \$0-blink;
+#X msg 21 252 stop;
+#N canvas 255 528 450 300 part 0;
+#X obj 97 49 route note;
+#X obj 48 81 unpack f f f f;
+#X obj 48 106 pipe f f f 500;
+#X obj 162 105 pipe s f 500;
+#X obj 162 80 unpack s f f;
+#X obj 97 21 inlet;
+#X obj 128 194 outlet;
+#X text 18 227 decode and schedule note and control messages for a
+single part;
+#X msg 48 158 note \$1 \$2 \$3;
+#X obj 48 133 pack f f f;
+#X obj 162 132 pack s f;
+#X msg 162 159 \$1 \$2;
+#X connect 0 0 1 0;
+#X connect 0 1 4 0;
+#X connect 1 0 2 0;
+#X connect 1 1 2 1;
+#X connect 1 2 2 2;
+#X connect 1 3 2 3;
+#X connect 2 0 9 0;
+#X connect 2 1 9 1;
+#X connect 2 2 9 2;
+#X connect 3 0 10 0;
+#X connect 3 1 10 1;
+#X connect 4 0 3 0;
+#X connect 4 1 3 1;
+#X connect 4 2 3 2;
+#X connect 5 0 0 0;
+#X connect 8 0 6 0;
+#X connect 9 0 8 0;
+#X connect 10 0 11 0;
+#X connect 11 0 6 0;
+#X restore 126 453 pd part;
+#X obj 126 483 outlet;
+#N canvas 255 528 450 300 part 0;
+#X obj 97 49 route note;
+#X obj 48 81 unpack f f f f;
+#X obj 48 106 pipe f f f 500;
+#X obj 162 105 pipe s f 500;
+#X obj 162 80 unpack s f f;
+#X obj 97 21 inlet;
+#X obj 128 194 outlet;
+#X text 18 227 decode and schedule note and control messages for a
+single part;
+#X msg 48 158 note \$1 \$2 \$3;
+#X obj 48 133 pack f f f;
+#X obj 162 132 pack s f;
+#X msg 162 159 \$1 \$2;
+#X connect 0 0 1 0;
+#X connect 0 1 4 0;
+#X connect 1 0 2 0;
+#X connect 1 1 2 1;
+#X connect 1 2 2 2;
+#X connect 1 3 2 3;
+#X connect 2 0 9 0;
+#X connect 2 1 9 1;
+#X connect 2 2 9 2;
+#X connect 3 0 10 0;
+#X connect 3 1 10 1;
+#X connect 4 0 3 0;
+#X connect 4 1 3 1;
+#X connect 4 2 3 2;
+#X connect 5 0 0 0;
+#X connect 8 0 6 0;
+#X connect 9 0 8 0;
+#X connect 10 0 11 0;
+#X connect 11 0 6 0;
+#X restore 284 457 pd part;
+#X obj 284 487 outlet;
+#X obj 21 282 s pulse;
+#X obj 21 218 route stop float;
+#X obj 267 14 pure-remote;
+#X obj 21 186 sequencer;
+#X text 30 16 Pd-Pure sequencer;
+#X text 21 61 3 part sequencer \, implemented in Pure;
+#X text 20 80 Takes note and control messages from the Pure sequencer
+and routes them to 3 parts.;
+#X connect 0 0 19 0;
+#X connect 0 1 15 0;
+#X connect 0 2 21 0;
+#X connect 1 0 4 0;
+#X connect 1 1 2 1;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 5 1 6 1;
+#X connect 5 2 3 1;
+#X connect 6 0 2 0;
+#X connect 7 0 13 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 12 0 13 1;
+#X connect 13 0 17 0;
+#X connect 13 0 26 0;
+#X connect 15 0 16 0;
+#X connect 18 0 23 0;
+#X connect 19 0 20 0;
+#X connect 21 0 22 0;
+#X connect 24 0 18 0;
+#X connect 24 1 23 0;
+#X connect 24 2 1 0;
+#X connect 26 0 24 0;
+#X coords 0 -1 1 1 200 50 1 0 0;
diff --git a/tools/faust2pd/examples/seqdemo/subtractive.dsp b/tools/faust2pd/examples/seqdemo/subtractive.dsp
index e185609..a414381 100644
--- a/tools/faust2pd/examples/seqdemo/subtractive.dsp
+++ b/tools/faust2pd/examples/seqdemo/subtractive.dsp
@@ -33,10 +33,10 @@ gate	= button("gate");			// 0/1
 // freq	= the desired frequency in Hz
 // mod	= the phase modulation signal, in radians
 
-tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,waveform,i&(n-1)) +
-			  d*rdtable(n,waveform,(i+1)&(n-1))
+tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,wave,i&(n-1)) +
+			  d*rdtable(n,wave,(i+1)&(n-1))
 with {
-	waveform 	= time*(2.0*PI)/n : f;
+	wave	 	= time*(2.0*PI)/n : f;
 	phase		= freq/SR : (+ : decimal) ~ _;
 	modphase	= decimal(phase+mod/(2*PI))*n;
 	i		= int(floor(modphase));
diff --git a/tools/faust2pd/examples/synth/Makefile b/tools/faust2pd/examples/synth/Makefile
index 4c99acf..52a46a2 100644
--- a/tools/faust2pd/examples/synth/Makefile
+++ b/tools/faust2pd/examples/synth/Makefile
@@ -17,6 +17,11 @@ ifneq "$(findstring -mingw,$(host))" ""
 DLL = .dll
 PDLIB = -Wl,--enable-auto-import -lpd
 endif
+ifneq "$(findstring -darwin,$(host))" ""
+# OSX
+DLL = .pd_darwin
+shared = -dynamiclib -Wl,-undefined -Wl,dynamic_lookup
+endif
 ifneq "$(findstring x86_64-,$(host))" ""
 # 64 bit, needs -fPIC flag
 EXTRA_CFLAGS += -fPIC
@@ -26,13 +31,7 @@ ifneq "$(findstring x86,$(host))" ""
 EXTRA_CFLAGS += -msse -ffast-math
 endif
 
-# Try to figure out the Pd include directory.
-pdincdir = $(strip $(shell pkg-config pd --cflags-only-I 2>/dev/null))
-ifeq "$(pdincdir)" ""
-# Try some common locations.
-pdincdir = $(addprefix -I,$(shell ls -d /usr/local/include/pdextended /usr/local/include/pd /usr/include/pdextended /usr/include/pd 2>/dev/null))
-endif
-EXTRA_CFLAGS += $(pdincdir)
+EXTRA_CFLAGS += -I ../../pd
 
 # Define the desired number of voices for synth (.syn) plugins here:
 NVOICES = 8
diff --git a/tools/faust2pd/examples/synth/chorus.dsp b/tools/faust2pd/examples/synth/chorus.dsp
index 8235ff4..18528d1 100644
--- a/tools/faust2pd/examples/synth/chorus.dsp
+++ b/tools/faust2pd/examples/synth/chorus.dsp
@@ -12,10 +12,10 @@ freq	= hslider("freq", 3, 0, 10, 0.01);
 dtime	= hslider("delay", 0.025, 0, 0.2, 0.001);
 depth	= hslider("depth", 0.02, 0, 1, 0.001);
 
-tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,waveform,i&(n-1)) +
-			  d*rdtable(n,waveform,(i+1)&(n-1))
+tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,wave,i&(n-1)) +
+			  d*rdtable(n,wave,(i+1)&(n-1))
 with {
-	waveform 	= time*(2.0*PI)/n : f;
+	wave	 	= time*(2.0*PI)/n : f;
 	phase		= freq/SR : (+ : decimal) ~ _;
 	modphase	= decimal(phase+mod/(2*PI))*n;
 	i		= int(floor(modphase));
diff --git a/tools/faust2pd/examples/synth/flanger.dsp b/tools/faust2pd/examples/synth/flanger.dsp
index b0416ae..ee5a3c6 100644
--- a/tools/faust2pd/examples/synth/flanger.dsp
+++ b/tools/faust2pd/examples/synth/flanger.dsp
@@ -28,10 +28,10 @@ depth			= hslider("depth", 0.5, 0, 1, 0.001);
 feedback		= hslider("feedback", 0.1, 0, 1, 0.001);
 stereo			= hslider("stereo", 1, 0, 1, 0.001);
 
-tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,waveform,i&(n-1)) +
-			  d*rdtable(n,waveform,(i+1)&(n-1))
+tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,wave,i&(n-1)) +
+			  d*rdtable(n,wave,(i+1)&(n-1))
 with {
-	waveform	= time*(2.0*PI)/n : f;
+	wave		= time*(2.0*PI)/n : f;
 	phase		= freq/SR : (+ : decimal) ~ _;
 	modphase	= decimal(phase+mod/(2*PI))*n;
 	i		= int(floor(modphase));
diff --git a/tools/faust2pd/examples/synth/freeverb.dsp b/tools/faust2pd/examples/synth/freeverb.dsp
old mode 100755
new mode 100644
diff --git a/tools/faust2pd/examples/synth/phasemod.syn b/tools/faust2pd/examples/synth/phasemod.syn
index 2ddf9f6..82cc357 100644
--- a/tools/faust2pd/examples/synth/phasemod.syn
+++ b/tools/faust2pd/examples/synth/phasemod.syn
@@ -29,10 +29,10 @@ gate	= button("gate");			// 0/1
 // freq	= the desired frequency in Hz
 // mod	= the phase modulation signal, in radians
 
-tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,waveform,i&(n-1)) +
-			  d*rdtable(n,waveform,(i+1)&(n-1))
+tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,wave,i&(n-1)) +
+			  d*rdtable(n,wave,(i+1)&(n-1))
 with {
-	waveform 	= time*(2.0*PI)/n : f;
+	wave	 	= time*(2.0*PI)/n : f;
 	phase		= freq/SR : (+ : decimal) ~ _;
 	modphase	= decimal(phase+mod/(2*PI))*n;
 	i		= int(floor(modphase));
diff --git a/tools/faust2pd/examples/synth/puredata.cpp b/tools/faust2pd/examples/synth/puredata.cpp
new file mode 100644
index 0000000..0e9ff9f
--- /dev/null
+++ b/tools/faust2pd/examples/synth/puredata.cpp
@@ -0,0 +1,636 @@
+/************************************************************************
+ ************************************************************************
+    FAUST Architecture File
+	Copyright (C) 2006-2011 Albert Graef <Dr.Graef at t-online.de>
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as 
+	published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+ 	License along with the GNU C Library; if not, write to the Free
+  	Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  	02111-1307 USA. 
+ ************************************************************************
+ ************************************************************************/
+
+/* Pd architecture file, written by Albert Graef <Dr.Graef at t-online.de>.
+   This was derived from minimal.cpp included in the Faust distribution.
+   Please note that this is to be compiled as a shared library, which is
+   then loaded dynamically by Pd as an external. */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string>
+
+#include "faust/misc.h"
+#include "faust/gui/UI.h"
+#include "faust/gui/meta.h"
+#include "faust/audio/dsp.h"
+
+//using namespace std;
+
+/******************************************************************************
+*******************************************************************************
+
+							       VECTOR INTRINSICS
+
+*******************************************************************************
+*******************************************************************************/
+
+<<includeIntrinsic>>
+
+/***************************************************************************
+   Pd UI interface
+ ***************************************************************************/
+
+enum ui_elem_type_t {
+  UI_BUTTON, UI_CHECK_BUTTON,
+  UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
+  UI_V_BARGRAPH, UI_H_BARGRAPH,
+  UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
+};
+
+struct ui_elem_t {
+  ui_elem_type_t type;
+  char *label;
+  float *zone;
+  float init, min, max, step;
+};
+
+class PdUI : public UI
+{
+public:
+  const char *name;
+  int nelems, level;
+  ui_elem_t *elems;
+		
+  PdUI();
+  PdUI(const char *nm, const char *s);
+  virtual ~PdUI();
+
+protected:
+  std::string path;
+  void add_elem(ui_elem_type_t type, const char *label = NULL);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float init, float min, float max, float step);
+  void add_elem(ui_elem_type_t type, const char *label, float *zone,
+		float min, float max);
+
+public:
+  virtual void addButton(const char* label, float* zone);
+  virtual void addCheckButton(const char* label, float* zone);
+  virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
+  virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
+
+  virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
+  virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
+  
+  virtual void openTabBox(const char* label);
+  virtual void openHorizontalBox(const char* label);
+  virtual void openVerticalBox(const char* label);
+  virtual void closeBox();
+	
+  virtual void run();
+};
+
+static std::string mangle(const char *name, int level, const char *s)
+{
+  const char *s0 = s;
+  std::string t = "";
+  if (!s) return t;
+  // Get rid of bogus "0x00" labels in recent Faust revisions. Also, for
+  // backward compatibility with old Faust versions, make sure that default
+  // toplevel groups and explicit toplevel groups with an empty label are
+  // treated alike (these both return "0x00" labels in the latest Faust, but
+  // would be treated inconsistently in earlier versions).
+  if (!*s || strcmp(s, "0x00") == 0) {
+    if (level == 0)
+      // toplevel group with empty label, map to dsp name
+      s = name;
+    else
+      // empty label
+      s = "";
+  }
+  while (*s)
+    if (isalnum(*s))
+      t += *(s++);
+    else {
+      const char *s1 = s;
+      while (*s && !isalnum(*s)) ++s;
+      if (s1 != s0 && *s) t += "-";
+    }
+  return t;
+}
+
+static std::string normpath(std::string path)
+{
+  path = std::string("/")+path;
+  int pos = path.find("//");
+  while (pos >= 0) {
+    path.erase(pos, 1);
+    pos = path.find("//");
+  }
+  size_t len = path.length();
+  if (len > 1 && path[len-1] == '/')
+    path.erase(len-1, 1);
+  return path;
+}
+
+static std::string pathcat(std::string path, std::string label)
+{
+  if (path.empty())
+    return normpath(label);
+  else if (label.empty())
+    return normpath(path);
+  else
+    return normpath(path+"/"+label);
+}
+
+PdUI::PdUI()
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = "";
+  path = "";
+}
+
+PdUI::PdUI(const char *nm, const char *s)
+{
+  nelems = level = 0;
+  elems = NULL;
+  name = nm?nm:"";
+  path = s?s:"";
+}
+
+PdUI::~PdUI()
+{
+  if (elems) {
+    for (int i = 0; i < nelems; i++)
+      if (elems[i].label)
+	free(elems[i].label);
+    free(elems);
+  }
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = NULL;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 0.0;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = 0.0;
+  elems[nelems].max = 1.0;
+  elems[nelems].step = 1.0;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float init, float min, float max, float step)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = init;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = step;
+  nelems++;
+}
+
+inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone,
+			  float min, float max)
+{
+  ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
+  if (elems1)
+    elems = elems1;
+  else
+    return;
+  std::string s = pathcat(path, mangle(name, level, label));
+  elems[nelems].type = type;
+  elems[nelems].label = strdup(s.c_str());
+  elems[nelems].zone = zone;
+  elems[nelems].init = 0.0;
+  elems[nelems].min = min;
+  elems[nelems].max = max;
+  elems[nelems].step = 0.0;
+  nelems++;
+}
+
+void PdUI::addButton(const char* label, float* zone)
+{ add_elem(UI_BUTTON, label, zone); }
+void PdUI::addCheckButton(const char* label, float* zone)
+{ add_elem(UI_CHECK_BUTTON, label, zone); }
+void PdUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
+void PdUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
+{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
+
+void PdUI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_H_BARGRAPH, label, zone, min, max); }
+void PdUI::addVerticalBargraph(const char* label, float* zone, float min, float max)
+{ add_elem(UI_V_BARGRAPH, label, zone, min, max); }
+
+void PdUI::openTabBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openHorizontalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::openVerticalBox(const char* label)
+{
+  if (!path.empty()) path += "/";
+  path += mangle(name, level, label);
+  level++;
+}
+void PdUI::closeBox()
+{
+  int pos = path.rfind("/");
+  if (pos < 0) pos = 0;
+  path.erase(pos);
+  level--;
+}
+
+void PdUI::run() {}
+
+/******************************************************************************
+*******************************************************************************
+
+			    FAUST DSP
+
+*******************************************************************************
+*******************************************************************************/
+
+//----------------------------------------------------------------------------
+//  FAUST generated signal processor
+//----------------------------------------------------------------------------
+		
+<<includeclass>>
+
+#include <stdio.h>
+#include <string>
+#include "m_pd.h"
+
+#define sym(name) xsym(name)
+#define xsym(name) #name
+#define faust_setup(name) xfaust_setup(name)
+#define xfaust_setup(name) name ## _tilde_setup(void)
+
+// time for "active" toggle xfades in secs
+#define XFADE_TIME 0.1f
+
+static t_class *faust_class;
+
+struct t_faust {
+  t_object x_obj;
+#ifdef __MINGW32__
+  /* This seems to be necessary as some as yet undetermined Pd routine seems
+     to write past the end of x_obj on Windows. */
+  int fence; /* dummy field (not used) */
+#endif
+  mydsp *dsp;
+  PdUI *ui;
+  std::string *label;
+  int active, xfade, n_xfade, rate, n_in, n_out;
+  t_sample **inputs, **outputs, **buf;
+  t_outlet *out;
+  t_sample f;
+};
+
+static t_symbol *s_button, *s_checkbox, *s_vslider, *s_hslider, *s_nentry,
+  *s_vbargraph, *s_hbargraph;
+
+static inline void zero_samples(int k, int n, t_sample **out)
+{
+  for (int i = 0; i < k; i++)
+#ifdef __STDC_IEC_559__
+    /* IEC 559 a.k.a. IEEE 754 floats can be initialized faster like this */
+    memset(out[i], 0, n*sizeof(t_sample));
+#else
+    for (int j = 0; j < n; j++)
+      out[i][j] = 0.0f;
+#endif
+}
+
+static inline void copy_samples(int k, int n, t_sample **out, t_sample **in)
+{
+  for (int i = 0; i < k; i++)
+    memcpy(out[i], in[i], n*sizeof(t_sample));
+}
+
+static t_int *faust_perform(t_int *w)
+{
+  t_faust *x = (t_faust *)(w[1]);
+  int n = (int)(w[2]);
+  if (!x->dsp || !x->buf) return (w+3);
+  AVOIDDENORMALS;
+  if (x->xfade > 0) {
+    float d = 1.0f/x->n_xfade, f = (x->xfade--)*d;
+    d = d/n;
+    x->dsp->compute(n, x->inputs, x->buf);
+    if (x->active)
+      if (x->n_in == x->n_out)
+	/* xfade inputs -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->inputs[i][j]+(1.0f-f)*x->buf[i][j];
+      else
+	/* xfade 0 -> buf */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = (1.0f-f)*x->buf[i][j];
+    else
+      if (x->n_in == x->n_out)
+	/* xfade buf -> inputs */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j]+(1.0f-f)*x->inputs[i][j];
+      else
+	/* xfade buf -> 0 */
+	for (int j = 0; j < n; j++, f -= d)
+	  for (int i = 0; i < x->n_out; i++)
+	    x->outputs[i][j] = f*x->buf[i][j];
+  } else if (x->active) {
+    x->dsp->compute(n, x->inputs, x->buf);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else if (x->n_in == x->n_out) {
+    copy_samples(x->n_out, n, x->buf, x->inputs);
+    copy_samples(x->n_out, n, x->outputs, x->buf);
+  } else
+    zero_samples(x->n_out, n, x->outputs);
+  return (w+3);
+}
+
+static void faust_dsp(t_faust *x, t_signal **sp)
+{
+  int n = sp[0]->s_n, sr = (int)sp[0]->s_sr;
+  if (x->rate <= 0) {
+    /* default sample rate is whatever Pd tells us */
+    PdUI *ui = x->ui;
+    float *z = NULL;
+    if (ui->nelems > 0 &&
+	(z = (float*)malloc(ui->nelems*sizeof(float)))) {
+      /* save the current control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  z[i] = *ui->elems[i].zone;
+    }
+    /* set the proper sample rate; this requires reinitializing the dsp */
+    x->rate = sr;
+    x->dsp->init(sr);
+    if (z) {
+      /* restore previous control values */
+      for (int i = 0; i < ui->nelems; i++)
+	if (ui->elems[i].zone)
+	  *ui->elems[i].zone = z[i];
+      free(z);
+    }
+  }
+  if (n > 0)
+    x->n_xfade = (int)(x->rate*XFADE_TIME/n);
+  dsp_add(faust_perform, 2, x, n);
+  for (int i = 0; i < x->n_in; i++)
+    x->inputs[i] = sp[i+1]->s_vec;
+  for (int i = 0; i < x->n_out; i++)
+    x->outputs[i] = sp[x->n_in+i+1]->s_vec;
+  if (x->buf != NULL)
+    for (int i = 0; i < x->n_out; i++) {
+      x->buf[i] = (t_sample*)malloc(n*sizeof(t_sample));
+      if (x->buf[i] == NULL) {
+	for (int j = 0; j < i; j++)
+	  free(x->buf[j]);
+	free(x->buf);
+	x->buf = NULL;
+	break;
+      }
+    }
+}
+
+static int pathcmp(const char *s, const char *t)
+{
+  int n = strlen(s), m = strlen(t);
+  if (n == 0 || m == 0)
+    return 0;
+  else if (t[0] == '/')
+    return strcmp(s, t);
+  else if (n <= m || s[n-m-1] != '/')
+    return strcmp(s+1, t);
+  else
+    return strcmp(s+n-m, t);
+}
+
+static void faust_any(t_faust *x, t_symbol *s, int argc, t_atom *argv)
+{
+  if (!x->dsp) return;
+  PdUI *ui = x->ui;
+  if (s == &s_bang) {
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label && ui->elems[i].zone) {
+	t_atom args[6];
+	t_symbol *_s;
+	switch (ui->elems[i].type) {
+	case UI_BUTTON:
+	  _s = s_button;
+	  break;
+	case UI_CHECK_BUTTON:
+	  _s = s_checkbox;
+	  break;
+	case UI_V_SLIDER:
+	  _s = s_vslider;
+	  break;
+	case UI_H_SLIDER:
+	  _s = s_hslider;
+	  break;
+	case UI_NUM_ENTRY:
+	  _s = s_nentry;
+	  break;
+	case UI_V_BARGRAPH:
+	  _s = s_vbargraph;
+	  break;
+	case UI_H_BARGRAPH:
+	  _s = s_hbargraph;
+	  break;
+	default:
+	  continue;
+	}
+	SETSYMBOL(&args[0], gensym(ui->elems[i].label));
+	SETFLOAT(&args[1], *ui->elems[i].zone);
+	SETFLOAT(&args[2], ui->elems[i].init);
+	SETFLOAT(&args[3], ui->elems[i].min);
+	SETFLOAT(&args[4], ui->elems[i].max);
+	SETFLOAT(&args[5], ui->elems[i].step);
+	outlet_anything(x->out, _s, 6, args);
+      }
+  } else {
+    const char *label = s->s_name;
+    int count = 0;
+    for (int i = 0; i < ui->nelems; i++)
+      if (ui->elems[i].label &&
+	  pathcmp(ui->elems[i].label, label) == 0) {
+	if (argc == 0) {
+	  if (ui->elems[i].zone) {
+	    t_atom arg;
+	    SETFLOAT(&arg, *ui->elems[i].zone);
+	    outlet_anything(x->out, gensym(ui->elems[i].label), 1, &arg);
+	  }
+	  ++count;
+	} else if (argc == 1 &&
+		   (argv[0].a_type == A_FLOAT ||
+		    argv[0].a_type == A_DEFFLOAT) &&
+		   ui->elems[i].zone) {
+	  float f = atom_getfloat(argv);
+	  *ui->elems[i].zone = f;
+	  ++count;
+	} else
+	  pd_error(x, "[faust] %s: bad control argument: %s",
+		   x->label->c_str(), label);
+      }
+    if (count == 0 && strcmp(label, "active") == 0) {
+      if (argc == 0) {
+	t_atom arg;
+	SETFLOAT(&arg, (float)x->active);
+	outlet_anything(x->out, gensym((char*)"active"), 1, &arg);
+      } else if (argc == 1 &&
+		 (argv[0].a_type == A_FLOAT ||
+		  argv[0].a_type == A_DEFFLOAT)) {
+	float f = atom_getfloat(argv);
+	x->active = (int)f;
+	x->xfade = x->n_xfade;
+      }
+    }
+  }
+}
+
+static void faust_free(t_faust *x)
+{
+  if (x->label) delete x->label;
+  if (x->dsp) delete x->dsp;
+  if (x->ui) delete x->ui;
+  if (x->inputs) free(x->inputs);
+  if (x->outputs) free(x->outputs);
+  if (x->buf) {
+    for (int i = 0; i < x->n_out; i++)
+      if (x->buf[i]) free(x->buf[i]);
+    free(x->buf);
+  }
+}
+
+static void *faust_new(t_symbol *s, int argc, t_atom *argv)
+{
+  t_faust *x = (t_faust*)pd_new(faust_class);
+  int sr = -1;
+  t_symbol *id = NULL;
+  x->active = 1;
+  for (int i = 0; i < argc; i++)
+    if (argv[i].a_type == A_FLOAT || argv[i].a_type == A_DEFFLOAT)
+      sr = (int)argv[i].a_w.w_float;
+    else if (argv[i].a_type == A_SYMBOL || argv[i].a_type == A_DEFSYMBOL)
+      id = argv[i].a_w.w_symbol;
+  x->rate = sr;
+  if (sr <= 0) sr = 44100;
+  x->xfade = 0; x->n_xfade = (int)(sr*XFADE_TIME/64);
+  x->inputs = x->outputs = x->buf = NULL;
+    x->label = new std::string(sym(mydsp) "~");
+  x->dsp = new mydsp();
+  x->ui = new PdUI(sym(mydsp), id?id->s_name:NULL);
+  if (!x->dsp || !x->ui || !x->label) goto error;
+  if (id) {
+    *x->label += " ";
+    *x->label += id->s_name;
+  }
+  x->n_in = x->dsp->getNumInputs();
+  x->n_out = x->dsp->getNumOutputs();
+  if (x->n_in > 0)
+    x->inputs = (t_sample**)malloc(x->n_in*sizeof(t_sample*));
+  if (x->n_out > 0) {
+    x->outputs = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+    x->buf = (t_sample**)malloc(x->n_out*sizeof(t_sample*));
+  }
+  if ((x->n_in > 0 && x->inputs == NULL) ||
+      (x->n_out > 0 && (x->outputs == NULL || x->buf == NULL)))
+    goto error;
+  for (int i = 0; i < x->n_out; i++)
+    x->buf[i] = NULL;
+  x->dsp->init(sr);
+  x->dsp->buildUserInterface(x->ui);
+  for (int i = 0; i < x->n_in; i++)
+    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+  x->out = outlet_new(&x->x_obj, 0);
+  for (int i = 0; i < x->n_out; i++)
+    outlet_new(&x->x_obj, &s_signal);
+  return (void *)x;
+ error:
+  faust_free(x);
+  x->dsp = NULL; x->ui = NULL;
+  x->inputs = x->outputs = x->buf = NULL;
+  return (void *)x;
+}
+
+extern "C" void faust_setup(mydsp)
+{
+  t_symbol *s = gensym(sym(mydsp) "~");
+  faust_class =
+    class_new(s, (t_newmethod)faust_new, (t_method)faust_free,
+	      sizeof(t_faust), CLASS_DEFAULT,
+	      A_GIMME, A_NULL);
+  class_addmethod(faust_class, (t_method)faust_dsp, gensym((char*)"dsp"), A_NULL);
+  class_addanything(faust_class, faust_any);
+  class_addmethod(faust_class, nullfn, &s_signal, A_NULL);
+  s_button = gensym((char*)"button");
+  s_checkbox = gensym((char*)"checkbox");
+  s_vslider = gensym((char*)"vslider");
+  s_hslider = gensym((char*)"hslider");
+  s_nentry = gensym((char*)"nentry");
+  s_vbargraph = gensym((char*)"vbargraph");
+  s_hbargraph = gensym((char*)"hbargraph");
+  /* give some indication that we're loaded and ready to go */
+  mydsp dsp = mydsp();
+  post("[faust] %s: %d inputs, %d outputs", sym(mydsp) "~",
+       dsp.getNumInputs(), dsp.getNumOutputs());
+}
diff --git a/tools/faust2pd/examples/synth/subtractive.syn b/tools/faust2pd/examples/synth/subtractive.syn
index e185609..a414381 100644
--- a/tools/faust2pd/examples/synth/subtractive.syn
+++ b/tools/faust2pd/examples/synth/subtractive.syn
@@ -33,10 +33,10 @@ gate	= button("gate");			// 0/1
 // freq	= the desired frequency in Hz
 // mod	= the phase modulation signal, in radians
 
-tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,waveform,i&(n-1)) +
-			  d*rdtable(n,waveform,(i+1)&(n-1))
+tblosc(n,f,freq,mod)	= (1-d)*rdtable(n,wave,i&(n-1)) +
+			  d*rdtable(n,wave,(i+1)&(n-1))
 with {
-	waveform 	= time*(2.0*PI)/n : f;
+	wave	 	= time*(2.0*PI)/n : f;
 	phase		= freq/SR : (+ : decimal) ~ _;
 	modphase	= decimal(phase+mod/(2*PI))*n;
 	i		= int(floor(modphase));
diff --git a/tools/faust2pd/faust2pd.pure b/tools/faust2pd/faust2pd.pure
index 79f9aa1..b2021c4 100755
--- a/tools/faust2pd/faust2pd.pure
+++ b/tools/faust2pd/faust2pd.pure
@@ -90,7 +90,7 @@ obj_str f	= str f otherwise;
 /* Construct dsp and synth patches. */
 
 comment y	= [text 0 (y+10) $ sprintf "Generated %s by faust2pd v%s. \
-See http://faust.grame.fr and http://pure-lang.googlecode.com."
+See http://faust.grame.fr and http://purelang.bitbucket.org."
 		   (strftime "%c" (localtime time),version)];
 
 make_dsp (name,descr,version,in,out,layout)
diff --git a/tools/faust2pd/faustxml.pure b/tools/faust2pd/faustxml.pure
index c3b0e74..2cf87b9 100644
--- a/tools/faust2pd/faustxml.pure
+++ b/tools/faust2pd/faustxml.pure
@@ -28,7 +28,7 @@ namespace faustxml;
    The faustxml module is provided along with faust2pd to retrieve the
    description of a Faust DSP from its XML file as a data structure which
    is ready to be processed by Pure programs. It may also be useful in other
-   Pure applications which need to inspect description of Faust DSPs.
+   Pure applications which need to inspect descriptions of Faust DSPs.
 
    The main entry point is the :func:`info` function which takes the name of a
    Faust-generated XML file as argument and returns a tuple ``(name, descr,
@@ -186,7 +186,7 @@ private parse parse_doc parse_node parse_prop parse_type
 info fname::string
 = case xml::load_file fname 0 of
     doc = name,descr,info when
-            name = basename fname; descr,info = parse doc;
+            name = basename fname; descr,info = parse name doc;
             descr = if null descr then name else descr;
           end if xml::docp doc;
     _ = throw "could not open XML file" otherwise;
@@ -222,7 +222,7 @@ tree n::pointer = node (xml::node_info n)
 
 /* Helper functions to parse the contents of a Faust XML file. */
 
-parse doc
+parse nm doc
 = case map (map tree . xml::select doc)
        ["/faust/name","/faust/version",
 	"/faust/inputs","/faust/outputs",
@@ -230,28 +230,28 @@ parse doc
 	"/faust/ui/passivewidgets/widget",
 	"/faust/ui/layout/group"] of
     [[name],[version],[in],[out],active,passive,layout] =
-      parse_doc (name,version,in,out,active+passive,layout);
+      parse_doc nm (name,version,in,out,active+passive,layout);
     _ = throw "invalid XML data" otherwise;
   end;
 
 private extern int atoi(char*);
 private extern double atof(char*);
 
-parse_doc (node (xml::element "name" _ _) name,
-	   node (xml::element "version" _ _) version,
-	   node (xml::element "inputs" _ _) in,
-	   node (xml::element "outputs" _ _) out,
-	   controls,layout)
-= case map (parse_group (dict controls)) layout of
+parse_doc nm (node (xml::element "name" _ _) name,
+	      node (xml::element "version" _ _) version,
+	      node (xml::element "inputs" _ _) in,
+	      node (xml::element "outputs" _ _) out,
+	      controls,layout)
+= case map (parse_group 0 nm (dict controls)) layout of
     [controls] = (name,version,in,out,controls);
     _ = throw "invalid XML data" otherwise;
   end when
     [name,version,in,out] = map parse_node [name,version,in,out];
     [name,version] = map (parse_prop.trim) [name,version];
     [in,out] = map atoi [in,out];
-    controls = map parse_control controls;
+    controls = map (parse_control nm) controls;
   end;
-parse_doc _ = throw "invalid XML data" otherwise;
+parse_doc _ _ = throw "invalid XML data" otherwise;
 
 parse_node [node (xml::text s::string) _] = s;
 parse_node [] = "";
@@ -267,10 +267,16 @@ parse_prop s
 
 parse_type s::string = eval $ "faustxml::"+s;
 
-parse_control (node (xml::element "widget" _ attrs) params)
+using system;
+check_label 0 nm "0x00" = nm;
+check_label 0 nm "" = nm;
+check_label _ _ "" = "";
+check_label _ _ s = s otherwise;
+
+parse_control nm (node (xml::element "widget" _ attrs) params)
 = case attrs!!["type","id"]+params!!["label"] of
     [ty,id,label] =
-      make_control (atoi id) ty (str_val label) params;
+      make_control (atoi id) ty (check_label 1 nm (str_val label)) params;
     _ = throw "invalid XML data" otherwise;
   end when
     attrs = dict attrs; params = dict $ map param params with
@@ -279,7 +285,7 @@ parse_control (node (xml::element "widget" _ attrs) params)
       param _ = throw "invalid XML data" otherwise;
     end;
   end;
-parse_control _ = throw "invalid XML data" otherwise;
+parse_control _ _ = throw "invalid XML data" otherwise;
 
 make_control id ty label params
 = id => parse_type ty label if any ((==)ty) ["button","checkbox"];
@@ -295,18 +301,19 @@ make_control id ty label params
   end if any ((==)ty) ["vbargraph","hbargraph"];
 make_control _ _ _ _ = throw "invalid XML data" otherwise;
 
-parse_group cdict (node (xml::element "group" _ attrs) params)
+parse_group lev nm cdict (node (xml::element "group" _ attrs) params)
 = case attrs!!["type"] of
-    [ty] = make_group cdict ty params;
+    [ty] = make_group lev nm cdict ty params;
     _ = throw "invalid XML data" otherwise;
   end when attrs = dict attrs end;
-parse_group cdict (node (xml::element "widgetref" _ ["id"=>id::string]) [])
+parse_group lev nm cdict (node (xml::element "widgetref" _ ["id"=>id::string]) [])
 = case cdict!![atoi id] of [c] = c; _ = throw "invalid XML data"; end;
-parse_group _ _ = throw "invalid XML data" otherwise;
+parse_group _ _ _ _ = throw "invalid XML data" otherwise;
 
-make_group cdict ty (node (xml::element "label" _ _) label:params)
-= case parse_type ty (str_val label,map (parse_group cdict) params) of
+make_group lev nm cdict ty (node (xml::element "label" _ _) label:params)
+= case parse_type ty (check_label lev nm (str_val label),
+		      map (parse_group (lev+1) nm cdict) params) of
     c = c if stringp label && controlp c;
     _ = throw "invalid XML data" otherwise;
   end when label = parse_node label end;
-make_group _ _ _ = throw "invalid XML data" otherwise;
+make_group _ _ _ _ _ = throw "invalid XML data" otherwise;
diff --git a/tools/faust2pd/pd/m_pd.h b/tools/faust2pd/pd/m_pd.h
new file mode 100644
index 0000000..629a3aa
--- /dev/null
+++ b/tools/faust2pd/pd/m_pd.h
@@ -0,0 +1,759 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
+
+#ifndef __m_pd_h_
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+#define PD_MAJOR_VERSION 0
+#define PD_MINOR_VERSION 45
+#define PD_BUGFIX_VERSION 0
+#define PD_TEST_VERSION ""
+extern int pd_compatibilitylevel;   /* e.g., 43 for pd 0.43 compatibility */
+
+/* old name for "MSW" flag -- we have to take it for the sake of many old
+"nmakefiles" for externs, which will define NT and not MSW */
+#if defined(NT) && !defined(MSW)
+#define MSW
+#endif
+
+/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans at at.or.at> */
+#ifdef _MSC_VER
+/* #pragma warning( disable : 4091 ) */
+#pragma warning( disable : 4305 )  /* uncast const double to float */
+#pragma warning( disable : 4244 )  /* uncast float/int conversion etc. */
+#pragma warning( disable : 4101 )  /* unused automatic variables */
+#endif /* _MSC_VER */
+
+    /* the external storage class is "extern" in UNIX; in MSW it's ugly. */
+#ifdef _WIN32
+#ifdef PD_INTERNAL
+#define EXTERN __declspec(dllexport) extern
+#else
+#define EXTERN __declspec(dllimport) extern
+#endif /* PD_INTERNAL */
+#else
+#define EXTERN extern
+#endif /* _WIN32 */
+
+    /* and depending on the compiler, hidden data structures are
+    declared differently: */
+#if defined( __GNUC__) || defined( __BORLANDC__ ) || defined( __MWERKS__ )
+#define EXTERN_STRUCT struct
+#else
+#define EXTERN_STRUCT extern struct
+#endif
+
+/* Define some attributes, specific to the compiler */
+#if defined(__GNUC__)
+#define ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__ ((format (printf, a, b)))
+#else
+#define ATTRIBUTE_FORMAT_PRINTF(a, b)
+#endif
+
+#if !defined(_SIZE_T) && !defined(_SIZE_T_)
+#include <stddef.h>     /* just for size_t -- how lame! */
+#endif
+
+/* Microsoft Visual Studio is not C99, it does not provide stdint.h */
+#ifdef _MSC_VER
+typedef signed __int8     int8_t;
+typedef signed __int16    int16_t;
+typedef signed __int32    int32_t;
+typedef signed __int64    int64_t;
+typedef unsigned __int8   uint8_t;
+typedef unsigned __int16  uint16_t;
+typedef unsigned __int32  uint32_t;
+typedef unsigned __int64  uint64_t;
+#else
+# include <stdint.h>
+#endif
+
+/* for FILE, needed by sys_fopen() and sys_fclose() only */
+#include <stdio.h>
+
+#define MAXPDSTRING 1000        /* use this for anything you want */
+#define MAXPDARG 5              /* max number of args we can typecheck today */
+
+/* signed and unsigned integer types the size of a pointer:  */
+#if !defined(PD_LONGINTTYPE)
+#define PD_LONGINTTYPE long
+#endif
+
+#if !defined(PD_FLOATSIZE)
+  /* normally, our floats (t_float, t_sample,...) are 32bit */
+# define PD_FLOATSIZE 32
+#endif
+
+#if PD_FLOATSIZE == 32
+# define PD_FLOATTYPE float
+/* an unsigned int of the same size as FLOATTYPE: */
+# define PD_FLOATUINTTYPE unsigned int
+
+#elif PD_FLOATSIZE == 64
+# define PD_FLOATTYPE double
+# define PD_FLOATUINTTYPE unsigned long
+#else
+# error invalid FLOATSIZE: must be 32 or 64
+#endif
+
+typedef PD_LONGINTTYPE t_int;       /* pointer-size integer */
+typedef PD_FLOATTYPE t_float;       /* a float type at most the same size */
+typedef PD_FLOATTYPE t_floatarg;    /* float type for function calls */
+
+typedef struct _symbol
+{
+    char *s_name;
+    struct _class **s_thing;
+    struct _symbol *s_next;
+} t_symbol;
+
+EXTERN_STRUCT _array;
+#define t_array struct _array       /* g_canvas.h */
+
+/* pointers to glist and array elements go through a "stub" which sticks
+around after the glist or array is freed.  The stub itself is deleted when
+both the glist/array is gone and the refcount is zero, ensuring that no
+gpointers are pointing here. */
+
+#define GP_NONE 0       /* the stub points nowhere (has been cut off) */
+#define GP_GLIST 1      /* the stub points to a glist element */
+#define GP_ARRAY 2      /* ... or array */
+
+typedef struct _gstub
+{
+    union
+    {
+        struct _glist *gs_glist;    /* glist we're in */
+        struct _array *gs_array;    /* array we're in */
+    } gs_un;
+    int gs_which;                   /* GP_GLIST/GP_ARRAY */
+    int gs_refcount;                /* number of gpointers pointing here */
+} t_gstub;
+
+typedef struct _gpointer           /* pointer to a gobj in a glist */
+{
+    union
+    {   
+        struct _scalar *gp_scalar;  /* scalar we're in (if glist) */
+        union word *gp_w;           /* raw data (if array) */
+    } gp_un;
+    int gp_valid;                   /* number which must match gpointee */
+    t_gstub *gp_stub;               /* stub which points to glist/array */
+} t_gpointer;
+
+typedef union word
+{
+    t_float w_float;
+    t_symbol *w_symbol;
+    t_gpointer *w_gpointer;
+    t_array *w_array;
+    struct _binbuf *w_binbuf;
+    int w_index;
+} t_word;
+
+typedef enum
+{
+    A_NULL,
+    A_FLOAT,
+    A_SYMBOL,
+    A_POINTER,
+    A_SEMI,
+    A_COMMA,
+    A_DEFFLOAT,
+    A_DEFSYM,
+    A_DOLLAR, 
+    A_DOLLSYM,
+    A_GIMME,
+    A_CANT
+}  t_atomtype;
+
+#define A_DEFSYMBOL A_DEFSYM    /* better name for this */
+
+typedef struct _atom
+{
+    t_atomtype a_type;
+    union word a_w;
+} t_atom;
+
+EXTERN_STRUCT _class;
+#define t_class struct _class
+
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+
+EXTERN_STRUCT _binbuf;
+#define t_binbuf struct _binbuf
+
+EXTERN_STRUCT _clock;
+#define t_clock struct _clock
+
+EXTERN_STRUCT _outconnect;
+#define t_outconnect struct _outconnect
+
+EXTERN_STRUCT _glist;
+#define t_glist struct _glist
+#define t_canvas struct _glist  /* LATER lose this */
+
+typedef t_class *t_pd;      /* pure datum: nothing but a class pointer */
+
+typedef struct _gobj        /* a graphical object */
+{
+    t_pd g_pd;              /* pure datum header (class) */
+    struct _gobj *g_next;   /* next in list */
+} t_gobj;
+
+typedef struct _scalar      /* a graphical object holding data */
+{
+    t_gobj sc_gobj;         /* header for graphical object */
+    t_symbol *sc_template;  /* template name (LATER replace with pointer) */
+    t_word sc_vec[1];       /* indeterminate-length array of words */
+} t_scalar;
+
+typedef struct _text        /* patchable object - graphical, with text */
+{
+    t_gobj te_g;                /* header for graphical object */
+    t_binbuf *te_binbuf;        /* holder for the text */
+    t_outlet *te_outlet;        /* linked list of outlets */
+    t_inlet *te_inlet;          /* linked list of inlets */
+    short te_xpix;              /* x&y location (within the toplevel) */
+    short te_ypix;
+    short te_width;             /* requested width in chars, 0 if auto */
+    unsigned int te_type:2;     /* from defs below */
+} t_text;
+
+#define T_TEXT 0        /* just a textual comment */
+#define T_OBJECT 1      /* a MAX style patchable object */
+#define T_MESSAGE 2     /* a MAX stype message */
+#define T_ATOM 3        /* a cell to display a number or symbol */
+
+#define te_pd te_g.g_pd
+
+   /* t_object is synonym for t_text (LATER unify them) */
+
+typedef struct _text t_object;
+
+#define ob_outlet te_outlet
+#define ob_inlet te_inlet
+#define ob_binbuf te_binbuf
+#define ob_pd te_g.g_pd
+#define ob_g te_g
+
+typedef void (*t_method)(void);
+typedef void *(*t_newmethod)( void);
+
+/* in ARM 64 a varargs prototype generates a different function call sequence
+from a fixed one, so in that special case we maek a more restrictive
+definition for t_gotfn.  This will break some code in the "chaos" package
+in Pd extended.  (that code will run incorrectly anyhow so why not catch it
+at compile time anyhow.) */
+#ifdef __aarch64__
+typedef void (*t_gotfn)(void *x);
+#else
+typedef void (*t_gotfn)(void *x, ...);
+#endif
+
+/* ---------------- pre-defined objects and symbols --------------*/
+EXTERN t_pd pd_objectmaker;     /* factory for creating "object" boxes */
+EXTERN t_pd pd_canvasmaker;     /* factory for creating canvases */
+EXTERN t_symbol s_pointer;
+EXTERN t_symbol s_float;
+EXTERN t_symbol s_symbol;
+EXTERN t_symbol s_bang;
+EXTERN t_symbol s_list;
+EXTERN t_symbol s_anything;
+EXTERN t_symbol s_signal;
+EXTERN t_symbol s__N;
+EXTERN t_symbol s__X;
+EXTERN t_symbol s_x;
+EXTERN t_symbol s_y;
+EXTERN t_symbol s_;
+
+/* --------- prototypes from the central message system ----------- */
+EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
+EXTERN t_symbol *gensym(const char *s);
+EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
+EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
+EXTERN void nullfn(void);
+EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...);
+
+/* the following macrose are for sending non-type-checkable mesages, i.e.,
+using function lookup but circumventing type checking on arguments.  Only
+use for internal messaging protected by A_CANT so that the message can't
+be generated at patch level. */
+#define mess0(x, s) ((*getfn((x), (s)))((x)))
+typedef void (*t_gotfn1)(void *x, void *arg1);
+#define mess1(x, s, a) ((*(t_gotfn1)getfn((x), (s)))((x), (a)))
+typedef void (*t_gotfn2)(void *x, void *arg1, void *arg2);
+#define mess2(x, s, a,b) ((*(t_gotfn2)getfn((x), (s)))((x), (a),(b)))
+typedef void (*t_gotfn3)(void *x, void *arg1, void *arg2, void *arg3);
+#define mess3(x, s, a,b,c) ((*(t_gotfn3)getfn((x), (s)))((x), (a),(b),(c)))
+typedef void (*t_gotfn4)(void *x,
+    void *arg1, void *arg2, void *arg3, void *arg4);
+#define mess4(x, s, a,b,c,d) \
+    ((*(t_gotfn4)getfn((x), (s)))((x), (a),(b),(c),(d)))
+typedef void (*t_gotfn5)(void *x,
+    void *arg1, void *arg2, void *arg3, void *arg4, void *arg5);
+#define mess5(x, s, a,b,c,d,e) \
+    ((*(t_gotfn5)getfn((x), (s)))((x), (a),(b),(c),(d),(e)))
+
+EXTERN void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_pd *pd_newest(void);
+
+/* --------------- memory management -------------------- */
+EXTERN void *getbytes(size_t nbytes);
+EXTERN void *getzbytes(size_t nbytes);
+EXTERN void *copybytes(void *src, size_t nbytes);
+EXTERN void freebytes(void *x, size_t nbytes);
+EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize);
+
+/* -------------------- atoms ----------------------------- */
+
+#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0)
+#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0)
+#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \
+    (atom)->a_w.w_gpointer = (gp))
+#define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f))
+#define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \
+    (atom)->a_w.w_symbol = (s))
+#define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \
+    (atom)->a_w.w_index = (n))
+#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \
+    (atom)->a_w.w_symbol= (s))
+
+EXTERN t_float atom_getfloat(t_atom *a);
+EXTERN t_int atom_getint(t_atom *a);
+EXTERN t_symbol *atom_getsymbol(t_atom *a);
+EXTERN t_symbol *atom_gensym(t_atom *a);
+EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv);
+EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv);
+EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv);
+
+EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize);
+
+/* ------------------  binbufs --------------- */
+
+EXTERN t_binbuf *binbuf_new(void);
+EXTERN void binbuf_free(t_binbuf *x);
+EXTERN t_binbuf *binbuf_duplicate(t_binbuf *y);
+
+EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size);
+EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp);
+EXTERN void binbuf_clear(t_binbuf *x);
+EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...);
+EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y);
+EXTERN void binbuf_addsemi(t_binbuf *x);
+EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_print(t_binbuf *x);
+EXTERN int binbuf_getnatom(t_binbuf *x);
+EXTERN t_atom *binbuf_getvec(t_binbuf *x);
+EXTERN int binbuf_resize(t_binbuf *x, int newsize);
+EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv);
+EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname,
+    int crflag);
+EXTERN int binbuf_read_via_canvas(t_binbuf *b, char *filename, t_canvas *canvas,
+    int crflag);
+EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname,
+    int crflag);
+EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir,
+    int crflag);
+EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir);
+EXTERN t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av,
+    int tonew);
+
+/* ------------------  clocks --------------- */
+
+EXTERN t_clock *clock_new(void *owner, t_method fn);
+EXTERN void clock_set(t_clock *x, double systime);
+EXTERN void clock_delay(t_clock *x, double delaytime);
+EXTERN void clock_unset(t_clock *x);
+EXTERN void clock_setunit(t_clock *x, double timeunit, int sampflag);
+EXTERN double clock_getlogicaltime(void);
+EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */
+EXTERN double clock_gettimesince(double prevsystime);
+EXTERN double clock_gettimesincewithunits(double prevsystime,
+    double units, int sampflag);
+EXTERN double clock_getsystimeafter(double delaytime);
+EXTERN void clock_free(t_clock *x);
+
+/* ----------------- pure data ---------------- */
+EXTERN t_pd *pd_new(t_class *cls);
+EXTERN void pd_free(t_pd *x);
+EXTERN void pd_bind(t_pd *x, t_symbol *s);
+EXTERN void pd_unbind(t_pd *x, t_symbol *s);
+EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c);
+EXTERN void pd_pushsym(t_pd *x);
+EXTERN void pd_popsym(t_pd *x);
+EXTERN t_symbol *pd_getfilename(void);
+EXTERN t_symbol *pd_getdirname(void);
+EXTERN void pd_bang(t_pd *x);
+EXTERN void pd_pointer(t_pd *x, t_gpointer *gp);
+EXTERN void pd_float(t_pd *x, t_float f);
+EXTERN void pd_symbol(t_pd *x, t_symbol *s);
+EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+#define pd_class(x) (*(x))
+
+/* ----------------- pointers ---------------- */
+EXTERN void gpointer_init(t_gpointer *gp);
+EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto);
+EXTERN void gpointer_unset(t_gpointer *gp);
+EXTERN int gpointer_check(const t_gpointer *gp, int headok);
+
+/* ----------------- patchable "objects" -------------- */
+EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
+    t_symbol *s2);
+EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
+EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp);
+EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
+EXTERN t_inlet *signalinlet_new(t_object *owner, t_float f);
+EXTERN void inlet_free(t_inlet *x);
+
+EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s);
+EXTERN void outlet_bang(t_outlet *x);
+EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp);
+EXTERN void outlet_float(t_outlet *x, t_float f);
+EXTERN void outlet_symbol(t_outlet *x, t_symbol *s);
+EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_symbol *outlet_getsymbol(t_outlet *x);
+EXTERN void outlet_free(t_outlet *x);
+EXTERN t_object *pd_checkobject(t_pd *x);
+
+
+/* -------------------- canvases -------------- */
+
+EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir);
+
+EXTERN void canvas_setargs(int argc, t_atom *argv);
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+EXTERN t_symbol *canvas_getcurrentdir(void);
+EXTERN t_glist *canvas_getcurrent(void);
+EXTERN void canvas_makefilename(t_glist *c, char *file,
+    char *result,int resultsize);
+EXTERN t_symbol *canvas_getdir(t_glist *x);
+EXTERN char sys_font[]; /* default typeface set in s_main.c */
+EXTERN char sys_fontweight[]; /* default font weight set in s_main.c */
+EXTERN int sys_fontwidth(int fontsize);
+EXTERN int sys_fontheight(int fontsize);
+EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b);
+EXTERN int canvas_open(t_canvas *x, const char *name, const char *ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+
+/* ---------------- widget behaviors ---------------------- */
+
+EXTERN_STRUCT _widgetbehavior;
+#define t_widgetbehavior struct _widgetbehavior
+
+EXTERN_STRUCT _parentwidgetbehavior;
+#define t_parentwidgetbehavior struct _parentwidgetbehavior
+EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x);
+
+/* -------------------- classes -------------- */
+
+#define CLASS_DEFAULT 0         /* flags for new classes below */
+#define CLASS_PD 1
+#define CLASS_GOBJ 2
+#define CLASS_PATCHABLE 3
+#define CLASS_NOINLET 8
+
+#define CLASS_TYPEMASK 3
+
+
+EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod,
+    t_method freemethod, size_t size, int flags, t_atomtype arg1, ...);
+EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s, 
+    t_atomtype type1, ...);
+EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
+    t_atomtype arg1, ...);
+EXTERN void class_addbang(t_class *c, t_method fn);
+EXTERN void class_addpointer(t_class *c, t_method fn);
+EXTERN void class_doaddfloat(t_class *c, t_method fn);
+EXTERN void class_addsymbol(t_class *c, t_method fn);
+EXTERN void class_addlist(t_class *c, t_method fn);
+EXTERN void class_addanything(t_class *c, t_method fn);
+EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s);
+EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w);
+EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w);
+EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c);
+EXTERN char *class_getname(t_class *c);
+EXTERN char *class_gethelpname(t_class *c);
+EXTERN char *class_gethelpdir(t_class *c);
+EXTERN void class_setdrawcommand(t_class *c);
+EXTERN int class_isdrawcommand(t_class *c);
+EXTERN void class_domainsignalin(t_class *c, int onset);
+EXTERN void class_set_extern_dir(t_symbol *s);
+#define CLASS_MAINSIGNALIN(c, type, field) \
+    class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
+
+         /* prototype for functions to save Pd's to a binbuf */
+typedef void (*t_savefn)(t_gobj *x, t_binbuf *b);
+EXTERN void class_setsavefn(t_class *c, t_savefn f);
+EXTERN t_savefn class_getsavefn(t_class *c);
+EXTERN void obj_saveformat(t_object *x, t_binbuf *bb); /* add format to bb */
+
+        /* prototype for functions to open properties dialogs */
+typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist);
+EXTERN void class_setpropertiesfn(t_class *c, t_propertiesfn f);
+EXTERN t_propertiesfn class_getpropertiesfn(t_class *c);
+
+#ifndef PD_CLASS_DEF
+#define class_addbang(x, y) class_addbang((x), (t_method)(y))
+#define class_addpointer(x, y) class_addpointer((x), (t_method)(y))
+#define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y))
+#define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y))
+#define class_addlist(x, y) class_addlist((x), (t_method)(y))
+#define class_addanything(x, y) class_addanything((x), (t_method)(y))
+#endif
+
+/* ------------   printing --------------------------------- */
+EXTERN void post(const char *fmt, ...);
+EXTERN void startpost(const char *fmt, ...);
+EXTERN void poststring(const char *s);
+EXTERN void postfloat(t_floatarg f);
+EXTERN void postatom(int argc, t_atom *argv);
+EXTERN void endpost(void);
+EXTERN void error(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+EXTERN void verbose(int level, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
+EXTERN void bug(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+EXTERN void pd_error(void *object, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
+EXTERN void logpost(const void *object, const int level, const char *fmt, ...)
+    ATTRIBUTE_FORMAT_PRINTF(3, 4);
+EXTERN void sys_logerror(const char *object, const char *s);
+EXTERN void sys_unixerror(const char *object);
+EXTERN void sys_ouch(void);
+
+
+/* ------------  system interface routines ------------------- */
+EXTERN int sys_isreadablefile(const char *name);
+EXTERN int sys_isabsolutepath(const char *dir);
+EXTERN void sys_bashfilename(const char *from, char *to);
+EXTERN void sys_unbashfilename(const char *from, char *to);
+EXTERN int open_via_path(const char *dir, const char *name, const char *ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+EXTERN int sched_geteventno(void);
+EXTERN double sys_getrealtime(void);
+EXTERN int (*sys_idlehook)(void);   /* hook to add idle time computation */
+
+/* Win32's open()/fopen() do not handle UTF-8 filenames so we need
+ * these internal versions that handle UTF-8 filenames the same across
+ * all platforms.  They are recommended for use in external
+ * objectclasses as well so they work with Unicode filenames on Windows */
+EXTERN int sys_open(const char *path, int oflag, ...);
+EXTERN int sys_close(int fd);
+EXTERN FILE *sys_fopen(const char *filename, const char *mode);
+EXTERN int sys_fclose(FILE *stream);
+
+/* ------------  threading ------------------- */ 
+EXTERN void sys_lock(void);
+EXTERN void sys_unlock(void);
+EXTERN int sys_trylock(void);
+
+
+/* --------------- signals ----------------------------------- */
+
+typedef PD_FLOATTYPE t_sample;
+typedef union _sampleint_union {
+  t_sample f;
+  PD_FLOATUINTTYPE i;
+} t_sampleint_union;
+#define MAXLOGSIG 32
+#define MAXSIGSIZE (1 << MAXLOGSIG)
+
+typedef struct _signal
+{
+    int s_n;            /* number of points in the array */
+    t_sample *s_vec;    /* the array */
+    t_float s_sr;         /* sample rate */
+    int s_refcount;     /* number of times used */
+    int s_isborrowed;   /* whether we're going to borrow our array */
+    struct _signal *s_borrowedfrom;     /* signal to borrow it from */
+    struct _signal *s_nextfree;         /* next in freelist */
+    struct _signal *s_nextused;         /* next in used list */
+    int s_vecsize;      /* allocated size of array in points */
+} t_signal;
+
+typedef t_int *(*t_perfroutine)(t_int *args);
+
+EXTERN t_int *plus_perform(t_int *args);
+EXTERN t_int *zero_perform(t_int *args);
+EXTERN t_int *copy_perform(t_int *args);
+
+EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n);
+EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_scalarcopy(t_float *in, t_sample *out, int n);
+EXTERN void dsp_add_zero(t_sample *out, int n);
+
+EXTERN int sys_getblksize(void);
+EXTERN t_float sys_getsr(void);
+EXTERN int sys_get_inchannels(void);
+EXTERN int sys_get_outchannels(void);
+
+EXTERN void dsp_add(t_perfroutine f, int n, ...);
+EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec);
+EXTERN void pd_fft(t_float *buf, int npoints, int inverse);
+EXTERN int ilog2(int n);
+
+EXTERN void mayer_fht(t_sample *fz, int n);
+EXTERN void mayer_fft(int n, t_sample *real, t_sample *imag);
+EXTERN void mayer_ifft(int n, t_sample *real, t_sample *imag);
+EXTERN void mayer_realfft(int n, t_sample *real);
+EXTERN void mayer_realifft(int n, t_sample *real);
+
+EXTERN float *cos_table;
+#define LOGCOSTABSIZE 9
+#define COSTABSIZE (1<<LOGCOSTABSIZE)
+
+EXTERN int canvas_suspend_dsp(void);
+EXTERN void canvas_resume_dsp(int oldstate);
+EXTERN void canvas_update_dsp(void);
+EXTERN int canvas_dspstate;
+
+/*   up/downsampling */
+typedef struct _resample
+{
+  int method;       /* up/downsampling method ID */
+
+  t_int downsample; /* downsampling factor */
+  t_int upsample;   /* upsampling factor */
+
+  t_sample *s_vec;   /* here we hold the resampled data */
+  int      s_n;
+
+  t_sample *coeffs;  /* coefficients for filtering... */
+  int      coefsize;
+
+  t_sample *buffer;  /* buffer for filtering */
+  int      bufsize;
+} t_resample;
+
+EXTERN void resample_init(t_resample *x);
+EXTERN void resample_free(t_resample *x);
+
+EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method);
+EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method);
+EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method);
+
+/* ----------------------- utility functions for signals -------------- */
+EXTERN t_float mtof(t_float);
+EXTERN t_float ftom(t_float);
+EXTERN t_float rmstodb(t_float);
+EXTERN t_float powtodb(t_float);
+EXTERN t_float dbtorms(t_float);
+EXTERN t_float dbtopow(t_float);
+
+EXTERN t_float q8_sqrt(t_float);
+EXTERN t_float q8_rsqrt(t_float);
+#ifndef N32     
+EXTERN t_float qsqrt(t_float);  /* old names kept for extern compatibility */
+EXTERN t_float qrsqrt(t_float);
+#endif
+/* --------------------- data --------------------------------- */
+
+    /* graphical arrays */
+EXTERN_STRUCT _garray;
+#define t_garray struct _garray
+
+EXTERN t_class *garray_class;
+EXTERN int garray_getfloatarray(t_garray *x, int *size, t_float **vec);
+EXTERN int garray_getfloatwords(t_garray *x, int *size, t_word **vec);
+EXTERN void garray_redraw(t_garray *x);
+EXTERN int garray_npoints(t_garray *x);
+EXTERN char *garray_vec(t_garray *x);
+EXTERN void garray_resize(t_garray *x, t_floatarg f);  /* avoid; use this: */
+EXTERN void garray_resize_long(t_garray *x, long n);   /* better version */
+EXTERN void garray_usedindsp(t_garray *x);
+EXTERN void garray_setsaveit(t_garray *x, int saveit);
+EXTERN t_glist *garray_getglist(t_garray *x);
+EXTERN t_array *garray_getarray(t_garray *x);
+EXTERN t_class *scalar_class;
+
+EXTERN t_float *value_get(t_symbol *s);
+EXTERN void value_release(t_symbol *s);
+EXTERN int value_getfloat(t_symbol *s, t_float *f);
+EXTERN int value_setfloat(t_symbol *s, t_float f);
+
+/* ------- GUI interface - functions to send strings to TK --------- */
+typedef void (*t_guicallbackfn)(t_gobj *client, t_glist *glist);
+
+EXTERN void sys_vgui(char *fmt, ...);
+EXTERN void sys_gui(char *s);
+EXTERN void sys_pretendguibytes(int n);
+EXTERN void sys_queuegui(void *client, t_glist *glist, t_guicallbackfn f);
+EXTERN void sys_unqueuegui(void *client);
+    /* dialog window creation and destruction */
+EXTERN void gfxstub_new(t_pd *owner, void *key, const char *cmd);
+EXTERN void gfxstub_deleteforkey(void *key);
+
+extern t_class *glob_pdobject;  /* object to send "pd" messages */
+
+/*-------------  Max 0.26 compatibility --------------------*/
+
+/* the following reflects the new way classes are laid out, with the class
+   pointing to the messlist and not vice versa. Externs shouldn't feel it. */
+typedef t_class *t_externclass;
+
+EXTERN void c_extern(t_externclass *cls, t_newmethod newroutine,
+    t_method freeroutine, t_symbol *name, size_t size, int tiny, \
+    t_atomtype arg1, ...);
+EXTERN void c_addmess(t_method fn, t_symbol *sel, t_atomtype arg1, ...);
+
+#define t_getbytes getbytes
+#define t_freebytes freebytes
+#define t_resizebytes resizebytes
+#define typedmess pd_typedmess
+#define vmess pd_vmess
+
+/* A definition to help gui objects straddle 0.34-0.35 changes.  If this is
+defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
+
+#define PD_USE_TE_XPIX
+
+#ifndef _MSC_VER /* Microoft compiler can't handle "inline" function/macros */
+#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+/* a test for NANs and denormals.  Should only be necessary on i386. */
+# if PD_FLOATSIZE == 32
+static inline int PD_BADFLOAT(t_sample f) {
+  t_sampleint_union u;
+  u.f=f;
+  return ((u.i & 0x7f800000)==0) || ((u.i&0x7f800000)==0x7f800000);
+}
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+static inline int PD_BIGORSMALL(t_sample f) {
+  t_sampleint_union u;
+  u.f=f;
+  return ((u.i & 0x60000000)==0) || ((u.i & 0x60000000)==0x60000000);
+}
+# else
+#  warning 64bit mode: BIGORSMALL not implemented yet
+#  define PD_BADFLOAT(f) 0
+#  define PD_BIGORSMALL(f) 0
+# endif
+#else
+# define PD_BADFLOAT(f) 0
+# define PD_BIGORSMALL(f) 0
+#endif
+#else   /* _MSC_VER */
+#define PD_BADFLOAT(f) ((((*(unsigned int*)&(f))&0x7f800000)==0) || \
+    (((*(unsigned int*)&(f))&0x7f800000)==0x7f800000))
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+#define PD_BIGORSMALL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
+    (((*(unsigned int*)&(f))&0x60000000)==0x60000000))
+#endif /* _MSC_VER */
+    /* get version number at run time */
+EXTERN void sys_getversion(int *major, int *minor, int *bugfix);
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
+
+#define __m_pd_h_
+#endif /* __m_pd_h_ */
diff --git a/tools/sound2faust/Makefile b/tools/sound2faust/Makefile
new file mode 100644
index 0000000..8644822
--- /dev/null
+++ b/tools/sound2faust/Makefile
@@ -0,0 +1,32 @@
+
+DESTDIR ?= 
+PREFIX ?= /usr/local
+
+prefix := $(DESTDIR)$(PREFIX)
+
+system	?= $(shell uname -s)
+
+## On Windows (mingw32) we must link against the socket library.
+ifneq ($(findstring MINGW32, $(system)),)
+LIBS = -lwsock32
+EXE = .exe
+endif
+
+sound2faust : sound2faust.cpp
+
+	$(CXX) -O3 sound2faust.cpp -I../../architecture `pkg-config --cflags --static --libs sndfile` -o sound2faust $(LIBS)
+
+static:
+
+	$(CXX) -O3 sound2faust.cpp -I../../architecture `pkg-config --cflags  sndfile`  /usr/local/lib/libsndfile.a -o sound2faust
+
+install :
+
+	install sound2faust $(prefix)/bin/
+	install sound2reader $(prefix)/bin/
+
+clean :
+	rm -f sound2faust$(EXE)
+
+
+	
diff --git a/tools/sound2faust/sound2faust.cpp b/tools/sound2faust/sound2faust.cpp
new file mode 100644
index 0000000..7c2ab73
--- /dev/null
+++ b/tools/sound2faust/sound2faust.cpp
@@ -0,0 +1,143 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <errno.h>
+#include <time.h>
+#include <sndfile.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#ifndef _WIN32
+#include <libgen.h>
+#endif
+
+#include "faust/misc.h"
+
+using namespace std;
+
+#define BUFFER_SIZE 1024
+
+// g++ -O3 sound2faust.cpp -lsndfile -o sound2faust
+
+static string RemoveEnding(const string& name)
+{
+    int match = name.rfind(".");
+    return (match != string::npos) ? name.substr(0, match) : name;
+}
+
+int main(int argc, char *argv[])
+{
+	SNDFILE* soundfile;
+	SF_INFO	snd_info;
+    char* base_name;
+    
+    const char* output = lopts(argv, "-o", "");
+    long interleaved = isopt(argv, "-i");
+    
+#ifndef _WIN32
+	base_name = basename(argv[1]);
+#else
+	base_name = new char[_MAX_FNAME];
+	_splitpath(argv[1], NULL, NULL, base_name, NULL);
+	printf("BASENAME = %s\n", base_name);
+#endif
+    if (argc < 2) {
+        printf("sound2faust <sound> -i (for interleaved) -o <file>\n");
+        printf("Generates : 'sound_n = waveform {....}' interleaved waveform\n");
+        printf("Generates : 'sound_0 = waveform {....} .... sound_x = waveform {....}' mono waveforms\n");
+        printf("Generates : 'sound = (sound_0,...sound_x):((!,_),...(!,_))' processor\n");
+        exit(1);
+    }
+    
+    if (isdigit(base_name[0])) {
+        printf("soundfile '%s' start with a digit, please rename it\n", base_name);
+        exit(0); 
+    }
+     
+    snd_info.format = 0;
+    soundfile = sf_open(argv[1], SFM_READ, &snd_info);
+    
+    if (!soundfile) { 
+        printf("soundfile '%s' cannot be opened\n", base_name);
+        exit(0); 
+    }
+    
+    std::ostream* dst;
+    if (strcmp(output, "") == 0) {
+        dst = &cout;
+    } else {
+        dst = new ofstream(output);
+    }
+    
+    double buffer[BUFFER_SIZE * snd_info.channels];
+    
+    char sep;
+    
+    if (interleaved) {
+        
+        // Generates one interleaved waveform
+        *dst << RemoveEnding(base_name) << "_n = waveform";
+        int nbf;
+        sep = '{';
+        do {
+            nbf = sf_readf_double(soundfile, buffer, BUFFER_SIZE);
+            for (int i = 0; i < nbf * snd_info.channels; i++) {
+                *dst << sep << buffer[i];
+                sep = ',';
+            }
+            
+        } while (nbf == BUFFER_SIZE);
+        *dst << "};" << std::endl;
+        
+    } else {
+    
+        // Generates separated mono waveforms
+        for (int chan = 0; chan < snd_info.channels; chan++) {
+            sf_seek(soundfile, 0, SEEK_SET);
+            *dst << RemoveEnding(base_name) << "_" << chan << " = waveform";
+            int nbf;
+            sep = '{';
+            do {
+                nbf = sf_readf_double(soundfile, buffer, BUFFER_SIZE);
+                for (int i = 0; i < nbf * snd_info.channels; i++) {
+                    if (i % snd_info.channels == chan) {
+                        *dst << sep << buffer[i];
+                        sep = ',';
+                    }
+                }
+                
+            } while (nbf == BUFFER_SIZE);
+            *dst << "};" << std::endl;
+        }
+        
+        // Generates one multi-channels processor
+        *dst << RemoveEnding(base_name) << " = ";
+        
+        sep = '(';
+        for (int chan = 0; chan < snd_info.channels; chan++) {
+            *dst << sep << RemoveEnding(base_name) << "_" << chan;
+            sep = ',';
+        }
+        
+        *dst << "):";
+        
+        sep = '(';
+        for (int chan = 0; chan < snd_info.channels; chan++) {
+            *dst << sep << "(!,_)";
+            sep = ',';
+        }
+        
+        *dst << ");" << std::endl;
+        
+        // And generate tables
+        for (int chan = 0; chan < snd_info.channels; chan++) {
+            *dst << RemoveEnding(base_name) << "_rtable_" << chan <<"(r) = (" << RemoveEnding(base_name) << "_" << chan << ",r):rdtable;" << endl;
+        }
+    }
+       
+    dst->flush();
+}
diff --git a/tools/sound2faust/sound2reader b/tools/sound2faust/sound2reader
new file mode 100755
index 0000000..eab9cf1
--- /dev/null
+++ b/tools/sound2faust/sound2reader
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+#-------------------------------------------------------------------
+# Analyze command arguments :
+# existing *.dsp files          -> FILES
+#
+
+LLVM="false"
+FAUSTFLOAT="float"
+
+for p in $@; do
+    if [ $p = "-help" ] || [ $p = "-h" ]; then
+        echo "sound2llvm [-llvm] <file.dsp>"
+        echo "Use '-llvm' to compile the sound reader code as a LLVM module"
+  	elif [[ -e "$p" ]]; then
+	    FILES="$FILES $p"
+    elif [ $p = "-llvm" ]; then
+	    LLVM="true"
+    elif [ $p = "-double" ]; then
+	    FAUSTFLOAT="double"
+	fi
+done
+
+#-------------------------------------------------------------------
+# compile the *.dsp files
+#
+
+for f in $FILES; do
+
+    name=${f%.wav}
+             
+    # compose the soundfile reader C code
+    echo "// SoundFile API" > $name.c
+    echo -n "#define FAUSTFLOAT " >> $name.c
+    echo $FAUSTFLOAT >> $name.c
+    echo "#include \"faust/sound-file.h\"" >> $name.c
+    echo "// Generated API" >> $name.c
+    echo "#ifdef __cplusplus" >> $name.c
+    echo "extern \"C\" {" >> $name.c
+    echo "#endif" >> $name.c
+    echo -n "static SoundFileReader* " >> $name.c
+    echo -n $name >> $name.c
+    echo "_reader = 0;" >> $name.c
+    
+    echo -n "int " >> $name.c
+    echo -n $name >> $name.c
+    echo -n "_size()" >> $name.c
+    echo -n " { if (!" >> $name.c
+    echo -n $name >> $name.c
+    echo -n "_reader) "  >> $name.c
+    echo -n $name >> $name.c
+    echo -n "_reader = createSFR(\"" >> $name.c
+    echo -n $f >> $name.c
+    echo -n "\"); return sizeSFR(" >> $name.c
+    echo -n $name >> $name.c
+    echo "_reader); }"  >> $name.c
+
+    echo -n "FAUSTFLOAT " >> $name.c
+    echo -n $name >> $name.c
+    echo -n "_sample(int channel, int index) { return sampleSFR(" >> $name.c
+    echo -n $name >> $name.c
+    echo "_reader, channel, index); }" >> $name.c
+    
+    echo -n "int " >> $name.c
+    echo -n $name >> $name.c
+    echo -n "_channels() { return channelsSFR(" >> $name.c
+    echo -n $name >> $name.c
+    echo "_reader); }" >> $name.c
+    echo "#ifdef __cplusplus" >> $name.c
+    echo "extern \"C\" }" >> $name.c
+    echo "#endif" >> $name.c
+    
+    if [ $LLVM = "true" ]; then
+        clang -emit-llvm -O3 -S $name.c 
+    fi
+
+done
diff --git a/windows/faust_vs2008.sln b/windows/faust_vs2008.sln
deleted file mode 100644
index 25d1e20..0000000
--- a/windows/faust_vs2008.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "faust_vs2008", "faust_vs2008.vcproj", "{5B179DA5-5826-46C2-AF2C-DBEF9181610D}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{5B179DA5-5826-46C2-AF2C-DBEF9181610D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{5B179DA5-5826-46C2-AF2C-DBEF9181610D}.Debug|Win32.Build.0 = Debug|Win32
-		{5B179DA5-5826-46C2-AF2C-DBEF9181610D}.Release|Win32.ActiveCfg = Release|Win32
-		{5B179DA5-5826-46C2-AF2C-DBEF9181610D}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/windows/faust_vs2008.vcproj b/windows/faust_vs2008.vcproj
deleted file mode 100644
index 99e3973..0000000
--- a/windows/faust_vs2008.vcproj
+++ /dev/null
@@ -1,991 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9,00"
-	Name="faust_vs2008"
-	ProjectGUID="{5B179DA5-5826-46C2-AF2C-DBEF9181610D}"
-	RootNamespace="faust_vs2008"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="_output/$(PlatformName)/$(ProjectName)/$(ConfigurationName)"
-			IntermediateDirectory="_output/$(PlatformName)/$(ProjectName)/$(ConfigurationName)/Int"
-			ConfigurationType="1"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/wd4554"
-				Optimization="0"
-				AdditionalIncludeDirectories="../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				LinkIncremental="2"
-				GenerateDebugInformation="true"
-				SubSystem="1"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="_output/$(PlatformName)/$(ProjectName)/$(ConfigurationName)"
-			IntermediateDirectory="_output/$(PlatformName)/$(ProjectName)/$(ConfigurationName)/Int"
-			ConfigurationType="1"
-			CharacterSet="2"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/wd4554"
-				Optimization="2"
-				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				LinkIncremental="1"
-				GenerateDebugInformation="true"
-				SubSystem="1"
-				OptimizeReferences="2"
-				EnableCOMDATFolding="2"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="boxes"
-			>
-			<File
-				RelativePath="..\compiler\boxes\boxcomplexity.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\boxes\boxcomplexity.h"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\boxes\boxes.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\boxes\boxes.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\boxes\boxtype.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\boxes\ppbox.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\boxes\ppbox.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="documentator"
-			>
-			<File
-				RelativePath="..\compiler\documentator\doc.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_autodoc.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_autodoc.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_compile.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_compile.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_lang.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_lang.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_metadatas.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_metadatas.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_notice.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_notice.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_sharing.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_Text.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\doc_Text.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\lateq.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\documentator\lateq.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="draw"
-			>
-			<File
-				RelativePath="..\compiler\draw\drawschema.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\draw\drawschema.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\draw\sigToGraph.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\draw\sigToGraph.hh"
-				>
-			</File>
-			<Filter
-				Name="device"
-				>
-				<File
-					RelativePath="..\compiler\draw\device\device.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\device\devLib.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\device\PSDev.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\device\PSDev.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\device\SVGDev.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\device\SVGDev.h"
-					>
-				</File>
-			</Filter>
-			<Filter
-				Name="schema"
-				>
-				<File
-					RelativePath="..\compiler\draw\schema\blockSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\blockSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\cableSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\cableSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\collector.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\cutSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\cutSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\decorateSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\decorateSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\enlargedSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\enlargedSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\inverterSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\inverterSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\mergeSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\mergeSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\parSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\parSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\recSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\recSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\schema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\seqSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\seqSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\splitSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\splitSchema.h"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\topSchema.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\compiler\draw\schema\topSchema.h"
-					>
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="errors"
-			>
-			<File
-				RelativePath="..\compiler\errors\errormsg.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\errors\errormsg.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\errors\timing.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\errors\timing.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="evaluate"
-			>
-			<File
-				RelativePath="..\compiler\evaluate\environment.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\evaluate\environment.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\evaluate\eval.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\evaluate\eval.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\evaluate\loopDetector.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\evaluate\loopDetector.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="extended"
-			>
-			<File
-				RelativePath="..\compiler\extended\absprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\acosprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\asinprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\atan2prim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\atanprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\ceilprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\cosprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\expprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\floorprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\fmodprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\log10prim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\logprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\maxprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\minprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\powprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\remainderprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\rintprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\sinprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\sqrtprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\tanprim.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\extended\xtended.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="generator"
-			>
-			<File
-				RelativePath="..\compiler\generator\compile.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile_scal.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile_scal.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile_sched.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile_sched.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile_vect.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\compile_vect.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\contextor.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\contextor.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\description.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\description.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\floats.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\floats.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\klass.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\klass.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\occurences.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\occurences.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\sharing.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\Text.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\Text.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\uitree.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\generator\uitree.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="normalize"
-			>
-			<File
-				RelativePath="..\compiler\normalize\aterm.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\aterm.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\mterm.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\mterm.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\normalize.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\normalize.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\privatise.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\privatise.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\simplify.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\normalize\simplify.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="parallelize"
-			>
-			<File
-				RelativePath="..\compiler\parallelize\colorize.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parallelize\colorize.h"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parallelize\graphSorting.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parallelize\graphSorting.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parallelize\loop.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parallelize\loop.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="parser"
-			>
-			<File
-				RelativePath="..\compiler\parser\enrobage.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parser\enrobage.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parser\faustlexer.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parser\faustparser.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parser\faustparser.hpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parser\sourcereader.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\parser\sourcereader.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="patternmatcher"
-			>
-			<File
-				RelativePath="..\compiler\patternmatcher\patternmatcher.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\patternmatcher\patternmatcher.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="propagate"
-			>
-			<File
-				RelativePath="..\compiler\propagate\labels.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\propagate\labels.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\propagate\propagate.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\propagate\propagate.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="signals"
-			>
-			<File
-				RelativePath="..\compiler\signals\binop.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\binop.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\interval.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\ppsig.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\ppsig.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\prim2.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\prim2.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\recursivness.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\recursivness.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\signals.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\signals.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigorderrules.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigorderrules.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigprint.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigprint.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigtype.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigtype.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigtyperules.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigtyperules.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigvisitor.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\sigvisitor.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\signals\subsignals.cpp"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="tlib"
-			>
-			<File
-				RelativePath="..\compiler\tlib\compatibility.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\compatibility.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\list.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\list.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\node.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\node.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\num.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\occurrences.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\occurrences.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\property.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\recursive-tree.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\shlysis.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\shlysis.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\smartpointer.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\symbol.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\symbol.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\tlib.hh"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\tree.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\tlib\tree.hh"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="utils"
-			>
-			<File
-				RelativePath="..\compiler\utils\names.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\compiler\utils\names.hh"
-				>
-			</File>
-		</Filter>
-		<File
-			RelativePath="..\compiler\main.cpp"
-			>
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/windows/faust_vs2012.vcxproj b/windows/faust_vs2012.vcxproj
new file mode 100644
index 0000000..f8ebfa2
--- /dev/null
+++ b/windows/faust_vs2012.vcxproj
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>faust_vs2012</ProjectName>
+    <ProjectGuid>{5B179DA5-5826-46C2-AF2C-DBEF9181610D}</ProjectGuid>
+    <RootNamespace>faust_vs2008</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\compiler\boxes\boxcomplexity.cpp" />
+    <ClCompile Include="..\compiler\boxes\boxes.cpp" />
+    <ClCompile Include="..\compiler\boxes\boxtype.cpp" />
+    <ClCompile Include="..\compiler\boxes\ppbox.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_autodoc.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_compile.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_lang.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_metadatas.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_notice.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_sharing.cpp" />
+    <ClCompile Include="..\compiler\documentator\doc_Text.cpp" />
+    <ClCompile Include="..\compiler\documentator\lateq.cpp" />
+    <ClCompile Include="..\compiler\draw\drawschema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\connectorSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\sigToGraph.cpp" />
+    <ClCompile Include="..\compiler\draw\device\PSDev.cpp" />
+    <ClCompile Include="..\compiler\draw\device\SVGDev.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\blockSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\cableSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\collector.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\cutSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\decorateSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\enlargedSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\inverterSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\mergeSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\parSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\recSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\seqSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\splitSchema.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\topSchema.cpp" />
+    <ClCompile Include="..\compiler\errors\errormsg.cpp" />
+    <ClCompile Include="..\compiler\errors\timing.cpp" />
+    <ClCompile Include="..\compiler\evaluate\environment.cpp" />
+    <ClCompile Include="..\compiler\evaluate\eval.cpp" />
+    <ClCompile Include="..\compiler\evaluate\loopDetector.cpp" />
+    <ClCompile Include="..\compiler\extended\absprim.cpp" />
+    <ClCompile Include="..\compiler\extended\acosprim.cpp" />
+    <ClCompile Include="..\compiler\extended\asinprim.cpp" />
+    <ClCompile Include="..\compiler\extended\atan2prim.cpp" />
+    <ClCompile Include="..\compiler\extended\atanprim.cpp" />
+    <ClCompile Include="..\compiler\extended\ceilprim.cpp" />
+    <ClCompile Include="..\compiler\extended\cosprim.cpp" />
+    <ClCompile Include="..\compiler\extended\expprim.cpp" />
+    <ClCompile Include="..\compiler\extended\floorprim.cpp" />
+    <ClCompile Include="..\compiler\extended\fmodprim.cpp" />
+    <ClCompile Include="..\compiler\extended\log10prim.cpp" />
+    <ClCompile Include="..\compiler\extended\logprim.cpp" />
+    <ClCompile Include="..\compiler\extended\maxprim.cpp" />
+    <ClCompile Include="..\compiler\extended\minprim.cpp" />
+    <ClCompile Include="..\compiler\extended\powprim.cpp" />
+    <ClCompile Include="..\compiler\extended\remainderprim.cpp" />
+    <ClCompile Include="..\compiler\extended\rintprim.cpp" />
+    <ClCompile Include="..\compiler\extended\sinprim.cpp" />
+    <ClCompile Include="..\compiler\extended\sqrtprim.cpp" />
+    <ClCompile Include="..\compiler\extended\tanprim.cpp" />
+    <ClCompile Include="..\compiler\generator\compile.cpp" />
+    <ClCompile Include="..\compiler\generator\compile_scal.cpp" />
+    <ClCompile Include="..\compiler\generator\compile_sched.cpp" />
+    <ClCompile Include="..\compiler\generator\compile_vect.cpp" />
+    <ClCompile Include="..\compiler\generator\contextor.cpp" />
+    <ClCompile Include="..\compiler\generator\description.cpp" />
+    <ClCompile Include="..\compiler\generator\floats.cpp" />
+    <ClCompile Include="..\compiler\generator\klass.cpp" />
+    <ClCompile Include="..\compiler\generator\occurences.cpp" />
+    <ClCompile Include="..\compiler\generator\sharing.cpp" />
+    <ClCompile Include="..\compiler\generator\Text.cpp" />
+    <ClCompile Include="..\compiler\generator\uitree.cpp" />
+    <ClCompile Include="..\compiler\normalize\aterm.cpp" />
+    <ClCompile Include="..\compiler\normalize\mterm.cpp" />
+    <ClCompile Include="..\compiler\normalize\normalize.cpp" />
+    <ClCompile Include="..\compiler\normalize\privatise.cpp" />
+    <ClCompile Include="..\compiler\normalize\simplify.cpp" />
+    <ClCompile Include="..\compiler\parallelize\colorize.cpp" />
+    <ClCompile Include="..\compiler\parallelize\graphSorting.cpp" />
+    <ClCompile Include="..\compiler\parallelize\loop.cpp" />
+    <ClCompile Include="..\compiler\parser\enrobage.cpp" />
+    <ClCompile Include="..\compiler\parser\faustlexer.cpp" />
+    <ClCompile Include="..\compiler\parser\faustparser.cpp" />
+    <ClCompile Include="..\compiler\parser\sourcefetcher.cpp" />
+    <ClCompile Include="..\compiler\parser\sourcereader.cpp" />
+    <ClCompile Include="..\compiler\patternmatcher\patternmatcher.cpp" />
+    <ClCompile Include="..\compiler\propagate\labels.cpp" />
+    <ClCompile Include="..\compiler\propagate\propagate.cpp" />
+    <ClCompile Include="..\compiler\signals\binop.cpp" />
+    <ClCompile Include="..\compiler\signals\ppsig.cpp" />
+    <ClCompile Include="..\compiler\signals\prim2.cpp" />
+    <ClCompile Include="..\compiler\signals\recursivness.cpp" />
+    <ClCompile Include="..\compiler\signals\signals.cpp" />
+    <ClCompile Include="..\compiler\signals\sigorderrules.cpp" />
+    <ClCompile Include="..\compiler\signals\sigprint.cpp" />
+    <ClCompile Include="..\compiler\signals\sigtype.cpp" />
+    <ClCompile Include="..\compiler\signals\sigtyperules.cpp" />
+    <ClCompile Include="..\compiler\signals\sigvisitor.cpp" />
+    <ClCompile Include="..\compiler\signals\subsignals.cpp" />
+    <ClCompile Include="..\compiler\tlib\compatibility.cpp" />
+    <ClCompile Include="..\compiler\tlib\list.cpp" />
+    <ClCompile Include="..\compiler\tlib\node.cpp" />
+    <ClCompile Include="..\compiler\tlib\occurrences.cpp" />
+    <ClCompile Include="..\compiler\tlib\recursive-tree.cpp" />
+    <ClCompile Include="..\compiler\tlib\shlysis.cpp" />
+    <ClCompile Include="..\compiler\tlib\symbol.cpp" />
+    <ClCompile Include="..\compiler\tlib\tree.cpp" />
+    <ClCompile Include="..\compiler\utils\files.cpp" />
+    <ClCompile Include="..\compiler\utils\names.cpp" />
+    <ClCompile Include="..\compiler\main.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\compiler\boxes\boxcomplexity.h" />
+    <ClInclude Include="..\compiler\draw\device\device.h" />
+    <ClInclude Include="..\compiler\draw\device\devLib.h" />
+    <ClInclude Include="..\compiler\draw\device\PSDev.h" />
+    <ClInclude Include="..\compiler\draw\device\SVGDev.h" />
+    <ClInclude Include="..\compiler\draw\schema\blockSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\cableSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\connectorSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\cutSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\decorateSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\enlargedSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\inverterSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\mergeSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\parSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\recSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\schema.h" />
+    <ClInclude Include="..\compiler\draw\schema\seqSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\splitSchema.h" />
+    <ClInclude Include="..\compiler\draw\schema\topSchema.h" />
+    <ClInclude Include="..\compiler\parallelize\colorize.h" />
+    <ClInclude Include="..\compiler\parser\faustparser.hpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\compiler\boxes\boxes.hh" />
+    <None Include="..\compiler\boxes\ppbox.hh" />
+    <None Include="..\compiler\documentator\doc.hh" />
+    <None Include="..\compiler\documentator\doc_autodoc.hh" />
+    <None Include="..\compiler\documentator\doc_compile.hh" />
+    <None Include="..\compiler\documentator\doc_lang.hh" />
+    <None Include="..\compiler\documentator\doc_metadatas.hh" />
+    <None Include="..\compiler\documentator\doc_notice.hh" />
+    <None Include="..\compiler\documentator\doc_Text.hh" />
+    <None Include="..\compiler\documentator\lateq.hh" />
+    <None Include="..\compiler\draw\drawschema.hh" />
+    <None Include="..\compiler\draw\sigToGraph.hh" />
+    <None Include="..\compiler\errors\errormsg.hh" />
+    <None Include="..\compiler\errors\timing.hh" />
+    <None Include="..\compiler\evaluate\environment.hh" />
+    <None Include="..\compiler\evaluate\eval.hh" />
+    <None Include="..\compiler\evaluate\loopDetector.hh" />
+    <None Include="..\compiler\extended\xtended.hh" />
+    <None Include="..\compiler\generator\compile.hh" />
+    <None Include="..\compiler\generator\compile_scal.hh" />
+    <None Include="..\compiler\generator\compile_sched.hh" />
+    <None Include="..\compiler\generator\compile_vect.hh" />
+    <None Include="..\compiler\generator\contextor.hh" />
+    <None Include="..\compiler\generator\description.hh" />
+    <None Include="..\compiler\generator\floats.hh" />
+    <None Include="..\compiler\generator\klass.hh" />
+    <None Include="..\compiler\generator\occurences.hh" />
+    <None Include="..\compiler\generator\Text.hh" />
+    <None Include="..\compiler\generator\uitree.hh" />
+    <None Include="..\compiler\normalize\aterm.hh" />
+    <None Include="..\compiler\normalize\mterm.hh" />
+    <None Include="..\compiler\normalize\normalize.hh" />
+    <None Include="..\compiler\normalize\privatise.hh" />
+    <None Include="..\compiler\normalize\simplify.hh" />
+    <None Include="..\compiler\parallelize\graphSorting.hh" />
+    <None Include="..\compiler\parallelize\loop.hh" />
+    <None Include="..\compiler\parser\enrobage.hh" />
+    <None Include="..\compiler\parser\sourcefetcher.hh" />
+    <None Include="..\compiler\parser\sourcereader.hh" />
+    <None Include="..\compiler\patternmatcher\patternmatcher.hh" />
+    <None Include="..\compiler\propagate\labels.hh" />
+    <None Include="..\compiler\propagate\propagate.hh" />
+    <None Include="..\compiler\signals\binop.hh" />
+    <None Include="..\compiler\signals\interval.hh" />
+    <None Include="..\compiler\signals\ppsig.hh" />
+    <None Include="..\compiler\signals\prim2.hh" />
+    <None Include="..\compiler\signals\recursivness.hh" />
+    <None Include="..\compiler\signals\signals.hh" />
+    <None Include="..\compiler\signals\sigorderrules.hh" />
+    <None Include="..\compiler\signals\sigprint.hh" />
+    <None Include="..\compiler\signals\sigtype.hh" />
+    <None Include="..\compiler\signals\sigtyperules.hh" />
+    <None Include="..\compiler\signals\sigvisitor.hh" />
+    <None Include="..\compiler\tlib\compatibility.hh" />
+    <None Include="..\compiler\tlib\list.hh" />
+    <None Include="..\compiler\tlib\node.hh" />
+    <None Include="..\compiler\tlib\num.hh" />
+    <None Include="..\compiler\tlib\occurrences.hh" />
+    <None Include="..\compiler\tlib\property.hh" />
+    <None Include="..\compiler\tlib\shlysis.hh" />
+    <None Include="..\compiler\tlib\smartpointer.hh" />
+    <None Include="..\compiler\tlib\symbol.hh" />
+    <None Include="..\compiler\tlib\tlib.hh" />
+    <None Include="..\compiler\tlib\tree.hh" />
+    <None Include="..\compiler\utils\files.hh" />
+    <None Include="..\compiler\utils\names.hh" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/windows/faust_vs2012.vcxproj.filters b/windows/faust_vs2012.vcxproj.filters
new file mode 100644
index 0000000..71af879
--- /dev/null
+++ b/windows/faust_vs2012.vcxproj.filters
@@ -0,0 +1,639 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="boxes">
+      <UniqueIdentifier>{df74490a-26bb-4f85-a2d5-72db3d4b6e02}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="documentator">
+      <UniqueIdentifier>{1192a7e0-f5c5-473c-bba2-de918f6c886f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="draw">
+      <UniqueIdentifier>{d388d7f1-959d-4fbb-be24-ab09b6f88797}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="draw\device">
+      <UniqueIdentifier>{c4561880-9b84-4cf8-9b53-461f884086e3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="draw\schema">
+      <UniqueIdentifier>{38ad8d6f-821f-4f36-989d-a7b9154fa468}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="errors">
+      <UniqueIdentifier>{34eee96a-4d99-470b-9b58-3e54b9ae8e46}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="evaluate">
+      <UniqueIdentifier>{daecc64a-6d58-4b5c-b1f1-4f64138885e7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="extended">
+      <UniqueIdentifier>{f99c4568-b4c5-4d13-b97d-beb37af1c9a4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="generator">
+      <UniqueIdentifier>{d87c524c-bd81-4fbf-85ca-887f85c0d4f4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="normalize">
+      <UniqueIdentifier>{1f153ef7-0d56-4235-9375-299f9cd707e9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="parallelize">
+      <UniqueIdentifier>{fa740d1e-dddb-4b4f-9fdd-b96986796040}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="parser">
+      <UniqueIdentifier>{0307cdbd-c886-4523-99a8-cdbb8e941ca5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="patternmatcher">
+      <UniqueIdentifier>{cd89ffc2-9856-43e7-8815-7539ad266d62}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="propagate">
+      <UniqueIdentifier>{3ab9b3fe-6d00-4c17-a484-eeb3b178cb3d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="signals">
+      <UniqueIdentifier>{bddcdf65-cf56-4ac7-a070-7e8967c8d7b1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="tlib">
+      <UniqueIdentifier>{581749ba-b4c3-4875-9b85-afb44a3750d3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="utils">
+      <UniqueIdentifier>{9e340713-4d42-49cf-976e-f1bcc63136c6}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\compiler\boxes\boxcomplexity.cpp">
+      <Filter>boxes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\boxes\boxes.cpp">
+      <Filter>boxes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\boxes\boxtype.cpp">
+      <Filter>boxes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\boxes\ppbox.cpp">
+      <Filter>boxes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_autodoc.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_compile.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_lang.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_metadatas.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_notice.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_sharing.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\doc_Text.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\documentator\lateq.cpp">
+      <Filter>documentator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\drawschema.cpp">
+      <Filter>draw</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\sigToGraph.cpp">
+      <Filter>draw</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\device\PSDev.cpp">
+      <Filter>draw\device</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\device\SVGDev.cpp">
+      <Filter>draw\device</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\blockSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\cableSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\collector.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\cutSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\decorateSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\enlargedSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\inverterSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\mergeSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\parSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\recSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\seqSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\splitSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\draw\schema\topSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\errors\errormsg.cpp">
+      <Filter>errors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\errors\timing.cpp">
+      <Filter>errors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\evaluate\environment.cpp">
+      <Filter>evaluate</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\evaluate\eval.cpp">
+      <Filter>evaluate</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\evaluate\loopDetector.cpp">
+      <Filter>evaluate</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\absprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\acosprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\asinprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\atan2prim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\atanprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\ceilprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\cosprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\expprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\floorprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\fmodprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\log10prim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\logprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\maxprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\minprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\powprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\remainderprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\rintprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\sinprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\sqrtprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\extended\tanprim.cpp">
+      <Filter>extended</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\compile.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\compile_scal.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\compile_sched.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\compile_vect.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\contextor.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\description.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\floats.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\klass.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\occurences.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\sharing.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\Text.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\generator\uitree.cpp">
+      <Filter>generator</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\normalize\aterm.cpp">
+      <Filter>normalize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\normalize\mterm.cpp">
+      <Filter>normalize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\normalize\normalize.cpp">
+      <Filter>normalize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\normalize\privatise.cpp">
+      <Filter>normalize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\normalize\simplify.cpp">
+      <Filter>normalize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parallelize\colorize.cpp">
+      <Filter>parallelize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parallelize\graphSorting.cpp">
+      <Filter>parallelize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parallelize\loop.cpp">
+      <Filter>parallelize</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parser\enrobage.cpp">
+      <Filter>parser</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parser\faustlexer.cpp">
+      <Filter>parser</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parser\faustparser.cpp">
+      <Filter>parser</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parser\sourcereader.cpp">
+      <Filter>parser</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\patternmatcher\patternmatcher.cpp">
+      <Filter>patternmatcher</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\propagate\labels.cpp">
+      <Filter>propagate</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\propagate\propagate.cpp">
+      <Filter>propagate</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\binop.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\ppsig.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\prim2.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\recursivness.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\signals.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\sigorderrules.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\sigprint.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\sigtype.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\sigtyperules.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\sigvisitor.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\signals\subsignals.cpp">
+      <Filter>signals</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\compatibility.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\list.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\node.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\occurrences.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\recursive-tree.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\shlysis.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\symbol.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\tlib\tree.cpp">
+      <Filter>tlib</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\utils\names.cpp">
+      <Filter>utils</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\main.cpp" />
+    <ClCompile Include="..\compiler\draw\schema\connectorSchema.cpp">
+      <Filter>draw\schema</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\parser\sourcefetcher.cpp">
+      <Filter>parser</Filter>
+    </ClCompile>
+    <ClCompile Include="..\compiler\utils\files.cpp">
+      <Filter>utils</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\compiler\boxes\boxcomplexity.h">
+      <Filter>boxes</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\device\device.h">
+      <Filter>draw\device</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\device\devLib.h">
+      <Filter>draw\device</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\device\PSDev.h">
+      <Filter>draw\device</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\device\SVGDev.h">
+      <Filter>draw\device</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\blockSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\cableSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\cutSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\decorateSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\enlargedSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\inverterSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\mergeSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\parSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\recSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\schema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\seqSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\splitSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\topSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\parallelize\colorize.h">
+      <Filter>parallelize</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\parser\faustparser.hpp">
+      <Filter>parser</Filter>
+    </ClInclude>
+    <ClInclude Include="..\compiler\draw\schema\connectorSchema.h">
+      <Filter>draw\schema</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\compiler\boxes\boxes.hh">
+      <Filter>boxes</Filter>
+    </None>
+    <None Include="..\compiler\boxes\ppbox.hh">
+      <Filter>boxes</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc_autodoc.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc_compile.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc_lang.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc_metadatas.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc_notice.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\doc_Text.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\documentator\lateq.hh">
+      <Filter>documentator</Filter>
+    </None>
+    <None Include="..\compiler\draw\drawschema.hh">
+      <Filter>draw</Filter>
+    </None>
+    <None Include="..\compiler\draw\sigToGraph.hh">
+      <Filter>draw</Filter>
+    </None>
+    <None Include="..\compiler\errors\errormsg.hh">
+      <Filter>errors</Filter>
+    </None>
+    <None Include="..\compiler\errors\timing.hh">
+      <Filter>errors</Filter>
+    </None>
+    <None Include="..\compiler\evaluate\environment.hh">
+      <Filter>evaluate</Filter>
+    </None>
+    <None Include="..\compiler\evaluate\eval.hh">
+      <Filter>evaluate</Filter>
+    </None>
+    <None Include="..\compiler\evaluate\loopDetector.hh">
+      <Filter>evaluate</Filter>
+    </None>
+    <None Include="..\compiler\extended\xtended.hh">
+      <Filter>extended</Filter>
+    </None>
+    <None Include="..\compiler\generator\compile.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\compile_scal.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\compile_sched.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\compile_vect.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\contextor.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\description.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\floats.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\klass.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\occurences.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\Text.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\generator\uitree.hh">
+      <Filter>generator</Filter>
+    </None>
+    <None Include="..\compiler\normalize\aterm.hh">
+      <Filter>normalize</Filter>
+    </None>
+    <None Include="..\compiler\normalize\mterm.hh">
+      <Filter>normalize</Filter>
+    </None>
+    <None Include="..\compiler\normalize\normalize.hh">
+      <Filter>normalize</Filter>
+    </None>
+    <None Include="..\compiler\normalize\privatise.hh">
+      <Filter>normalize</Filter>
+    </None>
+    <None Include="..\compiler\normalize\simplify.hh">
+      <Filter>normalize</Filter>
+    </None>
+    <None Include="..\compiler\parallelize\graphSorting.hh">
+      <Filter>parallelize</Filter>
+    </None>
+    <None Include="..\compiler\parallelize\loop.hh">
+      <Filter>parallelize</Filter>
+    </None>
+    <None Include="..\compiler\parser\enrobage.hh">
+      <Filter>parser</Filter>
+    </None>
+    <None Include="..\compiler\parser\sourcereader.hh">
+      <Filter>parser</Filter>
+    </None>
+    <None Include="..\compiler\patternmatcher\patternmatcher.hh">
+      <Filter>patternmatcher</Filter>
+    </None>
+    <None Include="..\compiler\propagate\labels.hh">
+      <Filter>propagate</Filter>
+    </None>
+    <None Include="..\compiler\propagate\propagate.hh">
+      <Filter>propagate</Filter>
+    </None>
+    <None Include="..\compiler\signals\binop.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\interval.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\ppsig.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\prim2.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\recursivness.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\signals.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\sigorderrules.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\sigprint.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\sigtype.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\sigtyperules.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\signals\sigvisitor.hh">
+      <Filter>signals</Filter>
+    </None>
+    <None Include="..\compiler\tlib\compatibility.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\list.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\node.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\num.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\occurrences.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\property.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\shlysis.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\smartpointer.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\symbol.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\tlib.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\tlib\tree.hh">
+      <Filter>tlib</Filter>
+    </None>
+    <None Include="..\compiler\utils\names.hh">
+      <Filter>utils</Filter>
+    </None>
+    <None Include="..\compiler\parser\sourcefetcher.hh">
+      <Filter>parser</Filter>
+    </None>
+    <None Include="..\compiler\utils\files.hh">
+      <Filter>utils</Filter>
+    </None>
+  </ItemGroup>
+</Project>
diff --git a/windows/libHTTPD.vcxproj b/windows/libHTTPD.vcxproj
new file mode 100644
index 0000000..1cb86cb
--- /dev/null
+++ b/windows/libHTTPD.vcxproj
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\architecture\httpdlib\src\hexa\jsscripts.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\hexa\stylesheet.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\html\htmlfactory.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\html\htmlpage.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\html\htmlui.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\HTTPDControler.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\httpd\Address.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\httpd\HTTPDServer.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\httpd\HTTPDSetup.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\json\jsoncontrol.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\json\jsonfactory.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\json\jsonfaustui.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\json\jsongroup.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\json\jsonroot.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\json\jsonui.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\msg\Message.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\nodes\FaustFactory.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\nodes\FaustNode.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\nodes\MessageDriven.cpp" />
+    <ClCompile Include="..\architecture\httpdlib\src\nodes\RootNode.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\architecture\httpdlib\src\html\htmlfactory.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\html\htmlpage.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\html\htmlui.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\html\jsscripts.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\html\stylesheet.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\httpd\Address.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\httpd\HTTPDServer.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\httpd\HTTPDSetup.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\include\HTTPDControler.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\include\jsonfaustui.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\json\jsoncontrol.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\json\jsonfactory.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\json\jsongroup.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\json\jsonnode.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\json\jsonroot.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\json\jsonui.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\lib\deelx.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\lib\smartpointer.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\msg\Message.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\msg\MessageProcessor.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\nodes\FaustFactory.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\nodes\FaustNode.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\nodes\MessageDriven.h" />
+    <ClInclude Include="..\architecture\httpdlib\src\nodes\RootNode.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>libHTTPD</ProjectName>
+    <ProjectGuid>{106283CC-0703-4C8F-B953-A717B67F3086}</ProjectGuid>
+    <RootNamespace>faust_vs2008</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>libHTTPDFaust</TargetName>
+    <TargetExt>.lib</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>libHTTPDFaust</TargetName>
+    <TargetExt>.lib</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\architecture\httpdlib\src;..\architecture\httpdlib\src\httpd;..\architecture\httpdlib\src\msg;..\architecture\httpdlib\src\html;..\architecture\httpdlib\src\nodes;..\architecture\httpdlib\src\include;..\architecture\httpdlib\src\json;..\architecture\httpdlib\src\lib;C:\Users\Sarah\DevTools\libmicrohttpd\include;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;_EXPORTING;_SECURE_SCL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;..\..\DevTools\llvm-3.4\include;..\compiler;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;LLVMAArch64AsmParser.lib;LLVMAArch64AsmPrinter.lib;LLVMAArch64CodeGen.lib;LLVMAArch64Desc.lib;LLVMAArch64Disassembler.lib;LLVMAArch64Info.lib;LLVMAArch64Utils.lib;LLVMAnalysis.lib;LLVMARMAsmParser.lib;LLVMARMAsmPrinter.lib;LLVMARMCodeGen.lib;LLVMARMDesc.lib;LLVMARMDisassembler.lib;LLVMARMInfo.lib;LLVMAsmParser.lib;LLVMAsmPrinter.lib;LLVMBitReader.lib;LLVMBitWriter.lib;LLVMCodeGen.lib;LLVMCore.lib;LLVMCppBackEndCodeGen.lib;LLVMCppBackEndInfo.lib;LLVMDebugInfo.lib;LLVMExecutionEngine.lib;LLVMHexagonAsmPrinter.lib;LLVMHexagonCodeGen.lib;LLVMHexagonDesc.lib;LLVMHexagonInfo.lib;LLVMInstCombine.lib;LLVMInstrumentation.lib;LLVMInterpreter.lib;LLVMipa.lib;LLVMipo.lib;LLVMIRReader.lib;LLVMJIT.lib;LLVMLinker.lib;LLVMLTO.lib;LLVMMC.lib;LLVMMCDisassembler.lib;LLVMMCJIT.lib;LLVMMCParser.lib;LLVMMipsAsmParser.lib;LLVMMipsAsmPrinter.lib;LLVMMipsCodeGen.lib;LLVMMipsDesc.lib;LLVMMipsDisassembler.lib;LLVMMipsInfo.lib;LLVMMSP430AsmPrinter.lib;LLVMMSP430CodeGen.lib;LLVMMSP430Desc.lib;LLVMMSP430Info.lib;LLVMNVPTXAsmPrinter.lib;LLVMNVPTXCodeGen.lib;LLVMNVPTXDesc.lib;LLVMNVPTXInfo.lib;LLVMObjCARCOpts.lib;LLVMObject.lib;LLVMOption.lib;LLVMPowerPCAsmParser.lib;LLVMPowerPCAsmPrinter.lib;LLVMPowerPCCodeGen.lib;LLVMPowerPCDesc.lib;LLVMPowerPCInfo.lib;LLVMR600AsmPrinter.lib;LLVMR600CodeGen.lib;LLVMR600Desc.lib;LLVMR600Info.lib;LLVMRuntimeDyld.lib;LLVMScalarOpts.lib;LLVMSelectionDAG.lib;LLVMSparcCodeGen.lib;LLVMSparcDesc.lib;LLVMSparcInfo.lib;LLVMSupport.lib;LLVMSystemZAsmParser.lib;LLVMSystemZAsmPrinter.lib;LLVMSystemZCodeGen.lib;LLVMSystemZDesc.lib;LLVMSystemZDisassembler.lib;LLVMSystemZInfo.lib;LLVMTableGen.lib;LLVMTarget.lib;LLVMTransformUtils.lib;LLVMVectorize.lib;LLVMX86AsmParser.lib;LLVMX86AsmPrinter.lib;LLVMX86CodeGen.lib;LLVMX86Desc.lib;LLVMX86Disassembler.lib;LLVMX86Info.lib;LLVMX86Utils.lib;LLVMXCoreAsmPrinter.lib;LLVMXCoreCodeGen.lib;LLVMXCoreDesc.lib;LLVMXCoreDisassembler.lib;LLVMXCoreInfo.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\DevTools\llvm-3.4\lib\Debug</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\architecture\httpdlib\src;..\architecture\httpdlib\src\html;..\architecture\httpdlib\src\httpd;..\architecture\httpdlib\src\include;..\architecture\httpdlib\src\json;..\architecture\httpdlib\src\lib;..\architecture\httpdlib\src\msg;..\architecture\httpdlib\src\nodes;C:\Users\Sarah\DevTools\libmicrohttpd\include;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>
+      </AdditionalLibraryDirectories>
+      <IgnoreSpecificDefaultLibraries>_</IgnoreSpecificDefaultLibraries>
+      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;../compiler;..\..\DevTools\llvm-3.4\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN64;YY_NO_UNISTD_H;LLVM_34;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;LLVMAArch64AsmParser.lib;LLVMAArch64AsmPrinter.lib;LLVMAArch64CodeGen.lib;LLVMAArch64Desc.lib;LLVMAArch64Disassembler.lib;LLVMAArch64Info.lib;LLVMAArch64Utils.lib;LLVMAnalysis.lib;LLVMARMAsmParser.lib;LLVMARMAsmPrinter.lib;LLVMARMCodeGen.lib;LLVMARMDesc.lib;LLVMARMDisassembler.lib;LLVMARMInfo.lib;LLVMAsmParser.lib;LLVMAsmPrinter.lib;LLVMBitReader.lib;LLVMBitWriter.lib;LLVMCodeGen.lib;LLVMCore.lib;LLVMCppBackEndCodeGen.lib;LLVMCppBackEndInfo.lib;LLVMDebugInfo.lib;LLVMExecutionEngine.lib;LLVMHexagonAsmPrinter.lib;LLVMHexagonCodeGen.lib;LLVMHexagonDesc.lib;LLVMHexagonInfo.lib;LLVMInstCombine.lib;LLVMInstrumentation.lib;LLVMInterpreter.lib;LLVMipa.lib;LLVMipo.lib;LLVMIRReader.lib;LLVMJIT.lib;LLVMLinker.lib;LLVMLTO.lib;LLVMMC.lib;LLVMMCDisassembler.lib;LLVMMCJIT.lib;LLVMMCParser.lib;LLVMMipsAsmParser.lib;LLVMMipsAsmPrinter.lib;LLVMMipsCodeGen.lib;LLVMMipsDesc.lib;LLVMMipsDisassembler.lib;LLVMMipsInfo.lib;LLVMMSP430AsmPrinter.lib;LLVMMSP430CodeGen.lib;LLVMMSP430Desc.lib;LLVMMSP430Info.lib;LLVMNVPTXAsmPrinter.lib;LLVMNVPTXCodeGen.lib;LLVMNVPTXDesc.lib;LLVMNVPTXInfo.lib;LLVMObjCARCOpts.lib;LLVMObject.lib;LLVMOption.lib;LLVMPowerPCAsmParser.lib;LLVMPowerPCAsmPrinter.lib;LLVMPowerPCCodeGen.lib;LLVMPowerPCDesc.lib;LLVMPowerPCInfo.lib;LLVMR600AsmPrinter.lib;LLVMR600CodeGen.lib;LLVMR600Desc.lib;LLVMR600Info.lib;LLVMRuntimeDyld.lib;LLVMScalarOpts.lib;LLVMSelectionDAG.lib;LLVMSparcCodeGen.lib;LLVMSparcDesc.lib;LLVMSparcInfo.lib;LLVMSupport.lib;LLVMSystemZAsmParser.lib;LLVMSystemZAsmPrinter.lib;LLVMSystemZCodeGen.lib;LLVMSystemZDesc.lib;LLVMSystemZDisassembler.lib;LLVMSystemZInfo.lib;LLVMTableGen.lib;LLVMTarget.lib;LLVMTransformUtils.lib;LLVMVectorize.lib;LLVMX86AsmParser.lib;LLVMX86AsmPrinter.lib;LLVMX86CodeGen.lib;LLVMX86Desc.lib;LLVMX86Disassembler.lib;LLVMX86Info.lib;LLVMX86Utils.lib;LLVMXCoreAsmPrinter.lib;LLVMXCoreCodeGen.lib;LLVMXCoreDesc.lib;LLVMXCoreDisassembler.lib;LLVMXCoreInfo.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\DevTools\llvm-3.4\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/windows/libOSCFaust.vcxproj b/windows/libOSCFaust.vcxproj
new file mode 100644
index 0000000..65197ac
--- /dev/null
+++ b/windows/libOSCFaust.vcxproj
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\architecture\osclib\faust\faust\OSCControler.h" />
+    <ClInclude Include="..\architecture\osclib\faust\faust\OSCIO.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\lib\deelx.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\lib\OSCFError.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\lib\OSCRegexp.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\nodes\RootNode.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\osc\OSCAddress.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\osc\OSCListener.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\osc\OSCSetup.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\osc\OSCStream.h" />
+    <ClInclude Include="..\architecture\osclib\faust\src\threads\TThreads.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\architecture\osclib\faust\src\lib\OSCFError.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\lib\OSCRegexp.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\msg\Message.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\nodes\FaustFactory.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\nodes\FaustNode.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\nodes\MessageDriven.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\nodes\RootNode.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\OSCControler.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\osc\OSCAddress.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\osc\OSCIO.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\osc\OSCListener.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\osc\OSCSetup.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\osc\OSCStream.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\threads\pthreads_impl.cpp" />
+    <ClCompile Include="..\architecture\osclib\faust\src\threads\winthreads_impl.cpp" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>libOSCFaust</ProjectName>
+    <ProjectGuid>{097B0E5B-2DF2-4A9A-98C1-728E75245E8B}</ProjectGuid>
+    <RootNamespace>faust_vs2008</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>libOSCFaust</TargetName>
+    <TargetExt>.lib</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>libOSCFaust</TargetName>
+    <TargetExt>.lib</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\architecture\osclib\oscpack;..\architecture\osclib\faust;..\architecture\osclib\faust\src;..\architecture\osclib\faust\src\lib;..\architecture\osclib\faust\src\nodes;..\architecture\osclib\faust\src\msg;..\architecture\osclib\faust\src\osc;..\architecture\osclib\faust\src\threads;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;_EXPORTING;_SECURE_SCL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;..\..\DevTools\llvm-3.4\include;..\compiler;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;LLVMAArch64AsmParser.lib;LLVMAArch64AsmPrinter.lib;LLVMAArch64CodeGen.lib;LLVMAArch64Desc.lib;LLVMAArch64Disassembler.lib;LLVMAArch64Info.lib;LLVMAArch64Utils.lib;LLVMAnalysis.lib;LLVMARMAsmParser.lib;LLVMARMAsmPrinter.lib;LLVMARMCodeGen.lib;LLVMARMDesc.lib;LLVMARMDisassembler.lib;LLVMARMInfo.lib;LLVMAsmParser.lib;LLVMAsmPrinter.lib;LLVMBitReader.lib;LLVMBitWriter.lib;LLVMCodeGen.lib;LLVMCore.lib;LLVMCppBackEndCodeGen.lib;LLVMCppBackEndInfo.lib;LLVMDebugInfo.lib;LLVMExecutionEngine.lib;LLVMHexagonAsmPrinter.lib;LLVMHexagonCodeGen.lib;LLVMHexagonDesc.lib;LLVMHexagonInfo.lib;LLVMInstCombine.lib;LLVMInstrumentation.lib;LLVMInterpreter.lib;LLVMipa.lib;LLVMipo.lib;LLVMIRReader.lib;LLVMJIT.lib;LLVMLinker.lib;LLVMLTO.lib;LLVMMC.lib;LLVMMCDisassembler.lib;LLVMMCJIT.lib;LLVMMCParser.lib;LLVMMipsAsmParser.lib;LLVMMipsAsmPrinter.lib;LLVMMipsCodeGen.lib;LLVMMipsDesc.lib;LLVMMipsDisassembler.lib;LLVMMipsInfo.lib;LLVMMSP430AsmPrinter.lib;LLVMMSP430CodeGen.lib;LLVMMSP430Desc.lib;LLVMMSP430Info.lib;LLVMNVPTXAsmPrinter.lib;LLVMNVPTXCodeGen.lib;LLVMNVPTXDesc.lib;LLVMNVPTXInfo.lib;LLVMObjCARCOpts.lib;LLVMObject.lib;LLVMOption.lib;LLVMPowerPCAsmParser.lib;LLVMPowerPCAsmPrinter.lib;LLVMPowerPCCodeGen.lib;LLVMPowerPCDesc.lib;LLVMPowerPCInfo.lib;LLVMR600AsmPrinter.lib;LLVMR600CodeGen.lib;LLVMR600Desc.lib;LLVMR600Info.lib;LLVMRuntimeDyld.lib;LLVMScalarOpts.lib;LLVMSelectionDAG.lib;LLVMSparcCodeGen.lib;LLVMSparcDesc.lib;LLVMSparcInfo.lib;LLVMSupport.lib;LLVMSystemZAsmParser.lib;LLVMSystemZAsmPrinter.lib;LLVMSystemZCodeGen.lib;LLVMSystemZDesc.lib;LLVMSystemZDisassembler.lib;LLVMSystemZInfo.lib;LLVMTableGen.lib;LLVMTarget.lib;LLVMTransformUtils.lib;LLVMVectorize.lib;LLVMX86AsmParser.lib;LLVMX86AsmPrinter.lib;LLVMX86CodeGen.lib;LLVMX86Desc.lib;LLVMX86Disassembler.lib;LLVMX86Info.lib;LLVMX86Utils.lib;LLVMXCoreAsmPrinter.lib;LLVMXCoreCodeGen.lib;LLVMXCoreDesc.lib;LLVMXCoreDisassembler.lib;LLVMXCoreInfo.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\DevTools\llvm-3.4\lib\Debug</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\architecture\osclib\faust;..\architecture;..\architecture\osclib\oscpack;..\architecture\osclib\faust\src\nodes;..\architecture\osclib\faust\src\lib;..\architecture\osclib\faust\src\osc;..\architecture\osclib\faust\src\msg;..\architecture\osclib\faust\src\threads;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>
+      </AdditionalLibraryDirectories>
+      <IgnoreSpecificDefaultLibraries>_</IgnoreSpecificDefaultLibraries>
+      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;../compiler;..\..\DevTools\llvm-3.4\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN64;YY_NO_UNISTD_H;LLVM_34;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;LLVMAArch64AsmParser.lib;LLVMAArch64AsmPrinter.lib;LLVMAArch64CodeGen.lib;LLVMAArch64Desc.lib;LLVMAArch64Disassembler.lib;LLVMAArch64Info.lib;LLVMAArch64Utils.lib;LLVMAnalysis.lib;LLVMARMAsmParser.lib;LLVMARMAsmPrinter.lib;LLVMARMCodeGen.lib;LLVMARMDesc.lib;LLVMARMDisassembler.lib;LLVMARMInfo.lib;LLVMAsmParser.lib;LLVMAsmPrinter.lib;LLVMBitReader.lib;LLVMBitWriter.lib;LLVMCodeGen.lib;LLVMCore.lib;LLVMCppBackEndCodeGen.lib;LLVMCppBackEndInfo.lib;LLVMDebugInfo.lib;LLVMExecutionEngine.lib;LLVMHexagonAsmPrinter.lib;LLVMHexagonCodeGen.lib;LLVMHexagonDesc.lib;LLVMHexagonInfo.lib;LLVMInstCombine.lib;LLVMInstrumentation.lib;LLVMInterpreter.lib;LLVMipa.lib;LLVMipo.lib;LLVMIRReader.lib;LLVMJIT.lib;LLVMLinker.lib;LLVMLTO.lib;LLVMMC.lib;LLVMMCDisassembler.lib;LLVMMCJIT.lib;LLVMMCParser.lib;LLVMMipsAsmParser.lib;LLVMMipsAsmPrinter.lib;LLVMMipsCodeGen.lib;LLVMMipsDesc.lib;LLVMMipsDisassembler.lib;LLVMMipsInfo.lib;LLVMMSP430AsmPrinter.lib;LLVMMSP430CodeGen.lib;LLVMMSP430Desc.lib;LLVMMSP430Info.lib;LLVMNVPTXAsmPrinter.lib;LLVMNVPTXCodeGen.lib;LLVMNVPTXDesc.lib;LLVMNVPTXInfo.lib;LLVMObjCARCOpts.lib;LLVMObject.lib;LLVMOption.lib;LLVMPowerPCAsmParser.lib;LLVMPowerPCAsmPrinter.lib;LLVMPowerPCCodeGen.lib;LLVMPowerPCDesc.lib;LLVMPowerPCInfo.lib;LLVMR600AsmPrinter.lib;LLVMR600CodeGen.lib;LLVMR600Desc.lib;LLVMR600Info.lib;LLVMRuntimeDyld.lib;LLVMScalarOpts.lib;LLVMSelectionDAG.lib;LLVMSparcCodeGen.lib;LLVMSparcDesc.lib;LLVMSparcInfo.lib;LLVMSupport.lib;LLVMSystemZAsmParser.lib;LLVMSystemZAsmPrinter.lib;LLVMSystemZCodeGen.lib;LLVMSystemZDesc.lib;LLVMSystemZDisassembler.lib;LLVMSystemZInfo.lib;LLVMTableGen.lib;LLVMTarget.lib;LLVMTransformUtils.lib;LLVMVectorize.lib;LLVMX86AsmParser.lib;LLVMX86AsmPrinter.lib;LLVMX86CodeGen.lib;LLVMX86Desc.lib;LLVMX86Disassembler.lib;LLVMX86Info.lib;LLVMX86Utils.lib;LLVMXCoreAsmPrinter.lib;LLVMXCoreCodeGen.lib;LLVMXCoreDesc.lib;LLVMXCoreDisassembler.lib;LLVMXCoreInfo.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\DevTools\llvm-3.4\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/windows/liboscpack.vcxproj b/windows/liboscpack.vcxproj
new file mode 100644
index 0000000..e68bbec
--- /dev/null
+++ b/windows/liboscpack.vcxproj
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\architecture\osclib\oscpack\ip\IpEndpointName.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\ip\NetworkingUtils.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\ip\PacketListener.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\ip\TimerListener.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\ip\UdpSocket.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\MessageMappingOscPacketListener.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscException.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscHostEndianness.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscOutboundPacketStream.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscPacketListener.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscPrintReceivedElements.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscReceivedElements.h" />
+    <ClInclude Include="..\architecture\osclib\oscpack\osc\OscTypes.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\architecture\osclib\oscpack\ip\IpEndpointName.cpp" />
+    <ClCompile Include="..\architecture\osclib\oscpack\ip\win32\NetworkingUtils.cpp" />
+    <ClCompile Include="..\architecture\osclib\oscpack\ip\win32\UdpSocket.cpp" />
+    <ClCompile Include="..\architecture\osclib\oscpack\osc\OscOutboundPacketStream.cpp" />
+    <ClCompile Include="..\architecture\osclib\oscpack\osc\OscPrintReceivedElements.cpp" />
+    <ClCompile Include="..\architecture\osclib\oscpack\osc\OscReceivedElements.cpp" />
+    <ClCompile Include="..\architecture\osclib\oscpack\osc\OscTypes.cpp" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>liboscpack</ProjectName>
+    <ProjectGuid>{DFACA603-DDD7-4582-A10E-E27B0323B6B7}</ProjectGuid>
+    <RootNamespace>faust_vs2008</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>liboscpack</TargetName>
+    <TargetExt>.lib</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>liboscpack</TargetName>
+    <TargetExt>.lib</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>_output\$(Platform)\$(ProjectName)\$(Configuration)\Int\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>faust</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\architecture\osclib\oscpack;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;_EXPORTING;_SECURE_SCL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;..\..\DevTools\llvm-3.4\include;..\compiler;..\architecture;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;LLVMAArch64AsmParser.lib;LLVMAArch64AsmPrinter.lib;LLVMAArch64CodeGen.lib;LLVMAArch64Desc.lib;LLVMAArch64Disassembler.lib;LLVMAArch64Info.lib;LLVMAArch64Utils.lib;LLVMAnalysis.lib;LLVMARMAsmParser.lib;LLVMARMAsmPrinter.lib;LLVMARMCodeGen.lib;LLVMARMDesc.lib;LLVMARMDisassembler.lib;LLVMARMInfo.lib;LLVMAsmParser.lib;LLVMAsmPrinter.lib;LLVMBitReader.lib;LLVMBitWriter.lib;LLVMCodeGen.lib;LLVMCore.lib;LLVMCppBackEndCodeGen.lib;LLVMCppBackEndInfo.lib;LLVMDebugInfo.lib;LLVMExecutionEngine.lib;LLVMHexagonAsmPrinter.lib;LLVMHexagonCodeGen.lib;LLVMHexagonDesc.lib;LLVMHexagonInfo.lib;LLVMInstCombine.lib;LLVMInstrumentation.lib;LLVMInterpreter.lib;LLVMipa.lib;LLVMipo.lib;LLVMIRReader.lib;LLVMJIT.lib;LLVMLinker.lib;LLVMLTO.lib;LLVMMC.lib;LLVMMCDisassembler.lib;LLVMMCJIT.lib;LLVMMCParser.lib;LLVMMipsAsmParser.lib;LLVMMipsAsmPrinter.lib;LLVMMipsCodeGen.lib;LLVMMipsDesc.lib;LLVMMipsDisassembler.lib;LLVMMipsInfo.lib;LLVMMSP430AsmPrinter.lib;LLVMMSP430CodeGen.lib;LLVMMSP430Desc.lib;LLVMMSP430Info.lib;LLVMNVPTXAsmPrinter.lib;LLVMNVPTXCodeGen.lib;LLVMNVPTXDesc.lib;LLVMNVPTXInfo.lib;LLVMObjCARCOpts.lib;LLVMObject.lib;LLVMOption.lib;LLVMPowerPCAsmParser.lib;LLVMPowerPCAsmPrinter.lib;LLVMPowerPCCodeGen.lib;LLVMPowerPCDesc.lib;LLVMPowerPCInfo.lib;LLVMR600AsmPrinter.lib;LLVMR600CodeGen.lib;LLVMR600Desc.lib;LLVMR600Info.lib;LLVMRuntimeDyld.lib;LLVMScalarOpts.lib;LLVMSelectionDAG.lib;LLVMSparcCodeGen.lib;LLVMSparcDesc.lib;LLVMSparcInfo.lib;LLVMSupport.lib;LLVMSystemZAsmParser.lib;LLVMSystemZAsmPrinter.lib;LLVMSystemZCodeGen.lib;LLVMSystemZDesc.lib;LLVMSystemZDisassembler.lib;LLVMSystemZInfo.lib;LLVMTableGen.lib;LLVMTarget.lib;LLVMTransformUtils.lib;LLVMVectorize.lib;LLVMX86AsmParser.lib;LLVMX86AsmPrinter.lib;LLVMX86CodeGen.lib;LLVMX86Desc.lib;LLVMX86Disassembler.lib;LLVMX86Info.lib;LLVMX86Utils.lib;LLVMXCoreAsmPrinter.lib;LLVMXCoreCodeGen.lib;LLVMXCoreDesc.lib;LLVMXCoreDisassembler.lib;LLVMXCoreInfo.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\DevTools\llvm-3.4\lib\Debug</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\architecture\osclib\oscpack;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CONSOLE;_CRT_SECURE_NO_WARNINGS;LLVM_34;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>
+      </AdditionalLibraryDirectories>
+      <IgnoreSpecificDefaultLibraries>_</IgnoreSpecificDefaultLibraries>
+      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalOptions>/wd4554 %(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>../compiler/tlib;../compiler/signals;../compiler/normalize;../compiler/generator;../compiler/parallelize;../compiler/propagate;../compiler/boxes;../compiler/errors;../compiler/parser;../compiler/evaluate;../compiler/documentator;../compiler/draw/schema;../compiler/draw/device;../compiler/draw;../compiler/extended;../compiler/utils;../compiler/patternmatcher;../compiler;..\..\DevTools\llvm-3.4\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN64;YY_NO_UNISTD_H;LLVM_34;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;LLVMAArch64AsmParser.lib;LLVMAArch64AsmPrinter.lib;LLVMAArch64CodeGen.lib;LLVMAArch64Desc.lib;LLVMAArch64Disassembler.lib;LLVMAArch64Info.lib;LLVMAArch64Utils.lib;LLVMAnalysis.lib;LLVMARMAsmParser.lib;LLVMARMAsmPrinter.lib;LLVMARMCodeGen.lib;LLVMARMDesc.lib;LLVMARMDisassembler.lib;LLVMARMInfo.lib;LLVMAsmParser.lib;LLVMAsmPrinter.lib;LLVMBitReader.lib;LLVMBitWriter.lib;LLVMCodeGen.lib;LLVMCore.lib;LLVMCppBackEndCodeGen.lib;LLVMCppBackEndInfo.lib;LLVMDebugInfo.lib;LLVMExecutionEngine.lib;LLVMHexagonAsmPrinter.lib;LLVMHexagonCodeGen.lib;LLVMHexagonDesc.lib;LLVMHexagonInfo.lib;LLVMInstCombine.lib;LLVMInstrumentation.lib;LLVMInterpreter.lib;LLVMipa.lib;LLVMipo.lib;LLVMIRReader.lib;LLVMJIT.lib;LLVMLinker.lib;LLVMLTO.lib;LLVMMC.lib;LLVMMCDisassembler.lib;LLVMMCJIT.lib;LLVMMCParser.lib;LLVMMipsAsmParser.lib;LLVMMipsAsmPrinter.lib;LLVMMipsCodeGen.lib;LLVMMipsDesc.lib;LLVMMipsDisassembler.lib;LLVMMipsInfo.lib;LLVMMSP430AsmPrinter.lib;LLVMMSP430CodeGen.lib;LLVMMSP430Desc.lib;LLVMMSP430Info.lib;LLVMNVPTXAsmPrinter.lib;LLVMNVPTXCodeGen.lib;LLVMNVPTXDesc.lib;LLVMNVPTXInfo.lib;LLVMObjCARCOpts.lib;LLVMObject.lib;LLVMOption.lib;LLVMPowerPCAsmParser.lib;LLVMPowerPCAsmPrinter.lib;LLVMPowerPCCodeGen.lib;LLVMPowerPCDesc.lib;LLVMPowerPCInfo.lib;LLVMR600AsmPrinter.lib;LLVMR600CodeGen.lib;LLVMR600Desc.lib;LLVMR600Info.lib;LLVMRuntimeDyld.lib;LLVMScalarOpts.lib;LLVMSelectionDAG.lib;LLVMSparcCodeGen.lib;LLVMSparcDesc.lib;LLVMSparcInfo.lib;LLVMSupport.lib;LLVMSystemZAsmParser.lib;LLVMSystemZAsmPrinter.lib;LLVMSystemZCodeGen.lib;LLVMSystemZDesc.lib;LLVMSystemZDisassembler.lib;LLVMSystemZInfo.lib;LLVMTableGen.lib;LLVMTarget.lib;LLVMTransformUtils.lib;LLVMVectorize.lib;LLVMX86AsmParser.lib;LLVMX86AsmPrinter.lib;LLVMX86CodeGen.lib;LLVMX86Desc.lib;LLVMX86Disassembler.lib;LLVMX86Info.lib;LLVMX86Utils.lib;LLVMXCoreAsmPrinter.lib;LLVMXCoreCodeGen.lib;LLVMXCoreDesc.lib;LLVMXCoreDisassembler.lib;LLVMXCoreInfo.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\DevTools\llvm-3.4\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file

-- 
faust packaging



More information about the pkg-multimedia-commits mailing list