changeset 509:0284d2152e17

Add support for outputting featutes using OSC (for use with the Wekinator, etc).
author tomwalters@google.com
date Fri, 22 Jun 2012 12:22:08 +0000
parents d609725e568a
children 3cc6c58171e9
files SConstruct external/oscpack/CHANGES external/oscpack/LICENSE external/oscpack/Makefile external/oscpack/README external/oscpack/TODO external/oscpack/examples/OscDump.cpp external/oscpack/examples/SimpleReceive.cpp external/oscpack/examples/SimpleSend.cpp external/oscpack/ip/IpEndpointName.cpp external/oscpack/ip/IpEndpointName.h external/oscpack/ip/NetworkingUtils.h external/oscpack/ip/PacketListener.h external/oscpack/ip/TimerListener.h external/oscpack/ip/UdpSocket.h external/oscpack/ip/posix/NetworkingUtils.cpp external/oscpack/ip/posix/UdpSocket.cpp external/oscpack/ip/win32/NetworkingUtils.cpp external/oscpack/ip/win32/UdpSocket.cpp external/oscpack/liboscpack.1.0.2.dylib external/oscpack/make.MinGW32.bat external/oscpack/osc/MessageMappingOscPacketListener.h external/oscpack/osc/OscException.h external/oscpack/osc/OscHostEndianness.h external/oscpack/osc/OscOutboundPacketStream.cpp external/oscpack/osc/OscOutboundPacketStream.h external/oscpack/osc/OscPacketListener.h external/oscpack/osc/OscPrintReceivedElements.cpp external/oscpack/osc/OscPrintReceivedElements.h external/oscpack/osc/OscReceivedElements.cpp external/oscpack/osc/OscReceivedElements.h external/oscpack/osc/OscTypes.cpp external/oscpack/osc/OscTypes.h external/oscpack/tests/OscReceiveTest.cpp external/oscpack/tests/OscReceiveTest.h external/oscpack/tests/OscSendTests.cpp external/oscpack/tests/OscSendTests.h external/oscpack/tests/OscUnitTests.cpp external/oscpack/tests/OscUnitTests.h src/Modules/Output/OSCOutput.cc src/Modules/Output/OSCOutput.h src/Support/ModuleFactory.cc
diffstat 42 files changed, 6161 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/SConstruct	Fri Jun 22 12:17:24 2012 +0000
+++ b/SConstruct	Fri Jun 22 12:22:08 2012 +0000
@@ -52,6 +52,7 @@
                   'Modules/Profile/ModuleScaler.cc',
                   'Modules/Output/FileOutputHTK.cc',
                   'Modules/Output/FileOutputAIMC.cc',
+                  'Modules/Output/OSCOutput.cc',
                   'Modules/Features/ModuleGaussians.cc',
                   'Modules/Features/ModuleBoxes.cc',]
                   #'Modules/Features/ModuleDCT.cc' ]
@@ -177,6 +178,9 @@
 deplibs = ['sndfile']
 deplibs += graphics_libraries
 
+env.Append(CPPPATH = ['#external/oscpack/oscpack/include/'])
+env.AppendUnique(LIBPATH = ['#external/oscpack/oscpack/lib/'])
+
 if target_platform != 'win32':
   for depname in deplibs:
     env.ParseConfig('pkg-config --cflags --libs ' + depname)
@@ -203,6 +207,8 @@
                     build_dir+'/libcairo-2.dll')
     env.Append(CPPPATH = [windows_cairo_location + '/include/cairo/'])
     env.AppendUnique(LIBPATH = [windows_cairo_location + '/lib/'])
+    
+deplibs.append('liboscpack')
 env.AppendUnique(LIBS = deplibs)
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/CHANGES	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,68 @@
+September 28, 2005
+------------------
+
+Compared to the previous official snapshot (November 2004) the 
+current version of oscpack includes a re-written set of network 
+classes and some changes to the syntax of the networking code. It no 
+longer uses threads, which means that you don't need to use sleep() 
+if you are writing a simple single-threaded server, or you need to 
+spawn your own threads in a more complex application.
+
+The list below summarises the changes if you are porting code from 
+the previous release.
+
+    - there are no longer any threads in oscpack. if you need to 
+    set up an asynchronous listener you can create your own thread 
+    and call Run on an instance of SocketReceiveMultiplexer or 
+    UdpListeningReceiveSocket (see ip/UdpSocket.h) yourself.
+    
+    - host byte order is now used for network (IP) addresses
+        
+    - functions which used to take two parameters <address, port> 
+    now take an instance of IpEndpointName (see 
+    ip/IpEndpointName.h) this class has a number of convenient 
+    constructors for converting numbers and strings to internet 
+    addresses. For example there is one which takes a string and 
+    another that take the dotted address components as separate 
+    parameters.
+    
+    - The UdpTransmitPort class, formerly in UdpTransmitPort.h, is 
+    now called UdpTransmitSocket, which is simply a convenience 
+    class derived from UdpSocket (see ip/UdpSocket.h). Where you 
+    used to use the constructor UdpTransmitPort( address, port) now 
+    you can use UdpTransmitSocket( IpEndpointName( address, port ) 
+    ) or you can any of the other possible ctors to IpEndpointName
+    () (see above). The Send() method is unchanged.
+    
+    - The packet listener base class is now located in 
+    ip/PacketListener.h instead of PacketListenerPort.h. The 
+    ProcessPacket method now has an additional parameter indicating 
+    the remote endpoint
+    
+    - The preferred way to set up listeners is with 
+    SocketReceiveMultiplexer (in ip/UdpSocket.h), this also allows 
+    attaching periodic timers. For simple applications which only 
+    listen to a single socket with no timers you can use 
+    UdpListeningReceiveSocket (also in UdpSocket.h) See 
+    osc/OscReceiveTest.cpp or osc/OscDump.cpp for examples of this. 
+    This is more or less equivalent to the UdpPacketListenerPort 
+    object in the old oscpack versions except that you need to 
+    explicitly call Run() before it will start receiving packets 
+    and it runs in the same thread, not a separate thread so Run() 
+    won't usually return.
+    
+    - Explicit calls to InitializeNetworking() and 
+    TerminateNetworking() are no longer required for simple 
+    applications (more complex windows applications should 
+    instantiate NetworkInitializer in main() or WinMain (see 
+    ip/NetworkingUtils.h/.cpp)
+    
+    - The OscPacketListener base class (OscPacketListener.h) was 
+    added to make traversing OSC packets easier, it handles bundle 
+    traversal automatically so you only need to process messages in 
+    your derived classes.
+    
+    - On Windows be sure to link with ws2_32.lib or you will see
+    a linker error about WSAEventSelect not being found. Also you 
+    will need to link with winmm.lib for timeGetTime()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/LICENSE	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,28 @@
+oscpack -- Open Sound Control packet manipulation library
+http://www.audiomulch.com/~rossb/code/oscpack
+
+Copyright (c) 2004 Ross Bencina <rossb@audiomulch.com>
+
+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
+requested to send the modifications to the original developer so that
+they can be incorporated into the canonical version.
+
+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.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/Makefile	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,99 @@
+# should be either OSC_HOST_BIG_ENDIAN or OSC_HOST_LITTLE_ENDIAN
+# Apple Mac OS X: OSC_HOST_BIG_ENDIAN
+# Win32: OSC_HOST_LITTLE_ENDIAN
+# i386 GNU/Linux: OSC_HOST_LITTLE_ENDIAN
+ENDIANESS=OSC_HOST_LITTLE_ENDIAN
+
+CXX = g++ 
+INCLUDES = -I./
+COPTS  = -Wall -O3
+CDEBUG = -Wall -g 
+CXXFLAGS = $(COPTS) $(INCLUDES) -D$(ENDIANESS) -arch i386
+
+PREFIX = /usr/local
+INSTALL = /usr/bin/install -c
+
+#Name definitions
+UNITTESTS=OscUnitTests
+SEND=OscSendTests
+RECEIVE=OscReceiveTest
+DUMP=OscDump
+
+INCLUDEDIR = oscpack
+LIBNAME = liboscpack
+LIBSONAME = $(LIBNAME)
+LIBFILENAME = $(LIBSONAME).1.0.2.dylib
+
+#Test and example source
+SENDSOURCES = ./tests/OscSendTests.cpp ./osc/OscOutboundPacketStream.cpp ./osc/OscTypes.cpp ./ip/posix/NetworkingUtils.cpp ./ip/posix/UdpSocket.cpp ./ip/IpEndpointName.cpp
+SENDOBJECTS = $(SENDSOURCES:.cpp=.o)
+
+RECEIVESOURCES = ./tests/OscReceiveTest.cpp ./osc/OscTypes.cpp ./osc/OscReceivedElements.cpp ./osc/OscPrintReceivedElements.cpp ./ip/posix/NetworkingUtils.cpp ./ip/posix/UdpSocket.cpp
+RECEIVEOBJECTS = $(RECEIVESOURCES:.cpp=.o)
+
+DUMPSOURCES = ./examples/OscDump.cpp ./osc/OscTypes.cpp ./osc/OscReceivedElements.cpp ./osc/OscPrintReceivedElements.cpp ./ip/posix/NetworkingUtils.cpp ./ip/posix/UdpSocket.cpp
+DUMPOBJECTS = $(DUMPSOURCES:.cpp=.o)
+
+UNITTESTSOURCES = ./tests/OscUnitTests.cpp ./osc/OscOutboundPacketStream.cpp ./osc/OscTypes.cpp ./osc/OscReceivedElements.cpp ./osc/OscPrintReceivedElements.cpp
+UNITTESTOBJECTS = $(UNITTESTSOURCES:.cpp=.o)
+
+#Library sources
+LIBSOURCES = ./ip/IpEndpointName.cpp \
+	./ip/posix/NetworkingUtils.cpp ./ip/posix/UdpSocket.cpp\
+	./osc/OscOutboundPacketStream.cpp ./osc/OscPrintReceivedElements.cpp ./osc/OscReceivedElements.cpp ./osc/OscTypes.cpp
+LIBOBJECTS = $(LIBSOURCES:.cpp=.o)
+
+all:	unittests send receive dump
+
+unittests : $(UNITTESTOBJECTS)
+	@if [ ! -d bin ] ; then mkdir bin ; fi
+	$(CXX) -o bin/$(UNITTESTS) $+ $(LIBS) 
+send : $(SENDOBJECTS)
+	@if [ ! -d bin ] ; then mkdir bin ; fi
+	$(CXX) -o bin/$(SEND) $+ $(LIBS) 
+receive : $(RECEIVEOBJECTS)
+	@if [ ! -d bin ] ; then mkdir bin ; fi
+	$(CXX) -o bin/$(RECEIVE) $+ $(LIBS) 
+dump : $(DUMPOBJECTS)
+	@if [ ! -d bin ] ; then mkdir bin ; fi
+	$(CXX) -o bin/$(DUMP) $+ $(LIBS) 
+
+clean:
+	rm -rf bin $(UNITTESTOBJECTS) $(SENDOBJECTS) $(RECEIVEOBJECTS) $(DUMPOBJECTS) $(LIBOBJECTS) $(LIBFILENAME) include lib oscpack &> /dev/null
+
+$(LIBFILENAME): $(LIBOBJECTS)
+	@#GNU/Linux case
+	#$(CXX) -shared -Wl,-soname,$(LIBSONAME) -o $(LIBFILENAME) $(LIBOBJECTS) -lc
+	@#Mac OS X case
+	$(CXX) -dynamiclib -Wl,-install_name,$(LIBSONAME) -o $(LIBFILENAME) $(LIBOBJECTS) -lc -arch i386
+	
+lib: $(LIBFILENAME)
+
+#Installs the library on a system global location
+install: lib
+	@$(INSTALL) -m 755 $(LIBFILENAME) $(PREFIX)/lib/$(LIBFILENAME)
+	@ln -s -f $(PREFIX)/lib/$(LIBFILENAME) $(PREFIX)/lib/$(LIBSONAME) 
+	@mkdir  -p $(PREFIX)/include/oscpack/ip $(PREFIX)/include/oscpack/osc
+	@$(INSTALL) -m 644 ip/*.h $(PREFIX)/include/oscpack/ip
+	@$(INSTALL) -m 644 osc/*.h $(PREFIX)/include/oscpack/osc
+	@echo "SUCCESS! oscpack has been installed in $(PREFIX)/lib and $(PREFIX)/include/ospack/"
+	@echo "now doing ldconfig..."
+	@ldconfig
+
+#Installs the include/lib structure locally
+install-local: lib
+	@echo ""
+	@echo " Installing in local directory <$(INCLUDEDIR)>"
+	@echo "   > Creating symbolic link"
+	@ln -s $(LIBFILENAME) $(LIBSONAME)
+	@echo "   > Creating directories"
+	@mkdir -p oscpack/lib
+	@mkdir -p oscpack/include/ip
+	@mkdir -p oscpack/include/osc
+	@echo "   > Copying files"
+	@mv $(LIBFILENAME) $(LIBSONAME) oscpack/lib
+	@cp ip/*.h oscpack/include/ip
+	@cp osc/*.h oscpack/include/osc
+	@echo ""
+	@echo "   > Success!"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/README	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,80 @@
+oscpack -- Open Sound Control packet manipulation library
+http://www.audiomulch.com/~rossb/code/oscpack
+
+Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+A simple C++ library for packing and unpacking OSC packets.
+
+
+Oscpack is simply a set of C++ classes for packing and unpacking OSC packets. 
+Oscpack includes a minimal set of UDP networking classes for windows and posix 
+which are sufficient for writing many OSC applications and servers, but you are 
+encouraged to use another networking framework if it better suits your needs. 
+Oscpack is not an OSC application framework, it doesn't include infrastructure for 
+constructing or routing OSC namespaces, just classes for easily constructing, 
+sending, receiving and parsing OSC packets. The library should also be easy to use 
+for other transport methods (eg serial).
+
+The key goals of the oscpack library are:
+
+	- to be a simple and complete implementation of OSC
+	- to be portable to a wide variety of platforms
+	- to allow easy development of robust OSC applications 
+		(for example it should be impossible to crash a server
+		 by sending it malformed packets, and difficult to 
+		 create malformed packets.)
+
+Here's a summary of the key files:
+
+osc/OscReceivedElements -- classes for parsing a packet
+osc/OscPrintRecievedElements -- iostream << operators for printing packet elements
+osc/OscOutboundPacket -- a class for packing messages into a packet
+osc/OscPacketListener -- base class for listening to OSC packets on a UdpSocket
+tests/OscUnitTests -- unit test program for the OSC modules
+tests/OscSendTests -- examples of how to send messages
+tests/OscReceiveTest -- example of how to receive the messages sent by OSCSendTests
+examples/OscDump -- a program that prints received OSC packets
+
+
+
+Building
+--------
+
+In general the idea is that you will embed this source code in your projects as you 
+see fit. The Makefile has an install rule for building a shared library and 
+installing headers in usr/local.
+
+The Makefile works for Linux and MaxOS X except that if you are on a big endian 
+machine such as PowerPC Macintosh you need to edit the line which sets the 
+endianness to OSC_HOST_BIG_ENDIAN (see the makefile comment for details) or it won't 
+work. If you want to build and install liboscpack as a library on OS X you also need 
+to edit the $(LIBFILENAME) rule by commenting out the Linux case and uncommenting 
+the OS X case since OS X uses different gcc flags for shared libraries.
+
+On Windows there is a batch file for doing a simple test build with MinGW gcc called 
+make.MinGW32.bat. This will build the test executables and oscdump in ./bin and run 
+the unit tests.
+
+--
+
+
+If you fix anything or write a set of TCP send/recieve classes 
+please consider sending me a patch. Thanks :)
+
+For more information about Open Sound Control, see:
+http://www.cnmat.berkeley.edu/OpenSoundControl/
+
+
+Thanks to Till Bovermann for helping with POSIX networking code and
+Mac compatibility, and to Martin Kaltenbrunner and the rest of the
+reacTable team for giving me a reason to finish this library. Thanks
+to Merlijn Blaauw for reviewing the interfaces. Thanks to Xavier Oliver
+for additional help with Linux builds and POSIX implementation details.
+
+Portions developed at the Music Technology Group, Audiovisual Institute, 
+University Pompeu Fabra, Barcelona, during my stay as a visiting
+researcher, November 2004 - September 2005. 
+
+See the file LICENSE for information about distributing and using this code.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/TODO	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,55 @@
+TODO:
+
+    - consider adding the local endpoint name to PacketListener::PacketReceived() params
+
+    - consider adding ListenerThread class to support old seperate thread listener functionality, something like:
+
+        class UdpSocketListenerThread{
+        public:
+            UdpSocketListenerThread( UdpSocket& socket, Listener *listener );
+            UdpSocketListenerThread( UdpSocketReceiveMultiplexer *mux );
+            ~UdpSocketListenerThread();
+
+            void Run();
+            void Stop();
+        };
+
+    - provide some kind of automatic endianness configuration (hopefully there
+        are gcc symbols for this)
+
+    - work out a way to make the parsing classes totally safe. at a minimum this
+    means adding functions to test for invalid float/doublevalues,
+    making sure the iterators never pass the end of the message, ...
+        (passing end of message can happen if:
+            - too many args in type tags
+                a. typetags overflow message size
+                b. args fulfilling typetags overflow message size
+            - strings too long or not terminated correctly
+            - blobs too long or not terminated correctly
+
+        if the message was fully checked during construction, the end() iterator
+        could be moved back until only arguments which fit withing size() may
+        be interated (this could be none). A flag could be set to indicate that
+        something was wrong.
+
+    - other packet badness could include:
+        - time tags too far into the future (the scheduler should deal with
+            that i guess).
+        - message address patterns which aren't correctly terminated
+
+    - improve the ability to parse messages without tags (SC uses methods which
+            get the data and advance the iterator in one step.)
+        - Check* could be modified to do this - ie if typetags are not present
+            it could check that reading the field won't escape the message size
+            and return the data, or return false if some consistency
+            constraint is violated.
+        (or alternately drop support for messages without type tags)
+        
+
+    - add a method to discard an inprogress message if it gets half
+        constructed and the buffer is full in OutboundPacket
+
+    - write a stress testing app which can send garbage packets to try to flush out other bugs in the parsing code.
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/examples/OscDump.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,83 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+
+/*
+    OscDump prints incoming Osc packets. Unlike the Berkeley dumposc program
+    OscDump uses a different printing format which indicates the type of each
+    message argument.
+*/
+
+
+#include <iostream>
+
+#include "osc/OscReceivedElements.h"
+#include "osc/OscPrintReceivedElements.h"
+
+#include "ip/UdpSocket.h"
+#include "ip/PacketListener.h"
+
+
+class OscDumpPacketListener : public PacketListener{
+public:
+	virtual void ProcessPacket( const char *data, int size, 
+			const IpEndpointName& remoteEndpoint )
+	{
+		std::cout << osc::ReceivedPacket( data, size );
+	}
+};
+
+int main(int argc, char* argv[])
+{
+	if( argc >= 2 && strcmp( argv[1], "-h" ) == 0 ){
+        std::cout << "usage: OscDump [port]\n";
+        return 0;
+    }
+
+	int port = 7000;
+
+	if( argc >= 2 )
+		port = atoi( argv[1] );
+
+	OscDumpPacketListener listener;
+    UdpListeningReceiveSocket s(
+            IpEndpointName( IpEndpointName::ANY_ADDRESS, port ),
+            &listener );
+
+	std::cout << "listening for input on port " << port << "...\n";
+	std::cout << "press ctrl-c to end\n";
+
+	s.RunUntilSigInt();
+
+	std::cout << "finishing.\n";	
+
+    return 0;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/examples/SimpleReceive.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,74 @@
+/* 
+    Example of two different ways to process received OSC messages using oscpack.
+    Receives the messages from the SimpleSend.cpp example.
+*/
+
+#include <iostream>
+
+#include "osc/OscReceivedElements.h"
+#include "osc/OscPacketListener.h"
+#include "ip/UdpSocket.h"
+
+
+#define PORT 7000
+
+class ExamplePacketListener : public osc::OscPacketListener {
+protected:
+
+    virtual void ProcessMessage( const osc::ReceivedMessage& m, 
+				const IpEndpointName& remoteEndpoint )
+    {
+        try{
+            // example of parsing single messages. osc::OsckPacketListener
+            // handles the bundle traversal.
+            
+            if( strcmp( m.AddressPattern(), "/test1" ) == 0 ){
+                // example #1 -- argument stream interface
+                osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
+                bool a1;
+                osc::int32 a2;
+                float a3;
+                const char *a4;
+                args >> a1 >> a2 >> a3 >> a4 >> osc::EndMessage;
+                
+                std::cout << "received '/test1' message with arguments: "
+                    << a1 << " " << a2 << " " << a3 << " " << a4 << "\n";
+                
+            }else if( strcmp( m.AddressPattern(), "/test2" ) == 0 ){
+                // example #2 -- argument iterator interface, supports
+                // reflection for overloaded messages (eg you can call 
+                // (*arg)->IsBool() to check if a bool was passed etc).
+                osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
+                bool a1 = (arg++)->AsBool();
+                int a2 = (arg++)->AsInt32();
+                float a3 = (arg++)->AsFloat();
+                const char *a4 = (arg++)->AsString();
+                if( arg != m.ArgumentsEnd() )
+                    throw osc::ExcessArgumentException();
+                
+                std::cout << "received '/test2' message with arguments: "
+                    << a1 << " " << a2 << " " << a3 << " " << a4 << "\n";
+            }
+        }catch( osc::Exception& e ){
+            // any parsing errors such as unexpected argument types, or 
+            // missing arguments get thrown as exceptions.
+            std::cout << "error while parsing message: "
+                << m.AddressPattern() << ": " << e.what() << "\n";
+        }
+    }
+};
+
+int main(int argc, char* argv[])
+{
+    ExamplePacketListener listener;
+    UdpListeningReceiveSocket s(
+            IpEndpointName( IpEndpointName::ANY_ADDRESS, PORT ),
+            &listener );
+
+    std::cout << "press ctrl-c to end\n";
+
+    s.RunUntilSigInt();
+
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/examples/SimpleSend.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,30 @@
+/* 
+    Simple example of sending an OSC message using oscpack.
+*/
+
+#include "osc/OscOutboundPacketStream.h"
+#include "ip/UdpSocket.h"
+
+
+#define ADDRESS "127.0.0.1"
+#define PORT 7000
+
+#define OUTPUT_BUFFER_SIZE 1024
+
+int main(int argc, char* argv[])
+{
+    UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) );
+    
+    char buffer[OUTPUT_BUFFER_SIZE];
+    osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );
+    
+    p << osc::BeginBundleImmediate
+        << osc::BeginMessage( "/test1" ) 
+            << true << 23 << (float)3.1415 << "hello" << osc::EndMessage
+        << osc::BeginMessage( "/test2" ) 
+            << true << 24 << (float)10.8 << "world" << osc::EndMessage
+        << osc::EndBundle;
+    
+    transmitSocket.Send( p.Data(), p.Size() );
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/IpEndpointName.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,81 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "IpEndpointName.h"
+
+#include <stdio.h>
+
+#include "NetworkingUtils.h"
+
+
+unsigned long IpEndpointName::GetHostByName( const char *s )
+{
+	return ::GetHostByName(s);
+}
+
+
+void IpEndpointName::AddressAsString( char *s ) const
+{
+	if( address == ANY_ADDRESS ){
+		sprintf( s, "<any>" );
+	}else{
+		sprintf( s, "%d.%d.%d.%d",
+				(int)((address >> 24) & 0xFF),
+				(int)((address >> 16) & 0xFF),
+				(int)((address >> 8) & 0xFF),
+				(int)(address & 0xFF) );
+	}
+}
+
+
+void IpEndpointName::AddressAndPortAsString( char *s ) const
+{
+	if( port == ANY_PORT ){
+		if( address == ANY_ADDRESS ){
+			sprintf( s, "<any>:<any>" );
+		}else{
+			sprintf( s, "%d.%d.%d.%d:<any>",
+				(int)((address >> 24) & 0xFF),
+				(int)((address >> 16) & 0xFF),
+				(int)((address >> 8) & 0xFF),
+				(int)(address & 0xFF) );
+		}
+	}else{
+		if( address == ANY_ADDRESS ){
+			sprintf( s, "<any>:%d", port );
+		}else{
+			sprintf( s, "%d.%d.%d.%d:%d",
+				(int)((address >> 24) & 0xFF),
+				(int)((address >> 16) & 0xFF),
+				(int)((address >> 8) & 0xFF),
+				(int)(address & 0xFF),
+				(int)port );
+		}
+	}	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/IpEndpointName.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,74 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_IPENDPOINTNAME_H
+#define INCLUDED_IPENDPOINTNAME_H
+
+
+class IpEndpointName{
+    static unsigned long GetHostByName( const char *s );
+public:
+    static const unsigned long ANY_ADDRESS = 0xFFFFFFFF;
+    static const int ANY_PORT = -1;
+
+    IpEndpointName()
+		: address( ANY_ADDRESS ), port( ANY_PORT ) {}
+    IpEndpointName( int port_ ) 
+		: address( ANY_ADDRESS ), port( port_ ) {}
+    IpEndpointName( unsigned long ipAddress_, int port_ ) 
+		: address( ipAddress_ ), port( port_ ) {}
+    IpEndpointName( const char *addressName, int port_=ANY_PORT )
+		: address( GetHostByName( addressName ) )
+		, port( port_ ) {}
+    IpEndpointName( int addressA, int addressB, int addressC, int addressD, int port_=ANY_PORT )
+		: address( ( (addressA << 24) | (addressB << 16) | (addressC << 8) | addressD ) )
+		, port( port_ ) {}
+
+	// address and port are maintained in host byte order here
+    unsigned long address;
+    int port;
+
+	enum { ADDRESS_STRING_LENGTH=17 };
+	void AddressAsString( char *s ) const;
+
+	enum { ADDRESS_AND_PORT_STRING_LENGTH=23};
+	void AddressAndPortAsString( char *s ) const;
+};
+
+inline bool operator==( const IpEndpointName& lhs, const IpEndpointName& rhs )
+{	
+	return (lhs.address == rhs.address && lhs.port == rhs.port );
+}
+
+inline bool operator!=( const IpEndpointName& lhs, const IpEndpointName& rhs )
+{
+	return !(lhs == rhs);
+}
+
+#endif /* INCLUDED_IPENDPOINTNAME_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/NetworkingUtils.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,49 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_NETWORKINGUTILS_H
+#define INCLUDED_NETWORKINGUTILS_H
+
+
+// in general NetworkInitializer is only used internally, but if you're 
+// application creates multiple sockets from different threads at runtime you
+// should instantiate one of these in main just to make sure the networking
+// layer is initialized.
+class NetworkInitializer{
+public:
+    NetworkInitializer();
+    ~NetworkInitializer();
+};
+
+
+// return ip address of host name in host byte order
+unsigned long GetHostByName( const char *name );
+
+
+#endif /* INCLUDED_NETWORKINGUTILS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/PacketListener.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,43 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_PACKETLISTENER_H
+#define INCLUDED_PACKETLISTENER_H
+
+
+class IpEndpointName;
+
+class PacketListener{
+public:
+    virtual ~PacketListener() {}
+    virtual void ProcessPacket( const char *data, int size, 
+			const IpEndpointName& remoteEndpoint ) = 0;
+};
+
+#endif /* INCLUDED_PACKETLISTENER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/TimerListener.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,40 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_TIMERLISTENER_H
+#define INCLUDED_TIMERLISTENER_H
+
+
+class TimerListener{
+public:
+    virtual ~TimerListener() {}
+    virtual void TimerExpired() = 0;
+};
+
+#endif /* INCLUDED_TIMERLISTENER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/UdpSocket.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,158 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_UDPSOCKET_H
+#define INCLUDED_UDPSOCKET_H
+
+#ifndef INCLUDED_NETWORKINGUTILITIES_H
+#include "NetworkingUtils.h"
+#endif /* INCLUDED_NETWORKINGUTILITIES_H */
+
+#ifndef INCLUDED_IPENDPOINTNAME_H
+#include "IpEndpointName.h"
+#endif /* INCLUDED_IPENDPOINTNAME_H */
+
+
+class PacketListener;
+class TimerListener;
+
+class UdpSocket;
+
+class SocketReceiveMultiplexer{
+    class Implementation;
+    Implementation *impl_;
+
+	friend class UdpSocket;
+
+public:
+    SocketReceiveMultiplexer();
+    ~SocketReceiveMultiplexer();
+
+	// only call the attach/detach methods _before_ calling Run
+
+    // only one listener per socket, each socket at most once
+    void AttachSocketListener( UdpSocket *socket, PacketListener *listener );
+    void DetachSocketListener( UdpSocket *socket, PacketListener *listener );
+
+    void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener );
+	void AttachPeriodicTimerListener(
+            int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener );
+    void DetachPeriodicTimerListener( TimerListener *listener );  
+
+    void Run();      // loop and block processing messages indefinitely
+	void RunUntilSigInt();
+    void Break();    // call this from a listener to exit once the listener returns
+    void AsynchronousBreak(); // call this from another thread or signal handler to exit the Run() state
+};
+
+
+class UdpSocket{
+    class Implementation;
+    Implementation *impl_;
+    
+	friend class SocketReceiveMultiplexer::Implementation;
+    
+public:
+
+	// ctor throws std::runtime_error if there's a problem
+	// initializing the socket.
+	UdpSocket();
+	virtual ~UdpSocket();
+
+	// 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
+	// connect to a remote endpoint using Connect(). To use
+	// ReceiveFrom you need to first bind to a local endpoint
+	// using Bind().
+
+	// retrieve the local endpoint name when sending to 'to'
+    IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const;
+
+	// Connect to a remote endpoint which is used as the target
+	// for calls to Send()
+	void Connect( const IpEndpointName& remoteEndpoint );	
+	void Send( const char *data, int size );
+    void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size );
+
+
+	// Bind a local endpoint to receive incoming data. Endpoint
+	// can be 'any' for the system to choose an endpoint
+	void Bind( const IpEndpointName& localEndpoint );
+	bool IsBound() const;
+
+	int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size );
+};
+
+
+// convenience classes for transmitting and receiving
+// they just call Connect and/or Bind in the ctor.
+// note that you can still use a receive socket
+// for transmitting etc
+
+class UdpTransmitSocket : public UdpSocket{
+public:
+	UdpTransmitSocket( const IpEndpointName& remoteEndpoint )
+		{ Connect( remoteEndpoint ); }
+};
+
+
+class UdpReceiveSocket : public UdpSocket{
+public:
+	UdpReceiveSocket( const IpEndpointName& localEndpoint )
+		{ Bind( localEndpoint ); }
+};
+
+
+// UdpListeningReceiveSocket provides a simple way to bind one listener
+// to a single socket without having to manually set up a SocketReceiveMultiplexer
+
+class UdpListeningReceiveSocket : public UdpSocket{
+    SocketReceiveMultiplexer mux_;
+    PacketListener *listener_;
+public:
+	UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener )
+        : listener_( listener )
+    {
+        Bind( localEndpoint );
+        mux_.AttachSocketListener( this, listener_ );
+    }
+
+    ~UdpListeningReceiveSocket()
+        { mux_.DetachSocketListener( this, listener_ ); }
+
+    // see SocketReceiveMultiplexer above for the behaviour of these methods...
+    void Run() { mux_.Run(); }
+	void RunUntilSigInt() { mux_.RunUntilSigInt(); }
+    void Break() { mux_.Break(); }
+    void AsynchronousBreak() { mux_.AsynchronousBreak(); }
+};
+
+
+#endif /* INCLUDED_UDPSOCKET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/posix/NetworkingUtils.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,57 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "ip/NetworkingUtils.h"
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <stdio.h>
+
+
+
+NetworkInitializer::NetworkInitializer() {}
+
+NetworkInitializer::~NetworkInitializer() {}
+
+
+unsigned long GetHostByName( const char *name )
+{
+    unsigned long result = 0;
+
+    struct hostent *h = gethostbyname( name );
+    if( h ){
+        struct in_addr a;
+        memcpy( &a, h->h_addr_list[0], h->h_length );
+        result = ntohl(a.s_addr);
+    }
+
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/posix/UdpSocket.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,546 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "ip/UdpSocket.h"
+
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <assert.h>
+#include <signal.h>
+#include <math.h>
+#include <errno.h>
+#include <string.h> // for memset
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h> // for sockaddr_in
+
+#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;
+#endif
+
+
+static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
+{
+    memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+    sockAddr.sin_family = AF_INET;
+
+	sockAddr.sin_addr.s_addr = 
+		(endpoint.address == IpEndpointName::ANY_ADDRESS)
+		? INADDR_ANY
+		: htonl( endpoint.address );
+
+	sockAddr.sin_port =
+		(endpoint.port == IpEndpointName::ANY_PORT)
+		? 0
+		: htons( endpoint.port );
+}
+
+
+static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )
+{
+	return IpEndpointName( 
+		(sockAddr.sin_addr.s_addr == INADDR_ANY) 
+			? IpEndpointName::ANY_ADDRESS 
+			: ntohl( sockAddr.sin_addr.s_addr ),
+		(sockAddr.sin_port == 0)
+			? IpEndpointName::ANY_PORT
+			: ntohs( sockAddr.sin_port )
+		);
+}
+
+
+class UdpSocket::Implementation{
+	bool isBound_;
+	bool isConnected_;
+
+	int socket_;
+	struct sockaddr_in connectedAddr_;
+	struct sockaddr_in sendToAddr_;
+
+public:
+
+	Implementation()
+		: isBound_( false )
+		, isConnected_( false )
+		, socket_( -1 )
+	{
+		if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 ){
+            throw std::runtime_error("unable to create udp socket\n");
+        }
+
+		memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
+        sendToAddr_.sin_family = AF_INET;
+	}
+
+	~Implementation()
+	{
+		if (socket_ != -1) close(socket_);
+	}
+
+	IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+	{
+		assert( isBound_ );
+
+		// first connect the socket to the remote server
+        
+        struct sockaddr_in connectSockAddr;
+		SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint );
+       
+        if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) {
+            throw std::runtime_error("unable to connect udp socket\n");
+        }
+
+        // get the address
+
+        struct sockaddr_in sockAddr;
+        memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+        socklen_t length = sizeof(sockAddr);
+        if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
+            throw std::runtime_error("unable to getsockname\n");
+        }
+        
+		if( isConnected_ ){
+			// reconnect to the connected address
+			
+			if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+				throw std::runtime_error("unable to connect udp socket\n");
+			}
+
+		}else{
+			// unconnect from the remote address
+		
+			struct sockaddr_in unconnectSockAddr;
+			memset( (char *)&unconnectSockAddr, 0, sizeof(unconnectSockAddr ) );
+			unconnectSockAddr.sin_family = AF_UNSPEC;
+			// address fields are zero
+			int connectResult = connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr));
+			if ( connectResult < 0 && errno != EAFNOSUPPORT ) {
+				throw std::runtime_error("unable to un-connect udp socket\n");
+			}
+		}
+
+		return IpEndpointNameFromSockaddr( sockAddr );
+	}
+
+	void Connect( const IpEndpointName& remoteEndpoint )
+	{
+		SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint );
+       
+        if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+            throw std::runtime_error("unable to connect udp socket\n");
+        }
+
+		isConnected_ = true;
+	}
+
+	void Send( const char *data, int size )
+	{
+		assert( isConnected_ );
+
+        send( socket_, data, size, 0 );
+	}
+
+    void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+	{
+		sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
+        sendToAddr_.sin_port = htons( remoteEndpoint.port );
+
+        sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
+	}
+
+	void Bind( const IpEndpointName& localEndpoint )
+	{
+		struct sockaddr_in bindSockAddr;
+		SockaddrFromIpEndpointName( bindSockAddr, localEndpoint );
+
+        if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) {
+            throw std::runtime_error("unable to bind udp socket\n");
+        }
+
+		isBound_ = true;
+	}
+
+	bool IsBound() const { return isBound_; }
+
+    int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+	{
+		assert( isBound_ );
+
+		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 )
+			return 0;
+
+		remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
+		remoteEndpoint.port = ntohs(fromAddr.sin_port);
+
+		return result;
+	}
+
+	int Socket() { return socket_; }
+};
+
+UdpSocket::UdpSocket()
+{
+	impl_ = new Implementation();
+}
+
+UdpSocket::~UdpSocket()
+{
+	delete impl_;
+}
+
+IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+{
+	return impl_->LocalEndpointFor( remoteEndpoint );
+}
+
+void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
+{
+	impl_->Connect( remoteEndpoint );
+}
+
+void UdpSocket::Send( const char *data, int size )
+{
+	impl_->Send( data, size );
+}
+
+void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+{
+	impl_->SendTo( remoteEndpoint, data, size );
+}
+
+void UdpSocket::Bind( const IpEndpointName& localEndpoint )
+{
+	impl_->Bind( localEndpoint );
+}
+
+bool UdpSocket::IsBound() const
+{
+	return impl_->IsBound();
+}
+
+int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+{
+	return impl_->ReceiveFrom( remoteEndpoint, data, size );
+}
+
+
+struct AttachedTimerListener{
+	AttachedTimerListener( int id, int p, TimerListener *tl )
+		: initialDelayMs( id )
+		, periodMs( p )
+		, listener( tl ) {}
+	int initialDelayMs;
+	int periodMs;
+	TimerListener *listener;
+};
+
+
+static bool CompareScheduledTimerCalls( 
+		const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs )
+{
+	return lhs.first < rhs.first;
+}
+
+
+SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;
+
+extern "C" /*static*/ void InterruptSignalHandler( int );
+/*static*/ void InterruptSignalHandler( int )
+{
+	multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak();
+	signal( SIGINT, SIG_DFL );
+}
+
+
+class SocketReceiveMultiplexer::Implementation{
+	std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;
+	std::vector< AttachedTimerListener > timerListeners_;
+
+	volatile bool break_;
+	int breakPipe_[2]; // [0] is the reader descriptor and [1] the writer
+
+	double GetCurrentTimeMs() const
+	{
+		struct timeval t;
+
+		gettimeofday( &t, 0 );
+
+		return ((double)t.tv_sec*1000.) + ((double)t.tv_usec / 1000.);
+	}
+
+public:
+    Implementation()
+	{
+		if( pipe(breakPipe_) != 0 )
+			throw std::runtime_error( "creation of asynchronous break pipes failed\n" );
+	}
+
+    ~Implementation()
+	{
+		close( breakPipe_[0] );
+		close( breakPipe_[1] );
+	}
+
+    void AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+	{
+		assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() );
+		// we don't check that the same socket has been added multiple times, even though this is an error
+		socketListeners_.push_back( std::make_pair( listener, socket ) );
+	}
+
+    void DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+	{
+		std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = 
+				std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) );
+		assert( i != socketListeners_.end() );
+
+		socketListeners_.erase( i );
+	}
+
+    void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+	{
+		timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) );
+	}
+
+	void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+	{
+		timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) );
+	}
+
+    void DetachPeriodicTimerListener( TimerListener *listener )
+	{
+		std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+		while( i != timerListeners_.end() ){
+			if( i->listener == listener )
+				break;
+			++i;
+		}
+
+		assert( i != timerListeners_.end() );
+
+		timerListeners_.erase( i );
+	}
+
+    void Run()
+	{
+		break_ = false;
+
+		// configure the master fd_set for select()
+
+		fd_set masterfds, tempfds;
+		FD_ZERO( &masterfds );
+		FD_ZERO( &tempfds );
+		
+		// in addition to listening to the inbound sockets we
+		// also listen to the asynchronous break pipe, so that AsynchronousBreak()
+		// can break us out of select() from another thread.
+		FD_SET( breakPipe_[0], &masterfds );
+		int fdmax = breakPipe_[0];		
+
+		for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+				i != socketListeners_.end(); ++i ){
+
+			if( fdmax < i->second->impl_->Socket() )
+				fdmax = i->second->impl_->Socket();
+			FD_SET( i->second->impl_->Socket(), &masterfds );
+		}
+
+
+		// configure the timer queue
+		double currentTimeMs = GetCurrentTimeMs();
+
+		// expiry time ms, listener
+		std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
+		for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+				i != timerListeners_.end(); ++i )
+			timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
+		std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+
+		const int MAX_BUFFER_SIZE = 4098;
+		char *data = new char[ MAX_BUFFER_SIZE ];
+		IpEndpointName remoteEndpoint;
+
+		struct timeval timeout;
+
+		while( !break_ ){
+			tempfds = masterfds;
+
+			struct timeval *timeoutPtr = 0;
+			if( !timerQueue_.empty() ){
+				double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
+				if( timeoutMs < 0 )
+					timeoutMs = 0;
+			
+				// 1000000 microseconds in a second
+				timeout.tv_sec = (long)(timeoutMs * .001);
+				timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
+				timeoutPtr = &timeout;
+			}
+
+			if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 && errno != EINTR ){
+   				throw std::runtime_error("select failed\n");
+			}
+
+			if ( FD_ISSET( breakPipe_[0], &tempfds ) ){
+				// clear pending data from the asynchronous break pipe
+				char c;
+				read( breakPipe_[0], &c, 1 );
+			}
+			
+			if( break_ )
+				break;
+
+			for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+					i != socketListeners_.end(); ++i ){
+
+				if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){
+
+					int size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
+					if( size > 0 ){
+						i->first->ProcessPacket( data, size, remoteEndpoint );
+						if( break_ )
+							break;
+					}
+				}
+			}
+
+			// execute any expired timers
+			currentTimeMs = GetCurrentTimeMs();
+			bool resort = false;
+			for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
+					i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
+
+				i->second.listener->TimerExpired();
+				if( break_ )
+					break;
+
+				i->first += i->second.periodMs;
+				resort = true;
+			}
+			if( resort )
+				std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+		}
+
+		delete [] data;
+	}
+
+    void Break()
+	{
+		break_ = true;
+	}
+
+    void AsynchronousBreak()
+	{
+		break_ = true;
+
+		// Send a termination message to the asynchronous break pipe, so select() will return
+		write( breakPipe_[1], "!", 1 );
+	}
+};
+
+
+
+SocketReceiveMultiplexer::SocketReceiveMultiplexer()
+{
+	impl_ = new Implementation();
+}
+
+SocketReceiveMultiplexer::~SocketReceiveMultiplexer()
+{	
+	delete impl_;
+}
+
+void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+	impl_->AttachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+	impl_->DetachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+{
+	impl_->AttachPeriodicTimerListener( periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+{
+	impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )
+{
+	impl_->DetachPeriodicTimerListener( listener );
+}
+
+void SocketReceiveMultiplexer::Run()
+{
+	impl_->Run();
+}
+
+void SocketReceiveMultiplexer::RunUntilSigInt()
+{
+	assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */
+	multiplexerInstanceToAbortWithSigInt_ = this;
+	signal( SIGINT, InterruptSignalHandler );
+	impl_->Run();
+	signal( SIGINT, SIG_DFL );
+	multiplexerInstanceToAbortWithSigInt_ = 0;
+}
+
+void SocketReceiveMultiplexer::Break()
+{
+	impl_->Break();
+}
+
+void SocketReceiveMultiplexer::AsynchronousBreak()
+{
+	impl_->AsynchronousBreak();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/win32/NetworkingUtils.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,88 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "ip/NetworkingUtils.h"
+
+#include <winsock2.h>   // this must come first to prevent errors with MSVC7
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+static LONG initCount_ = 0;
+static bool winsockInitialized_ = false;
+
+NetworkInitializer::NetworkInitializer()
+{
+    if( InterlockedIncrement( &initCount_ ) == 1 ){
+        // there is a race condition here if one thread tries to access
+        // the library while another is still initializing it. 
+        // i can't think of an easy way to fix it so i'm telling you here
+        // incase you need to init the library from two threads at once.
+        // this is why the header file advises to instantiate one of these 
+        // in main() so that the initialization happens globally
+
+        // initialize winsock
+	    WSAData wsaData;
+	    int nCode = WSAStartup(MAKEWORD(1, 1), &wsaData);
+	    if( nCode != 0 ){
+	        //std::cout << "WSAStartup() failed with error code " << nCode << "\n";
+        }else{
+            winsockInitialized_ = true;
+        }
+    }
+}
+
+
+NetworkInitializer::~NetworkInitializer()
+{
+    if( InterlockedDecrement( &initCount_ ) == 0 ){
+        if( winsockInitialized_ ){
+            WSACleanup();
+            winsockInitialized_ = false;
+        }
+    }
+}
+
+
+unsigned long GetHostByName( const char *name )
+{
+    NetworkInitializer networkInitializer;
+
+    unsigned long result = 0;
+
+    struct hostent *h = gethostbyname( name );
+    if( h ){
+        struct in_addr a;
+        memcpy( &a, h->h_addr_list[0], h->h_length );
+        result = ntohl(a.s_addr);
+    }
+
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/ip/win32/UdpSocket.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,521 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "ip/UdpSocket.h"
+
+#include <winsock2.h>   // this must come first to prevent errors with MSVC7
+#include <windows.h>
+#include <mmsystem.h>   // for timeGetTime()
+
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <assert.h>
+#include <signal.h>
+
+#include "ip/NetworkingUtils.h"
+#include "ip/PacketListener.h"
+#include "ip/TimerListener.h"
+
+
+typedef int socklen_t;
+
+
+static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
+{
+    memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+    sockAddr.sin_family = AF_INET;
+
+	sockAddr.sin_addr.s_addr = 
+		(endpoint.address == IpEndpointName::ANY_ADDRESS)
+		? INADDR_ANY
+		: htonl( endpoint.address );
+
+	sockAddr.sin_port =
+		(endpoint.port == IpEndpointName::ANY_PORT)
+		? (short)0
+		: htons( (short)endpoint.port );
+}
+
+
+static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )
+{
+	return IpEndpointName( 
+		(sockAddr.sin_addr.s_addr == INADDR_ANY) 
+			? IpEndpointName::ANY_ADDRESS 
+			: ntohl( sockAddr.sin_addr.s_addr ),
+		(sockAddr.sin_port == 0)
+			? IpEndpointName::ANY_PORT
+			: ntohs( sockAddr.sin_port )
+		);
+}
+
+
+class UdpSocket::Implementation{
+    NetworkInitializer networkInitializer_;
+
+	bool isBound_;
+	bool isConnected_;
+
+	SOCKET socket_;
+	struct sockaddr_in connectedAddr_;
+	struct sockaddr_in sendToAddr_;
+
+public:
+
+	Implementation()
+		: isBound_( false )
+		, isConnected_( false )
+		, socket_( INVALID_SOCKET )
+	{
+		if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == INVALID_SOCKET ){
+            throw std::runtime_error("unable to create udp socket\n");
+        }
+
+		memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
+        sendToAddr_.sin_family = AF_INET;
+	}
+
+	~Implementation()
+	{
+		if (socket_ != INVALID_SOCKET) closesocket(socket_);
+	}
+
+	IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+	{
+		assert( isBound_ );
+
+		// first connect the socket to the remote server
+        
+        struct sockaddr_in connectSockAddr;
+		SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint );
+       
+        if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) {
+            throw std::runtime_error("unable to connect udp socket\n");
+        }
+
+        // get the address
+
+        struct sockaddr_in sockAddr;
+        memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+        socklen_t length = sizeof(sockAddr);
+        if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
+            throw std::runtime_error("unable to getsockname\n");
+        }
+        
+		if( isConnected_ ){
+			// reconnect to the connected address
+			
+			if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+				throw std::runtime_error("unable to connect udp socket\n");
+			}
+
+		}else{
+			// unconnect from the remote address
+		
+			struct sockaddr_in unconnectSockAddr;
+			SockaddrFromIpEndpointName( unconnectSockAddr, IpEndpointName() );
+
+			if( connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr)) < 0 
+					&& WSAGetLastError() != WSAEADDRNOTAVAIL ){
+				throw std::runtime_error("unable to un-connect udp socket\n");
+			}
+		}
+
+		return IpEndpointNameFromSockaddr( sockAddr );
+	}
+
+	void Connect( const IpEndpointName& remoteEndpoint )
+	{
+		SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint );
+       
+        if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+            throw std::runtime_error("unable to connect udp socket\n");
+        }
+
+		isConnected_ = true;
+	}
+
+	void Send( const char *data, int size )
+	{
+		assert( isConnected_ );
+
+        send( socket_, data, size, 0 );
+	}
+
+    void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+	{
+		sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
+        sendToAddr_.sin_port = htons( (short)remoteEndpoint.port );
+
+        sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
+	}
+
+	void Bind( const IpEndpointName& localEndpoint )
+	{
+		struct sockaddr_in bindSockAddr;
+		SockaddrFromIpEndpointName( bindSockAddr, localEndpoint );
+
+        if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) {
+            throw std::runtime_error("unable to bind udp socket\n");
+        }
+
+		isBound_ = true;
+	}
+
+	bool IsBound() const { return isBound_; }
+
+    int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+	{
+		assert( isBound_ );
+
+		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 )
+			return 0;
+
+		remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
+		remoteEndpoint.port = ntohs(fromAddr.sin_port);
+
+		return result;
+	}
+
+	SOCKET& Socket() { return socket_; }
+};
+
+UdpSocket::UdpSocket()
+{
+	impl_ = new Implementation();
+}
+
+UdpSocket::~UdpSocket()
+{
+	delete impl_;
+}
+
+IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+{
+	return impl_->LocalEndpointFor( remoteEndpoint );
+}
+
+void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
+{
+	impl_->Connect( remoteEndpoint );
+}
+
+void UdpSocket::Send( const char *data, int size )
+{
+	impl_->Send( data, size );
+}
+
+void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+{
+	impl_->SendTo( remoteEndpoint, data, size );
+}
+
+void UdpSocket::Bind( const IpEndpointName& localEndpoint )
+{
+	impl_->Bind( localEndpoint );
+}
+
+bool UdpSocket::IsBound() const
+{
+	return impl_->IsBound();
+}
+
+int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+{
+	return impl_->ReceiveFrom( remoteEndpoint, data, size );
+}
+
+
+struct AttachedTimerListener{
+	AttachedTimerListener( int id, int p, TimerListener *tl )
+		: initialDelayMs( id )
+		, periodMs( p )
+		, listener( tl ) {}
+	int initialDelayMs;
+	int periodMs;
+	TimerListener *listener;
+};
+
+
+static bool CompareScheduledTimerCalls( 
+		const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs )
+{
+	return lhs.first < rhs.first;
+}
+
+
+SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;
+
+extern "C" /*static*/ void InterruptSignalHandler( int );
+/*static*/ void InterruptSignalHandler( int )
+{
+	multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak();
+	signal( SIGINT, SIG_DFL );
+}
+
+
+class SocketReceiveMultiplexer::Implementation{
+    NetworkInitializer networkInitializer_;
+
+	std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;
+	std::vector< AttachedTimerListener > timerListeners_;
+
+	volatile bool break_;
+	HANDLE breakEvent_;
+
+	double GetCurrentTimeMs() const
+	{
+		return timeGetTime(); // FIXME: bad choice if you want to run for more than 40 days
+	}
+
+public:
+    Implementation()
+	{
+		breakEvent_ = CreateEvent( NULL, FALSE, FALSE, NULL );
+	}
+
+    ~Implementation()
+	{
+		CloseHandle( breakEvent_ );
+	}
+
+    void AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+	{
+		assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() );
+		// we don't check that the same socket has been added multiple times, even though this is an error
+		socketListeners_.push_back( std::make_pair( listener, socket ) );
+	}
+
+    void DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+	{
+		std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = 
+				std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) );
+		assert( i != socketListeners_.end() );
+
+		socketListeners_.erase( i );
+	}
+
+    void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+	{
+		timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) );
+	}
+
+	void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+	{
+		timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) );
+	}
+
+    void DetachPeriodicTimerListener( TimerListener *listener )
+	{
+		std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+		while( i != timerListeners_.end() ){
+			if( i->listener == listener )
+				break;
+			++i;
+		}
+
+		assert( i != timerListeners_.end() );
+
+		timerListeners_.erase( i );
+	}
+
+    void Run()
+	{
+		break_ = false;
+
+		// prepare the window events which we use to wake up on incoming data
+		// we use this instead of select() primarily to support the AsyncBreak() 
+		// mechanism.
+
+		std::vector<HANDLE> events( socketListeners_.size() + 1, 0 );
+		int j=0;
+		for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+				i != socketListeners_.end(); ++i, ++j ){
+
+			HANDLE event = CreateEvent( NULL, FALSE, FALSE, NULL );
+			WSAEventSelect( i->second->impl_->Socket(), event, FD_READ ); // note that this makes the socket non-blocking which is why we can safely call RecieveFrom() on all sockets below
+			events[j] = event;
+		}
+
+
+		events[ socketListeners_.size() ] = breakEvent_; // last event in the collection is the break event
+
+		
+		// configure the timer queue
+		double currentTimeMs = GetCurrentTimeMs();
+
+		// expiry time ms, listener
+		std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
+		for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+				i != timerListeners_.end(); ++i )
+			timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
+		std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+
+		const int MAX_BUFFER_SIZE = 4098;
+		char *data = new char[ MAX_BUFFER_SIZE ];
+		IpEndpointName remoteEndpoint;
+
+		while( !break_ ){
+
+			double currentTimeMs = GetCurrentTimeMs();
+
+            DWORD waitTime = INFINITE;
+            if( !timerQueue_.empty() ){
+
+                waitTime = (DWORD)( timerQueue_.front().first >= currentTimeMs
+                            ? timerQueue_.front().first - currentTimeMs
+                            : 0 );
+            }
+
+			DWORD waitResult = WaitForMultipleObjects( (DWORD)socketListeners_.size() + 1, &events[0], FALSE, waitTime );
+			if( break_ )
+				break;
+
+			if( waitResult != WAIT_TIMEOUT ){
+				for( int i = waitResult - WAIT_OBJECT_0; i < (int)socketListeners_.size(); ++i ){
+					int size = socketListeners_[i].second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
+					if( size > 0 ){
+						socketListeners_[i].first->ProcessPacket( data, size, remoteEndpoint );
+						if( break_ )
+							break;
+					}
+				}
+			}
+
+			// execute any expired timers
+			currentTimeMs = GetCurrentTimeMs();
+			bool resort = false;
+			for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
+					i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
+
+				i->second.listener->TimerExpired();
+				if( break_ )
+					break;
+
+				i->first += i->second.periodMs;
+				resort = true;
+			}
+			if( resort )
+				std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+		}
+
+		delete [] data;
+
+		// free events
+		j = 0;
+		for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+				i != socketListeners_.end(); ++i, ++j ){
+
+			WSAEventSelect( i->second->impl_->Socket(), events[j], 0 ); // remove association between socket and event
+			CloseHandle( events[j] );
+			unsigned long enableNonblocking = 0;
+			ioctlsocket( i->second->impl_->Socket(), FIONBIO, &enableNonblocking );  // make the socket blocking again
+		}
+	}
+
+    void Break()
+	{
+		break_ = true;
+	}
+
+    void AsynchronousBreak()
+	{
+		break_ = true;
+		SetEvent( breakEvent_ );
+	}
+};
+
+
+
+SocketReceiveMultiplexer::SocketReceiveMultiplexer()
+{
+	impl_ = new Implementation();
+}
+
+SocketReceiveMultiplexer::~SocketReceiveMultiplexer()
+{	
+	delete impl_;
+}
+
+void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+	impl_->AttachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+	impl_->DetachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+{
+	impl_->AttachPeriodicTimerListener( periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+{
+	impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )
+{
+	impl_->DetachPeriodicTimerListener( listener );
+}
+
+void SocketReceiveMultiplexer::Run()
+{
+	impl_->Run();
+}
+
+void SocketReceiveMultiplexer::RunUntilSigInt()
+{
+	assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */
+	multiplexerInstanceToAbortWithSigInt_ = this;
+	signal( SIGINT, InterruptSignalHandler );
+	impl_->Run();
+	signal( SIGINT, SIG_DFL );
+	multiplexerInstanceToAbortWithSigInt_ = 0;
+}
+
+void SocketReceiveMultiplexer::Break()
+{
+	impl_->Break();
+}
+
+void SocketReceiveMultiplexer::AsynchronousBreak()
+{
+	impl_->AsynchronousBreak();
+}
+
Binary file external/oscpack/liboscpack.1.0.2.dylib has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/make.MinGW32.bat	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,19 @@
+del bin\OscUnitTests.exe
+del bin\OscDump.exe
+del bin\OscSendTests.exe
+del bin\OscReceiveTest.exe
+mkdir bin
+
+g++ tests\OscUnitTests.cpp osc\OscTypes.cpp osc\OscReceivedElements.cpp osc\OscPrintReceivedElements.cpp osc\OscOutboundPacketStream.cpp -Wall -I. -lws2_32 -o bin\OscUnitTests.exe
+
+g++ examples\OscDump.cpp osc\OscTypes.cpp osc\OscReceivedElements.cpp osc\OscPrintReceivedElements.cpp ip\win32\NetworkingUtils.cpp ip\win32\UdpSocket.cpp -Wall -I. -lws2_32 -lwinmm -o bin\OscDump.exe
+
+g++ examples\SimpleSend.cpp osc\OscTypes.cpp osc\OscOutboundPacketStream.cpp ip\win32\NetworkingUtils.cpp ip\win32\UdpSocket.cpp ip\IpEndpointName.cpp -Wall -I. -lws2_32 -lwinmm -o bin\SimpleSend.exe
+
+g++ examples\SimpleReceive.cpp osc\OscTypes.cpp osc\OscReceivedElements.cpp ip\win32\NetworkingUtils.cpp ip\win32\UdpSocket.cpp -Wall -I. -lws2_32 -lwinmm -o bin\SimpleReceive.exe
+
+g++ tests\OscSendTests.cpp osc\OscTypes.cpp osc\OscOutboundPacketStream.cpp ip\win32\NetworkingUtils.cpp ip\win32\UdpSocket.cpp ip\IpEndpointName.cpp -Wall -I. -lws2_32 -lwinmm -o bin\OscSendTests.exe
+
+g++ tests\OscReceiveTest.cpp osc\OscTypes.cpp osc\OscReceivedElements.cpp ip\win32\NetworkingUtils.cpp ip\win32\UdpSocket.cpp -Wall -I. -lws2_32 -lwinmm -o bin\OscReceiveTest.exe
+
+.\bin\OscUnitTests.exe
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/MessageMappingOscPacketListener.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,73 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
+#define INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
+
+#include <string.h>
+#include <map>
+
+#include "OscPacketListener.h"
+
+
+
+namespace osc{
+
+template< class T >
+class MessageMappingOscPacketListener : public OscPacketListener{
+public:
+    typedef void (T::*function_type)(const osc::ReceivedMessage&, const IpEndpointName&);
+
+protected:
+    void RegisterMessageFunction( const char *addressPattern, function_type f )
+    {
+        functions_.insert( std::make_pair( addressPattern, f ) );
+    }
+
+    virtual void ProcessMessage( const osc::ReceivedMessage& m,
+		const IpEndpointName& remoteEndpoint )
+    {
+        typename function_map_type::iterator i = functions_.find( m.AddressPattern() );
+        if( i != functions_.end() )
+            (dynamic_cast<T*>(this)->*(i->second))( m, remoteEndpoint );
+    }
+    
+private:
+    struct cstr_compare{
+        bool operator()( const char *lhs, const char *rhs ) const
+            { return strcmp( lhs, rhs ) < 0; }
+    };
+
+    typedef std::map<const char*, function_type, cstr_compare> function_map_type;
+    function_map_type functions_;
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscException.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,54 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSC_EXCEPTION_H
+#define INCLUDED_OSC_EXCEPTION_H
+
+#include <exception>
+
+namespace osc{
+
+class Exception : public std::exception {
+    const char *what_;
+    
+public:
+    Exception() throw() {}
+    Exception( const Exception& src ) throw()
+        : what_( src.what_ ) {}
+    Exception( const char *w ) throw()
+        : what_( w ) {}
+    Exception& operator=( const Exception& src ) throw()
+        { what_ = src.what_; return *this; }
+    virtual ~Exception() throw() {}
+    virtual const char* what() const throw() { return what_; }
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSC_EXCEPTION_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscHostEndianness.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,69 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef OSC_HOSTENDIANNESS_H
+#define OSC_HOSTENDIANNESS_H
+
+/*
+    Make sure either OSC_HOST_LITTLE_ENDIAN or OSC_HOST_BIG_ENDIAN is defined
+
+    If you know a way to enhance the detection below for Linux and/or MacOSX
+    please let me know! I've tried a few things which don't work.
+*/
+
+#if defined(OSC_HOST_LITTLE_ENDIAN) || defined(OSC_HOST_BIG_ENDIAN)
+
+// you can define one of the above symbols from the command line
+// then you don't have to edit this file.
+
+#elif defined(__WIN32__) || defined(WIN32)
+
+// assume that __WIN32__ is only defined on little endian systems
+
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+
+#elif defined(__APPLE__)
+
+#if defined(__LITTLE_ENDIAN__)
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+#else
+#define OSC_HOST_BIG_ENDIAN 1
+#undef OSC_HOST_LITTLE_ENDIAN
+#endif
+
+#else
+
+#error please edit OSCHostEndianness.h to configure endianness
+
+#endif
+
+#endif /* OSC_HOSTENDIANNESS_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscOutboundPacketStream.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,639 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscOutboundPacketStream.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#if defined(__WIN32__) || defined(WIN32)
+#include <malloc.h> // for alloca
+#endif
+
+#include "OscHostEndianness.h"
+
+
+namespace osc{
+
+static void FromInt32( char *p, int32 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int32 i;
+        char c[4];
+    } u;
+
+    u.i = x;
+
+    p[3] = u.c[0];
+    p[2] = u.c[1];
+    p[1] = u.c[2];
+    p[0] = u.c[3];
+#else
+    *reinterpret_cast<int32*>(p) = x;
+#endif
+}
+
+
+static void FromUInt32( char *p, uint32 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint32 i;
+        char c[4];
+    } u;
+
+    u.i = x;
+
+    p[3] = u.c[0];
+    p[2] = u.c[1];
+    p[1] = u.c[2];
+    p[0] = u.c[3];
+#else
+    *reinterpret_cast<uint32*>(p) = x;
+#endif
+}
+
+
+static void FromInt64( char *p, int64 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int64 i;
+        char c[8];
+    } u;
+
+    u.i = x;
+
+    p[7] = u.c[0];
+    p[6] = u.c[1];
+    p[5] = u.c[2];
+    p[4] = u.c[3];
+    p[3] = u.c[4];
+    p[2] = u.c[5];
+    p[1] = u.c[6];
+    p[0] = u.c[7];
+#else
+    *reinterpret_cast<int64*>(p) = x;
+#endif
+}
+
+
+static void FromUInt64( char *p, uint64 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint64 i;
+        char c[8];
+    } u;
+
+    u.i = x;
+
+    p[7] = u.c[0];
+    p[6] = u.c[1];
+    p[5] = u.c[2];
+    p[4] = u.c[3];
+    p[3] = u.c[4];
+    p[2] = u.c[5];
+    p[1] = u.c[6];
+    p[0] = u.c[7];
+#else
+    *reinterpret_cast<uint64*>(p) = x;
+#endif
+}
+
+
+static inline long RoundUp4( long x )
+{
+    return ((x-1) & (~0x03L)) + 4;
+}
+
+
+OutboundPacketStream::OutboundPacketStream( char *buffer, unsigned long capacity )
+    : data_( buffer )
+    , end_( data_ + capacity )
+    , typeTagsCurrent_( end_ )
+    , messageCursor_( data_ )
+    , argumentCurrent_( data_ )
+    , elementSizePtr_( 0 )
+    , messageIsInProgress_( false )
+{
+
+}
+
+
+OutboundPacketStream::~OutboundPacketStream()
+{
+
+}
+
+
+char *OutboundPacketStream::BeginElement( char *beginPtr )
+{
+    if( elementSizePtr_ == 0 ){
+
+        elementSizePtr_ = reinterpret_cast<uint32*>(data_);
+
+        return beginPtr;
+
+    }else{
+        // store an offset to the old element size ptr in the element size slot
+        // we store an offset rather than the actual pointer to be 64 bit clean.
+        *reinterpret_cast<uint32*>(beginPtr) =
+                (uint32)(reinterpret_cast<char*>(elementSizePtr_) - data_);
+
+        elementSizePtr_ = reinterpret_cast<uint32*>(beginPtr);
+
+        return beginPtr + 4;
+    }
+}
+
+
+void OutboundPacketStream::EndElement( char *endPtr )
+{
+    assert( elementSizePtr_ != 0 );
+
+    if( elementSizePtr_ == reinterpret_cast<uint32*>(data_) ){
+
+        elementSizePtr_ = 0;
+
+    }else{
+        // while building an element, an offset to the containing element's
+        // size slot is stored in the elements size slot (or a ptr to data_
+        // if there is no containing element). We retrieve that here
+        uint32 *previousElementSizePtr =
+                (uint32*)(data_ + *reinterpret_cast<uint32*>(elementSizePtr_));
+
+        // then we store the element size in the slot, note that the element
+        // size does not include the size slot, hence the - 4 below.
+        uint32 elementSize =
+                (endPtr - reinterpret_cast<char*>(elementSizePtr_)) - 4;
+        FromUInt32( reinterpret_cast<char*>(elementSizePtr_), elementSize );
+
+        // finally, we reset the element size ptr to the containing element
+        elementSizePtr_ = previousElementSizePtr;
+    }
+}
+
+
+bool OutboundPacketStream::ElementSizeSlotRequired() const
+{
+    return (elementSizePtr_ != 0);
+}
+
+
+void OutboundPacketStream::CheckForAvailableBundleSpace()
+{
+    unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
+
+    if( required > Capacity() )
+        throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
+{
+    // plus 4 for at least four bytes of type tag
+     unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0)
+            + RoundUp4(strlen(addressPattern) + 1) + 4;
+
+    if( required > Capacity() )
+        throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )
+{
+    // plus three for extra type tag, comma and null terminator
+     unsigned long required = (argumentCurrent_ - data_) + argumentLength
+            + RoundUp4( (end_ - typeTagsCurrent_) + 3 );
+
+    if( required > Capacity() )
+        throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::Clear()
+{
+    typeTagsCurrent_ = end_;
+    messageCursor_ = data_;
+    argumentCurrent_ = data_;
+    elementSizePtr_ = 0;
+    messageIsInProgress_ = false;
+}
+
+
+unsigned int OutboundPacketStream::Capacity() const
+{
+    return end_ - data_;
+}
+
+
+unsigned int OutboundPacketStream::Size() const
+{
+    unsigned int result = argumentCurrent_ - data_;
+    if( IsMessageInProgress() ){
+        // account for the length of the type tag string. the total type tag
+        // includes an initial comma, plus at least one terminating \0
+        result += RoundUp4( (end_ - typeTagsCurrent_) + 2 );
+    }
+
+    return result;
+}
+
+
+const char *OutboundPacketStream::Data() const
+{
+    return data_;
+}
+
+
+bool OutboundPacketStream::IsReady() const
+{
+    return (!IsMessageInProgress() && !IsBundleInProgress());
+}
+
+
+bool OutboundPacketStream::IsMessageInProgress() const
+{
+    return messageIsInProgress_;
+}
+
+
+bool OutboundPacketStream::IsBundleInProgress() const
+{
+    return (elementSizePtr_ != 0);
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )
+{
+    if( IsMessageInProgress() )
+        throw MessageInProgressException();
+
+    CheckForAvailableBundleSpace();
+
+    messageCursor_ = BeginElement( messageCursor_ );
+
+    memcpy( messageCursor_, "#bundle\0", 8 );
+    FromUInt64( messageCursor_ + 8, rhs.timeTag );
+
+    messageCursor_ += 16;
+    argumentCurrent_ = messageCursor_;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator& rhs )
+{
+    (void) rhs;
+
+    if( !IsBundleInProgress() )
+        throw BundleNotInProgressException();
+    if( IsMessageInProgress() )
+        throw MessageInProgressException();
+
+    EndElement( messageCursor_ );
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )
+{
+    if( IsMessageInProgress() )
+        throw MessageInProgressException();
+
+    CheckForAvailableMessageSpace( rhs.addressPattern );
+
+    messageCursor_ = BeginElement( messageCursor_ );
+
+    strcpy( messageCursor_, rhs.addressPattern );
+    unsigned long rhsLength = strlen(rhs.addressPattern);
+    messageCursor_ += rhsLength + 1;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhsLength + 1;
+    while( i & 0x3 ){
+        *messageCursor_++ = '\0';
+        ++i;
+    }
+
+    argumentCurrent_ = messageCursor_;
+    typeTagsCurrent_ = end_;
+
+    messageIsInProgress_ = true;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs )
+{
+    (void) rhs;
+
+    if( !IsMessageInProgress() )
+        throw MessageNotInProgressException();
+
+    int typeTagsCount = end_ - typeTagsCurrent_;
+
+    if( typeTagsCount ){
+
+        char *tempTypeTags = (char*)alloca(typeTagsCount);
+        memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );
+
+        // slot size includes comma and null terminator
+        int typeTagSlotSize = RoundUp4( typeTagsCount + 2 );
+
+        uint32 argumentsSize = argumentCurrent_ - messageCursor_;
+
+        memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );
+
+        messageCursor_[0] = ',';
+        // copy type tags in reverse (really forward) order
+        for( int i=0; i < typeTagsCount; ++i )
+            messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ];
+
+        char *p = messageCursor_ + 1 + typeTagsCount;
+        for( int i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )
+            *p++ = '\0';
+
+        typeTagsCurrent_ = end_;
+
+        // advance messageCursor_ for next message
+        messageCursor_ += typeTagSlotSize + argumentsSize;
+
+    }else{
+        // send an empty type tags string
+        memcpy( messageCursor_, ",\0\0\0", 4 );
+
+        // advance messageCursor_ for next message
+        messageCursor_ += 4;
+    }
+
+    argumentCurrent_ = messageCursor_;
+
+    EndElement( messageCursor_ );
+
+    messageIsInProgress_ = false;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )
+{
+    CheckForAvailableArgumentSpace(0);
+
+    *(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG);
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )
+{
+    (void) rhs;
+    CheckForAvailableArgumentSpace(0);
+
+    *(--typeTagsCurrent_) = NIL_TYPE_TAG;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )
+{
+    (void) rhs;
+    CheckForAvailableArgumentSpace(0);
+
+    *(--typeTagsCurrent_) = INFINITUM_TYPE_TAG;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = INT32_TYPE_TAG;
+    FromInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = FLOAT_TYPE_TAG;
+
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        float f;
+        char c[4];
+    } u;
+
+    u.f = rhs;
+
+    argumentCurrent_[3] = u.c[0];
+    argumentCurrent_[2] = u.c[1];
+    argumentCurrent_[1] = u.c[2];
+    argumentCurrent_[0] = u.c[3];
+#else
+    *reinterpret_cast<float*>(argumentCurrent_) = rhs;
+#endif
+
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = CHAR_TYPE_TAG;
+    FromInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG;
+    FromUInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG;
+    FromUInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )
+{
+    CheckForAvailableArgumentSpace(8);
+
+    *(--typeTagsCurrent_) = INT64_TYPE_TAG;
+    FromInt64( argumentCurrent_, rhs );
+    argumentCurrent_ += 8;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )
+{
+    CheckForAvailableArgumentSpace(8);
+
+    *(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG;
+    FromUInt64( argumentCurrent_, rhs );
+    argumentCurrent_ += 8;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
+{
+    CheckForAvailableArgumentSpace(8);
+
+    *(--typeTagsCurrent_) = DOUBLE_TYPE_TAG;
+
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        double f;
+        char c[8];
+    } u;
+
+    u.f = rhs;
+
+    argumentCurrent_[7] = u.c[0];
+    argumentCurrent_[6] = u.c[1];
+    argumentCurrent_[5] = u.c[2];
+    argumentCurrent_[4] = u.c[3];
+    argumentCurrent_[3] = u.c[4];
+    argumentCurrent_[2] = u.c[5];
+    argumentCurrent_[1] = u.c[6];
+    argumentCurrent_[0] = u.c[7];
+#else
+    *reinterpret_cast<double*>(argumentCurrent_) = rhs;
+#endif
+
+    argumentCurrent_ += 8;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
+{
+    CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
+
+    *(--typeTagsCurrent_) = STRING_TYPE_TAG;
+    strcpy( argumentCurrent_, rhs );
+    unsigned long rhsLength = strlen(rhs);
+    argumentCurrent_ += rhsLength + 1;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhsLength + 1;
+    while( i & 0x3 ){
+        *argumentCurrent_++ = '\0';
+        ++i;
+    }
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
+{
+    CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
+
+    *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
+    strcpy( argumentCurrent_, rhs );
+    unsigned long rhsLength = strlen(rhs);
+    argumentCurrent_ += rhsLength + 1;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhsLength + 1;
+    while( i & 0x3 ){
+        *argumentCurrent_++ = '\0';
+        ++i;
+    }
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
+{
+    CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );
+
+    *(--typeTagsCurrent_) = BLOB_TYPE_TAG;
+    FromUInt32( argumentCurrent_, rhs.size );
+    argumentCurrent_ += 4;
+    
+    memcpy( argumentCurrent_, rhs.data, rhs.size );
+    argumentCurrent_ += rhs.size;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhs.size;
+    while( i & 0x3 ){
+        *argumentCurrent_++ = '\0';
+        ++i;
+    }
+
+    return *this;
+}
+
+} // namespace osc
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscOutboundPacketStream.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,142 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCOUTBOUNDPACKET_H
+#define INCLUDED_OSCOUTBOUNDPACKET_H
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+class OutOfBufferMemoryException : public Exception{
+public:
+    OutOfBufferMemoryException( const char *w="out of buffer memory" )
+        : Exception( w ) {}
+};
+
+class BundleNotInProgressException : public Exception{
+public:
+    BundleNotInProgressException(
+            const char *w="call to EndBundle when bundle is not in progress" )
+        : Exception( w ) {}
+};
+
+class MessageInProgressException : public Exception{
+public:
+    MessageInProgressException(
+            const char *w="opening or closing bundle or message while message is in progress" )
+        : Exception( w ) {}
+};
+
+class MessageNotInProgressException : public Exception{
+public:
+    MessageNotInProgressException(
+            const char *w="call to EndMessage when message is not in progress" )
+        : Exception( w ) {}
+};
+
+
+class OutboundPacketStream{
+public:
+	OutboundPacketStream( char *buffer, unsigned long capacity );
+	~OutboundPacketStream();
+
+    void Clear();
+
+    unsigned int Capacity() const;
+
+    // invariant: size() is valid even while building a message.
+    unsigned int Size() const;
+
+    const char *Data() const;
+
+    // indicates that all messages have been closed with a matching EndMessage
+    // and all bundles have been closed with a matching EndBundle
+    bool IsReady() const;
+
+    bool IsMessageInProgress() const;
+    bool IsBundleInProgress() const;
+
+    OutboundPacketStream& operator<<( const BundleInitiator& rhs );
+    OutboundPacketStream& operator<<( const BundleTerminator& rhs );
+    
+    OutboundPacketStream& operator<<( const BeginMessage& rhs );
+    OutboundPacketStream& operator<<( const MessageTerminator& rhs );
+
+    OutboundPacketStream& operator<<( bool rhs );
+    OutboundPacketStream& operator<<( const NilType& rhs );
+    OutboundPacketStream& operator<<( const InfinitumType& rhs );
+    OutboundPacketStream& operator<<( int32 rhs );
+
+#ifndef x86_64
+    OutboundPacketStream& operator<<( int rhs )
+            { *this << (int32)rhs; return *this; }
+#endif
+
+    OutboundPacketStream& operator<<( float rhs );
+    OutboundPacketStream& operator<<( char rhs );
+    OutboundPacketStream& operator<<( const RgbaColor& rhs );
+    OutboundPacketStream& operator<<( const MidiMessage& rhs );
+    OutboundPacketStream& operator<<( int64 rhs );
+    OutboundPacketStream& operator<<( const TimeTag& rhs );
+    OutboundPacketStream& operator<<( double rhs );
+    OutboundPacketStream& operator<<( const char* rhs );
+    OutboundPacketStream& operator<<( const Symbol& rhs );
+    OutboundPacketStream& operator<<( const Blob& rhs );
+
+private:
+
+    char *BeginElement( char *beginPtr );
+    void EndElement( char *endPtr );
+
+    bool ElementSizeSlotRequired() const;
+    void CheckForAvailableBundleSpace();
+    void CheckForAvailableMessageSpace( const char *addressPattern );
+    void CheckForAvailableArgumentSpace( long argumentLength );
+
+    char *data_;
+    char *end_;
+
+    char *typeTagsCurrent_; // stored in reverse order
+    char *messageCursor_;
+    char *argumentCurrent_;
+
+    // elementSizePtr_ has two special values: 0 indicates that a bundle
+    // isn't open, and elementSizePtr_==data_ indicates that a bundle is
+    // open but that it doesn't have a size slot (ie the outermost bundle)
+    uint32 *elementSizePtr_;
+
+    bool messageIsInProgress_;
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSC_OUTBOUND_PACKET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscPacketListener.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,72 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCPACKETLISTENER_H
+#define INCLUDED_OSCPACKETLISTENER_H
+
+#include "OscReceivedElements.h"
+#include "../ip/PacketListener.h"
+
+
+namespace osc{
+
+class OscPacketListener : public PacketListener{ 
+protected:
+    virtual void ProcessBundle( const osc::ReceivedBundle& b, 
+				const IpEndpointName& remoteEndpoint )
+    {
+        // ignore bundle time tag for now
+
+        for( ReceivedBundle::const_iterator i = b.ElementsBegin(); 
+				i != b.ElementsEnd(); ++i ){
+            if( i->IsBundle() )
+                ProcessBundle( ReceivedBundle(*i), remoteEndpoint );
+            else
+                ProcessMessage( ReceivedMessage(*i), remoteEndpoint );
+        }
+    }
+
+    virtual void ProcessMessage( const osc::ReceivedMessage& m, 
+				const IpEndpointName& remoteEndpoint ) = 0;
+    
+public:
+	virtual void ProcessPacket( const char *data, int size, 
+			const IpEndpointName& remoteEndpoint )
+    {
+        osc::ReceivedPacket p( data, size );
+        if( p.IsBundle() )
+            ProcessBundle( ReceivedBundle(p), remoteEndpoint );
+        else
+            ProcessMessage( ReceivedMessage(p), remoteEndpoint );
+    }
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCPACKETLISTENER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscPrintReceivedElements.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,240 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscPrintReceivedElements.h"
+
+#include <iostream>
+#include <iomanip>
+#include <ctime>
+
+
+namespace osc{
+
+
+std::ostream& operator<<( std::ostream & os,
+        const ReceivedMessageArgument& arg )
+{
+    switch( arg.TypeTag() ){
+        case TRUE_TYPE_TAG:
+            os << "bool:true";
+            break;
+                
+        case FALSE_TYPE_TAG:
+            os << "bool:false";
+            break;
+
+        case NIL_TYPE_TAG:
+            os << "(Nil)";
+            break;
+
+        case INFINITUM_TYPE_TAG:
+            os << "(Infinitum)";
+            break;
+
+        case INT32_TYPE_TAG:
+            os << "int32:" << arg.AsInt32Unchecked();
+            break;
+
+        case FLOAT_TYPE_TAG:
+            os << "float32:" << arg.AsFloatUnchecked();
+            break;
+
+        case CHAR_TYPE_TAG:
+            {
+                char s[2] = {0};
+                s[0] = arg.AsCharUnchecked();
+                os << "char:'" << s << "'";
+            }
+            break;
+
+        case RGBA_COLOR_TYPE_TAG:
+            {
+                uint32 color = arg.AsRgbaColorUnchecked();
+                
+                os << "RGBA:0x"
+                        << std::hex << std::setfill('0')
+                        << std::setw(2) << (int)((color>>24) & 0xFF)
+                        << std::setw(2) << (int)((color>>16) & 0xFF)
+                        << std::setw(2) << (int)((color>>8) & 0xFF)
+                        << std::setw(2) << (int)(color & 0xFF)
+                        << std::setfill(' ');
+                os.unsetf(std::ios::basefield);
+            }
+            break;
+
+        case MIDI_MESSAGE_TYPE_TAG:
+            {
+                uint32 m = arg.AsMidiMessageUnchecked();
+                os << "midi (port, status, data1, data2):<<"
+                        << std::hex << std::setfill('0')
+                        << "0x" << std::setw(2) << (int)((m>>24) & 0xFF)
+                        << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF)
+                        << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF)
+                        << " 0x" << std::setw(2) << (int)(m & 0xFF)
+                        << std::setfill(' ') << ">>";
+                os.unsetf(std::ios::basefield);
+            }
+            break;
+				
+        case INT64_TYPE_TAG:
+            os << "int64:" << arg.AsInt64Unchecked();
+            break;
+
+        case TIME_TAG_TYPE_TAG:
+            {
+                os << "OSC-timetag:" << arg.AsTimeTagUnchecked();
+
+                std::time_t t =
+                        (unsigned long)( arg.AsTimeTagUnchecked() >> 32 );
+
+                // strip trailing newline from string returned by ctime
+                const char *timeString = std::ctime( &t );
+                size_t len = strlen( timeString );
+                char *s = new char[ len + 1 ];
+                strcpy( s, timeString );
+                if( len )
+                    s[ len - 1 ] = '\0';
+                    
+                os << " " << s;
+            }
+            break;
+                
+        case DOUBLE_TYPE_TAG:
+            os << "double:" << arg.AsDoubleUnchecked();
+            break;
+
+        case STRING_TYPE_TAG:
+            os << "OSC-string:`" << arg.AsStringUnchecked() << "'";
+            break;
+                
+        case SYMBOL_TYPE_TAG: 
+            os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'";
+            break;
+
+        case BLOB_TYPE_TAG:
+            {
+                unsigned long size;
+                const void *data;
+                arg.AsBlobUnchecked( data, size );
+                os << "OSC-blob:<<" << std::hex << std::setfill('0');
+                unsigned char *p = (unsigned char*)data;
+                for( unsigned long i = 0; i < size; ++i ){
+                    os << "0x" << std::setw(2) << int(p[i]);
+                    if( i != size-1 )
+                        os << ' ';
+                }
+                os.unsetf(std::ios::basefield);
+                os << ">>" << std::setfill(' ');
+            }
+            break;
+
+        default:
+            os << "unknown";
+    }
+
+    return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )
+{
+
+    os << "[" << m.AddressPattern();
+    bool first = true;
+
+    for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
+            i != m.ArgumentsEnd(); ++i ){
+        if( first ){
+            os << " ";
+            first = false;
+        }else{
+            os << ", ";
+        }
+
+        os << *i;
+    }
+
+    os << "]";
+
+    return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )
+{
+    static int indent = 0;
+
+    for( int j=0; j < indent; ++j )
+        os << "  ";
+    os << "{ ( ";
+    if( b.TimeTag() == 1 )
+        os << "immediate";
+    else
+        os << b.TimeTag();
+    os << " )\n";
+
+    ++indent;
+    
+    for( ReceivedBundle::const_iterator i = b.ElementsBegin();
+            i != b.ElementsEnd(); ++i ){
+        if( i->IsBundle() ){
+            ReceivedBundle b(*i);
+            os << b << "\n";
+        }else{
+            ReceivedMessage m(*i);
+            for( int j=0; j < indent; ++j )
+                os << "  ";
+            os << m << "\n";
+        }
+    }
+
+    --indent;
+
+    for( int j=0; j < indent; ++j )
+        os << "  ";
+    os << "}";
+
+    return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )
+{
+    if( p.IsBundle() ){
+        ReceivedBundle b(p);
+        os << b << "\n";
+    }else{
+        ReceivedMessage m(p);
+        os << m << "\n";
+    }
+
+    return os;
+}
+
+} // namespace osc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscPrintReceivedElements.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,49 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
+#define INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
+
+#include <iosfwd>
+
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#include "OscReceivedElements.h"
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
+
+
+namespace osc{
+
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p );
+std::ostream& operator<<( std::ostream & os, const ReceivedMessageArgument& arg );
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m );
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b );
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCPRINTRECEIVEDELEMENTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscReceivedElements.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,722 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscReceivedElements.h"
+
+#include <cassert>
+
+#include "OscHostEndianness.h"
+
+
+namespace osc{
+
+
+// return the first 4 byte boundary after the end of a str4
+// be careful about calling this version if you don't know whether
+// the string is terminated correctly.
+static inline const char* FindStr4End( const char *p )
+{
+	if( p[0] == '\0' )    // special case for SuperCollider integer address pattern
+		return p + 4;
+
+    p += 3;
+
+    while( *p )
+        p += 4;
+
+    return p + 1;
+}
+
+
+// return the first 4 byte boundary after the end of a str4
+// returns 0 if p == end or if the string is unterminated
+static inline const char* FindStr4End( const char *p, const char *end )
+{
+    if( p >= end )
+        return 0;
+
+	if( p[0] == '\0' )    // special case for SuperCollider integer address pattern
+		return p + 4;
+
+    p += 3;
+    end -= 1;
+
+    while( p < end && *p )
+        p += 4;
+
+    if( *p )
+        return 0;
+    else
+        return p + 1;
+}
+
+
+static inline unsigned long RoundUp4( unsigned long x )
+{
+    unsigned long remainder = x & 0x3UL;
+    if( remainder )
+        return x + (4 - remainder);
+    else
+        return x;
+}
+
+
+static inline int32 ToInt32( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int32 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[3];
+    u.c[1] = p[2];
+    u.c[2] = p[1];
+    u.c[3] = p[0];
+
+    return u.i;
+#else
+	return *(int32*)p;
+#endif
+}
+
+
+static inline uint32 ToUInt32( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint32 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[3];
+    u.c[1] = p[2];
+    u.c[2] = p[1];
+    u.c[3] = p[0];
+
+    return u.i;
+#else
+	return *(uint32*)p;
+#endif
+}
+
+
+int64 ToInt64( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int64 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[7];
+    u.c[1] = p[6];
+    u.c[2] = p[5];
+    u.c[3] = p[4];
+    u.c[4] = p[3];
+    u.c[5] = p[2];
+    u.c[6] = p[1];
+    u.c[7] = p[0];
+
+    return u.i;
+#else
+	return *(int64*)p;
+#endif
+}
+
+
+uint64 ToUInt64( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint64 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[7];
+    u.c[1] = p[6];
+    u.c[2] = p[5];
+    u.c[3] = p[4];
+    u.c[4] = p[3];
+    u.c[5] = p[2];
+    u.c[6] = p[1];
+    u.c[7] = p[0];
+
+    return u.i;
+#else
+	return *(uint64*)p;
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedPacket::IsBundle() const
+{
+    return (Size() > 0 && Contents()[0] == '#');
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedBundleElement::IsBundle() const
+{
+    return (Size() > 0 && Contents()[0] == '#');
+}
+
+
+int32 ReceivedBundleElement::Size() const
+{
+    return ToUInt32( size_ );
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedMessageArgument::AsBool() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == TRUE_TYPE_TAG )
+		return true;
+	else if( *typeTag_ == FALSE_TYPE_TAG )
+		return false;
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+bool ReceivedMessageArgument::AsBoolUnchecked() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == TRUE_TYPE_TAG )
+		return true;
+    else
+	    return false;
+}
+
+
+int32 ReceivedMessageArgument::AsInt32() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == INT32_TYPE_TAG )
+		return AsInt32Unchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+int32 ReceivedMessageArgument::AsInt32Unchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int32 i;
+        char c[4];
+    } u;
+
+    u.c[0] = argument_[3];
+    u.c[1] = argument_[2];
+    u.c[2] = argument_[1];
+    u.c[3] = argument_[0];
+
+    return u.i;
+#else
+	return *(int32*)argument_;
+#endif
+}
+
+
+float ReceivedMessageArgument::AsFloat() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == FLOAT_TYPE_TAG )
+		return AsFloatUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+float ReceivedMessageArgument::AsFloatUnchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        float f;
+        char c[4];
+    } u;
+
+    u.c[0] = argument_[3];
+    u.c[1] = argument_[2];
+    u.c[2] = argument_[1];
+    u.c[3] = argument_[0];
+
+    return u.f;
+#else
+	return *(float*)argument_;
+#endif
+}
+
+
+char ReceivedMessageArgument::AsChar() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == CHAR_TYPE_TAG )
+		return AsCharUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+char ReceivedMessageArgument::AsCharUnchecked() const
+{
+    return (char)ToInt32( argument_ );
+}
+
+
+uint32 ReceivedMessageArgument::AsRgbaColor() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == RGBA_COLOR_TYPE_TAG )
+		return AsRgbaColorUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const
+{
+	return ToUInt32( argument_ );
+}
+
+
+uint32 ReceivedMessageArgument::AsMidiMessage() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == MIDI_MESSAGE_TYPE_TAG )
+		return AsMidiMessageUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const
+{
+	return ToUInt32( argument_ );
+}
+
+
+int64 ReceivedMessageArgument::AsInt64() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == INT64_TYPE_TAG )
+		return AsInt64Unchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+int64 ReceivedMessageArgument::AsInt64Unchecked() const
+{
+    return ToInt64( argument_ );
+}
+
+
+uint64 ReceivedMessageArgument::AsTimeTag() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == TIME_TAG_TYPE_TAG )
+		return AsTimeTagUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const
+{
+    return ToUInt64( argument_ );
+}
+
+
+double ReceivedMessageArgument::AsDouble() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == DOUBLE_TYPE_TAG )
+		return AsDoubleUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+double ReceivedMessageArgument::AsDoubleUnchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        double d;
+        char c[8];
+    } u;
+
+    u.c[0] = argument_[7];
+    u.c[1] = argument_[6];
+    u.c[2] = argument_[5];
+    u.c[3] = argument_[4];
+    u.c[4] = argument_[3];
+    u.c[5] = argument_[2];
+    u.c[6] = argument_[1];
+    u.c[7] = argument_[0];
+
+    return u.d;
+#else
+	return *(double*)argument_;
+#endif
+}
+
+
+const char* ReceivedMessageArgument::AsString() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == STRING_TYPE_TAG )
+		return argument_;
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+const char* ReceivedMessageArgument::AsSymbol() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == SYMBOL_TYPE_TAG )
+		return argument_;
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+void ReceivedMessageArgument::AsBlob( const void*& data, unsigned long& size ) const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == BLOB_TYPE_TAG )
+		AsBlobUnchecked( data, size );
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, unsigned long& size ) const
+{
+    size = ToUInt32( argument_ );
+	data = (void*)(argument_+4);
+}
+
+//------------------------------------------------------------------------------
+
+void ReceivedMessageArgumentIterator::Advance()
+{
+    if( !value_.typeTag_ )
+        return;
+        
+    switch( *value_.typeTag_++ ){
+        case '\0':
+            // don't advance past end
+            --value_.typeTag_;
+            break;
+            
+        case TRUE_TYPE_TAG:
+        case FALSE_TYPE_TAG:
+        case NIL_TYPE_TAG:
+        case INFINITUM_TYPE_TAG:
+
+            // zero length
+            break;
+
+        case INT32_TYPE_TAG:
+        case FLOAT_TYPE_TAG: 					
+        case CHAR_TYPE_TAG:
+        case RGBA_COLOR_TYPE_TAG:
+        case MIDI_MESSAGE_TYPE_TAG:
+
+            value_.argument_ += 4;
+            break;
+
+        case INT64_TYPE_TAG:
+        case TIME_TAG_TYPE_TAG:
+        case DOUBLE_TYPE_TAG:
+				
+            value_.argument_ += 8;
+            break;
+
+        case STRING_TYPE_TAG: 
+        case SYMBOL_TYPE_TAG:
+
+            // we use the unsafe function FindStr4End(char*) here because all of
+            // the arguments have already been validated in
+            // ReceivedMessage::Init() below.
+            
+            value_.argument_ = FindStr4End( value_.argument_ );
+            break;
+
+        case BLOB_TYPE_TAG:
+            {
+                uint32 blobSize = ToUInt32( value_.argument_ );
+                value_.argument_ = value_.argument_ + 4 + RoundUp4( blobSize );
+            }
+            break;
+
+        default:    // unknown type tag
+            // don't advance
+            --value_.typeTag_;
+            break;
+            
+
+        //    not handled:
+        //    [ Indicates the beginning of an array. The tags following are for
+        //        data in the Array until a close brace tag is reached.
+        //    ] Indicates the end of an array.
+    }
+}
+
+//------------------------------------------------------------------------------
+
+ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )
+    : addressPattern_( packet.Contents() )
+{
+    Init( packet.Contents(), packet.Size() );
+}
+
+
+ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )
+    : addressPattern_( bundleElement.Contents() )
+{
+    Init( bundleElement.Contents(), bundleElement.Size() );
+}
+
+
+bool ReceivedMessage::AddressPatternIsUInt32() const
+{
+	return (addressPattern_[0] == '\0');
+}
+
+
+uint32 ReceivedMessage::AddressPatternAsUInt32() const
+{
+    return ToUInt32( addressPattern_ );
+}
+
+
+void ReceivedMessage::Init( const char *message, unsigned long size )
+{
+    if( size == 0 )
+        throw MalformedMessageException( "zero length messages not permitted" );
+
+    if( (size & 0x03L) != 0 )
+        throw MalformedMessageException( "message size must be multiple of four" );
+
+    const char *end = message + size;
+
+    typeTagsBegin_ = FindStr4End( addressPattern_, end );
+    if( typeTagsBegin_ == 0 ){
+        // address pattern was not terminated before end
+        throw MalformedMessageException( "unterminated address pattern" );
+    }
+
+    if( typeTagsBegin_ == end ){
+        // message consists of only the address pattern - no arguments or type tags.
+        typeTagsBegin_ = 0;
+        typeTagsEnd_ = 0;
+        arguments_ = 0;
+            
+    }else{
+        if( *typeTagsBegin_ != ',' )
+            throw MalformedMessageException( "type tags not present" );
+
+        if( *(typeTagsBegin_ + 1) == '\0' ){
+            // zero length type tags
+            typeTagsBegin_ = 0;
+            typeTagsEnd_ = 0;
+            arguments_ = 0;
+
+        }else{
+            // check that all arguments are present and well formed
+                
+            arguments_ = FindStr4End( typeTagsBegin_, end );
+            if( arguments_ == 0 ){
+                throw MalformedMessageException( "type tags were not terminated before end of message" );
+            }
+
+            ++typeTagsBegin_; // advance past initial ','
+            
+            const char *typeTag = typeTagsBegin_;
+            const char *argument = arguments_;
+                        
+            do{
+                switch( *typeTag ){
+                    case TRUE_TYPE_TAG:
+                    case FALSE_TYPE_TAG:
+                    case NIL_TYPE_TAG:
+                    case INFINITUM_TYPE_TAG:
+
+                        // zero length
+                        break;
+
+                    case INT32_TYPE_TAG:
+                    case FLOAT_TYPE_TAG:
+                    case CHAR_TYPE_TAG:
+                    case RGBA_COLOR_TYPE_TAG:
+                    case MIDI_MESSAGE_TYPE_TAG:
+
+                        if( argument == end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        argument += 4;
+                        if( argument > end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        break;
+
+                    case INT64_TYPE_TAG:
+                    case TIME_TAG_TYPE_TAG:
+                    case DOUBLE_TYPE_TAG:
+
+                        if( argument == end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        argument += 8;
+                        if( argument > end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        break;
+
+                    case STRING_TYPE_TAG: 
+                    case SYMBOL_TYPE_TAG:
+                    
+                        if( argument == end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        argument = FindStr4End( argument, end );
+                        if( argument == 0 )
+                            throw MalformedMessageException( "unterminated string argument" );
+                        break;
+
+                    case BLOB_TYPE_TAG:
+                        {
+                            if( argument + 4 > end )
+                                MalformedMessageException( "arguments exceed message size" );
+                                
+                            uint32 blobSize = ToUInt32( argument );
+                            argument = argument + 4 + RoundUp4( blobSize );
+                            if( argument > end )
+                                MalformedMessageException( "arguments exceed message size" );
+                        }
+                        break;
+                        
+                    default:
+                        throw MalformedMessageException( "unknown type tag" );
+
+                    //    not handled:
+                    //    [ Indicates the beginning of an array. The tags following are for
+                    //        data in the Array until a close brace tag is reached.
+                    //    ] Indicates the end of an array.
+                }
+
+            }while( *++typeTag != '\0' );
+            typeTagsEnd_ = typeTag;
+        }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )
+    : elementCount_( 0 )
+{
+    Init( packet.Contents(), packet.Size() );
+}
+
+
+ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )
+    : elementCount_( 0 )
+{
+    Init( bundleElement.Contents(), bundleElement.Size() );
+}
+
+
+void ReceivedBundle::Init( const char *bundle, unsigned long size )
+{
+    if( size < 16 )
+        throw MalformedBundleException( "packet too short for bundle" );
+
+    if( (size & 0x03L) != 0 )
+        throw MalformedBundleException( "bundle size must be multiple of four" );
+
+    if( bundle[0] != '#'
+        || bundle[1] != 'b'
+        || bundle[2] != 'u'
+        || bundle[3] != 'n'
+        || bundle[4] != 'd'
+        || bundle[5] != 'l'
+        || bundle[6] != 'e'
+        || bundle[7] != '\0' )
+            throw MalformedBundleException( "bad bundle address pattern" );    
+
+    end_ = bundle + size;
+
+    timeTag_ = bundle + 8;
+
+    const char *p = timeTag_ + 8;
+        
+    while( p < end_ ){
+        if( p + 4 > end_ )
+            throw MalformedBundleException( "packet too short for elementSize" );
+
+        uint32 elementSize = ToUInt32( p );
+        if( (elementSize & 0x03L) != 0 )
+            throw MalformedBundleException( "bundle element size must be multiple of four" );
+
+        p += 4 + elementSize;
+        if( p > end_ )
+            throw MalformedBundleException( "packet too short for bundle element" );
+
+        ++elementCount_;
+    }
+
+    if( p != end_ )
+        throw MalformedBundleException( "bundle contents " );
+}
+
+
+uint64 ReceivedBundle::TimeTag() const
+{
+    return ToUInt64( timeTag_ );
+}
+
+
+} // namespace osc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscReceivedElements.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,486 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#define INCLUDED_OSCRECEIVEDELEMENTS_H
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+
+class MalformedMessageException : public Exception{
+public:
+    MalformedMessageException( const char *w="malformed message" )
+        : Exception( w ) {}
+};
+
+class MalformedBundleException : public Exception{
+public:
+    MalformedBundleException( const char *w="malformed bundle" )
+        : Exception( w ) {}
+};
+
+class WrongArgumentTypeException : public Exception{
+public:
+    WrongArgumentTypeException( const char *w="wrong argument type" )
+        : Exception( w ) {}
+};
+
+class MissingArgumentException : public Exception{
+public:
+    MissingArgumentException( const char *w="missing argument" )
+        : Exception( w ) {}
+};
+
+class ExcessArgumentException : public Exception{
+public:
+    ExcessArgumentException( const char *w="too many arguments" )
+        : Exception( w ) {}
+};
+
+
+class ReceivedPacket{
+public:
+    ReceivedPacket( const char *contents, int32 size )
+        : contents_( contents )
+        , size_( size ) {}
+
+    bool IsMessage() const { return !IsBundle(); }
+    bool IsBundle() const;
+
+    int32 Size() const { return size_; }
+    const char *Contents() const { return contents_; }
+
+private:
+    const char *contents_;
+    int32 size_;
+};
+
+
+class ReceivedBundleElement{
+public:
+    ReceivedBundleElement( const char *size )
+        : size_( size ) {}
+
+    friend class ReceivedBundleElementIterator;
+
+    bool IsMessage() const { return !IsBundle(); }
+    bool IsBundle() const;
+
+    int32 Size() const;
+    const char *Contents() const { return size_ + 4; }
+
+private:
+    const char *size_;
+};
+
+
+class ReceivedBundleElementIterator{
+public:
+	ReceivedBundleElementIterator( const char *sizePtr )
+        : value_( sizePtr ) {}
+
+	ReceivedBundleElementIterator operator++()
+	{
+        Advance();
+        return *this;
+	}
+
+    ReceivedBundleElementIterator operator++(int)
+    {
+        ReceivedBundleElementIterator old( *this );
+        Advance();
+        return old;
+    }
+
+	const ReceivedBundleElement& operator*() const { return value_; }
+
+    const ReceivedBundleElement* operator->() const { return &value_; }
+
+	friend bool operator==(const ReceivedBundleElementIterator& lhs,
+            const ReceivedBundleElementIterator& rhs );
+
+private:
+	ReceivedBundleElement value_;
+
+	void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
+
+    bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
+    {
+        return value_.size_ == rhs.value_.size_;
+    }
+};
+
+inline bool operator==(const ReceivedBundleElementIterator& lhs,
+        const ReceivedBundleElementIterator& rhs )
+{	
+	return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedBundleElementIterator& lhs,
+        const ReceivedBundleElementIterator& rhs )
+{
+	return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgument{
+public:
+	ReceivedMessageArgument( const char *typeTag, const char *argument )
+		: typeTag_( typeTag )
+		, argument_( argument ) {}
+
+    friend class ReceivedMessageArgumentIterator;
+    
+	const char TypeTag() const { return *typeTag_; }
+
+    // the unchecked methods below don't check whether the argument actually
+    // is of the specified type. they should only be used if you've already
+    // checked the type tag or the associated IsType() method.
+
+    bool IsBool() const
+        { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
+    bool AsBool() const;
+    bool AsBoolUnchecked() const;
+
+    bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
+    bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
+
+    bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
+    int32 AsInt32() const;
+    int32 AsInt32Unchecked() const;
+
+    bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
+    float AsFloat() const;
+    float AsFloatUnchecked() const;
+
+    bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
+    char AsChar() const;
+    char AsCharUnchecked() const;
+
+    bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
+    uint32 AsRgbaColor() const;
+    uint32 AsRgbaColorUnchecked() const;
+
+    bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
+    uint32 AsMidiMessage() const;
+    uint32 AsMidiMessageUnchecked() const;
+
+    bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
+    int64 AsInt64() const;
+    int64 AsInt64Unchecked() const;
+
+    bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
+    uint64 AsTimeTag() const;
+    uint64 AsTimeTagUnchecked() const;
+
+    bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
+    double AsDouble() const;
+    double AsDoubleUnchecked() const;
+
+    bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
+    const char* AsString() const;
+    const char* AsStringUnchecked() const { return argument_; }
+
+    bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
+    const char* AsSymbol() const;
+    const char* AsSymbolUnchecked() const { return argument_; }
+
+    bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
+    void AsBlob( const void*& data, unsigned long& size ) const;
+    void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
+    
+private:
+	const char *typeTag_;
+	const char *argument_;
+};
+
+
+class ReceivedMessageArgumentIterator{
+public:
+	ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
+        : value_( typeTags, arguments ) {}
+
+	ReceivedMessageArgumentIterator operator++()
+	{
+        Advance();
+        return *this;
+	}
+
+    ReceivedMessageArgumentIterator operator++(int)
+    {
+        ReceivedMessageArgumentIterator old( *this );
+        Advance();
+        return old;
+    }
+
+	const ReceivedMessageArgument& operator*() const { return value_; }
+
+    const ReceivedMessageArgument* operator->() const { return &value_; }
+
+	friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
+            const ReceivedMessageArgumentIterator& rhs );
+
+private:
+	ReceivedMessageArgument value_;
+
+	void Advance();
+
+    bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
+    {
+        return value_.typeTag_ == rhs.value_.typeTag_;
+    }
+};
+
+inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
+        const ReceivedMessageArgumentIterator& rhs )
+{	
+	return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
+        const ReceivedMessageArgumentIterator& rhs )
+{	
+	return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgumentStream{
+    friend class ReceivedMessage;
+    ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
+            const ReceivedMessageArgumentIterator& end )
+        : p_( begin )
+        , end_( end ) {}
+
+    ReceivedMessageArgumentIterator p_, end_;
+    
+public:
+
+    // end of stream
+    bool Eos() const { return p_ == end_; }
+
+    ReceivedMessageArgumentStream& operator>>( bool& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsBool();
+        return *this;
+    }
+
+    // not sure if it would be useful to stream Nil and Infinitum
+    // for now it's not possible
+
+    ReceivedMessageArgumentStream& operator>>( int32& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsInt32();
+        return *this;
+    }     
+
+    ReceivedMessageArgumentStream& operator>>( float& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsFloat();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( char& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsChar();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsRgbaColor();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsMidiMessage();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( int64& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsInt64();
+        return *this;
+    }
+    
+    ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsTimeTag();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( double& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsDouble();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( Blob& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        (*p_++).AsBlob( rhs.data, rhs.size );
+        return *this;
+    }
+    
+    ReceivedMessageArgumentStream& operator>>( const char*& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsString();
+        return *this;
+    }
+    
+    ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsSymbol();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
+    {
+        if( !Eos() )
+            throw ExcessArgumentException();
+
+        return *this;
+    }
+};
+
+
+class ReceivedMessage{
+    void Init( const char *bundle, unsigned long size );
+public:
+    explicit ReceivedMessage( const ReceivedPacket& packet );
+    explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
+
+	const char *AddressPattern() const { return addressPattern_; }
+
+	// Support for non-standad SuperCollider integer address patterns:
+	bool AddressPatternIsUInt32() const;
+	uint32 AddressPatternAsUInt32() const;
+
+	unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
+
+    const char *TypeTags() const { return typeTagsBegin_; }
+
+
+    typedef ReceivedMessageArgumentIterator const_iterator;
+    
+	ReceivedMessageArgumentIterator ArgumentsBegin() const
+    {
+        return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
+    }
+     
+	ReceivedMessageArgumentIterator ArgumentsEnd() const
+    {
+        return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
+    }
+
+    ReceivedMessageArgumentStream ArgumentStream() const
+    {
+        return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
+    }
+
+private:
+	const char *addressPattern_;
+	const char *typeTagsBegin_;
+	const char *typeTagsEnd_;
+    const char *arguments_;
+};
+
+
+class ReceivedBundle{
+    void Init( const char *message, unsigned long size );
+public:
+    explicit ReceivedBundle( const ReceivedPacket& packet );
+    explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
+
+    uint64 TimeTag() const;
+
+    unsigned long ElementCount() const { return elementCount_; }
+
+    typedef ReceivedBundleElementIterator const_iterator;
+    
+	ReceivedBundleElementIterator ElementsBegin() const
+    {
+        return ReceivedBundleElementIterator( timeTag_ + 8 );
+    }
+     
+	ReceivedBundleElementIterator ElementsEnd() const
+    {
+        return ReceivedBundleElementIterator( end_ );
+    }
+
+private:
+    const char *timeTag_;
+    const char *end_;
+    unsigned long elementCount_;
+};
+
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscTypes.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,40 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscTypes.h"
+
+namespace osc{
+
+BundleInitiator BeginBundleImmediate(1);
+BundleTerminator EndBundle;
+MessageTerminator EndMessage;
+NilType Nil;
+InfinitumType Infinitum;
+
+} // namespace osc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/osc/OscTypes.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,178 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCTYPES_H
+#define INCLUDED_OSCTYPES_H
+
+
+namespace osc{
+
+// basic types
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+
+#else
+
+typedef long long int64;
+typedef unsigned long long uint64;
+
+#endif
+
+
+
+#ifdef x86_64
+
+typedef signed int int32;
+typedef unsigned int uint32;
+
+#else
+
+typedef signed long int32;
+typedef unsigned long uint32;
+
+#endif
+
+
+
+enum TypeTagValues {
+    TRUE_TYPE_TAG = 'T',
+    FALSE_TYPE_TAG = 'F',
+    NIL_TYPE_TAG = 'N',
+    INFINITUM_TYPE_TAG = 'I',
+    INT32_TYPE_TAG = 'i',
+    FLOAT_TYPE_TAG = 'f',
+    CHAR_TYPE_TAG = 'c',
+    RGBA_COLOR_TYPE_TAG = 'r',
+    MIDI_MESSAGE_TYPE_TAG = 'm',
+    INT64_TYPE_TAG = 'h',
+    TIME_TAG_TYPE_TAG = 't',
+    DOUBLE_TYPE_TAG = 'd',
+    STRING_TYPE_TAG = 's',
+    SYMBOL_TYPE_TAG = 'S',
+    BLOB_TYPE_TAG = 'b'
+};
+
+
+
+// i/o manipulators used for streaming interfaces
+
+struct BundleInitiator{
+    explicit BundleInitiator( uint64 timeTag_ ) : timeTag( timeTag_ ) {}
+    uint64 timeTag;
+};
+
+extern BundleInitiator BeginBundleImmediate;
+
+inline BundleInitiator BeginBundle( uint64 timeTag=1 )
+{
+    return BundleInitiator(timeTag);
+}
+
+
+struct BundleTerminator{
+};
+
+extern BundleTerminator EndBundle;
+
+struct BeginMessage{
+    explicit BeginMessage( const char *addressPattern_ ) : addressPattern( addressPattern_ ) {}
+    const char *addressPattern;
+};
+
+struct MessageTerminator{
+};
+
+extern MessageTerminator EndMessage;
+
+
+// osc specific types. they are defined as structs so they can be used
+// as separately identifiable types with the streaming operators.
+
+struct NilType{
+};
+
+extern NilType Nil;
+
+
+struct InfinitumType{
+};
+
+extern InfinitumType Infinitum;
+
+struct RgbaColor{
+    RgbaColor() {}
+    explicit RgbaColor( uint32 value_ ) : value( value_ ) {}
+    uint32 value;
+
+    operator uint32() const { return value; }
+};
+
+
+struct MidiMessage{
+    MidiMessage() {}
+    explicit MidiMessage( uint32 value_ ) : value( value_ ) {}
+    uint32 value;
+
+    operator uint32() const { return value; }
+};
+
+
+struct TimeTag{
+    TimeTag() {}
+    explicit TimeTag( uint64 value_ ) : value( value_ ) {}
+    uint64 value;
+
+    operator uint64() const { return value; }
+};
+
+
+struct Symbol{
+    Symbol() {}
+    explicit Symbol( const char* value_ ) : value( value_ ) {}
+    const char* value;
+
+    operator const char *() const { return value; }
+};
+
+
+struct Blob{
+    Blob() {}
+    explicit Blob( const void* data_, unsigned long size_ )
+            : data( data_ ), size( size_ ) {}
+    const void* data;
+    unsigned long size;
+};
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCTYPES_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/tests/OscReceiveTest.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,261 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscReceiveTest.h"
+
+#include <string.h>
+#include <iostream>
+
+#include "osc/OscReceivedElements.h"
+
+#include "ip/UdpSocket.h"
+#include "osc/OscPacketListener.h"
+
+
+namespace osc{
+
+class OscReceiveTestPacketListener : public OscPacketListener{
+protected:
+
+    void ProcessMessage( const osc::ReceivedMessage& m, const IpEndpointName& remoteEndpoint )
+    {
+        // a more complex scheme involving std::map or some other method of
+        // processing address patterns could be used here 
+		// (see MessageMappingOscPacketListener.h for example). however, the main
+        // purpose of this example is to illustrate and test different argument
+        // parsing methods
+
+        try {
+            // argument stream, and argument iterator, used in different
+            // examples below.
+            ReceivedMessageArgumentStream args = m.ArgumentStream();
+            ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
+            
+            if( strcmp( m.AddressPattern(), "/test1" ) == 0 ){
+
+                // example #1:
+                // parse an expected format using the argument stream interface:
+                bool a1;
+                osc::int32 a2;
+                float a3;
+                const char *a4;
+                args >> a1 >> a2 >> a3 >> a4 >> osc::EndMessage;
+
+                std::cout << "received '/test1' message with arguments: "
+                        << a1 << " " << a2 << " " << a3 << " " << a4 << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/test2" ) == 0 ){
+
+                // example #2:
+                // parse an expected format using the argument iterator interface
+                // this is a more complicated example of doing the same thing
+                // as above.
+                bool a1 = (arg++)->AsBool();
+                int a2 = (arg++)->AsInt32();
+                float a3 = (arg++)->AsFloat();
+                const char *a4 = (arg++)->AsString();
+                if( arg != m.ArgumentsEnd() )
+                    throw ExcessArgumentException();
+
+                std::cout << "received '/test2' message with arguments: "
+                         << a1 << " " << a2 << " " << a3 << " " << a4 << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/test3" ) == 0 ){
+
+                // example #3:
+                // parse a variable argument format using the argument iterator
+                // interface. this is where it is necessary to use
+                // argument iterators instead of streams.
+                // When messages may contain arguments of varying type, you can
+                // use the argument iterator interface to query the types at
+                // runtime. this is more flexible that the argument stream
+                // interface, which requires each argument to have a fixed type
+                
+                if( arg->IsBool() ){
+                    bool a = (arg++)->AsBoolUnchecked();
+                    std::cout << "received '/test3' message with bool argument: "
+                        << a << "\n";
+                }else if( arg->IsInt32() ){
+                    int a = (arg++)->AsInt32Unchecked();
+                    std::cout << "received '/test3' message with int32 argument: "
+                        << a << "\n";
+                }else if( arg->IsFloat() ){
+                    float a = (arg++)->AsFloatUnchecked();
+                    std::cout << "received '/test3' message with float argument: "
+                        << a << "\n";
+                }else if( arg->IsString() ){
+                    const char *a = (arg++)->AsStringUnchecked();
+                    std::cout << "received '/test3' message with string argument: '"
+                        << a << "'\n";
+                }else{
+                    std::cout << "received '/test3' message with unexpected argument type\n";
+                }
+                
+                if( arg != m.ArgumentsEnd() )
+                    throw ExcessArgumentException();
+
+                    
+            }else if( strcmp( m.AddressPattern(), "/no_arguments" ) == 0 ){
+
+                args >> osc::EndMessage;
+                std::cout << "received '/no_arguments' message\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_bool" ) == 0 ){
+
+                bool a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_bool' message: " << a << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/nil" ) == 0 ){
+
+                std::cout << "received '/nil' message\n";
+
+            }else if( strcmp( m.AddressPattern(), "/inf" ) == 0 ){
+
+                std::cout << "received '/inf' message\n";
+
+            }else if( strcmp( m.AddressPattern(), "/an_int" ) == 0 ){
+
+                osc::int32 a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/an_int' message: " << a << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_float" ) == 0 ){
+
+                float a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_float' message: " << a << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_char" ) == 0 ){
+
+                char a;
+                args >> a >> osc::EndMessage;
+                char s[2] = {0};
+                s[0] = a;
+                std::cout << "received '/a_char' message: '" << s << "'\n";
+
+            }else if( strcmp( m.AddressPattern(), "/an_rgba_color" ) == 0 ){
+
+                osc::RgbaColor a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/an_rgba_color' message: " << a.value << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_midi_message" ) == 0 ){
+
+                osc::MidiMessage a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_midi_message' message: " << a.value << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/an_int64" ) == 0 ){
+
+                osc::int64 a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/an_int64' message: " << a << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_time_tag" ) == 0 ){
+
+                osc::TimeTag a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_time_tag' message: " << a.value << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_double" ) == 0 ){
+
+                double a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_double' message: " << a << "\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_string" ) == 0 ){
+
+                const char *a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_string' message: '" << a << "'\n";
+
+            }else if( strcmp( m.AddressPattern(), "/a_symbol" ) == 0 ){
+
+                osc::Symbol a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_symbol' message: '" << a.value << "'\n";
+
+             }else if( strcmp( m.AddressPattern(), "/a_blob" ) == 0 ){
+
+                osc::Blob a;
+                args >> a >> osc::EndMessage;
+                std::cout << "received '/a_blob' message\n";
+
+            }else{
+                std::cout << "unrecognised address pattern: "
+                        << m.AddressPattern() << "\n";
+            }
+
+        }catch( Exception& e ){
+            std::cout << "error while parsing message: "
+                        << m.AddressPattern() << ": " << e.what() << "\n";
+        }
+    }    
+};
+
+
+void RunReceiveTest( int port )
+{
+    osc::OscReceiveTestPacketListener listener;
+	UdpListeningReceiveSocket s(
+            IpEndpointName( IpEndpointName::ANY_ADDRESS, port ),
+            &listener );
+
+	std::cout << "listening for input on port " << port << "...\n";
+	std::cout << "press ctrl-c to end\n";
+
+	s.RunUntilSigInt();
+
+	std::cout << "finishing.\n";
+}
+
+} // namespace osc
+
+#ifndef NO_OSC_TEST_MAIN
+
+int main(int argc, char* argv[])
+{
+	if( argc >= 2 && strcmp( argv[1], "-h" ) == 0 ){
+        std::cout << "usage: OscReceiveTest [port]\n";
+        return 0;
+    }
+
+	int port = 7000;
+
+	if( argc >= 2 )
+		port = atoi( argv[1] );
+
+    osc::RunReceiveTest( port );
+
+    return 0;
+}
+
+#endif /* NO_OSC_TEST_MAIN */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/tests/OscReceiveTest.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,40 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+
+#ifndef INCLUDED_OSCRECEIVETEST_H
+#define INCLUDED_OSCRECEIVETEST_H
+
+namespace osc{
+
+void RunReceiveTest( int port );
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCSENDTESTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/tests/OscSendTests.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,213 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscSendTests.h"
+
+#include <iostream>
+#include <string.h>
+
+#include "osc/OscOutboundPacketStream.h"
+
+#include "ip/UdpSocket.h"
+#include "ip/IpEndpointName.h"
+
+#define IP_MTU_SIZE 1536
+
+namespace osc{
+    
+void RunSendTests( const IpEndpointName& host )
+{
+    char buffer[IP_MTU_SIZE];
+    osc::OutboundPacketStream p( buffer, IP_MTU_SIZE );
+	UdpTransmitSocket socket( host );
+
+    p.Clear();
+    p << osc::BeginMessage( "/test1" )
+            << true << 23 << (float)3.1415 << "hello" << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    // test1 message with too few arguments
+    p.Clear();
+    p << osc::BeginMessage( "/test1" )
+            << true << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    // test1 message with too many arguments
+    p.Clear();
+    p << osc::BeginMessage( "/test1" )
+            << true << 23 << (float)3.1415 << "hello" << 42 << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    // test1 message with wrong argument type
+    p.Clear();
+    p << osc::BeginMessage( "/test1" )
+            << true << 1.0 << (float)3.1415 << "hello" << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    p.Clear();
+    p << osc::BeginMessage( "/test2" )
+            << true << 23 << (float)3.1415 << "hello" << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    // send four /test3 messages, each with a different type of argument
+    p.Clear();
+    p << osc::BeginMessage( "/test3" )
+            << true << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    p.Clear();
+    p << osc::BeginMessage( "/test3" )
+            << 23 << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    p.Clear();
+    p << osc::BeginMessage( "/test3" )
+            << (float)3.1415 << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+
+    p.Clear();
+    p << osc::BeginMessage( "/test3" )
+           << "hello" << osc::EndMessage;
+    socket.Send( p.Data(), p.Size() );
+    
+
+    // send a bundle
+    p.Clear();
+    p << osc::BeginBundle();
+
+        p << osc::BeginMessage( "/no_arguments" )
+            << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_bool" )
+            << true << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_bool" )
+            << false << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_bool" )
+            << (bool)1234 << osc::EndMessage;
+
+        p << osc::BeginMessage( "/nil" )
+            << osc::Nil << osc::EndMessage;
+
+        p << osc::BeginMessage( "/inf" )
+            << osc::Infinitum << osc::EndMessage;
+
+        p << osc::BeginMessage( "/an_int" ) << 1234 << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_float" )
+            << 3.1415926f << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_char" )
+            << 'c' << osc::EndMessage;
+
+        p << osc::BeginMessage( "/an_rgba_color" )
+            << osc::RgbaColor(0x22334455) << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_midi_message" )
+            << MidiMessage(0x7F) << osc::EndMessage;
+
+        p << osc::BeginMessage( "/an_int64" )
+            << (int64)(0xFFFFFFF) << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_time_tag" )
+            << osc::TimeTag(0xFFFFFFFUL) << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_double" )
+            << (double)3.1415926 << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_string" )
+            << "hello world" << osc::EndMessage;
+
+        p << osc::BeginMessage( "/a_symbol" )
+            << osc::Symbol("foobar") << osc::EndMessage;
+
+        // blob
+        {
+            char blobData[] = "abcd";
+
+            p << osc::BeginMessage( "/a_blob" )
+                << osc::Blob( blobData, 4 )
+                << osc::EndMessage;
+        }
+
+    p << osc::EndBundle;
+    socket.Send( p.Data(), p.Size() );
+
+
+
+    // nested bundles, and multiple messages in bundles...
+    p.Clear();
+    p << osc::BeginBundle( 1234 )
+        << osc::BeginMessage( "/an_int" ) << 1 << osc::EndMessage
+        << osc::BeginMessage( "/an_int" ) << 2 << osc::EndMessage
+        << osc::BeginMessage( "/an_int" ) << 3 << osc::EndMessage
+        << osc::BeginMessage( "/an_int" ) << 4 << osc::EndMessage
+        << osc::BeginBundle( 12345 )
+            << osc::BeginMessage( "/an_int" ) << 5 << osc::EndMessage
+            << osc::BeginMessage( "/an_int" ) << 6 << osc::EndMessage
+        << osc::EndBundle
+    << osc::EndBundle;
+
+    socket.Send( p.Data(), p.Size() );
+}
+
+} // namespace osc
+
+#ifndef NO_OSC_TEST_MAIN
+
+int main(int argc, char* argv[])
+{
+    if( argc >= 2 && strcmp( argv[1], "-h" ) == 0 ){
+        std::cout << "usage: OscSendTests [hostname [port]]\n";
+        return 0;
+    }
+
+    char *hostName = "localhost";
+    int port = 7000;
+    
+    if( argc >= 2 )
+        hostName = argv[1];
+
+    if( argc >= 3 )
+        port = atoi( argv[2] );
+
+
+	IpEndpointName host( hostName, port );
+
+	char hostIpAddress[ IpEndpointName::ADDRESS_STRING_LENGTH ];
+	host.AddressAsString( hostIpAddress );
+
+    std::cout << "sending test messages to " << hostName 
+		<< " (" << hostIpAddress << ") on port " << port << "...\n";
+
+    osc::RunSendTests( host );
+}
+
+#endif /* NO_OSC_TEST_MAIN */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/tests/OscSendTests.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,39 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCSENDTESTS_H
+#define INCLUDED_OSCSENDTESTS_H
+
+namespace osc{
+
+void RunSendTests( unsigned long address, int port );
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCSENDTESTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/tests/OscUnitTests.cpp	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,409 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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 "OscUnitTests.h"
+
+#include <iostream>
+#include <iomanip>
+
+#include "osc/OscReceivedElements.h"
+#include "osc/OscPrintReceivedElements.h"
+#include "osc/OscOutboundPacketStream.h"
+
+
+namespace osc{
+
+static int passCount_=0, failCount_=0;
+
+void PrintTestSummary()
+{
+    std::cout << (passCount_+failCount_) << " tests run, " << passCount_ << " passed, " << failCount_ << " failed.\n";
+}
+
+void pass_equality( const char *slhs, const char *srhs, const char *file, int line )
+{
+    ++passCount_;
+    std::cout << file << "(" << line << "): PASSED : " << slhs << " == " << srhs << "\n";
+}
+
+void fail_equality( const char *slhs, const char *srhs, const char *file, int line )
+{
+    ++failCount_;
+    std::cout << file << "(" << line << "): FAILED : " << slhs << " != " << srhs << "\n";
+}
+
+template <typename T>
+void assertEqual_( const T& lhs, const T& rhs, const char *slhs, const char *srhs, const char *file, int line )
+{
+    if( lhs == rhs )
+        pass_equality( slhs, srhs, file, line );
+    else
+        fail_equality( slhs, srhs, file, line );
+}
+
+template <typename T>
+void assertEqual_( const T* lhs, const T* rhs, const char *slhs, const char *srhs, const char *file, int line )
+{
+    if( lhs == rhs )
+        pass_equality( slhs, srhs, file, line );
+    else
+        fail_equality( slhs, srhs, file, line );
+}
+
+template <>
+void assertEqual_( const char* lhs, const char* rhs, const char *slhs, const char *srhs, const char *file, int line )
+{
+    if( strcmp( lhs, rhs ) == 0 )
+        pass_equality( slhs, srhs, file, line );
+    else
+        fail_equality( slhs, srhs, file, line );
+}
+
+
+#define assertEqual( a, b ) assertEqual_( (a), (b), #a, #b, __FILE__, __LINE__ )
+
+//---------------------------------------------------------------------------
+char * AllocateAligned4( unsigned long size )
+{
+    char *s = new char[ size + 4 ];   //allocate on stack to get 4 byte alignment
+    return (char*)((long)(s-1) & (~0x03L)) + 4;
+}
+
+// allocate a 4 byte aligned copy of s
+char * NewMessageBuffer( const char *s, unsigned long length )
+{
+    char *p = AllocateAligned4( length );
+    memcpy( p, s, length );
+    return p;
+}
+
+void test1()
+{
+    const char s[] = "/test\0\0\0,fiT\0\0\0\0\0\0\0\0\0\0\0A";
+    char *buffer = NewMessageBuffer( s, sizeof(s)-1 );
+
+    // test argument iterator interface
+    bool unexpectedExceptionCaught = false;
+    try{
+        ReceivedMessage m( ReceivedPacket(buffer, sizeof(s)-1) );
+
+        assertEqual( strcmp( m.AddressPattern(), "/test" ), 0 );
+        assertEqual( strcmp( m.TypeTags(), "fiT" ), 0 );
+        
+        ReceivedMessage::const_iterator i = m.ArgumentsBegin();
+        ++i;
+        ++i;
+        ++i;
+        assertEqual( i, m.ArgumentsEnd() );
+
+        i = m.ArgumentsBegin();
+        float f = (i++)->AsFloat();
+        (void)f;
+        int n = (i++)->AsInt32();
+        (void)n;
+        bool b = (i++)->AsBool();
+        (void)b;
+        
+        i = m.ArgumentsBegin();
+        bool exceptionThrown = false;
+        try{
+            int n = (i++)->AsInt32();
+            (void)n;
+        }catch( Exception& ){
+            exceptionThrown = true;
+        }
+        assertEqual( exceptionThrown, true );
+
+    }catch( Exception& e ){
+        std::cout << "unexpected exception: " << e.what() << "\n";
+        unexpectedExceptionCaught = true;
+    }
+    assertEqual( unexpectedExceptionCaught, false );
+
+
+    // test argument stream interface
+    unexpectedExceptionCaught = false;
+    try{
+        ReceivedMessage m( ReceivedPacket(buffer, sizeof(s)-1) );
+        ReceivedMessageArgumentStream args = m.ArgumentStream();
+        assertEqual( args.Eos(), false );
+
+        float f;
+        long n;
+        bool b;
+        args >> f >> n >> b;
+
+        (void) f;
+        (void) n;
+        (void) b;
+        
+        assertEqual( args.Eos(), true );
+
+    }catch( Exception& e ){
+        std::cout << "unexpected exception: " << e.what() << "\n";
+        unexpectedExceptionCaught = true;
+    }
+    assertEqual( unexpectedExceptionCaught, false );
+}
+
+//---------------------------------------------------------------------------
+
+
+#define TEST2_PRINT( ss )\
+    {\
+        const char s[] = ss;\
+        ReceivedPacket p( NewMessageBuffer( s, sizeof(s)-1 ), sizeof(s)-1 ); \
+        ReceivedMessage m( p );\
+        std::cout << m << "\n";\
+    }
+
+void test2()
+{
+    bool unexpectedExceptionCaught = false;
+    try{
+        //            012301230 1 2 3
+        TEST2_PRINT( "/no_args\0\0\0\0" );
+
+        //            012301230 1 2 3 01 2 3
+        TEST2_PRINT( "/no_args\0\0\0\0,\0\0\0" );
+        
+        //            01230123 012 3 0 1 2 3
+        TEST2_PRINT( "/an_int\0,i\0\0\0\0\0A" );
+        //            012301230 1 2 3 012 3 0 1 2 3 
+        TEST2_PRINT( "/a_float\0\0\0\0,f\0\0\0\0\0\0" );
+        //            0123012301 2 3 012 3 012301230123 
+        TEST2_PRINT( "/a_string\0\0\0,s\0\0hello world\0" );
+        //            01230123 012 3 0 1 2 3  0  1  2  3
+        TEST2_PRINT( "/a_blob\0,b\0\0\0\0\0\x4\x0\x1\x2\x3" );
+
+        //            0123012301 2 3 012 3 0 1 2 3 0 1 2 3
+        TEST2_PRINT( "/an_int64\0\0\0,h\0\0\0\0\0\0\0\0\0\x1" );
+        //            01230123012 3 012 3 0 1 2 3 0 1 2 3
+        TEST2_PRINT( "/a_timetag\0\0,t\0\0\0\0\0\0\0\0\0\x1" );
+        //            0123012301 2 3 012 3 0 1 2 3 0 1 2 3
+        TEST2_PRINT( "/a_double\0\0\0,d\0\0\0\0\0\0\0\0\0\0" );
+        //            0123012301 2 3 012 3 012301230123 
+        TEST2_PRINT( "/a_symbol\0\0\0,S\0\0hello world\0" );
+        //            01230123 012 3 0 1 2 3
+        TEST2_PRINT( "/a_char\0,c\0\0\0\0\0A" );
+        //            012301230 1 2 3 012 3 0 1 2 3 
+        TEST2_PRINT( "/a_color\0\0\0\0,r\0\0\0\0\0\0" );
+        //            012301230123012 3 012 3 0 1 2 3
+        TEST2_PRINT( "/a_midimessage\0\0,m\0\0\0\0\0\0" );
+        //            01230123 012 3 
+        TEST2_PRINT( "/a_bool\0,T\0\0" );
+        //            01230123 012 3 
+        TEST2_PRINT( "/a_bool\0,F\0\0" );
+        //            01230 1 2 3 012 3
+        TEST2_PRINT( "/Nil\0\0\0\0,N\0\0" );
+        //            01230 1 2 3 012 3
+        TEST2_PRINT( "/Inf\0\0\0\0,I\0\0" );
+
+        TEST2_PRINT( "/test\0\0\0,fiT\0\0\0\0\0\0\0\0\0\0\0A" );
+                                                        
+        bool exceptionThrown = false;
+        try{
+            TEST2_PRINT( "/a_char\0,x\0\0\0\0\0A" ); // unknown type tag 'x'
+        }catch( Exception& ){
+            exceptionThrown = true;
+        }
+        assertEqual( exceptionThrown, true );
+        
+    }catch( Exception& e ){
+        std::cout << "unexpected exception: " << e.what() << "\n";
+        unexpectedExceptionCaught = true;
+    }
+    assertEqual( unexpectedExceptionCaught, false );
+}
+
+//-----------------------------------------------------------------------
+
+// pack a message and then unpack it and check that the result is the same
+// also print each message
+// repeat the process inside a bundle
+
+#define TEST_PACK_UNPACK0( addressPattern, argument, value, recieveGetter ) \
+    {                                    \
+        memset( buffer, 0x74, bufferSize );   \
+        OutboundPacketStream ps( buffer, bufferSize ); \
+        ps << BeginMessage( addressPattern )  \
+            << argument \
+            << EndMessage;\
+        assertEqual( ps.IsReady(), true );\
+        ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );\
+        std::cout << m << "\n";\
+        assertEqual( m.ArgumentsBegin()-> recieveGetter () , value );\
+    }  \
+    {                                    \
+        memset( buffer, 0x74, bufferSize );   \
+        OutboundPacketStream ps( buffer, bufferSize ); \
+        ps << BeginBundle( 1234 ) \
+            << BeginMessage( addressPattern )  \
+            << argument \
+            << EndMessage \
+            << EndBundle;\
+        assertEqual( ps.IsReady(), true );\
+        ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );\
+        ReceivedMessage m( *b.ElementsBegin() );\
+        std::cout << m << "\n";\
+        assertEqual( m.ArgumentsBegin()-> recieveGetter () , value );\
+    }
+    
+#define TEST_PACK_UNPACK( addressPattern, argument, type, recieveGetter ) \
+    {                                    \
+        memset( buffer, 0x74, bufferSize );   \
+        OutboundPacketStream ps( buffer, bufferSize ); \
+        ps << BeginMessage( addressPattern )  \
+            << argument \
+            << EndMessage;\
+        assertEqual( ps.IsReady(), true );\
+        ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );\
+        std::cout << m << "\n";\
+        assertEqual( m.ArgumentsBegin()-> recieveGetter () , ( type ) argument );\
+    }  \
+    {                                    \
+        memset( buffer, 0x74, bufferSize );   \
+        OutboundPacketStream ps( buffer, bufferSize ); \
+        ps << BeginBundle( 1234 ) \
+            << BeginMessage( addressPattern )  \
+            << argument \
+            << EndMessage \
+            << EndBundle;\
+        assertEqual( ps.IsReady(), true );\
+        ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );\
+        ReceivedMessage m( *b.ElementsBegin() );\
+        std::cout << m << "\n";\
+        assertEqual( m.ArgumentsBegin()-> recieveGetter () , ( type ) argument );\
+    }
+
+void test3()
+{
+    int bufferSize = 1000;
+    char *buffer = AllocateAligned4( bufferSize );
+
+// single message tests
+    // empty message
+    {
+        memset( buffer, 0x74, bufferSize );
+        OutboundPacketStream ps( buffer, bufferSize );
+        ps << BeginMessage( "/no_arguments" )
+            << EndMessage;
+        assertEqual( ps.IsReady(), true );
+        ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );
+        std::cout << m << "\n";\
+    }
+
+    TEST_PACK_UNPACK( "/a_bool", true, bool, AsBool );
+    TEST_PACK_UNPACK( "/a_bool", false, bool, AsBool );
+    TEST_PACK_UNPACK( "/a_bool", (bool)1, bool, AsBool );
+
+    TEST_PACK_UNPACK0( "/nil", Nil, true, IsNil );
+    TEST_PACK_UNPACK0( "/inf", Infinitum, true, IsInfinitum );
+
+    TEST_PACK_UNPACK( "/an_int", (int32)1234, int32, AsInt32 );
+
+    TEST_PACK_UNPACK( "/a_float", 3.1415926f, float, AsFloat );
+
+    TEST_PACK_UNPACK( "/a_char", 'c', char, AsChar );
+
+    TEST_PACK_UNPACK( "/an_rgba_color", RgbaColor(0x22334455), uint32, AsRgbaColor );
+
+    TEST_PACK_UNPACK( "/a_midi_message", MidiMessage(0x7F), uint32, AsMidiMessage );
+
+    TEST_PACK_UNPACK( "/an_int64", (int64)(0xFFFFFFFF), int64, AsInt64 );
+
+    TEST_PACK_UNPACK( "/a_time_tag", TimeTag(0xFFFFFFFF), uint64, AsTimeTag );
+
+    TEST_PACK_UNPACK( "/a_double", (double)3.1415926, double, AsDouble );
+
+    // blob
+    {
+        char blobData[] = "abcd";
+        memset( buffer, 0x74, bufferSize );
+        OutboundPacketStream ps( buffer, bufferSize );
+        ps << BeginMessage( "/a_blob" )
+            << Blob( blobData, 4 )
+            << EndMessage;
+        assertEqual( ps.IsReady(), true );
+        ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );
+        std::cout << m << "\n";
+
+        const void *value;
+        unsigned long size;
+        m.ArgumentsBegin()->AsBlob( value, size );
+        assertEqual( size, (unsigned long)4 );
+        assertEqual( (memcmp( value, blobData, 4 ) == 0), true );
+    }
+
+
+    TEST_PACK_UNPACK( "/a_string", "hello world", const char*, AsString );
+
+    TEST_PACK_UNPACK( "/a_symbol", Symbol("foobar"), const char*, AsSymbol );
+
+
+    // nested bundles, and multiple messages in bundles...
+
+    {
+        memset( buffer, 0x74, bufferSize );
+        OutboundPacketStream ps( buffer, bufferSize );
+        ps << BeginBundle()
+            << BeginMessage( "/message_one" ) << 1 << 2 << 3 << 4 << EndMessage
+            << BeginMessage( "/message_two" ) << 1 << 2 << 3 << 4 << EndMessage
+            << BeginMessage( "/message_three" ) << 1 << 2 << 3 << 4 << EndMessage
+            << BeginMessage( "/message_four" ) << 1 << 2 << 3 << 4 << EndMessage
+            << EndBundle;
+        assertEqual( ps.IsReady(), true );
+        ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );
+        std::cout << b << "\n";
+    }
+}
+
+
+void RunUnitTests()
+{
+    test1();
+    test2();
+    test3();
+    PrintTestSummary();
+}
+
+} // namespace osc
+
+
+#ifndef NO_OSC_TEST_MAIN
+
+int main(int argc, char* argv[])
+{
+    (void)argc;
+    (void)argv;
+    
+    osc::RunUnitTests();
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/external/oscpack/tests/OscUnitTests.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,39 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	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
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	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.
+*/
+#ifndef INCLUDED_OSCUNITTESTS_H
+#define INCLUDED_OSCUNITTESTS_H
+
+namespace osc{
+
+void RunUnitTests();
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCUNITTESTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Modules/Output/OSCOutput.cc	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,125 @@
+// Copyright 2012, Tom Walters
+//
+// AIM-C: A C++ implementation of the Auditory Image Model
+// http://www.acousticscale.org/AIMC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*!
+ * \author Tom Walters <tom@acousticscale.org>
+ * \date created 2012/02/17
+ * \version \$Id$
+ */
+
+#include "Modules/Output/OSCOutput.h"
+
+namespace aimc {
+OSCOutput::OSCOutput(Parameters *params) : Module(params) {
+  module_description_ = "OSC output";
+  module_identifier_ = "osc_out";
+  module_type_ = "output";
+  module_version_ = "$Id$";
+
+  // Read parameter values from the parameter store. Setting any default
+  // values as necessary. The module should set defaults for all parameters
+  // that is uses here. The parameters_->DefaultType() methods look for a
+  // parameter with a given name. If it already exists in the parameter
+  // store, they return the current value. If the parameter doesn't already
+  // exist, it is added, set to the default value given, and that value is
+  // returned.
+  // Examples:
+  // integer_param_ = parameters_->DefaultInt("module.param_name", 4);
+  // boolean_param_ = parameters_->DefaultBool("module.param_name", true);
+  // float_param_ = parameters_->DefaultFloat("module.param_name", 4.4f);
+  
+  address_ = parameters_->DefaultString("osc.send_address", "127.0.0.1");
+  port_ = parameters_->DefaultInt("osc.send_port", 6448);
+  output_buffer_size_ = parameters_->DefaultInt("osc.output_min_buffer_size", 1024);
+}
+
+OSCOutput::~OSCOutput() {
+}
+
+bool OSCOutput::InitializeInternal(const SignalBank &input) {
+  // Copy the parameters of the input signal bank into internal variables, so
+  // that they can be checked later.
+  sample_rate_ = input.sample_rate();
+  buffer_length_ = input.buffer_length();
+  channel_count_ = input.channel_count();
+  
+  int output_byte_count = buffer_length_ * channel_count_ * 4 + 2048;  // TODO(tom) Find out what the real byte overhead is.
+  if (output_buffer_size_ < output_byte_count) {
+    output_buffer_size_ = output_byte_count;
+  }
+  LOG_INFO("Output buffer size is %d", output_buffer_size_);
+  LOG_INFO("Feature count is %d", buffer_length_ * channel_count_);
+  transmit_socket_ = new UdpTransmitSocket(IpEndpointName(address_.c_str(), port_));
+  buffer_ = new char[output_buffer_size_];
+  packet_stream_ = new osc::OutboundPacketStream(buffer_, output_buffer_size_);
+
+  // If this module produces any output, then the output signal bank needs to
+  // be initialized here.
+  // Example:
+  // output_.Initialize(channel_count, buffer_length, sample_rate);
+  return true;
+}
+
+void OSCOutput::ResetInternal() {
+  // Reset any internal state variables to their default values here. After a
+  // call to ResetInternal(), the module should be in the same state as it is
+  // just after a call to InitializeInternal().
+}
+
+void OSCOutput::Process(const SignalBank &input) {
+  // Check to see if the module has been initialized. If not, processing
+  // should not continue.
+  if (!initialized_) {
+    LOG_ERROR(_T("Module %s not initialized."), module_identifier_.c_str());
+    return;
+  }
+
+  // Check that ths input this time is the same as the input passed to
+  // Initialize()
+  if (buffer_length_ != input.buffer_length()
+      || channel_count_ != input.channel_count()) {
+    LOG_ERROR(_T("Mismatch between input to Initialize() and input to "
+                 "Process() in module %s."), module_identifier_.c_str());
+    return;
+  }
+
+  // Input is read from the input signal bank using calls like
+  // float value = input_.sample(channel_number, sample_index);
+
+  (*packet_stream_) << osc::BeginMessage( "/oscCustomFeatures" );
+  for (int ch = 0; ch < input.channel_count(); ch++) {
+    for (int i = 0; i < input.buffer_length(); i++) {
+      float s = input.sample(ch, i);
+      (*packet_stream_) << s;  
+    }
+  }
+  (*packet_stream_) << osc::EndMessage;
+  transmit_socket_->Send(packet_stream_->Data(), packet_stream_->Size());
+  packet_stream_->Clear();
+
+  // Output is fed into the output signal bank (assuming that it was
+  // initialized during the call to InitializeInternal()) like this:
+  // output_.set_sample(channel_number, sample_index, sample_value);
+
+  // If the output bank is set up, a call to PushOutput() will pass the output
+  // on to all the target modules of this module. PushOutput() can be called
+  // multiple times within each call to Process().
+  // Example:
+  // PushOutput();
+}
+}  // namespace aimc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Modules/Output/OSCOutput.h	Fri Jun 22 12:22:08 2012 +0000
@@ -0,0 +1,68 @@
+// Copyright 2012, Tom Walters
+//
+// AIM-C: A C++ implementation of the Auditory Image Model
+// http://www.acousticscale.org/AIMC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*!
+ * \author Tom Walters <tom@acousticscale.org>
+ * \date created 2012/02/17
+ * \version \$Id$
+ */
+
+#ifndef AIMC_MODULES_OUTPUT_OSC_H_
+#define AIMC_MODULES_OUTPUT_OSC_H_
+
+#include "Support/Module.h"
+
+#include <string>
+
+#include "osc/OscOutboundPacketStream.h"
+#include "ip/UdpSocket.h"
+
+namespace aimc {
+class OSCOutput : public Module {
+ public:
+  explicit OSCOutput(Parameters *pParam);
+  virtual ~OSCOutput();
+
+  /*! \brief Process a buffer
+   */
+  virtual void Process(const SignalBank &input);
+
+ private:
+  /*! \brief Reset the internal state of the module
+   */
+  virtual void ResetInternal();
+
+  /*! \brief Prepare the module
+   *  \param input Input signal
+   *  \param output true on success false on failure
+   */
+  virtual bool InitializeInternal(const SignalBank &input);
+
+  float sample_rate_;
+  int buffer_length_;
+  int channel_count_;
+  string address_;
+  int port_;
+  int output_buffer_size_;
+  
+  UdpTransmitSocket* transmit_socket_;
+  osc::OutboundPacketStream* packet_stream_;
+  char* buffer_;
+};
+}  // namespace aimc
+
+#endif  // AIMC_MODULES_OUTPUT_OSC_H_
--- a/src/Support/ModuleFactory.cc	Fri Jun 22 12:17:24 2012 +0000
+++ b/src/Support/ModuleFactory.cc	Fri Jun 22 12:22:08 2012 +0000
@@ -23,6 +23,7 @@
 #include "Modules/NAP/ModuleHCL.h"
 #include "Modules/Output/FileOutputHTK.h"
 #include "Modules/Output/FileOutputAIMC.h"
+#include "Modules/Output/OSCOutput.h"
 #include "Modules/Output/Graphics/GraphicsViewTime.h"
 #include "Modules/Profile/ModuleSlice.h"
 #include "Modules/Profile/ModuleScaler.h"
@@ -57,6 +58,9 @@
   if (module_name_.compare("htk_out") == 0)
     return new FileOutputHTK(params);
 
+  if (module_name_.compare("osc_out") == 0)
+    return new OSCOutput(params);
+
   if (module_name_.compare("aimc_out") == 0)
     return new FileOutputAIMC(params);