changeset 0:b299a65a3ad0

start project
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 16 Aug 2011 11:29:59 +0100
parents
children 1a32ce016bb9
files addons/ofxFileDialogOSX/.DS_Store addons/ofxFileDialogOSX/src/.DS_Store addons/ofxFileDialogOSX/src/ofxFileDialogOSX.cpp addons/ofxFileDialogOSX/src/ofxFileDialogOSX.h addons/ofxOsc/install.xml addons/ofxOsc/libs/oscpack/include/ip/IpEndpointName.h addons/ofxOsc/libs/oscpack/include/ip/NetworkingUtils.h addons/ofxOsc/libs/oscpack/include/ip/PacketListener.h addons/ofxOsc/libs/oscpack/include/ip/TimerListener.h addons/ofxOsc/libs/oscpack/include/ip/UdpSocket.h addons/ofxOsc/libs/oscpack/include/osc/MessageMappingOscPacketListener.h addons/ofxOsc/libs/oscpack/include/osc/OscException.h addons/ofxOsc/libs/oscpack/include/osc/OscHostEndianness.h addons/ofxOsc/libs/oscpack/include/osc/OscOutboundPacketStream.h addons/ofxOsc/libs/oscpack/include/osc/OscPacketListener.h addons/ofxOsc/libs/oscpack/include/osc/OscPrintReceivedElements.h addons/ofxOsc/libs/oscpack/include/osc/OscReceivedElements.h addons/ofxOsc/libs/oscpack/include/osc/OscTypes.h addons/ofxOsc/libs/oscpack/lib/osx/osc.a addons/ofxOsc/src/ofxOsc.h addons/ofxOsc/src/ofxOscArg.h addons/ofxOsc/src/ofxOscBundle.cpp addons/ofxOsc/src/ofxOscBundle.h addons/ofxOsc/src/ofxOscMessage.cpp addons/ofxOsc/src/ofxOscMessage.h addons/ofxOsc/src/ofxOscReceiver.cpp addons/ofxOsc/src/ofxOscReceiver.h addons/ofxOsc/src/ofxOscSender.cpp addons/ofxOsc/src/ofxOscSender.h midi division.rtf midiFileReader/MIDIComposition.h midiFileReader/MIDIEvent.h midiFileReader/MIDIFileReader.cpp midiFileReader/MIDIFileReader.h src/BayesianArrayStructure.cpp src/BayesianArrayStructure.h src/DynamicBayesianArray.cpp src/DynamicBayesianArray.h src/DynamicVector.cpp src/DynamicVector.h src/drawMidiNotes.cpp src/drawMidiNotes.h src/main.cpp src/midiEventHolder.cpp src/midiEventHolder.h src/testApp.cpp src/testApp.h src/untitled.h workingNotes.rtf
diffstat 49 files changed, 6562 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
Binary file addons/ofxFileDialogOSX/.DS_Store has changed
Binary file addons/ofxFileDialogOSX/src/.DS_Store has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxFileDialogOSX/src/ofxFileDialogOSX.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,147 @@
+/*
+ *  ofxFileDialogOSX.cpp
+ *
+ *  Created by timknapen on 07/05/10.
+ *	www.wereldderindianen.be
+ *	code stolen from 'mantissa' over here:
+ *	http://www.openframeworks.cc/forum/viewtopic.php?p=5028#p5028
+ *
+ */
+
+#include "ofxFileDialogOSX.h"
+
+
+//---------------------------------------------------------------------------------
+int ofxFileDialogOSX::saveFile(string& URL, string& fileURL){
+	
+	short fRefNumOut;
+	FSRef output_file;
+	OSStatus err;
+	
+	NavDialogCreationOptions options;
+	NavGetDefaultDialogCreationOptions( &options );
+	options.modality = kWindowModalityAppModal;
+	
+	NavDialogRef dialog;
+	err = NavCreatePutFileDialog(&options, '.mov', 'Moov', NULL, NULL, &dialog);
+	err = NavDialogRun(dialog);
+	
+	NavUserAction action;
+	action = NavDialogGetUserAction( dialog );
+	if (action == kNavUserActionNone || action == kNavUserActionCancel)	return 0;
+	
+	NavReplyRecord reply;
+	err = NavDialogGetReply(dialog, &reply); 
+	if ( err != noErr )	return 0;
+	
+	if ( reply.replacing )
+	{
+		printf("need to replace\n");
+	}
+	
+	AEKeyword keyword;
+	DescType actual_type;
+	Size actual_size;
+	FSRef output_dir;
+	err = AEGetNthPtr(&(reply.selection), 1, typeFSRef, &keyword, &actual_type,
+					  &output_dir, sizeof(output_file), &actual_size);
+		
+	
+	
+	CFURLRef cfUrl = CFURLCreateFromFSRef( kCFAllocatorDefault, &output_dir );
+	CFStringRef cfString = NULL;
+	if ( cfUrl != NULL )
+	{
+		cfString = CFURLCopyFileSystemPath( cfUrl, kCFURLPOSIXPathStyle ); // LEAK?
+		CFRelease( cfUrl );
+	}
+	
+	// copy from a CFString into a local c string (http://www.carbondev.com/site/?page=CStrings+)
+	const int kBufferSize = 255;
+	
+	char folderURL[kBufferSize];
+	Boolean bool1 = CFStringGetCString(cfString,folderURL,kBufferSize,kCFStringEncodingMacRoman);
+	
+	char fileName[kBufferSize];
+	Boolean bool2 = CFStringGetCString(reply.saveFileName,fileName,kBufferSize,kCFStringEncodingMacRoman);
+	
+	URL = folderURL;
+	fileURL = fileName;
+	// cleanup dialog
+	NavDialogDispose(dialog);
+	// dispose of reply:
+	NavDisposeReply(&reply);
+	// dispose of cfString
+	CFRelease( cfString );
+	
+	
+	return 1;
+}
+
+
+//---------------------------------------------------------------------------------
+int ofxFileDialogOSX::openFile(string& URL){
+	
+	short fRefNumOut;
+	FSRef output_file;
+	OSStatus err;
+	
+	NavDialogCreationOptions options;
+	NavGetDefaultDialogCreationOptions( &options );
+	options.modality = kWindowModalityAppModal;
+	// adding a banner
+	// options.message =  CFStringCreateWithCString(kCFAllocatorDefault, "hello world", kCFStringEncodingMacRoman);
+	NavDialogRef dialog;
+	
+	err = NavCreateGetFileDialog(&options, NULL, NULL ,NULL, NULL, NULL, &dialog);
+	err = NavDialogRun(dialog);
+	
+	NavUserAction action;
+	action = NavDialogGetUserAction( dialog );
+	
+	if (action == kNavUserActionNone || action == kNavUserActionCancel) {
+		cout << "no action or action cancel" << endl;
+		return 0;
+	}
+	
+	// get dialog reply
+	NavReplyRecord reply;
+	err = NavDialogGetReply(dialog, &reply);
+	if ( err != noErr ){
+		cout << "error getting DialogReply" << endl;
+		return 0;
+	}
+	if ( reply.replacing )
+	{
+		cout << (" need to replace\n ") << endl;
+	}
+	
+	AEKeyword keyword;
+	DescType actual_type;
+	Size actual_size;
+	FSRef output_dir;
+	err = AEGetNthPtr(&(reply.selection), 1, typeFSRef, &keyword, &actual_type,
+					  &output_dir, sizeof(output_file), &actual_size);
+		
+	CFURLRef cfUrl = CFURLCreateFromFSRef( kCFAllocatorDefault, &output_dir );
+	CFStringRef cfString = NULL;
+	if ( cfUrl != NULL )
+	{ 
+		cfString = CFURLCopyFileSystemPath( cfUrl, kCFURLPOSIXPathStyle );
+		CFRelease( cfUrl );
+	}
+
+	// copy from a CFString into a local c string (http://www.carbondev.com/site/?page=CStrings+)
+	const int kBufferSize = 255;
+ 
+	char fileURL[kBufferSize];
+	Boolean bool1 = CFStringGetCString(cfString,fileURL,kBufferSize,kCFStringEncodingMacRoman);
+	URL = fileURL;
+	// cleanup dialog
+	NavDialogDispose(dialog);
+	// dispose of reply:
+	NavDisposeReply(&reply);
+	// dispose of cfString
+	CFRelease( cfString );
+	return 1;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxFileDialogOSX/src/ofxFileDialogOSX.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,26 @@
+/*
+ *  ofxFileDialogOSX.h
+ *
+ *  Created by timknapen on 07/05/10.
+ *	www.wereldderindianen.be
+ *	code stolen from 'mantissa' over here:
+ *	http://www.openframeworks.cc/forum/viewtopic.php?p=5028#p5028
+ *
+ */
+
+
+#ifndef _OFX_FILE_DIALOG_OSX_
+#define _OFX_FILE_DIALOG_OSX_
+
+#include "ofMain.h"
+
+class ofxFileDialogOSX {
+public:
+	static int openFile(string& URL);
+	static int saveFile(string& URL, string& fileURL);
+private:
+	
+	
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/install.xml	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,45 @@
+<install>
+	<name>ofxOsc</name>
+	<version>0.04</version>
+	<author>damian stewart</author>
+	<url>http://frey.co.nz/ofxosc</url>
+
+	<add>	
+		<!-- 	=====================================================================	-->
+		<!--	========================== add per project using this addon =========	-->
+		<!-- 	=====================================================================	-->
+
+		<src>
+			<folder name="addons/ofxOsc/src">			
+			<file>../../../addons/ofxOsc/src/ofxOsc.h</file>
+			<file>../../../addons/ofxOsc/src/ofxOscArg.h</file>
+			<file>../../../addons/ofxOsc/src/ofxOscBundle.cpp</file>
+			<file>../../../addons/ofxOsc/src/ofxOscBundle.h</file>
+			<file>../../../addons/ofxOsc/src/ofxOscMessage.h</file>
+			<file>../../../addons/ofxOsc/src/ofxOscMessage.cpp</file>
+			<file>../../../addons/ofxOsc/src/ofxOscReceiver.h</file>
+			<file>../../../addons/ofxOsc/src/ofxOscReceiver.cpp</file>
+			<file>../../../addons/ofxOsc/src/ofxOscSender.cpp</file>
+			<file>../../../addons/ofxOsc/src/ofxOscSender.h</file>
+			</folder>
+		</src>
+
+		<include>
+			<path>../../../addons/ofxOsc/src</path>
+			<path>../../../addons/ofxOsc/libs/oscpack/include/ip</path>
+			<path>../../../addons/ofxOsc/libs/oscpack/include/osc</path>
+		</include>
+		
+		<link>
+			<lib os="win_cb" compiler="codeblocks">../../../addons/ofxOsc/libs/oscpack/lib/win32/oscpack.a</lib>
+			<lib os="win_vs2008" compiler="visualstudio">../../../addons/ofxOsc/libs/oscpack/lib/win32/oscpack.lib</lib>
+			<lib os="linux" compiler="codeblocks, makefile">../../../addons/ofxOsc/libs/oscpack/lib/linux/liboscpack.a</lib>
+			<lib os="linux64" compiler="codeblocks, makefile">../../../addons/ofxOsc/libs/oscpack/lib/linux64/liboscpack.a</lib>
+			<lib os="mac"   compiler="xcode">../../../addons/ofxOsc/libs/oscpack/lib/mac/libOsc.a</lib>
+		</link>
+
+	</add>
+	
+	
+</install>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/libs/oscpack/include/ip/IpEndpointName.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/ip/NetworkingUtils.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/ip/PacketListener.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/ip/TimerListener.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/ip/UdpSocket.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/MessageMappingOscPacketListener.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/OscException.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/OscHostEndianness.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/OscOutboundPacketStream.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,284 @@
+/*
+
+	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/addons/ofxOsc/libs/oscpack/include/osc/OscPacketListener.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/OscPrintReceivedElements.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/OscReceivedElements.h	Tue Aug 16 11:29:59 2011 +0100
@@ -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/addons/ofxOsc/libs/oscpack/include/osc/OscTypes.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,356 @@
+/*
+
+	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 */
+
Binary file addons/ofxOsc/libs/oscpack/lib/osx/osc.a has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOsc.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,37 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OFXOSC_H
+#define _OFXOSC_H
+
+#include "ofxOscArg.h"
+#include "ofxOscMessage.h"
+#include "ofxOscSender.h"
+#include "ofxOscReceiver.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscArg.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,135 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OFXOSCARG_H
+#define _OFXOSCARG_H
+
+#include "ofConstants.h"
+#include <string>
+
+typedef enum _ofxOscArgType
+{
+	OFXOSC_TYPE_NONE,
+	OFXOSC_TYPE_INT32,
+	OFXOSC_TYPE_FLOAT,
+	OFXOSC_TYPE_STRING,
+	OFXOSC_TYPE_BLOB,
+	OFXOSC_TYPE_BUNDLE,
+	OFXOSC_TYPE_INDEXOUTOFBOUNDS
+} ofxOscArgType;
+
+/*
+
+ofxOscArg
+
+base class for arguments
+
+*/
+
+class ofxOscArg
+{
+public:
+	ofxOscArg() {};
+	virtual ~ofxOscArg() {};
+
+	virtual ofxOscArgType getType() { return OFXOSC_TYPE_NONE; }
+	virtual string getTypeName() { return "none"; }
+
+private:
+};
+
+
+/*
+
+subclasses for each possible argument type
+
+*/
+
+#if defined TARGET_WIN32 && defined _MSC_VER
+// required because MSVC isn't ANSI-C compliant
+typedef long int32_t;
+#endif
+
+class ofxOscArgInt32 : public ofxOscArg
+{
+public:
+	ofxOscArgInt32( int32_t _value ) { value = _value; }
+	~ofxOscArgInt32() {};
+
+	/// return the type of this argument
+	ofxOscArgType getType() { return OFXOSC_TYPE_INT32; }
+	string getTypeName() { return "int32"; }
+
+	/// return value
+	int32_t get() const { return value; }
+	/// set value
+	void set( int32_t _value ) { value = _value; }
+
+private:
+	int32_t value;
+};
+
+class ofxOscArgFloat : public ofxOscArg
+{
+public:
+	ofxOscArgFloat( float _value ) { value = _value; }
+	~ofxOscArgFloat() {};
+
+	/// return the type of this argument
+	ofxOscArgType getType() { return OFXOSC_TYPE_FLOAT; }
+	string getTypeName() { return "float"; }
+
+	/// return value
+	float get() const { return value; }
+	/// set value
+	void set( float _value ) { value = _value; }
+
+private:
+		float value;
+};
+
+class ofxOscArgString : public ofxOscArg
+{
+public:
+	ofxOscArgString( string _value ) { value = _value; }
+	~ofxOscArgString() {};
+
+	/// return the type of this argument
+	ofxOscArgType getType() { return OFXOSC_TYPE_STRING; }
+	string getTypeName() { return "string"; }
+
+	/// return value
+	string get() const { return value; }
+	/// set value
+	void set( const char* _value ) { value = _value; }
+
+private:
+	std::string value;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscBundle.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,64 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ofxOscBundle.h"
+
+
+ofxOscBundle::ofxOscBundle()
+{
+}
+
+ofxOscBundle::~ofxOscBundle()
+{
+}
+
+ofxOscBundle& ofxOscBundle::copy( const ofxOscBundle& other )
+{
+	for ( int i=0; i<other.bundles.size(); i++ )
+	{
+		bundles.push_back( other.bundles[i] );
+	}
+	for ( int i=0; i<other.messages.size(); i++ )
+	{
+		messages.push_back( other.messages[i] );
+	}
+	return *this;
+}
+
+
+
+void ofxOscBundle::addBundle( const ofxOscBundle& bundle )
+{
+	bundles.push_back( bundle );
+}
+
+void ofxOscBundle::addMessage( const ofxOscMessage& message )
+{
+	messages.push_back( message );
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscBundle.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,67 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OFXOSCBUNDLE_H
+#define _OFXOSCBUNDLE_H
+
+#include <vector>
+#include "ofxOscMessage.h"
+
+class ofxOscBundle
+{
+public:	
+	ofxOscBundle();
+	~ofxOscBundle();
+	ofxOscBundle( const ofxOscBundle& other ) { copy ( other ); }
+	ofxOscBundle& operator= ( const ofxOscBundle& other ) { return copy( other ); }
+	/// for operator= and copy constructor
+	ofxOscBundle& copy( const ofxOscBundle& other );
+	
+	/// erase contents
+	void clear() { messages.clear(); bundles.clear(); }
+
+	/// add bundle elements
+	void addBundle( const ofxOscBundle& element );
+	void addMessage( const ofxOscMessage& message );
+	
+	/// get bundle elements
+	int getBundleCount() const { return bundles.size(); }
+	int getMessageCount() const { return messages.size(); }
+	/// return the bundle or message at the given index
+	ofxOscBundle& getBundleAt( int i ) { return bundles[i]; }
+	ofxOscMessage& getMessageAt( int i ) { return messages[i]; }
+	
+private:
+		
+	std::vector< ofxOscMessage > messages;
+	std::vector< ofxOscBundle > bundles;
+};
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscMessage.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,210 @@
+/*
+
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+   names of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ofxOscMessage.h"
+#include <iostream>
+#include <assert.h>
+
+ofxOscMessage::ofxOscMessage()
+
+{
+}
+
+ofxOscMessage::~ofxOscMessage()
+{
+	clear();
+}
+
+void ofxOscMessage::clear()
+{
+	for ( unsigned int i=0; i<args.size(); ++i )
+		delete args[i];
+	args.clear();
+	address = "";
+}
+
+/*
+
+get methods
+
+*/
+
+int ofxOscMessage::getNumArgs() const
+{
+	return (int)args.size();
+}
+
+ofxOscArgType ofxOscMessage::getArgType( int index ) const
+{
+    if ( index >= (int)args.size() )
+    {
+        fprintf(stderr,"ofxOscMessage::getArgType: index %d out of bounds\n", index );
+        return OFXOSC_TYPE_INDEXOUTOFBOUNDS;
+    }
+    else
+        return args[index]->getType();
+}
+
+string ofxOscMessage::getArgTypeName( int index ) const
+{
+    if ( index >= (int)args.size() )
+    {
+        fprintf(stderr,"ofxOscMessage::getArgTypeName: index %d out of bounds\n", index );
+        return "INDEX OUT OF BOUNDS";
+    }
+    else
+        return args[index]->getTypeName();
+}
+
+
+int32_t ofxOscMessage::getArgAsInt32( int index ) const
+{
+	if ( getArgType(index) != OFXOSC_TYPE_INT32 )
+	{
+	    if ( getArgType( index ) == OFXOSC_TYPE_FLOAT )
+        {
+            fprintf(stderr, "ofxOscMessage:getArgAsInt32: warning: converting int32 to float for argument %i\n", index );
+            return ((ofxOscArgFloat*)args[index])->get();
+        }
+        else
+        {
+            fprintf(stderr, "ofxOscMessage:getArgAsInt32: error: argument %i is not a number\n", index );
+            return 0;
+        }
+	}
+	else
+        return ((ofxOscArgInt32*)args[index])->get();
+}
+
+
+float ofxOscMessage::getArgAsFloat( int index ) const
+{
+	if ( getArgType(index) != OFXOSC_TYPE_FLOAT )
+	{
+	    if ( getArgType( index ) == OFXOSC_TYPE_INT32 )
+        {
+            fprintf(stderr, "ofxOscMessage:getArgAsFloat: warning: converting float to int32 for argument %i\n", index );
+            return ((ofxOscArgInt32*)args[index])->get();
+        }
+        else
+        {
+            fprintf(stderr, "ofxOscMessage:getArgAsFloat: error: argument %i is not a number\n", index );
+            return 0;
+        }
+	}
+	else
+        return ((ofxOscArgFloat*)args[index])->get();
+}
+
+
+string ofxOscMessage::getArgAsString( int index ) const
+{
+    if ( getArgType(index) != OFXOSC_TYPE_STRING )
+	{
+	    if ( getArgType( index ) == OFXOSC_TYPE_FLOAT )
+        {
+            char buf[1024];
+            sprintf(buf,"%f",((ofxOscArgFloat*)args[index])->get() );
+            fprintf(stderr, "ofxOscMessage:getArgAsString: warning: converting float to string for argument %i\n", index );
+            return buf;
+        }
+	    else if ( getArgType( index ) == OFXOSC_TYPE_INT32 )
+        {
+            char buf[1024];
+            sprintf(buf,"%i",((ofxOscArgInt32*)args[index])->get() );
+            fprintf(stderr, "ofxOscMessage:getArgAsString: warning: converting int32 to string for argument %i\n", index );
+            return buf;
+        }
+        else
+        {
+            fprintf(stderr, "ofxOscMessage:getArgAsString: error: argument %i is not a string\n", index );
+            return "";
+        }
+	}
+	else
+        return ((ofxOscArgString*)args[index])->get();
+}
+
+
+
+/*
+
+set methods
+
+*/
+
+
+void ofxOscMessage::addIntArg( int32_t argument )
+{
+
+	args.push_back( new ofxOscArgInt32( argument ) );
+}
+
+void ofxOscMessage::addFloatArg( float argument )
+{
+	args.push_back( new ofxOscArgFloat( argument ) );
+}
+
+void ofxOscMessage::addStringArg( string argument )
+{
+	args.push_back( new ofxOscArgString( argument ) );
+}
+
+
+/*
+
+ housekeeping
+
+ */
+
+ofxOscMessage& ofxOscMessage::copy( const ofxOscMessage& other )
+{
+	// copy address
+	address = other.address;
+
+	remote_host = other.remote_host;
+	remote_port = other.remote_port;
+
+	// copy arguments
+	for ( int i=0; i<(int)other.args.size(); ++i )
+	{
+		ofxOscArgType argType = other.getArgType( i );
+		if ( argType == OFXOSC_TYPE_INT32 )
+			args.push_back( new ofxOscArgInt32( other.getArgAsInt32( i ) ) );
+		else if ( argType == OFXOSC_TYPE_FLOAT )
+			args.push_back( new ofxOscArgFloat( other.getArgAsFloat( i ) ) );
+		else if ( argType == OFXOSC_TYPE_STRING )
+			args.push_back( new ofxOscArgString( other.getArgAsString( i ) ) );
+		else
+		{
+			assert( false && "bad argument type" );
+		}
+	}
+
+	return *this;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscMessage.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,96 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _ofxOscMESSAGE_H
+#define _ofxOscMESSAGE_H
+
+#include "ofxOscArg.h"
+#include <vector>
+#include <string>
+
+using namespace std;
+
+class ofxOscMessage
+{
+public:
+	ofxOscMessage();
+	~ofxOscMessage();
+	ofxOscMessage( const ofxOscMessage& other ){ copy ( other ); }
+	ofxOscMessage& operator= ( const ofxOscMessage& other ) { return copy( other ); }
+	/// for operator= and copy constructor
+	ofxOscMessage& copy( const ofxOscMessage& other );
+
+	/// clear this message, erase all contents
+	void clear();
+
+	/// return the address
+	string getAddress() const { return address; }
+
+	/// return the remote ip
+	string getRemoteIp() { return remote_host; }
+	/// return the remote port
+	int getRemotePort() { return remote_port; }
+
+	/// return number of argumentsļ
+	int getNumArgs() const;
+	/// return argument type code for argument # index
+	ofxOscArgType getArgType( int index ) const;
+	/// return argument type name as string
+	/// - either "int", "float", or "string"
+	string getArgTypeName( int index ) const;
+
+	/// get the argument with the given index as an int, float, or string
+	/// ensure that the type matches what you're requesting
+	/// (eg for an int argument, getArgType(index)==OF_TYPE_INT32
+	/// or getArgTypeName(index)=="int32")
+	int32_t getArgAsInt32( int index ) const;
+	float getArgAsFloat( int index ) const;
+	string getArgAsString( int index ) const;
+
+	/// message construction
+	void setAddress( string _address ) { address = _address; };
+	/// host and port of the remote endpoint
+	void setRemoteEndpoint( string host, int port ) { remote_host = host; remote_port = port; }
+	void addIntArg( int32_t argument );
+	void addFloatArg( float argument );
+	void addStringArg( string argument );
+
+
+private:
+
+	string address;
+	vector<ofxOscArg*> args;
+
+	string remote_host;
+	int remote_port;
+
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscReceiver.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,240 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ofxOscReceiver.h"
+
+#ifndef TARGET_WIN32
+        #include <pthread.h>
+#endif
+#include <iostream>
+#include <assert.h>
+
+ofxOscReceiver::ofxOscReceiver()
+{
+	listen_socket = NULL;
+}
+
+void ofxOscReceiver::setup( int listen_port )
+{
+	// if we're already running, shutdown before running again
+	if ( listen_socket )
+		shutdown();
+	
+	// create the mutex
+	#ifdef TARGET_WIN32
+	mutex = CreateMutexA( NULL, FALSE, NULL );
+	#else
+	pthread_mutex_init( &mutex, NULL );
+	#endif
+	
+	// create socket
+	socketHasShutdown = false;
+	listen_socket = new UdpListeningReceiveSocket( IpEndpointName( IpEndpointName::ANY_ADDRESS, listen_port ), this );
+
+	// start thread
+	#ifdef TARGET_WIN32
+	thread	= CreateThread(
+							   NULL,              // default security attributes
+							   0,                 // use default stack size
+							&ofxOscReceiver::startThread,        // thread function
+							   (void*)this,             // argument to thread function
+							   0,                 // use default creation flags
+							   NULL);             // we don't the the thread id
+
+	#else
+	pthread_create( &thread, NULL, &ofxOscReceiver::startThread, (void*)this );
+	#endif
+}
+
+void ofxOscReceiver::shutdown()
+{
+	if ( listen_socket )
+	{
+		// tell the socket to shutdown
+		listen_socket->AsynchronousBreak();
+		// wait for shutdown to complete
+		while (!socketHasShutdown)
+		{
+			#ifdef TARGET_WIN32
+			Sleep(1);
+			#else
+			// sleep 0.1ms
+			usleep(100);
+			#endif
+		}
+		
+		// thread will clean up itself
+		
+		// clean up the mutex
+		#ifdef TARGET_WIN32
+		ReleaseMutex( mutex );
+		#else
+		pthread_mutex_destroy( &mutex );	
+		#endif
+		
+		// delete the socket
+		delete listen_socket;
+		listen_socket = NULL;
+	}
+}
+
+ofxOscReceiver::~ofxOscReceiver()
+{
+	shutdown();
+}
+
+#ifdef TARGET_WIN32
+DWORD WINAPI
+#else
+void*
+#endif
+		ofxOscReceiver::startThread( void* receiverInstance )
+{
+	// cast the instance
+	ofxOscReceiver* instance = (ofxOscReceiver*)receiverInstance;
+	// start the socket listener
+	instance->listen_socket->Run();
+	// socket listener has finished - remember this fact
+	instance->socketHasShutdown = true;
+	// return
+    #ifdef TARGET_WIN32
+	return 0;
+    #else
+	return NULL;
+    #endif
+}
+
+void ofxOscReceiver::ProcessMessage( const osc::ReceivedMessage &m, const IpEndpointName& remoteEndpoint )
+{
+	// convert the message to an ofxOscMessage
+	ofxOscMessage* ofMessage = new ofxOscMessage();
+
+	// set the address
+	ofMessage->setAddress( m.AddressPattern() );
+
+	// set the sender ip/host
+	char endpoint_host[ IpEndpointName::ADDRESS_STRING_LENGTH ];
+	remoteEndpoint.AddressAsString( endpoint_host );
+    ofMessage->setRemoteEndpoint( endpoint_host, remoteEndpoint.port );
+
+	// transfer the arguments
+	for ( osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
+		  arg != m.ArgumentsEnd();
+		  ++arg )
+	{
+		if ( arg->IsInt32() )
+			ofMessage->addIntArg( arg->AsInt32Unchecked() );
+		else if ( arg->IsFloat() )
+			ofMessage->addFloatArg( arg->AsFloatUnchecked() );
+		else if ( arg->IsString() )
+			ofMessage->addStringArg( arg->AsStringUnchecked() );
+		else
+		{
+			assert( false && "message argument is not int, float, or string" );
+		}
+	}
+
+	// now add to the queue
+
+	// at this point we are running inside the thread created by startThread,
+	// so anyone who calls hasWaitingMessages() or getNextMessage() is coming
+	// from a different thread
+
+	// so we have to practise shared memory management
+
+	// grab a lock on the queue
+	grabMutex();
+
+	// add incoming message on to the queue
+	messages.push_back( ofMessage );
+
+	// release the lock
+	releaseMutex();
+}
+
+bool ofxOscReceiver::hasWaitingMessages()
+{
+	// grab a lock on the queue
+	grabMutex();
+
+	// check the length of the queue
+	int queue_length = (int)messages.size();
+
+	// release the lock
+	releaseMutex();
+
+	// return whether we have any messages
+	return queue_length > 0;
+}
+
+bool ofxOscReceiver::getNextMessage( ofxOscMessage* message )
+{
+	// grab a lock on the queue
+	grabMutex();
+
+	// check if there are any to be got
+	if ( messages.size() == 0 )
+	{
+		// no: release the mutex
+		releaseMutex();
+		return false;
+	}
+
+	// copy the message from the queue to message
+	ofxOscMessage* src_message = messages.front();
+	message->copy( *src_message );
+
+	// now delete the src message
+	delete src_message;
+	// and remove it from the queue
+	messages.pop_front();
+
+	// release the lock on the queue
+	releaseMutex();
+
+	// return success
+	return true;
+}
+
+void ofxOscReceiver::grabMutex()
+{
+#ifdef TARGET_WIN32
+	WaitForSingleObject( mutex, INFINITE );
+#else
+	pthread_mutex_lock( &mutex );
+#endif
+}
+
+void ofxOscReceiver::releaseMutex()
+{
+#ifdef TARGET_WIN32
+	ReleaseMutex( mutex );
+#else
+	pthread_mutex_unlock( &mutex );
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscReceiver.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,108 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _ofxOscRECEIVER_H
+#define _ofxOscRECEIVER_H
+
+#include <deque>
+#include "ofMain.h"
+
+#ifdef TARGET_WIN32
+// threads
+#include <windows.h>
+#else
+// threads
+#include <pthread.h>
+#endif
+
+// osc
+#include "OscTypes.h"
+#include "OscPacketListener.h"
+#include "UdpSocket.h"
+
+// ofxOsc
+#include "ofxOscMessage.h"
+
+class ofxOscReceiver : public osc::OscPacketListener
+{
+public:
+	ofxOscReceiver();
+	~ofxOscReceiver();
+
+	/// listen_port is the port to listen for messages on
+	void setup( int listen_port );
+
+	/// returns true if there are any messages waiting for collection
+	bool hasWaitingMessages();
+	/// take the next message on the queue of received messages, copy its details into message, and
+	/// remove it from the queue. return false if there are no more messages to be got, otherwise
+	/// return true
+	bool getNextMessage( ofxOscMessage* );
+
+protected:
+	/// process an incoming osc message and add it to the queue
+	virtual void ProcessMessage( const osc::ReceivedMessage &m, const IpEndpointName& remoteEndpoint );
+
+private:
+	// shutdown the listener
+	void shutdown();
+
+	// start the listening thread
+#ifdef TARGET_WIN32
+	static DWORD WINAPI startThread( void* ofxOscReceiverInstance );
+#else
+	static void* startThread( void* ofxOscReceiverInstance );
+#endif
+	// queue of osc messages
+	std::deque< ofxOscMessage* > messages;
+
+	// socket to listen on
+	UdpListeningReceiveSocket* listen_socket;
+
+	// mutex helpers
+	void grabMutex();
+	void releaseMutex();
+
+#ifdef TARGET_WIN32
+	// thread to listen with
+	HANDLE thread;
+	// mutex for the thread queue
+	HANDLE mutex;
+#else
+	// thread to listen with
+	pthread_t thread;
+	// mutex for the message queue
+	pthread_mutex_t mutex;
+#endif
+	// ready to be deleted
+	bool socketHasShutdown;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscSender.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,121 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "ofxOscSender.h"
+
+
+#include "UdpSocket.h"
+
+#include <assert.h>
+
+ofxOscSender::ofxOscSender()
+{
+	socket = NULL;
+}
+
+ofxOscSender::~ofxOscSender()
+{
+	if ( socket )
+		shutdown();
+}
+
+void ofxOscSender::setup( std::string hostname, int port )
+{
+	if ( socket )
+		shutdown();
+	
+	socket = new UdpTransmitSocket( IpEndpointName( hostname.c_str(), port ) );
+}
+
+void ofxOscSender::shutdown()
+{
+	if ( socket )
+		delete socket;
+	socket = NULL;
+}
+
+void ofxOscSender::sendBundle( ofxOscBundle& bundle )
+{
+	static const int OUTPUT_BUFFER_SIZE = 32768;
+	char buffer[OUTPUT_BUFFER_SIZE];
+	osc::OutboundPacketStream p(buffer, OUTPUT_BUFFER_SIZE );
+
+	// serialise the bundle
+	appendBundle( bundle, p );
+
+	socket->Send( p.Data(), p.Size() );
+}
+
+void ofxOscSender::sendMessage( ofxOscMessage& message )
+{
+	static const int OUTPUT_BUFFER_SIZE = 16384;
+	char buffer[OUTPUT_BUFFER_SIZE];
+    osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );
+
+	// serialise the message
+	p << osc::BeginBundleImmediate;
+	appendMessage( message, p );
+	p << osc::EndBundle;
+
+	socket->Send( p.Data(), p.Size() );
+}
+
+void ofxOscSender::appendBundle( ofxOscBundle& bundle, osc::OutboundPacketStream& p )
+{
+	// recursively serialise the bundle
+	p << osc::BeginBundleImmediate;
+	for ( int i=0; i<bundle.getBundleCount(); i++ )
+	{
+		appendBundle( bundle.getBundleAt( i ), p );
+	}
+	for ( int i=0; i<bundle.getMessageCount(); i++ )
+	{
+		appendMessage( bundle.getMessageAt( i ), p );
+	}
+	p << osc::EndBundle;
+}
+
+void ofxOscSender::appendMessage( ofxOscMessage& message, osc::OutboundPacketStream& p )
+{
+    p << osc::BeginMessage( message.getAddress().c_str() );
+	for ( int i=0; i< message.getNumArgs(); ++i )
+	{
+		if ( message.getArgType(i) == OFXOSC_TYPE_INT32 )
+			p << message.getArgAsInt32( i );
+		else if ( message.getArgType( i ) == OFXOSC_TYPE_FLOAT )
+			p << message.getArgAsFloat( i );
+		else if ( message.getArgType( i ) == OFXOSC_TYPE_STRING )
+			p << message.getArgAsString( i ).c_str();
+		else
+		{
+			assert( false && "bad argument type" );
+		}
+	}
+	p << osc::EndMessage;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/addons/ofxOsc/src/ofxOscSender.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,75 @@
+/*
+ 
+ Copyright (c) 2007-2009, Damian Stewart
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the developer nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef _ofxOscSENDER_H
+#define _ofxOscSENDER_H
+
+/**
+
+ofxOscSender
+
+an ofxOscSender sends messages to a single host/port
+
+*/
+
+class UdpTransmitSocket;
+#include <string>
+#include "OscTypes.h"
+#include "OscOutboundPacketStream.h"
+
+#include "ofxOscBundle.h"
+#include "ofxOscMessage.h"
+
+
+class ofxOscSender
+{
+public:
+	ofxOscSender();
+	~ofxOscSender();
+
+	/// send messages to hostname and port
+	void setup( std::string hostname, int port );
+
+	/// send the given message
+	void sendMessage( ofxOscMessage& message );
+	/// send the given bundle
+	void sendBundle( ofxOscBundle& bundle );
+
+private:
+	void shutdown();
+		
+	// helper methods for constructing messages
+	void appendBundle( ofxOscBundle& bundle, osc::OutboundPacketStream& p );
+	void appendMessage( ofxOscMessage& message, osc::OutboundPacketStream& p );
+
+	UdpTransmitSocket* socket;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/midi division.rtf	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,11 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0
+\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
+
+\f0\fs24 \cf0 midi :\
+\
+z ppq: parts in a bar\
+\
+bar dividing by x/y time sig - i.e. x measures of  (z/y)}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/midiFileReader/MIDIComposition.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,43 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    This is a modified version of a source file from the 
+    Rosegarden MIDI and audio sequencer and notation editor.
+    This file copyright 2000-2010 Richard Bown and Chris Cannam.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 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.
+
+    Except as contained in this notice, the names of the authors
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#ifndef _MIDI_COMPOSITION_H_
+#define _MIDI_COMPOSITION_H_
+
+#include "MIDIEvent.h"
+#include <vector>
+#include <map>
+
+typedef std::vector<MIDIEvent> MIDITrack;
+typedef std::map<unsigned int, MIDITrack> MIDIComposition;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/midiFileReader/MIDIEvent.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,242 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    This is a modified version of a source file from the 
+    Rosegarden MIDI and audio sequencer and notation editor.
+    This file copyright 2000-2010 Richard Bown and Chris Cannam.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 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.
+
+    Except as contained in this notice, the names of the authors
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#ifndef _MIDI_EVENT_H_
+#define _MIDI_EVENT_H_
+
+#include <string>
+#include <iostream>
+
+typedef unsigned char MIDIByte;
+
+namespace MIDIConstants
+{
+    static const char *const MIDI_FILE_HEADER         = "MThd";
+    static const char *const MIDI_TRACK_HEADER        = "MTrk";
+
+    static const MIDIByte MIDI_STATUS_BYTE_MASK       = 0x80;
+    static const MIDIByte MIDI_MESSAGE_TYPE_MASK      = 0xF0;
+    static const MIDIByte MIDI_CHANNEL_NUM_MASK       = 0x0F;
+
+    static const MIDIByte MIDI_NOTE_OFF               = 0x80;
+    static const MIDIByte MIDI_NOTE_ON                = 0x90;
+    static const MIDIByte MIDI_POLY_AFTERTOUCH        = 0xA0;
+    static const MIDIByte MIDI_CTRL_CHANGE            = 0xB0;
+    static const MIDIByte MIDI_PROG_CHANGE            = 0xC0;
+    static const MIDIByte MIDI_CHNL_AFTERTOUCH        = 0xD0;
+    static const MIDIByte MIDI_PITCH_BEND             = 0xE0;
+    static const MIDIByte MIDI_SELECT_CHNL_MODE       = 0xB0;
+    static const MIDIByte MIDI_SYSTEM_EXCLUSIVE       = 0xF0;
+    static const MIDIByte MIDI_TC_QUARTER_FRAME       = 0xF1;
+    static const MIDIByte MIDI_SONG_POSITION_PTR      = 0xF2;
+    static const MIDIByte MIDI_SONG_SELECT            = 0xF3;
+    static const MIDIByte MIDI_TUNE_REQUEST           = 0xF6;
+    static const MIDIByte MIDI_END_OF_EXCLUSIVE       = 0xF7;
+    static const MIDIByte MIDI_TIMING_CLOCK           = 0xF8;
+    static const MIDIByte MIDI_START                  = 0xFA;
+    static const MIDIByte MIDI_CONTINUE               = 0xFB;
+    static const MIDIByte MIDI_STOP                   = 0xFC;
+    static const MIDIByte MIDI_ACTIVE_SENSING         = 0xFE;
+    static const MIDIByte MIDI_SYSTEM_RESET           = 0xFF;
+    static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL    = 0x7D;
+    static const MIDIByte MIDI_SYSEX_NON_RT           = 0x7E;
+    static const MIDIByte MIDI_SYSEX_RT               = 0x7F;
+    static const MIDIByte MIDI_SYSEX_RT_COMMAND       = 0x06;
+    static const MIDIByte MIDI_SYSEX_RT_RESPONSE      = 0x07;
+    static const MIDIByte MIDI_MMC_STOP               = 0x01;
+    static const MIDIByte MIDI_MMC_PLAY               = 0x02;
+    static const MIDIByte MIDI_MMC_DEFERRED_PLAY      = 0x03;
+    static const MIDIByte MIDI_MMC_FAST_FORWARD       = 0x04;
+    static const MIDIByte MIDI_MMC_REWIND             = 0x05;
+    static const MIDIByte MIDI_MMC_RECORD_STROBE      = 0x06;
+    static const MIDIByte MIDI_MMC_RECORD_EXIT        = 0x07;
+    static const MIDIByte MIDI_MMC_RECORD_PAUSE       = 0x08;
+    static const MIDIByte MIDI_MMC_PAUSE              = 0x08;
+    static const MIDIByte MIDI_MMC_EJECT              = 0x0A;
+    static const MIDIByte MIDI_MMC_LOCATE             = 0x44;
+    static const MIDIByte MIDI_FILE_META_EVENT        = 0xFF;
+    static const MIDIByte MIDI_SEQUENCE_NUMBER        = 0x00;
+    static const MIDIByte MIDI_TEXT_EVENT             = 0x01;
+    static const MIDIByte MIDI_COPYRIGHT_NOTICE       = 0x02;
+    static const MIDIByte MIDI_TRACK_NAME             = 0x03;
+    static const MIDIByte MIDI_INSTRUMENT_NAME        = 0x04;
+    static const MIDIByte MIDI_LYRIC                  = 0x05;
+    static const MIDIByte MIDI_TEXT_MARKER            = 0x06;
+    static const MIDIByte MIDI_CUE_POINT              = 0x07;
+    static const MIDIByte MIDI_CHANNEL_PREFIX         = 0x20;
+    static const MIDIByte MIDI_CHANNEL_PREFIX_OR_PORT = 0x21;
+    static const MIDIByte MIDI_END_OF_TRACK           = 0x2F;
+    static const MIDIByte MIDI_SET_TEMPO              = 0x51;
+    static const MIDIByte MIDI_SMPTE_OFFSET           = 0x54;
+    static const MIDIByte MIDI_TIME_SIGNATURE         = 0x58;
+    static const MIDIByte MIDI_KEY_SIGNATURE          = 0x59;
+    static const MIDIByte MIDI_SEQUENCER_SPECIFIC     = 0x7F;
+    static const MIDIByte MIDI_CONTROLLER_BANK_MSB      = 0x00;
+    static const MIDIByte MIDI_CONTROLLER_VOLUME        = 0x07;
+    static const MIDIByte MIDI_CONTROLLER_BANK_LSB      = 0x20;
+    static const MIDIByte MIDI_CONTROLLER_MODULATION    = 0x01;
+    static const MIDIByte MIDI_CONTROLLER_PAN           = 0x0A;
+    static const MIDIByte MIDI_CONTROLLER_SUSTAIN       = 0x40;
+    static const MIDIByte MIDI_CONTROLLER_RESONANCE     = 0x47;
+    static const MIDIByte MIDI_CONTROLLER_RELEASE       = 0x48;
+    static const MIDIByte MIDI_CONTROLLER_ATTACK        = 0x49;
+    static const MIDIByte MIDI_CONTROLLER_FILTER        = 0x4A;
+    static const MIDIByte MIDI_CONTROLLER_REVERB        = 0x5B;
+    static const MIDIByte MIDI_CONTROLLER_CHORUS        = 0x5D;
+    static const MIDIByte MIDI_CONTROLLER_NRPN_1        = 0x62;
+    static const MIDIByte MIDI_CONTROLLER_NRPN_2        = 0x63;
+    static const MIDIByte MIDI_CONTROLLER_RPN_1         = 0x64;
+    static const MIDIByte MIDI_CONTROLLER_RPN_2         = 0x65;
+    static const MIDIByte MIDI_CONTROLLER_SOUNDS_OFF    = 0x78;
+    static const MIDIByte MIDI_CONTROLLER_RESET         = 0x79;
+    static const MIDIByte MIDI_CONTROLLER_LOCAL         = 0x7A;
+    static const MIDIByte MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7B;
+    static const MIDIByte MIDI_PERCUSSION_CHANNEL       = 9;
+
+    typedef enum {
+	MIDI_SINGLE_TRACK_FILE          = 0x00,
+	MIDI_SIMULTANEOUS_TRACK_FILE    = 0x01,
+	MIDI_SEQUENTIAL_TRACK_FILE      = 0x02,
+	MIDI_FILE_BAD_FORMAT            = 0xFF
+    } MIDIFileFormatType;
+}
+
+class MIDIEvent
+{
+public:
+    MIDIEvent(unsigned long deltaTime,
+              MIDIByte eventCode,
+              MIDIByte data1 = 0,
+              MIDIByte data2 = 0) :
+	m_deltaTime(deltaTime),
+	m_duration(0),
+	m_eventCode(eventCode),
+	m_data1(data1),
+	m_data2(data2),
+	m_metaEventCode(0)
+    { }
+
+    MIDIEvent(unsigned long deltaTime,
+              MIDIByte eventCode,
+              MIDIByte metaEventCode,
+              const std::string &metaMessage) :
+	m_deltaTime(deltaTime),
+	m_duration(0),
+	m_eventCode(eventCode),
+	m_data1(0),
+	m_data2(0),
+	m_metaEventCode(metaEventCode),
+	m_metaMessage(metaMessage)
+    { }
+
+    MIDIEvent(unsigned long deltaTime,
+              MIDIByte eventCode,
+              const std::string &sysEx) :
+	m_deltaTime(deltaTime),
+	m_duration(0),
+	m_eventCode(eventCode),
+	m_data1(0),
+	m_data2(0),
+	m_metaEventCode(0),
+	m_metaMessage(sysEx)
+    { }
+
+    ~MIDIEvent() { }
+
+    void setTime(const unsigned long &time) { m_deltaTime = time; }
+    void setDuration(const unsigned long& duration) { m_duration = duration;}
+    unsigned long addTime(const unsigned long &time) {
+	m_deltaTime += time;
+	return m_deltaTime;
+    }
+
+    int getMessageType() const
+        { return (m_eventCode & MIDIConstants::MIDI_MESSAGE_TYPE_MASK); }
+
+    int getChannelNumber() const
+        { return (m_eventCode & MIDIConstants::MIDI_CHANNEL_NUM_MASK); }
+
+    unsigned long getTime() const { return m_deltaTime; }
+    unsigned long getDuration() const { return m_duration; }
+
+    int getPitch() const { return m_data1; }
+    int getVelocity() const { return m_data2; }
+    int getData1() const { return m_data1; }
+    int getData2() const { return m_data2; }
+    int getEventCode() const { return m_eventCode; }
+
+    bool isMeta() const { return (m_eventCode == MIDIConstants::MIDI_FILE_META_EVENT); }
+
+    int getMetaEventCode() const { return m_metaEventCode; }
+    std::string getMetaMessage() const { return m_metaMessage; }
+    void setMetaMessage(const std::string &meta) { m_metaMessage = meta; }
+
+    friend bool operator<(const MIDIEvent &a, const MIDIEvent &b);
+
+private:
+    unsigned long  m_deltaTime;
+    unsigned long  m_duration;
+    MIDIByte       m_eventCode;
+    MIDIByte       m_data1;         // or Note
+    MIDIByte       m_data2;         // or Velocity
+    MIDIByte       m_metaEventCode;
+    std::string    m_metaMessage;
+};
+
+// Comparator for sorting
+//
+struct MIDIEventCmp
+{
+    bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const
+    { return mE1.getTime() < mE2.getTime(); }
+
+    bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const
+    { return mE1->getTime() < mE2->getTime(); }
+};
+
+class MIDIException : virtual public std::exception
+{
+public:
+    MIDIException(std::string message) throw() : m_message(message) {
+        std::cerr << "WARNING: MIDI exception: " << message.c_str() << std::endl;
+    }
+    virtual ~MIDIException() throw() { }
+
+    virtual const char *what() const throw() {
+	return m_message.c_str();
+    }
+
+protected:
+    std::string m_message;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/midiFileReader/MIDIFileReader.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,664 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    This is a modified version of a source file from the 
+    Rosegarden MIDI and audio sequencer and notation editor.
+    This file copyright 2000-2010 Richard Bown and Chris Cannam.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 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.
+
+    Except as contained in this notice, the names of the authors
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cstdio>
+
+#include "MIDIFileReader.h"
+#include "MIDIEvent.h"
+
+#include <sstream>
+
+using std::string;
+using std::ifstream;
+using std::stringstream;
+using std::cerr;
+using std::endl;
+using std::ends;
+using std::ios;
+
+using namespace MIDIConstants;
+
+//#define DEBUG_MIDI_FILE_READER 1
+
+#define throw_exception(...) do { \
+        char message[128]; \
+        snprintf(message, 128, __VA_ARGS__); \
+        throw MIDIException(std::string(message)); \
+    } while (0)
+    
+
+
+MIDIFileReader::MIDIFileReader(std::string path) :
+    m_timingDivision(0),
+    m_format(MIDI_FILE_BAD_FORMAT),
+    m_numberOfTracks(0),
+    m_trackByteCount(0),
+    m_decrementCount(false),
+    m_path(path),
+    m_midiFile(0),
+    m_fileSize(0)
+{
+    if (parseFile()) {
+	m_error = "";
+    }
+}
+
+MIDIFileReader::~MIDIFileReader()
+{
+}
+
+bool
+MIDIFileReader::isOK() const
+{
+    return (m_error == "");
+}
+
+std::string
+MIDIFileReader::getError() const
+{
+    return m_error;
+}
+
+long
+MIDIFileReader::midiBytesToLong(const string& bytes)
+{
+    if (bytes.length() != 4) {
+	throw_exception("Wrong length for long data in MIDI stream (%d, should be %d)", (int)bytes.length(), 4);
+    }
+
+    long longRet = ((long)(((MIDIByte)bytes[0]) << 24)) |
+                   ((long)(((MIDIByte)bytes[1]) << 16)) |
+                   ((long)(((MIDIByte)bytes[2]) << 8)) |
+                   ((long)((MIDIByte)(bytes[3])));
+
+    return longRet;
+}
+
+int
+MIDIFileReader::midiBytesToInt(const string& bytes)
+{
+    if (bytes.length() != 2) {
+	throw_exception("Wrong length for int data in MIDI stream (%d, should be %d)", (int)bytes.length(), 2);
+    }
+
+    int intRet = ((int)(((MIDIByte)bytes[0]) << 8)) |
+                 ((int)(((MIDIByte)bytes[1])));
+    return(intRet);
+}
+
+
+// Gets a single byte from the MIDI byte stream.  For each track
+// section we can read only a specified number of bytes held in
+// m_trackByteCount.
+//
+MIDIByte
+MIDIFileReader::getMIDIByte()
+{
+    if (!m_midiFile) {
+	throw_exception("getMIDIByte called but no MIDI file open");
+    }
+
+    if (m_midiFile->eof()) {
+        throw_exception("End of MIDI file encountered while reading");
+    }
+
+    if (m_decrementCount && m_trackByteCount <= 0) {
+        throw_exception("Attempt to get more bytes than expected on Track");
+    }
+
+    char byte;
+    if (m_midiFile->read(&byte, 1)) {
+	--m_trackByteCount;
+	return (MIDIByte)byte;
+    }
+
+    throw_exception("Attempt to read past MIDI file end");
+}
+
+
+// Gets a specified number of bytes from the MIDI byte stream.  For
+// each track section we can read only a specified number of bytes
+// held in m_trackByteCount.
+//
+string
+MIDIFileReader::getMIDIBytes(unsigned long numberOfBytes)
+{
+    if (!m_midiFile) {
+	throw_exception("getMIDIBytes called but no MIDI file open");
+    }
+
+    if (m_midiFile->eof()) {
+        throw_exception("End of MIDI file encountered while reading");
+    }
+
+    if (m_decrementCount && (numberOfBytes > (unsigned long)m_trackByteCount)) {
+        throw_exception("Attempt to get more bytes than available on Track (%lu, only have %ld)", numberOfBytes, m_trackByteCount);
+    }
+
+    string stringRet;
+    char fileMIDIByte;
+
+    while (stringRet.length() < numberOfBytes &&
+           m_midiFile->read(&fileMIDIByte, 1)) {
+        stringRet += fileMIDIByte;
+    }
+
+    // if we've reached the end of file without fulfilling the
+    // quota then panic as our parsing has performed incorrectly
+    //
+    if (stringRet.length() < numberOfBytes) {
+        stringRet = "";
+        throw_exception("Attempt to read past MIDI file end");
+    }
+
+    // decrement the byte count
+    if (m_decrementCount)
+        m_trackByteCount -= stringRet.length();
+
+    return stringRet;
+}
+
+
+// Get a long number of variable length from the MIDI byte stream.
+//
+long
+MIDIFileReader::getNumberFromMIDIBytes(int firstByte)
+{
+    if (!m_midiFile) {
+	throw_exception("getNumberFromMIDIBytes called but no MIDI file open");
+    }
+
+    long longRet = 0;
+    MIDIByte midiByte;
+
+    if (firstByte >= 0) {
+	midiByte = (MIDIByte)firstByte;
+    } else if (m_midiFile->eof()) {
+	return longRet;
+    } else {
+	midiByte = getMIDIByte();
+    }
+
+    longRet = midiByte;
+    if (midiByte & 0x80) {
+	longRet &= 0x7F;
+	do {
+	    midiByte = getMIDIByte();
+	    longRet = (longRet << 7) + (midiByte & 0x7F);
+	} while (!m_midiFile->eof() && (midiByte & 0x80));
+    }
+
+    return longRet;
+}
+
+
+// Seek to the next track in the midi file and set the number
+// of bytes to be read in the counter m_trackByteCount.
+//
+bool
+MIDIFileReader::skipToNextTrack()
+{
+    if (!m_midiFile) {
+	throw_exception("skipToNextTrack called but no MIDI file open");
+    }
+
+    string buffer, buffer2;
+    m_trackByteCount = -1;
+    m_decrementCount = false;
+
+    while (!m_midiFile->eof() && (m_decrementCount == false)) {
+        buffer = getMIDIBytes(4); 
+	if (buffer.compare(0, 4, MIDI_TRACK_HEADER) == 0) {
+	    m_trackByteCount = midiBytesToLong(getMIDIBytes(4));
+	    m_decrementCount = true;
+	}
+    }
+
+    if (m_trackByteCount == -1) { // we haven't found a track
+        return false;
+    } else {
+        return true;
+    }
+}
+
+
+// Read in a MIDI file.  The parsing process throws exceptions back up
+// here if we run into trouble which we can then pass back out to
+// whoever called us using a nice bool.
+//
+bool
+MIDIFileReader::parseFile()
+{
+    m_error = "";
+
+#ifdef DEBUG_MIDI_FILE_READER
+    cerr << "MIDIFileReader::open() : fileName = " << m_path.toStdString() << endl;
+#endif
+
+    // Open the file
+    m_midiFile = new ifstream(m_path.c_str(), ios::in | ios::binary);
+
+    if (!*m_midiFile) {
+	m_error = "File not found or not readable.";
+	m_format = MIDI_FILE_BAD_FORMAT;
+	delete m_midiFile;
+        m_midiFile = 0;
+	return false;
+    }
+
+    bool retval = false;
+
+    try {
+
+	// Set file size so we can count it off
+	//
+	m_midiFile->seekg(0, ios::end);
+	m_fileSize = m_midiFile->tellg();
+	m_midiFile->seekg(0, ios::beg);
+
+	// Parse the MIDI header first.  The first 14 bytes of the file.
+	if (!parseHeader(getMIDIBytes(14))) {
+	    m_format = MIDI_FILE_BAD_FORMAT;
+	    m_error = "Not a MIDI file.";
+	    goto done;
+	}
+
+	for (unsigned int j = 0; j < m_numberOfTracks; ++j) {
+
+#ifdef DEBUG_MIDI_FILE_READER
+	    cerr << "Parsing Track " << j << endl;
+#endif
+
+	    if (!skipToNextTrack()) {
+#ifdef DEBUG_MIDI_FILE_READER
+		cerr << "Couldn't find Track " << j << endl;
+#endif
+		m_error = "File corrupted or in non-standard format?";
+		m_format = MIDI_FILE_BAD_FORMAT;
+		goto done;
+	    }
+
+#ifdef DEBUG_MIDI_FILE_READER
+	    cerr << "Track has " << m_trackByteCount << " bytes" << endl;
+#endif
+
+	    // Run through the events taking them into our internal
+	    // representation.
+	    if (!parseTrack(j)) {
+#ifdef DEBUG_MIDI_FILE_READER
+		cerr << "Track " << j << " parsing failed" << endl;
+#endif
+		m_error = "File corrupted or in non-standard format?";
+		m_format = MIDI_FILE_BAD_FORMAT;
+		goto done;
+	    }
+	}
+	
+	retval = true;
+
+    } catch (MIDIException e) {
+
+        cerr << "MIDIFileReader::open() - caught exception - " << e.what() << endl;
+	m_error = e.what();
+    }
+    
+done:
+    m_midiFile->close();
+    delete m_midiFile;
+
+    for (unsigned int track = 0; track < m_numberOfTracks; ++track) {
+
+        // Convert the deltaTime to an absolute time since the track
+        // start.  The addTime method returns the sum of the current
+        // MIDI Event delta time plus the argument.
+
+	unsigned long acc = 0;
+
+        for (MIDITrack::iterator i = m_midiComposition[track].begin();
+             i != m_midiComposition[track].end(); ++i) {
+#ifdef DEBUG_MIDI_FILE_READER
+            cerr << "converting delta time " << i->getTime();
+#endif
+            acc = i->addTime(acc);
+#ifdef DEBUG_MIDI_FILE_READER
+            cerr << " to " << i->getTime() << endl;
+#endif
+        }
+
+        consolidateNoteOffEvents(track);
+    }
+
+    return retval;
+}
+
+// Parse and ensure the MIDI Header is legitimate
+//
+bool
+MIDIFileReader::parseHeader(const string &midiHeader)
+{
+    if (midiHeader.size() < 14) {
+#ifdef DEBUG_MIDI_FILE_READER
+        cerr << "MIDIFileReader::parseHeader() - file header undersized" << endl;
+#endif
+        return false;
+    }
+
+    if (midiHeader.compare(0, 4, MIDI_FILE_HEADER) != 0) {
+#ifdef DEBUG_MIDI_FILE_READER
+	cerr << "MIDIFileReader::parseHeader()"
+	     << "- file header not found or malformed"
+	     << endl;
+#endif
+	return false;
+    }
+
+    if (midiBytesToLong(midiHeader.substr(4,4)) != 6L) {
+#ifdef DEBUG_MIDI_FILE_READER
+        cerr << "MIDIFileReader::parseHeader()"
+	     << " - header length incorrect"
+	     << endl;
+#endif
+        return false;
+    }
+
+    m_format = (MIDIFileFormatType) midiBytesToInt(midiHeader.substr(8,2));
+    m_numberOfTracks = midiBytesToInt(midiHeader.substr(10,2));
+    m_timingDivision = midiBytesToInt(midiHeader.substr(12,2));
+
+#ifdef DEBUG_MIDI_FILE_READER
+    if (m_timingDivision < 0) {
+        cerr << "MIDIFileReader::parseHeader()"
+                  << " - file uses SMPTE timing"
+                  << endl;
+    }
+#endif
+
+    return true; 
+}
+
+// Extract the contents from a MIDI file track and places it into
+// our local map of MIDI events.
+//
+bool
+MIDIFileReader::parseTrack(unsigned int trackNum)
+{
+    MIDIByte midiByte, metaEventCode, data1, data2;
+    MIDIByte eventCode = 0x80;
+    string metaMessage;
+    unsigned int messageLength;
+    unsigned long deltaTime;
+    unsigned long accumulatedTime = 0;
+
+    // Remember the last non-meta status byte (-1 if we haven't seen one)
+    int runningStatus = -1;
+
+    while (!m_midiFile->eof() && (m_trackByteCount > 0)) {
+
+	if (eventCode < 0x80) {
+#ifdef DEBUG_MIDI_FILE_READER
+	    cerr << "WARNING: Invalid event code " << eventCode
+		 << " in MIDI file" << endl;
+#endif
+	    throw_exception("Invalid event code %d found", int(eventCode));
+	}
+
+        deltaTime = getNumberFromMIDIBytes();
+
+#ifdef DEBUG_MIDI_FILE_READER
+	cerr << "read delta time " << deltaTime << endl;
+#endif
+
+        // Get a single byte
+        midiByte = getMIDIByte();
+
+        if (!(midiByte & MIDI_STATUS_BYTE_MASK)) {
+
+	    if (runningStatus < 0) {
+		throw_exception("Running status used for first event in track");
+	    }
+
+	    eventCode = (MIDIByte)runningStatus;
+	    data1 = midiByte;
+
+#ifdef DEBUG_MIDI_FILE_READER
+	    cerr << "using running status (byte " << int(midiByte) << " found)" << endl;
+#endif
+        } else {
+#ifdef DEBUG_MIDI_FILE_READER
+	    cerr << "have new event code " << int(midiByte) << endl;
+#endif
+            eventCode = midiByte;
+	    data1 = getMIDIByte();
+	}
+
+        if (eventCode == MIDI_FILE_META_EVENT) {
+
+	    metaEventCode = data1;
+            messageLength = getNumberFromMIDIBytes();
+
+#ifdef DEBUG_MIDI_FILE_READER
+		cerr << "Meta event of type " << int(metaEventCode) << " and " << messageLength << " bytes found, putting on track " << metaTrack << endl;
+#endif
+            metaMessage = getMIDIBytes(messageLength);
+
+	    accumulatedTime += deltaTime;
+
+            MIDIEvent e(deltaTime,
+                        MIDI_FILE_META_EVENT,
+                        metaEventCode,
+                        metaMessage);
+
+	    m_midiComposition[trackNum].push_back(e);
+
+	    if (metaEventCode == MIDI_TRACK_NAME) {
+		m_trackNames[trackNum] = metaMessage.c_str();
+	    }
+
+        } else { // non-meta events
+
+	    runningStatus = eventCode;
+
+	    int channel = (eventCode & MIDI_CHANNEL_NUM_MASK);
+	    
+	    accumulatedTime += deltaTime;
+
+            switch (eventCode & MIDI_MESSAGE_TYPE_MASK) {
+
+            case MIDI_NOTE_ON:
+            case MIDI_NOTE_OFF:
+            case MIDI_POLY_AFTERTOUCH:
+            case MIDI_CTRL_CHANGE:
+                data2 = getMIDIByte();
+
+                {
+                // create and store our event
+                MIDIEvent midiEvent(deltaTime, eventCode, data1, data2);
+
+#ifdef DEBUG_MIDI_FILE_READER
+		cerr << "MIDI event for channel " << channel << " (track "
+                     << trackNum << ") with delta time " << deltaTime << endl;
+#endif
+
+                m_midiComposition[trackNum].push_back(midiEvent);
+                }
+                break;
+
+            case MIDI_PITCH_BEND:
+                data2 = getMIDIByte();
+
+                {
+                // create and store our event
+                MIDIEvent midiEvent(deltaTime, eventCode, data1, data2);
+                m_midiComposition[trackNum].push_back(midiEvent);
+                }
+                break;
+
+            case MIDI_PROG_CHANGE:
+            case MIDI_CHNL_AFTERTOUCH:
+                
+                {
+                // create and store our event
+                MIDIEvent midiEvent(deltaTime, eventCode, data1);
+                m_midiComposition[trackNum].push_back(midiEvent);
+                }
+                break;
+
+            case MIDI_SYSTEM_EXCLUSIVE:
+                messageLength = getNumberFromMIDIBytes(data1);
+
+#ifdef DEBUG_MIDI_FILE_READER
+		cerr << "SysEx of " << messageLength << " bytes found" << endl;
+#endif
+
+                metaMessage= getMIDIBytes(messageLength);
+
+                if (MIDIByte(metaMessage[metaMessage.length() - 1]) !=
+                        MIDI_END_OF_EXCLUSIVE)
+                {
+#ifdef DEBUG_MIDI_FILE_READER
+                    cerr << "MIDIFileReader::parseTrack() - "
+                              << "malformed or unsupported SysEx type"
+                              << endl;
+#endif
+                    continue;
+                }
+
+                // chop off the EOX 
+                // length fixed by Pedro Lopez-Cabanillas (20030523)
+                //
+                metaMessage = metaMessage.substr(0, metaMessage.length()-1);
+
+                {
+                MIDIEvent midiEvent(deltaTime,
+                                    MIDI_SYSTEM_EXCLUSIVE,
+                                    metaMessage);
+                m_midiComposition[trackNum].push_back(midiEvent);
+                }
+                break;
+
+            case MIDI_END_OF_EXCLUSIVE:
+#ifdef DEBUG_MIDI_FILE_READER
+                cerr << "MIDIFileReader::parseTrack() - "
+                          << "Found a stray MIDI_END_OF_EXCLUSIVE" << endl;
+#endif
+                break;
+
+            default:
+#ifdef DEBUG_MIDI_FILE_READER
+                cerr << "MIDIFileReader::parseTrack()" 
+                          << " - Unsupported MIDI Event Code:  "
+                          << (int)eventCode << endl;
+#endif
+                break;
+            } 
+        }
+    }
+
+    return true;
+}
+
+// Delete dead NOTE OFF and NOTE ON/Zero Velocity Events after
+// reading them and modifying their relevant NOTE ONs.  Return true
+// if there are some notes in this track.
+//
+bool
+MIDIFileReader::consolidateNoteOffEvents(unsigned int track)
+{
+    bool notesOnTrack = false;
+    bool noteOffFound;
+
+    MIDITrack &t = m_midiComposition[track];
+
+    for (MIDITrack::iterator i = t.begin(); i != t.end(); ++i) {
+
+        if (i->getMessageType() == MIDI_NOTE_ON && i->getVelocity() > 0) {
+
+#ifdef DEBUG_MIDI_FILE_READER
+            cerr << "Looking for note-offs for note at " << i->getTime() << " (pitch " << (int)i->getPitch() << ")" <<  endl;
+#endif
+
+	    notesOnTrack = true;
+            noteOffFound = false;
+
+            for (MIDITrack::iterator j = i; j != t.end(); ++j) {
+
+                if ((j->getChannelNumber() == i->getChannelNumber()) &&
+		    (j->getPitch() == i->getPitch()) &&
+                    (j->getMessageType() == MIDI_NOTE_OFF ||
+                    (j->getMessageType() == MIDI_NOTE_ON &&
+                     j->getVelocity() == 0x00))) {
+
+#ifdef DEBUG_MIDI_FILE_READER
+                    cerr << "Found note-off at " << j->getTime() << " for note at " << i->getTime() << endl;
+#endif
+
+                    i->setDuration(j->getTime() - i->getTime());
+
+#ifdef DEBUG_MIDI_FILE_READER
+                    cerr << "Duration is now " << i->getDuration() << endl;
+#endif
+
+                    t.erase(j);
+
+                    noteOffFound = true;
+                    break;
+                }
+            }
+
+            // If no matching NOTE OFF has been found then set
+            // Event duration to length of track
+            //
+            if (!noteOffFound) {
+#ifdef DEBUG_MIDI_FILE_READER
+                cerr << "Failed to find note-off for note at " << i->getTime() << endl;
+#endif
+		MIDITrack::iterator j = t.end();
+		--j;
+                i->setDuration(j->getTime() - i->getTime());
+	    }
+        }
+    }
+
+    return notesOnTrack;
+}
+
+MIDIComposition
+MIDIFileReader::load() const
+{
+    return m_midiComposition;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/midiFileReader/MIDIFileReader.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,93 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    This is a modified version of a source file from the 
+    Rosegarden MIDI and audio sequencer and notation editor.
+    This file copyright 2000-2010 Richard Bown and Chris Cannam.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 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.
+
+    Except as contained in this notice, the names of the authors
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#ifndef _MIDI_FILE_READER_H_
+#define _MIDI_FILE_READER_H_
+
+#include "MIDIComposition.h"
+
+#include <set>
+#include <iostream>
+
+typedef unsigned char MIDIByte;
+
+class MIDIFileReader
+{
+public:
+    MIDIFileReader(std::string path);
+    virtual ~MIDIFileReader();
+
+    virtual bool isOK() const;
+    virtual std::string getError() const;
+
+    virtual MIDIComposition load() const;
+
+    MIDIConstants::MIDIFileFormatType getFormat() const { return m_format; }
+    int getTimingDivision() const { return m_timingDivision; }
+
+protected:
+
+    bool parseFile();
+    bool parseHeader(const std::string &midiHeader);
+    bool parseTrack(unsigned int trackNum);
+    bool consolidateNoteOffEvents(unsigned int track);
+
+    // Internal convenience functions
+    //
+    int  midiBytesToInt(const std::string &bytes);
+    long midiBytesToLong(const std::string &bytes);
+
+    long getNumberFromMIDIBytes(int firstByte = -1);
+
+    MIDIByte getMIDIByte();
+    std::string getMIDIBytes(unsigned long bytes);
+
+    bool skipToNextTrack();
+
+    int                    m_timingDivision;   // pulses per quarter note
+    MIDIConstants::MIDIFileFormatType m_format;
+    unsigned int           m_numberOfTracks;
+
+    long                   m_trackByteCount;
+    bool                   m_decrementCount;
+
+    std::map<int, std::string> m_trackNames;
+    MIDIComposition        m_midiComposition;
+
+    std::string            m_path;
+    std::ifstream         *m_midiFile;
+    size_t                 m_fileSize;
+    std::string            m_error;
+};
+
+
+#endif // _MIDI_FILE_READER_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/BayesianArrayStructure.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,386 @@
+/*
+ *  BayesianArrayStructure.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "BayesianArrayStructure.h"
+
+BayesianArrayStructure::BayesianArrayStructure(){
+	printf("Bayesian structure: DeFault constructor called");
+	
+	prior.createVector(1);
+	likelihood.createVector(1);
+	posterior.createVector(1);
+
+	
+	tmpPrior.createVector(240);
+	tmpPrior.addGaussianShape(100, 40, 1);
+	tmpPrior.addGaussianShape(200, 10, 0.2);
+	tmpPrior.translateDistribution(20);
+	
+	lastEventTime = ofGetElapsedTimeMillis();
+	
+	speedDecayWidth = 20;
+	speedDecayAmount = 10;
+}
+
+BayesianArrayStructure::BayesianArrayStructure(int length){
+	printf("BAYESIAN STURTUCRE CREATED LENGTH: %i\n", length);
+	//this constructor isnt called  it seems
+	prior.createVector(length);
+	likelihood.createVector(length);
+	posterior.createVector(length);
+
+}
+
+
+
+void BayesianArrayStructure::resetSize(int length){
+	printf("BAYESIAN STRUCTURE size is : %i\n", length);
+	
+	prior.createVector(length);
+	likelihood.createVector(length);
+	posterior.createVector(length);
+	
+	acceleration.createVector(length);
+	
+}
+
+
+
+void BayesianArrayStructure::resetSpeedToOne(){
+	relativeSpeedPrior.zero();
+	relativeSpeedPosterior.zero();
+	relativeSpeedLikelihood.zero();
+	
+	relativeSpeedPosterior.addGaussianShape(40, 5, 0.6);
+	
+	relativeSpeedPosterior.addGaussianShape(100, 5, 0.8);
+	relativeSpeedPosterior.renormalise();
+	relativeSpeedPosterior.getMaximum();
+	
+	acceleration.addGaussianShape(2000, 20, 0.8);
+	
+}
+
+void BayesianArrayStructure::resetSpeedSize(int length){
+	printf("BAYESIAN SPEED size is : %i\n", length);
+	
+	relativeSpeedPrior.createVector(length);
+	relativeSpeedLikelihood.createVector(length);
+	relativeSpeedPosterior.createVector(length);
+	
+	
+
+}
+void BayesianArrayStructure::setRelativeSpeedScalar(double f){
+	relativeSpeedPrior.scalar = f;
+	relativeSpeedPosterior.scalar = f;
+	relativeSpeedLikelihood.scalar = f;
+}
+
+void BayesianArrayStructure::simpleExample(){
+	//simple example
+	prior.addGaussianShape(50, 10, 1);
+	prior.addGaussianShape(150, 30, 0.3);
+	prior.addGaussianShape(250, 30, 0.2);
+	
+	likelihood.addGaussianShape(90, 20, 0.6);
+	likelihood.addConstant(0.02);
+	posterior.doProduct(prior, likelihood);
+	
+//	relativeSpeedPosterior.addToIndex(100, 1);
+//	relativeSpeedPosterior.addToIndex(40, 0.7);	
+	relativeSpeedPosterior.addGaussianShape(100, 20, 1);
+//	relativeSpeedPosterior.addGaussianShape(10, 2, 0.5);
+	relativeSpeedPosterior.getMaximum();
+	
+}
+
+void BayesianArrayStructure::copyPriorToPosterior(){
+
+	for (int i = 0;i < prior.arraySize;i++){
+		posterior.array[i] = prior.array[i];
+	}
+}
+
+void BayesianArrayStructure::resetArrays(){
+	prior.zero();
+	likelihood.zero();
+	prior.addGaussianShape(0, 80, 1);
+	likelihood.addConstant(1);
+	posterior.zero();
+	posterior.addGaussianShape(0, 60, 1);
+	setNewDistributionOffsets(0);
+	bestEstimate = 0;
+//	lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
+	
+}
+
+void BayesianArrayStructure::updateBestEstimate(){
+	double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
+	
+	bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
+	// 
+	//lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
+}
+
+void BayesianArrayStructure::calculatePosterior(){
+	posterior.doProduct(prior, likelihood);
+	posterior.renormalise();
+	
+	/*
+	int i;
+	for (i = 0;i < prior.length;i++){
+	//	printf("priori [%i] is %f\n", i, prior[i]);
+		*(posterior+i) = *(prior+i);
+	//	posterior[i] = likelihood[i] * prior[i];
+	}
+	 */
+
+	 
+}
+
+
+
+
+void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
+	prior.offset = newOffset;
+	likelihood.offset = newOffset;
+//	posterior.offset = newOffset;
+}
+
+
+void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
+	//set the cutoff for offset of position first! XXX
+	
+//	printf("time difference %f, ", timeDifference);
+	
+	double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
+	
+	prior.zero();//kill prior
+	calculateNewPriorOffset(timeDifference);//set new prior offset here
+	
+	for (int i = 0;i < speed.arraySize;i++){
+//		printf("[%i] %f\n", i, speed.array[i]);
+		//set speed
+		double speedValue = speed.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
+
+		//so we have moved 
+		int distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
+		
+		if (speed.array[i] != 0){
+			
+		//	printf("speed [%i] gives %f moved %i\n", i, speedValue, distanceMoved);
+			
+		for (int postIndex = 0;postIndex < position.arraySize;postIndex++){
+		//old posterior contributing to new prior
+			int newPriorIndex = postIndex + position.offset - prior.offset + distanceMoved;
+			if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
+				prior.addToIndex(newPriorIndex, position.array[postIndex]*speed.array[i]);
+			//	printf("adding [%i] : %f\n", newPriorIndex, posterior.array[postIndex]*speed.array[i]);
+			}
+		
+		}
+			
+		}//if not zero
+	}//end speed
+
+	prior.renormalise();
+
+}
+
+void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
+	
+	double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
+	//	printf("Maxspeed is %f\n", maxSpeed);
+	
+	double priorMax = posterior.getMaximum();
+	double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
+	double newMaxLocation = posterior.MAPestimate + distanceTravelled;
+	//	printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
+	
+}
+
+
+void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
+	
+	// commented for the moment
+	 double relativeAmount = max(1.0, timeDifference/1000.);
+//	printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
+	relativeAmount *= speedDecayAmount;
+	relativeSpeedPosterior.renormalise();
+	relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
+	
+	relativeSpeedPosterior.renormalise();
+	double newMax = relativeSpeedPosterior.getMaximum();
+	
+	//old code
+//	relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
+	//relativeSpeedPosterior.addConstant(1);
+	
+	/*
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+	relativeSpeedLikelihood.zero();
+	relativeSpeedLikelihood.addConstant(0.2);
+	relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
+	relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+	relativeSpeedPosterior.renormalise();
+	 */
+	
+
+	
+}
+
+void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
+	//speedratio is speed of played relative to the recording
+	
+	double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
+//	printf("\nindex of likelihood would be %f\n", index);
+	if (index >= 0 && index < relativeSpeedPrior.length){
+		//then we can do update
+		
+		//set new likelihood
+		relativeSpeedLikelihood.zero();
+		relativeSpeedLikelihood.addConstant(0.02);
+		
+	relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
+	
+
+	//copy posterior to prior
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+
+	//update
+	relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+
+	//normalise
+	relativeSpeedPosterior.renormalise();
+		
+	relativeSpeedPosterior.getMaximum();	
+	}//end if within range
+	
+
+}
+
+
+void BayesianArrayStructure::setFlatTempoLikelihood(){	//set new likelihood
+	relativeSpeedLikelihood.zero();
+	relativeSpeedLikelihood.addConstant(0.3);
+}
+
+void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
+	
+	double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
+
+	if (index >= 0 && index < relativeSpeedPrior.length){
+		relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5);//*matchFactor);
+	}
+}
+
+
+void BayesianArrayStructure::calculateTempoUpdate(){
+	//copy posterior to prior
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+	
+	//update
+	relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+	
+	//normalise
+	relativeSpeedPosterior.renormalise();
+	
+	relativeSpeedPosterior.getMaximum();	
+	
+}
+
+
+void BayesianArrayStructure::drawArrays(){
+	
+	//bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
+	//bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
+	
+	int displaySize = prior.arraySize;
+	ofSetColor(255,0,0);
+	prior.drawVector(0, displaySize);
+	ofSetColor(0,255,0);
+	likelihood.drawVector(0, displaySize);
+	ofSetColor(0,0,255);
+	posterior.drawVector(0, displaySize);
+	ofSetColor(255,255,0);
+	relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
+	
+//	ofSetColor(255,255,255);
+//	tmpPrior.drawVector(0,300);
+	
+}
+
+
+void BayesianArrayStructure::drawTempoArrays(){
+	ofSetColor(0,255,255);
+	relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
+	
+	ofSetColor(255,0,255);
+	relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
+	
+	ofSetColor(255,255,0);
+	relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
+	
+	ofSetColor(255,255, 255);
+	ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
+	
+	ofSetColor(0, 255, 0);
+	double fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
+	ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
+}
+
+
+void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
+
+	screenWidth = ofGetWidth();
+	
+	int startArrayIndex = 0;
+	
+	if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
+		//i.e. the array is on the page
+	
+	while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
+		startArrayIndex++;
+	}
+	int endArrayIndex = prior.arraySize-1;
+	//could find constraints here
+	if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
+		endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
+	
+	//so we need to figure where start and end array are on screen
+	int startScreenPosition, endScreenPosition;
+	double screenWidthMillis = endTimeMillis - startTimeMillis;
+		
+	startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
+	endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
+		
+	ofSetColor(0,0,100);
+	string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
+	relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
+//	relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+")  ";
+	relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
+	ofDrawBitmapString(relativeString, 100, 180);
+		
+	ofSetColor(0, 200, 0);
+	likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+
+	ofSetColor(0,0,200);
+	prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+		
+	ofSetColor(200, 0, 0);
+	posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+		
+//	ofSetColor(0, 200, 255);
+//	acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+		
+		
+	}
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/BayesianArrayStructure.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,72 @@
+/*
+ *  BayesianArrayStructure.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "ofMain.h"
+//#include "DynamicBayesianArray.h"
+#include "DynamicVector.h"
+
+class BayesianArrayStructure {
+	
+public:
+//	BayesianArrayStructure();
+	BayesianArrayStructure();
+	BayesianArrayStructure(int length);
+	
+	void calculatePosterior();
+	void drawArrays();
+	void drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis);
+
+	void drawTempoArrays();
+	
+	void resetSize(int length);
+	void resetArrays();
+	void simpleExample();
+	
+	double screenWidth;
+	
+	void copyPriorToPosterior();
+//	DynamicBayesianArray bayesArray;
+	
+	double lastEventTime;
+	
+	DynamicVector tmpPrior;
+	
+	DynamicVector prior;
+	DynamicVector posterior;
+	DynamicVector likelihood;
+	
+	DynamicVector relativeSpeedPrior;
+	DynamicVector relativeSpeedLikelihood;
+	DynamicVector relativeSpeedPosterior;
+	DynamicVector acceleration;
+	
+	void resetSpeedToOne();
+	
+	double bestEstimate;
+	void updateBestEstimate();
+//	double lastBestEstimateUpdateTime;
+	
+	double speedDecayWidth, speedDecayAmount;
+	void decaySpeedDistribution(double timeDifference);
+	
+	void resetSpeedSize(int length);
+	void setRelativeSpeedScalar(double f);
+	void calculateNewPriorOffset(const double& timeDifference);
+	void setNewDistributionOffsets(const double& newOffset);
+	
+	void updateTempoDistribution(const double& speedRatio, const double& matchFactor);
+	
+	void setFlatTempoLikelihood();
+	void calculateTempoUpdate();
+	void updateTempoLikelihood(const double& speedRatio, const double& matchFactor);
+	
+	void crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference);
+	
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/DynamicBayesianArray.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,326 @@
+/*
+ *  DynamicDynamicBayesianArray.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "DynamicBayesianArray.h"
+#include "math.h"
+#include "ofMain.h"
+
+DynamicBayesianArray::DynamicBayesianArray(){
+	
+//	prior.createVector(240);
+//	likelihood.createVector(240);
+//	posterior.createVector(240);	
+	testVector.createVector(240);
+	testVector.addGaussianShape(100,10, 0.1);
+	
+	
+	likelihoodNoise = 0.5;
+	likelihoodMean = ARRAY_SIZE/2;
+	likelihoodStdDev = ARRAY_SIZE / 12;
+	initialiseArray();
+}
+
+void DynamicBayesianArray::initialiseArray(){
+	
+	//maximumIndex = 12;//change this
+	setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1);	
+	setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev);
+	
+	calculatePosterior();
+	renormalisePosterior();
+	posteriorDecayRate = 0.06;
+	
+	eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4
+	earlySixteenthNoteProportion = 0;
+	lateSixteenthNoteProportion = 0;
+	decayNoiseAmount = 0.1;
+	decayNoiseStdDev = ARRAY_SIZE/24;
+	standardDeviation = likelihoodStdDev;
+	setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev);
+	
+	setGaussianLikelihood(likelihoodMean, likelihoodStdDev);
+}
+
+
+void DynamicBayesianArray::setGaussianPrior(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		prior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+		//posterior[i] = prior[i];
+	}
+}
+
+void DynamicBayesianArray::setGaussianPosterior(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+}
+
+
+void DynamicBayesianArray::setGaussianLikelihood(float mean, float StdDev){
+	if (mean >= 0 && mean <= ARRAY_SIZE){
+		int i;	float eighthDifference;
+		int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
+		float mainDifference;
+		float gaussianProportion = 1 - likelihoodNoise;
+		
+		for (i=0;i < ARRAY_SIZE;i++){
+			
+			mainDifference = min( double(fabs(i-mean)) , (double)(i + ARRAY_SIZE - mean));
+			//without * (1 - eighthNoteProportion)
+			likelihood[i] = gaussianProportion  * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
+			
+			likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
+			//likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , 
+			//(double) (likelihoodNoise / ARRAY_SIZE) );
+		}
+		//	renormaliseArray(&likelihood[0], ARRAY_SIZE);
+	}//end if mean within limits
+}
+
+void DynamicBayesianArray::calculatePosterior(){
+	int i;
+	for (i=0;i < ARRAY_SIZE;i++){
+		posterior[i] = likelihood[i] * prior[i];
+	}
+	//renormalisePosterior();
+}
+
+
+float DynamicBayesianArray::getMaximum(float *ptr, int length){
+	int i;
+	float max = 0;
+	for (i=0;i < length;i++){	
+		if (*(ptr+i)>max)
+			max = *(ptr+i);
+	}
+	maximumValue = max;
+	return max;
+}
+
+float* DynamicBayesianArray::getMaximumEstimate(float *ptr, int length){
+	float returnArray[2];
+	int i;
+	float max = 0;
+	maximumIndex = 0;
+	for (i=0;i < length;i++){	
+		if (*(ptr+i)>max){
+			max = *(ptr+i);
+			maximumIndex = i;
+		}
+	}
+	returnArray[0] = max;
+	returnArray[1] = maximumIndex;
+	maximumValue = max;
+	return &returnArray[0];
+}
+
+
+
+double DynamicBayesianArray::getIntegratedEstimateIndex(){
+	int i;
+	float integratedQuantity = 0;
+	float integratedTotal = 0;
+	double integratedIndex = 0;
+	for (i=0;i < ARRAY_SIZE;i++){	
+		integratedQuantity += posterior[i];//the values of the probability distribution
+		integratedTotal += i*posterior[i];
+	}
+	if (integratedQuantity > 0){
+		integratedIndex = integratedTotal / integratedQuantity;
+	}
+	integratedEstimate = (float) integratedIndex;
+	return integratedIndex;
+}
+
+
+double DynamicBayesianArray::calculateStandardDeviation(){
+	
+	double total = 0;
+	double pdfSum;
+	double variance = 0;
+	for (int i=0;i < ARRAY_SIZE;i++){	
+		//*posterior[i] * 		
+		total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution
+		pdfSum += posterior[i];
+	}
+	
+	if (pdfSum > 0)
+		variance = total / pdfSum;
+	else 
+		variance = ARRAY_SIZE;
+	
+	standardDeviation = sqrt(variance);
+	return standardDeviation;
+}
+
+
+
+void DynamicBayesianArray::renormaliseArray(float *ptr, int length){
+	int i;
+	float totalArea = 0;
+	for (i=0;i < length;i++){
+		totalArea += *(ptr+i);
+	}
+	
+	for (i=0;i < length;i++){
+		*(ptr+i) /= totalArea;
+	}
+	
+}
+
+void DynamicBayesianArray::resetPrior(){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		prior[i] = posterior[i];
+	}
+}
+
+void DynamicBayesianArray::renormalisePosterior(){
+	int i;
+	float totalArea = 0;
+	for (i=0;i < ARRAY_SIZE;i++){
+		totalArea += posterior[i];
+	}
+	
+	for (i=0;i < ARRAY_SIZE;i++){
+		posterior[i] /= totalArea;
+	}
+	
+}
+
+void DynamicBayesianArray::decayPosterior(){
+	float *pointer;
+	pointer = getMaximumEstimate(&posterior[0], ARRAY_SIZE);	
+	float maximum;
+	maximum = *pointer;
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] += (maximum - posterior[i]) * posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
+	}
+	maximumIndex = *(pointer+1);
+}
+
+void DynamicBayesianArray::setDecayNoiseGaussian(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		decayNoiseArray[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+}
+
+void DynamicBayesianArray::decayPosteriorWithGaussianNoise(){
+	
+	int i;
+	float currentMaximum = getMaximum(&posterior[0], ARRAY_SIZE);
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] += decayNoiseArray[(i - (int)maximumIndex + ((3*ARRAY_SIZE)/2)) % ARRAY_SIZE] * currentMaximum * decayNoiseAmount;
+		//posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
+	}
+	
+}
+
+void DynamicBayesianArray::resetMaximumPosterior(){
+	int i;
+	float max = 0;
+	for (i=0;i < ARRAY_SIZE;i++){	
+		if (posterior[i]>max){
+			maximumIndex = i;
+			max = posterior[i];
+		}
+	}
+}
+
+void DynamicBayesianArray::translateDistribution(int translationIndex){
+	int tmpIndex;
+	//copy array
+	int i;
+	for (i=0;i < ARRAY_SIZE;i++){
+		tempPosteriorArray[i] =	posterior[i] ;
+	}
+	//translate values
+	for (i=0;i < ARRAY_SIZE;i++){
+		tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE;
+		posterior[tmpIndex] = tempPosteriorArray[i]; 
+	}
+	//now delete tmp array
+}
+
+
+void DynamicBayesianArray::drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex){
+	
+	if (minIndex >= 0){
+	
+		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
+		double screenHeight = ofGetHeight();
+		double maxVal = getMaximum(&arrayToDraw[0], maxIndex);
+
+		for (int i = minIndex+1;i < maxIndex;i++){
+		
+			ofLine (stepSize*(i-1), screenHeight * (1 - arrayToDraw[i-1] / maxVal), stepSize*i, screenHeight * (1 - arrayToDraw[i] / maxVal) );
+		}
+	
+	}
+		
+		
+}
+
+ 
+
+/*
+void DynamicBayesianArray::drawDoubleArray(double[]& arrayToDraw, const int& minIndex, const int& maxIndex){
+
+	if (minIndex >= 0 && maxIndex <= arrayToDraw.size(0))
+
+}
+*/
+/*
+ void DynamicBayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){
+ //this has eighth and sixteenth positions included
+ 
+ if (mean >= 0 && mean <= ARRAY_SIZE){
+ int i;	float eighthDifference;
+ int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
+ int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;;
+ int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;;
+ 
+ float mainDifference, sixteenthDifference;
+ float gaussianProportion = 1 - likelihoodNoise;
+ float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion);
+ 
+ for (i=0;i < ARRAY_SIZE;i++){
+ 
+ mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean));
+ likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
+ 
+ eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition);
+ eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ;
+ 
+ sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition);
+ sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
+ 
+ sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition);
+ sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
+ 
+ 
+ 
+ likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
+ //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , 
+ //(double) (likelihoodNoise / ARRAY_SIZE) );
+ }
+ //	renormaliseArray(&likelihood[0], ARRAY_SIZE);
+ }//end if mean within limits
+ }
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/DynamicBayesianArray.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,104 @@
+/*
+ *  DynamicBayesianArray.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+/*
+ *  DynamicBayesianArray.cpp
+ *  bayesianTest5
+ *
+ *  Created by Andrew Robertson on 08/05/2010.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+/*
+ *  DynamicBayesianArray.h
+ *  bayesianTest5
+ *
+ *  Created by Andrew Robertson on 08/05/2010.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "ofMain.h"
+
+#include "DynamicVector.h"
+
+#ifndef	_DYNAMIC_BAYESIAN_ARRAY
+#define _DYNAMIC_BAYESIAN_ARRAY
+
+#define ARRAY_SIZE 240
+
+
+class DynamicBayesianArray{
+	
+public:
+	
+	DynamicBayesianArray();
+	void initialiseArray();
+	
+//	void setGaussianLikelihoodForBeats(float mean, float StdDev);		
+	void setGaussianLikelihood(float mean, float StdDev);	
+	void setGaussianPrior(float mean, float StdDev);
+	void setGaussianPosterior(float mean, float StdDev);
+	
+	void calculatePosterior();
+	void renormalisePosterior();
+	void resetMaximumPosterior();//resets the max index
+	void decayPosteriorWithGaussianNoise();
+	void translateDistribution(int translationIndex);
+	void setDecayNoiseGaussian(float mean, float StdDev);
+	double calculateStandardDeviation();
+	
+	int arraySize;
+	
+	
+	float getMaximum(float *ptr, int length);
+	void renormaliseArray(float *ptr, int length);
+	void resetPrior();
+	void decayPosterior();
+	float* getMaximumEstimate(float *ptr, int length);
+	double getIntegratedEstimateIndex();
+	
+//	void drawArray(const int& minIndex, const int& maxIndex);
+	void drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex);
+	void drawDoubleArray(double* arrayToDraw, const int& minIndex, const int& maxIndex);		
+
+	
+	typedef std::vector<double> DoubleVector;
+//	typedef std::vector<IntVector> DoubleMatrix;
+	
+	
+//	DynamicVector prior;
+//	DynamicVector posterior;
+//	DynamicVector likelihood;
+	
+	DynamicVector testVector;	
+//	DynamicVector prior;
+	
+	float prior [ARRAY_SIZE];
+	float posterior [ARRAY_SIZE];
+	float likelihood [ARRAY_SIZE];	
+	float tempPosteriorArray[ARRAY_SIZE];
+	
+	float decayNoiseArray[ARRAY_SIZE];
+	float decayNoiseStdDev, decayNoiseAmount;
+	
+	float likelihoodMean, likelihoodStdDev, likelihoodNoise;
+	float maximumTest, posteriorDecayRate, maximumValue;
+	float eighthNoteProportion, earlySixteenthNoteProportion, lateSixteenthNoteProportion ;
+	float maximumEstimate, maximumIndex, integratedEstimate;
+	double standardDeviation;
+	
+private:
+};
+
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/DynamicVector.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,175 @@
+/*
+ *  DynamicVector.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 18/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "DynamicVector.h"
+
+DynamicVector::DynamicVector(){
+	length = 0;
+	arraySize = 0;
+	maximumValue = 0;
+	MAPestimate = 0;
+	offset = 0;
+	scalar = 1;
+}
+
+void DynamicVector::copyFromDynamicVector(const DynamicVector& dynamicVec){
+	if (dynamicVec.length == length){
+		for (int i = 0;i < length;i++)
+			array[i] = dynamicVec.array[i];
+	}
+	else{
+		printf("CANNOT COPY VECTORS OF NON SAME LENGTH!!\n");
+	}
+}
+
+void DynamicVector::createVector(int len){
+	array.clear();
+	for (int i = 0; i < len;i++){
+		array.push_back(0);
+	}
+	length = len;
+	arraySize = array.size();
+}
+
+
+double DynamicVector::getMaximum(){
+	int i;
+	double max = 0;
+	for (i=0;i < length;i++){	
+		if (array[i] > max){
+			max = array[i];
+			MAPestimate = i;
+		}
+	}
+	maximumValue = max;
+	return max;
+}
+
+void DynamicVector::zero(){
+	for (int i = 0;i < array.size();i++)
+		array[i] = 0;
+}
+
+void DynamicVector::renormalise(){
+	double tmpMax = getMaximum();
+	if (tmpMax > 0){
+//	printf("renormalise : max is %f and size is %i\n", tmpMax, arraySize);		
+		for (int i = 0;i < array.size();i++)
+			array[i] /= tmpMax;
+
+	}
+	//printArray();
+}
+
+void DynamicVector::doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo){
+
+	for (int i = 0;i < arrayOne.length;i++)
+		array[i] = arrayOne.array[i] * arrayTwo.array[i];
+}
+
+
+void DynamicVector::printArray(){
+	for (int i = 0;i < arraySize;i++){
+		printf("[%i] = %f\n", i, array[i]);
+	}
+}
+
+void DynamicVector::translateDistribution(int translationIndex){
+	int tmpIndex;
+	DoubleVector tmpArray;
+	int i;
+
+	for (i=0;i < arraySize;i++){
+		tmpArray.push_back(array[i]);
+	}
+	//translate values
+	for (i=0;i < arraySize;i++){
+		tmpIndex = (i + translationIndex + arraySize)%arraySize;
+		array[tmpIndex] = tmpArray[i]; 
+	}
+	tmpArray.clear();
+	//now delete tmp array
+}
+
+void DynamicVector::addGaussianShape(double mean, double StdDev, double factor){
+	int i;
+	for (i=0;i<array.size();i++){
+		array[i] += factor*(1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+	//printf("ADDED GAUSSIAN SHAPE %i\n", (int)array.size());
+}
+
+void DynamicVector::addConstant(double value){
+	for (int i=0;i<array.size();i++){
+		array[i] += value;
+	}
+}
+
+
+void DynamicVector::addToIndex(int index, double constant){
+	array[index] += constant;
+}
+
+
+double DynamicVector::getIndexInRealTerms(const int& index){
+	if (index < arraySize)
+		return (offset + scalar*index);
+	else
+		return 0;
+}
+
+double DynamicVector::getRealTermsAsIndex(double value){
+	value -= offset;
+	value /= scalar;
+	
+	return value;
+	
+}
+
+void DynamicVector::drawVector(const int& minIndex, const int& maxIndex){
+
+		
+		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
+		double screenHeight = ofGetHeight();
+		double maxVal = getMaximum();
+		
+		for (int i = max(1,minIndex+1);i < min(maxIndex, (int)array.size());i++){
+		ofLine (stepSize*(i-1), screenHeight * (1 - array[i-1] / maxVal), stepSize*i, screenHeight * (1 - array[i] / maxVal) );
+		}
+	
+}
+
+
+void DynamicVector::drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex){
+	//constrain the height and width
+	
+	double stepSize = (maxScreenIndex - minScreenIndex) / (double)(maxIndex - minIndex);//step size in pixels per array bin 
+	double screenHeight = ofGetHeight();
+	double maxVal = getMaximum();
+
+	//OPTIMIZE!! XXX could just add stepsize each time
+	//not add minindex each time
+	int i = max(1,minIndex+1);
+//	ofDrawBitmapString("i = "+ofToString(i)+"  :: screen min: "+ofToString(minScreenIndex + stepSize*(i-minIndex-1)), 20, 640);
+	
+	while ((minScreenIndex + stepSize*(i-minIndex)) < 0)
+		i++;//only draw what is on the screen
+	
+	for ( ; i < min(maxIndex+1, (int)array.size());i++){
+		ofLine (minScreenIndex + (stepSize*(i-minIndex-1)), screenHeight * (1 - array[i-1] / maxVal), 
+				minScreenIndex + (stepSize*(i-minIndex)),	 screenHeight * (1 - array[i] / maxVal) );
+		
+	}
+	
+	ofLine(minScreenIndex, screenHeight, minScreenIndex, screenHeight/2);
+	ofLine(maxScreenIndex, screenHeight, maxScreenIndex, screenHeight/2);
+	
+//	ofDrawBitmapString(ofToString(stepSize, 2)+"  "+ofToString(maxScreenIndex - minScreenIndex, 0), 20, 600);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/DynamicVector.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,56 @@
+/*
+ *  DynamicVector.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 18/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+//OPTIMIZE CONSTRAINED VECTOR
+
+#include "stdlib.h"
+#include "ofMain.h"
+
+#ifndef _DYNAMIC_VECTOR
+#define _DYNAMIC_VECTOR
+
+class DynamicVector{
+public:
+	DynamicVector();
+
+	void createVector(int len);
+	void renormalise();
+	void translateDistribution(int translationIndex);
+	typedef std::vector<double> DoubleVector;
+	DoubleVector array;
+	double getMaximum();
+	void drawVector(const int& minIndex, const int& maxIndex);
+	void drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex);
+
+	void addConstant(double value);
+	void addGaussianShape(double mean, double stddev, double factor);
+	void addToIndex(int index, double constant);
+	
+	void doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo);
+		
+	double getIndexInRealTerms(const int& index);
+	double getRealTermsAsIndex(double value);
+	
+	void printArray();
+	void zero();
+	
+	void copyFromDynamicVector(const DynamicVector& dynamicVec);
+	
+	//variables
+	int length, arraySize;
+	double maximumValue;
+	int MAPestimate;
+	
+	double offset;
+	double scalar;//each array point is this much of the quantity
+	//i.e. array[index] contributes to (offset + scalar*index) in real terms
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/drawMidiNotes.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,87 @@
+/*
+ *  drawMidiNotes.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "drawMidiNotes.h"
+
+drawMidiNotes::drawMidiNotes(){
+
+	
+	ticksPerScreen = 8000;
+	tickLocation = 0;
+	pulsesPerQuarternote = 240;
+	noteArrayIndex = 0;
+	noteMinimum = 30;
+	noteMaximum = 96;
+	screenWidth = ofGetWidth();
+	screenHeight = ofGetHeight();
+	noteHeight = screenHeight / (float)(noteMaximum - noteMinimum);
+}
+
+void drawMidiNotes::reset(){
+	noteArrayIndex = 0;
+	tickLocation = 0;
+	lastPeriodUpdateTime = ofGetElapsedTimeMillis();
+	
+}
+
+void drawMidiNotes::updatePlayPosition(){
+	double timeDifference = ofGetElapsedTimeMillis() - lastPeriodUpdateTime;
+	//this is time diff in milliseconds
+	//then we have 
+	double quarterNoteIntervals = (timeDifference / period);
+	tickLocation = quarterNoteIntervals * pulsesPerQuarternote; 
+
+}
+
+void drawMidiNotes::drawFile(const IntMatrix& noteOnMatrix){
+	int size = noteOnMatrix.size();
+	if (size > 0){
+
+		int numberOfScreensIn = tickLocation / ticksPerScreen;
+		
+	while (noteArrayIndex < noteOnMatrix.size() && tickLocation > noteOnMatrix[noteArrayIndex][0] )
+		noteArrayIndex++;
+	
+	while (noteArrayIndex > 0 && noteArrayIndex < size && tickLocation < noteOnMatrix[noteArrayIndex][0])
+		noteArrayIndex--;
+		
+		//need to start where we currently are in file
+		int maxNoteIndexToPrint	= noteArrayIndex;
+		int minNoteIndexToPrint = noteArrayIndex;
+		
+		
+		while (maxNoteIndexToPrint < noteOnMatrix.size() && noteOnMatrix[maxNoteIndexToPrint][0] < (numberOfScreensIn+1)*ticksPerScreen )
+			maxNoteIndexToPrint++;
+		
+		while (minNoteIndexToPrint > 0 && minNoteIndexToPrint < size && noteOnMatrix[minNoteIndexToPrint][0] > numberOfScreensIn*ticksPerScreen)
+			minNoteIndexToPrint--;
+		
+		
+		for (int tmpIndex = minNoteIndexToPrint;tmpIndex < maxNoteIndexToPrint;tmpIndex++){
+		int xLocation = (float)(noteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*screenWidth/(float)ticksPerScreen;
+			int duration = (float)(noteOnMatrix[tmpIndex][3]*screenWidth)/(float)ticksPerScreen;
+			
+			
+		int yLocation = screenHeight - ((noteOnMatrix[tmpIndex][1] - noteMinimum )*screenHeight/ (float)(noteMaximum - noteMinimum));						 
+		ofRect(xLocation,yLocation, duration,  noteHeight);
+		
+		}
+		
+			int xLocation = (float)(tickLocation - numberOfScreensIn*ticksPerScreen)*screenWidth/(float)ticksPerScreen;
+		ofLine(xLocation, 0, xLocation, screenHeight);
+	
+	//	if (noteArrayIndex < size )
+	//		printf("tick %i :: note array :%i: %i\n", tickLocation, noteArrayIndex, noteOnMatrix[noteArrayIndex][0]);
+	//	else
+	//		printf("end of file\n");
+
+		
+	}	
+		
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/drawMidiNotes.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,42 @@
+/*
+ *  drawMidiNotes.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+
+#include "ofMain.h"
+
+class drawMidiNotes{
+public:
+	drawMidiNotes();
+	void updatePlayPosition();
+	
+	typedef std::vector<double> DoubleVector;
+	typedef std::vector<DoubleVector> DoubleMatrix;
+	
+	DoubleMatrix beatPeriodMatrix;
+	
+	typedef std::vector<int> IntVector;
+	typedef std::vector<IntVector> IntMatrix;
+	
+	void drawFile(const IntMatrix& noteOnMatrix);
+	void reset();
+	
+	int ticksPerScreen;
+	int tickLocation;
+	int noteArrayIndex;
+	
+	int noteMinimum, noteMaximum;
+	int screenWidth, screenHeight;
+	float noteHeight;
+	float tempo;
+	double period;
+	int pulsesPerQuarternote;
+	double lastPeriodUpdateTime;
+					 
+	
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,16 @@
+#include "ofMain.h"
+#include "testApp.h"
+#include "ofAppGlutWindow.h"
+
+//========================================================================
+int main( ){
+
+    ofAppGlutWindow window;
+	ofSetupOpenGL(&window, 1024,768, OF_WINDOW);			// <-------- setup the GL context
+
+	// this kicks off the running of my app
+	// can be OF_WINDOW or OF_FULLSCREEN
+	// pass in width and height too:
+	ofRunApp( new testApp());
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/midiEventHolder.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,429 @@
+/*
+ *  midiEventHolder.cpp
+ *  midiCannamReader3
+ *
+ *  Created by Andrew on 19/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+//hello
+
+#include "midiEventHolder.h"
+
+midiEventHolder::midiEventHolder(){
+//	recordedNoteOnIndex = 0;
+	
+	width = ofGetWidth();
+	height = ofGetHeight();
+	screenWidth= &width;
+	screenHeight = &height;
+	
+	ticksPerScreen = 4000;
+	tickLocation = 0;
+	pulsesPerQuarternote = 240;
+	noteArrayIndex = 0;
+	noteMinimum = 30;
+	noteMaximum = 96;
+	
+	minimumMatchSpeed = 0.5;
+	maximumMatchSpeed = 2.0;
+	likelihoodWidth = 100;
+	likelihoodToNoiseRatio = 50;
+	
+	matchWindowWidth = 6000;//window size for matching in ms 
+	
+	bayesStruct.resetSize(4000);
+	bayesStruct.resetSpeedSize(200);
+	bayesStruct.setRelativeSpeedScalar(0.01);
+	bayesStruct.relativeSpeedPrior.getMaximum();
+	bayesStruct.simpleExample();
+	
+	noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum);
+}
+
+
+
+void midiEventHolder::reset(){
+	noteArrayIndex = 0;
+	tickLocation = 0;
+	lastPeriodUpdateTime = ofGetElapsedTimeMillis();
+	bayesStruct.lastEventTime = ofGetElapsedTimeMillis();
+	numberOfScreensIn = 0;
+//	recordedNoteOnIndex = 0;
+	bayesStruct.setNewDistributionOffsets(0);
+	bayesStruct.posterior.offset = 0;
+	
+	playedEventTimes.clear();
+	playedNoteOnMatrix.clear();
+	matchMatrix.clear();
+	
+	bayesStruct.resetSpeedToOne();
+	
+}
+
+void midiEventHolder::printNotes(){
+	printf("RECORDED MATRIX");
+	for (int i = 0;i < recordedNoteOnMatrix.size();i++){
+		printf("%i :: %i @ %f\n", recordedNoteOnMatrix[i][0], recordedNoteOnMatrix[i][1], recordedEventTimes[i]);
+	}
+}
+
+
+double midiEventHolder::getEventTimeTicks(double millis){
+	return (millis * pulsesPerQuarternote / period);
+}
+
+double midiEventHolder::getEventTimeMillis(double ticks){
+	return (period * ticks / (double) pulsesPerQuarternote);
+}
+
+void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){
+	
+	//MOVE INTO BAYESSTRUCT?? XXX
+	//bayesStruct.copyPriorToPosterior();
+	//why was this here??
+	bayesStruct.prior.copyFromDynamicVector(bayesStruct.posterior);//try the otehr way
+	//bayesStruct.copyPriorToPosterior();
+	//need to get new MAP position and set the offset of the arrays
+	//currently bestEstimate is the approx for the new MAP position
+	
+	
+	//add the new event to our played information matrix
+	IntVector v;
+	v.push_back(pitch);
+	v.push_back(velocity);
+	playedNoteOnMatrix.push_back(v);
+
+	
+	//would update the arrays at this point to show where out current location (phase) and tempo is.
+	double timeNow = ofGetElapsedTimeMillis() - startTime;
+	recentNoteOnTime = timeNow;
+	
+	printf("Max time %f OF time %f \n", timePlayed, timeNow);
+	
+	playedEventTimes.push_back(timePlayed);
+	
+	double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime; 
+	
+	//addnoise to the tempo distribution
+	bayesStruct.decaySpeedDistribution(timeDifference);
+
+	
+//	double newMAPestimateTime = bayesStruct.posterior.getIndexInRealTerms(bayesStruct.posterior.MAPestimate);
+	//was offset + bayesStruct.posterior.MAPestimate; but this doesnt include scalar to convert to millis
+
+	timeString = "Pitch:"+ofToString(pitch);
+	timeString += ", time now:"+ofToString(timeNow, 1);
+	timeString += "  TD "+ofToString(timeDifference, 1);
+	timeString += "  offset "+ofToString(bayesStruct.posterior.offset , 0);
+	timeString += " map Est: "+ofToString(bayesStruct.posterior.MAPestimate, 0); 
+//	timeString += " Previous time" + ofToString(newMAPestimateTime,0);
+	timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 2);
+	timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 2);
+	
+//	newMAPestimateTime += (timeDifference * bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
+//	timeString += " :  Predicted MAP time" + ofToString(newMAPestimateTime,0);
+
+	//then we recalculate the window start based on MAP being central
+	//then we do the matches on these and the likelihood on these.
+	
+	bayesStruct.setNewDistributionOffsets(max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)));
+//	bayesStruct.prior.offset = max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
+	
+	timeString += " \n :  new offset " + ofToString(bayesStruct.prior.offset , 0);
+	timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1);
+	timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 1);
+	timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 1);
+	
+	
+	//be able to draw the prior in correct location relative to the midi notes
+	bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, timeDifference);
+//	bayesStruct.crossUpdateArrays(bayesStruct.prior, bayesStruct.relativeSpeedPosterior, timeDifference);
+
+	
+	timeString += " new OFF "+ofToString(bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2), 1);
+	timeString += " notearrayindex "+ofToString(noteArrayIndex, 0);
+	//when this is off teh screen there is a problem somehow XXX
+	bayesStruct.posterior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
+//	bayesStruct.prior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
+	//trying to switch to prior
+	
+	bayesStruct.lastEventTime = ofGetElapsedTimeMillis();
+	
+	//do the cross update to find current posterior for location
+	int numberOfMatchesFound = findLocalMatches(pitch);
+	setMatchLikelihoods(numberOfMatchesFound);
+	bayesStruct.calculatePosterior();
+	
+	//having found matches we have matches for new note and matches for previous notes
+	findLocalTempoPairs();
+	
+	
+	 
+}
+
+int midiEventHolder::findLocalMatches(int notePitch){
+
+	//here we find the matches to the new note within appropriate range
+		
+	matchString += ", "+ofToString(notePitch);	
+	
+	windowStartTime = max(0.0,(bayesStruct.bestEstimate - matchWindowWidth/2));//was playPositionInMillis
+	int numberOfMatches = findMatch(notePitch, windowStartTime, windowStartTime + matchWindowWidth);
+	
+	return numberOfMatches;
+	
+	
+}
+
+
+void midiEventHolder::setMatchLikelihoods(int numberOfMatches){
+//reset the offset to match the prior
+	bayesStruct.likelihood.offset = bayesStruct.prior.offset;
+	bayesStruct.likelihood.zero();//set to zero
+	
+	
+	
+	for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){
+	//	printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset);
+		//this is the vent time since start of file
+		if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize){
+		bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, 0.5 * likelihoodToNoiseRatio);
+		}//end if
+	}
+	bayesStruct.likelihood.addConstant(0.01);
+}
+
+int midiEventHolder::findMatch(const int& notePitch, const int& startTime, const int& endTime){
+
+	matchesFound.clear();
+	int startIndex = 0;
+	
+	if (recordedEventTimes.size() > 0){
+	
+		//get to the right range of events to check in
+		while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < startTime)
+			startIndex++;
+		   
+		}
+
+	
+	while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < endTime){
+		if (recordedNoteOnMatrix[startIndex][1] == notePitch){
+			matchesFound.push_back(startIndex);
+		}
+		startIndex++;
+	}
+	 
+//	printf("%i MATCHES TO Note %i found\n", (int)matchesFound.size(), notePitch);
+	int size = matchesFound.size();
+
+	IntVector v;
+	v.push_back(size);
+	for (int i = 0;i < matchesFound.size();i++)
+		v.push_back(matchesFound[i]);
+	
+	matchMatrix.push_back(v);
+	
+	return size;
+}
+
+bool midiEventHolder::checkIfMatchedNote(const int& tmpIndex){
+	for (int i = 0;i < matchesFound.size();i++){
+	if (matchesFound[i] == tmpIndex)
+		return true;
+	}
+	return false;
+}
+
+
+
+void midiEventHolder::findLocalTempoPairs(){
+
+	int currentPlayedIndex = playedNoteOnMatrix.size()-1;
+//	printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]);
+//	printMatchesFound();
+//	printMatchMatrix();
+//	printf("possible notes \n");
+	
+	
+	for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){
+
+		int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1];
+		
+		int previousIndex = currentPlayedIndex-1;
+		
+		while (previousIndex >= 0 && playedEventTimes[previousIndex] + 2000 > playedEventTimes[currentPlayedIndex]) {
+			double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex];
+
+			for (int k = 0;k < matchMatrix[previousIndex][0];k++){
+				int recordedPreviousIndex = matchMatrix[previousIndex][k+1];
+				
+	//			printf("(%i)", matchMatrix[currentPlayedIndex][i+1]);
+	//			printf("[%i] :: ", recordedPreviousIndex);
+
+				double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex];
+	///			printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference);
+				
+				//we want the speed of the recording relative to that of the playing live
+				
+				double speedRatio = recordedTimeDifference / playedTimeDifference;
+				if (speedRatio <= maximumMatchSpeed && speedRatio >= minimumMatchSpeed){
+
+					//			printf("update on speed ratio %f", speedRatio);
+				//	commented for debug
+					bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match
+			
+				}
+	//		printf("\n");	
+			}
+			
+			previousIndex--;
+		}//end while previousindex countdown
+	}//end for loop through possible current matches
+	
+		
+}
+
+
+void midiEventHolder::updatePlayPosition(){
+	
+	//in actual fact if we are changing the speed of the play position 
+	//we will need to update this via the file
+	
+	double timeDifference = ofGetElapsedTimeMillis() - lastPeriodUpdateTime;
+	//this is time diff in milliseconds
+	//then we have 
+	double quarterNoteIntervals = (timeDifference / period);
+	tickLocation = quarterNoteIntervals * pulsesPerQuarternote; 
+	
+	playPositionInMillis = timeDifference;//based on updating from when we change period
+	//this to be added
+	
+	bayesStruct.updateBestEstimate();
+	
+}
+
+
+void midiEventHolder::drawFile(){
+	//draws midi file on scrolling screen
+	int size = recordedNoteOnMatrix.size();
+	if (size > 0){
+		
+		numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in
+		
+	//	numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down
+		timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen);
+		
+		while (noteArrayIndex < recordedNoteOnMatrix.size() && tickLocation > recordedNoteOnMatrix[noteArrayIndex][0] )
+			noteArrayIndex++;
+		
+		
+		while (noteArrayIndex > 0 && noteArrayIndex < size && tickLocation < recordedNoteOnMatrix[noteArrayIndex][0])
+			noteArrayIndex--;
+		
+		//need to start where we currently are in file
+		int maxNoteIndexToPrint	= noteArrayIndex;
+		int minNoteIndexToPrint = noteArrayIndex;
+		
+		while (maxNoteIndexToPrint < recordedNoteOnMatrix.size() && recordedNoteOnMatrix[maxNoteIndexToPrint][0] < (numberOfScreensIn+1)*ticksPerScreen )
+			maxNoteIndexToPrint++;
+		
+		while (minNoteIndexToPrint > 0 && minNoteIndexToPrint < size && recordedNoteOnMatrix[minNoteIndexToPrint][0] > numberOfScreensIn*ticksPerScreen)
+			minNoteIndexToPrint--;
+		
+		for (int tmpIndex = max(0,minNoteIndexToPrint);tmpIndex < min(maxNoteIndexToPrint, (int)recordedNoteOnMatrix.size());tmpIndex++){
+			
+			if (checkIfMatchedNote(tmpIndex))
+				ofSetColor(0,0,255);
+			else
+				ofSetColor(255,255,255);
+
+	//		 XXX replace ofgetwidth below
+			//if (tmpIndex >= 0 && tmpIndex < size)
+			int xLocation = (float)(recordedNoteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen;
+			int duration = (float)(recordedNoteOnMatrix[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen;
+			
+			
+			int yLocation = (*screenHeight) - ((recordedNoteOnMatrix[tmpIndex][1] - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum));						 
+			ofRect(xLocation,yLocation, duration,  noteHeight);
+			
+		}
+		
+		
+		int xLocation;// = getLocationFromTicks(tickLocation);
+	//	ofLine(xLocation, 0, xLocation, (*screenHeight));
+		
+		//orange line at best estimate
+		xLocation = getLocationFromMillis(bayesStruct.bestEstimate);
+		ofSetColor(250,100,0);
+		ofLine(xLocation, 0, xLocation, (*screenHeight));
+		
+		
+		//lines where matching window start and end are 
+		ofSetColor(0,100,255);
+		xLocation = getLocationFromMillis(windowStartTime);
+		ofLine(xLocation, 0, xLocation, (*screenHeight));
+		xLocation = getLocationFromMillis(windowStartTime+matchWindowWidth);
+		ofLine(xLocation, 0, xLocation, (*screenHeight));
+		 
+		
+	}	
+	
+	ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20);
+	
+	ofDrawBitmapString(timeString, 20, 60);
+	
+//	bayesStruct.drawArrays();
+	
+//	ofSetColor(200,200,0);
+//	bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800);
+	
+	//need to draw arrays within correct timescope
+	bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen));
+	
+	//bayesStruct.drawTempoArrays();
+	
+	ofDrawBitmapString(matchString, 20, ofGetHeight() - 20);
+	
+}
+
+int midiEventHolder::getLocationFromTicks(double tickPosition){
+	return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen);
+}
+
+int midiEventHolder::getLocationFromMillis(double millisPosition){
+	//(getEventTimeTicks(windowStartTime+matchWindowWidth) - numberOfScreensIn*ticksPerScreen)*(*screenWidth) / (double)ticksPerScreen
+	return (millisPosition - timeOffsetForScreen)*(*screenWidth)/getEventTimeMillis(ticksPerScreen);
+}
+
+
+void midiEventHolder::exampleCrossUpdate(){
+	
+	bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, 200);
+	
+}
+
+
+void midiEventHolder::setStartPlayingTimes(){
+	lastPeriodUpdateTime = ofGetElapsedTimeMillis();
+	bayesStruct.lastEventTime = ofGetElapsedTimeMillis();
+	startTime = lastPeriodUpdateTime;
+	
+	bayesStruct.resetArrays();
+//	bayesStruct.lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
+	matchString = "";
+}
+
+
+void midiEventHolder::printMatchMatrix(){
+	printf("match matrix:\n");
+	for (int i = 0;i < matchMatrix.size();i++){
+		for (int k = 0;k < matchMatrix[i].size();k++){
+			printf("%i , ", matchMatrix[i][k]);
+		}
+		printf("\n");
+	}
+	
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/midiEventHolder.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,106 @@
+/*
+ *  midiEventHolder.h
+ *  midiCannamReader3
+ *
+ *  Created by Andrew on 19/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+#include "ofMain.h"
+#include "BayesianArrayStructure.h"
+
+class midiEventHolder{
+
+public:
+	
+	midiEventHolder();
+	void printNotes();
+	
+	typedef std::vector<int> IntVector;
+	typedef std::vector<IntVector> IntMatrix;
+	
+	typedef std::vector<bool> BoolVector;
+	
+	typedef std::vector<double> DoubleVector;
+	typedef std::vector<DoubleVector> DoubleMatrix;
+	
+	//the rehearsal version
+	IntMatrix recordedNoteOnMatrix;//note, velocity, duration
+	IntVector matchesFound;
+	BoolVector noteOnMatches;
+//	int recordedNoteOnIndex;
+	DoubleVector recordedEventTimes;
+	
+	IntMatrix playedNoteOnMatrix;
+	DoubleVector playedEventTimes;
+	int playedNoteIndex;
+	IntMatrix matchMatrix;
+	
+	
+	double minimumMatchSpeed , maximumMatchSpeed;
+	
+	double period, pulsesPerQuarternote;
+	double getEventTimeMillis(double ticks);
+	double getEventTimeTicks(double millis);
+	
+	int getLocationFromTicks(double tickPosition);
+	int getLocationFromMillis(double millisPosition);
+	
+	double windowStartTime;
+	
+	//functions for finding match to incoming note
+	void newNoteOnEvent(int pitch, int velocity, double timePlayed);
+	int findLocalMatches(int notePitch);
+	bool checkIfMatchedNote(const int& tmpIndex);
+	int findMatch(const int& notePitch, const int& startTime, const int& endTime);
+	
+	
+	void findLocalTempoPairs();
+	
+	
+	double likelihoodWidth;
+	double likelihoodToNoiseRatio;
+	
+	void printMatchMatrix();
+	
+	void setMatchLikelihoods(int numberOfMatches);
+	
+	void setStartPlayingTimes();
+	
+	int width, height;
+	/////
+	string matchString;
+	void updatePlayPosition();
+	
+	DoubleMatrix beatPeriodMatrix;
+	
+	void drawFile();
+	void reset();
+	
+	int ticksPerScreen;
+	int tickLocation;
+	int numberOfScreensIn;
+	int noteArrayIndex;
+	
+	int matchWindowWidth;
+	
+	int noteMinimum, noteMaximum;
+	int* screenWidth;
+	int* screenHeight;
+	float noteHeight;
+	float tempo;
+	double lastPeriodUpdateTime;
+	
+	double playPositionInMillis;
+	
+	double timeOffsetForScreen;
+	
+	double recentNoteOnTime;
+	
+	void exampleCrossUpdate();
+	BayesianArrayStructure bayesStruct;
+
+	string timeString;
+	double startTime;
+	
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testApp.cpp	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,424 @@
+#include "testApp.h"
+
+//--------------------------------------------------------------
+void testApp::setup(){
+	midiFileName = "../../../data/entertainer.mid";
+	int retVal = cannamMainFunction();
+	
+	playing = false;
+	/*
+	 bayesStruct.resetSize(1000);
+	 bayesStruct.resetSpeedSize(200);
+	 bayesStruct.setRelativeSpeedScalar(0.01);
+	 bayesStruct.simpleExample();
+	 */
+	
+	receiver.setup( PORT );
+	
+	screenWidth = ofGetWidth();
+	screenHeight = ofGetHeight();
+	midiEvents.screenWidth = &screenWidth;
+	midiEvents.screenHeight = &screenHeight;
+	ofSetFrameRate(100);
+}
+
+//--------------------------------------------------------------
+void testApp::update(){
+	if (playing){
+		midiEvents.updatePlayPosition();
+		midiEvents.bayesStruct.updateBestEstimate();
+	}
+//	drawer.tickLocation+=20;
+	
+	// check for waiting messages
+	while( receiver.hasWaitingMessages() )
+	{
+		ofxOscMessage m;
+		receiver.getNextMessage( &m );
+		
+		if ( m.getAddress() == "/midinoteon" )
+		{
+			int newMidiOnPitch = m.getArgAsInt32(0);
+			int velocity = m.getArgAsInt32(1);
+			double time = m.getArgAsFloat(2);
+			
+			if (velocity != 0)
+			midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time);
+
+		}
+		
+		if ( m.getAddress() == "/startplaying" )
+		{
+			startPlaying();
+		}
+		
+		if ( m.getAddress() == "/stopplaying" )
+		{
+			stopPlaying();
+		}
+	}//end while osc
+	
+}
+
+//--------------------------------------------------------------
+void testApp::draw(){
+
+	midiEvents.drawFile();
+	
+}
+
+//--------------------------------------------------------------
+void testApp::keyPressed(int key){
+
+	
+	if (key == ' '){
+		startPlaying();
+	}
+	
+	if (key == 'c'){
+		double timenow = ofGetElapsedTimeMillis();
+		midiEvents.exampleCrossUpdate();
+		timenow *= -1;
+		timenow += ofGetElapsedTimeMillis();
+		printf("CROSS UPDATE TOOK %f", timenow);
+	}
+	
+	if (key == OF_KEY_RETURN)
+		stopPlaying();
+	
+	if (key == OF_KEY_UP){
+		if (midiEvents.ticksPerScreen >= 4000)
+		midiEvents.ticksPerScreen += 2000;
+		else 
+			midiEvents.ticksPerScreen += 500;
+	}
+	
+	if (key == 'm'){
+//		midiEvents.findMatch(84, 0, 10000);
+	}
+	
+	if (key == OF_KEY_DOWN){
+		if (midiEvents.ticksPerScreen >= 4000)
+		midiEvents.ticksPerScreen -= 2000;
+	else if (midiEvents.ticksPerScreen > 500)
+		midiEvents.ticksPerScreen -= 500;
+	}
+	
+	if (key == 'w')
+		midiEvents.printMatchMatrix();
+	
+	if (key == 'p'){
+		midiEvents.printNotes();
+	}
+
+	if (key == 'l')
+		midiEvents.bayesStruct.decaySpeedDistribution(100);
+	
+	if (key == 'o'){
+		//open audio file
+		string *filePtr;
+		filePtr = &midiFileName;	
+		
+		if (getFilenameFromDialogBox(filePtr)){
+			printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str());	
+			cannamMainFunction();
+		}
+	
+	}
+}
+
+//--------------------------------------------------------------
+void testApp::keyReleased(int key){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseMoved(int x, int y ){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseDragged(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mousePressed(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseReleased(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::windowResized(int w, int h){
+	screenWidth = w;
+	screenHeight = h;
+	midiEvents.noteHeight = screenHeight / (float)(midiEvents.noteMaximum - midiEvents.noteMinimum);
+	
+}
+
+
+
+void testApp::startPlaying(){
+	playing = !playing;
+	midiEvents.reset();
+	midiEvents.setStartPlayingTimes();
+	//this is where we stop and start playing
+}
+
+void testApp::stopPlaying(){
+	playing = false;
+}
+
+bool testApp::getFilenameFromDialogBox(string* fileNameToSave){
+	//this uses a pointer structure within the loader and returns true if the dialogue box was used successfully
+	// first, create a string that will hold the URL
+	string URL;
+	
+	// openFile(string& URL) returns 1 if a file was picked
+	// returns 0 when something went wrong or the user pressed 'cancel'
+	int response = ofxFileDialogOSX::openFile(URL);
+	if(response){
+		// now you can use the URL 
+		*fileNameToSave = URL;
+		//printf("\n filename is %s \n", soundFileName.c_str());
+		return true;
+	}
+	else {
+		//	soundFileName = "OPEN canceled. ";
+		printf("\n open file cancelled \n");
+		return false;
+	}
+	
+	
+	
+}
+
+
+
+
+int testApp::cannamMainFunction(){
+
+
+	midiEvents.recordedNoteOnMatrix.clear();//where we store the note ons
+	
+	//int main(int argc, char **argv)
+	//{
+	//	if (argc != 2) {
+	//		cerr << "Usage: midifile <file.mid>" << endl;
+	//		return 1;
+	//	}
+		
+	std::string filename = midiFileName;//argv[1];
+		
+		MIDIFileReader fr(filename);
+		if (!fr.isOK()) {
+			std::cerr << "Error: " << fr.getError().c_str() << std::endl;
+			return 1;
+		}
+		
+		MIDIComposition c = fr.load();
+		
+		switch (fr.getFormat()) {
+			case MIDI_SINGLE_TRACK_FILE: cout << "Format: MIDI Single Track File" << endl; break;
+			case MIDI_SIMULTANEOUS_TRACK_FILE: cout << "Format: MIDI Simultaneous Track File" << endl; break;
+			case MIDI_SEQUENTIAL_TRACK_FILE: cout << "Format: MIDI Sequential Track File" << endl; break;
+			default: cout << "Format: Unknown MIDI file format?" << endl; break;
+		}
+		
+		cout << "Tracks: " << c.size() << endl;
+		
+		int td = fr.getTimingDivision();
+		if (td < 32768) {
+			cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl;
+			
+			midiEvents.pulsesPerQuarternote = fr.getTimingDivision();
+		} else {
+			int frames = 256 - (td >> 8);
+			int subframes = td & 0xff;
+			cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl;
+		}
+		
+		for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) {
+			
+			cout << "Start of track: " << i->first+1 << endl;
+			
+			for (MIDITrack::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
+				
+				unsigned int t = j->getTime();
+				int ch = j->getChannelNumber();
+				
+				if (j->isMeta()) {
+					int code = j->getMetaEventCode();
+					string name;
+					bool printable = true;
+					switch (code) {
+							
+						case MIDI_END_OF_TRACK:
+							cout << t << ": End of track" << endl;
+							break;
+							
+						case MIDI_TEXT_EVENT: name = "Text"; break;
+						case MIDI_COPYRIGHT_NOTICE: name = "Copyright"; break;
+						case MIDI_TRACK_NAME: name = "Track name"; break;
+						case MIDI_INSTRUMENT_NAME: name = "Instrument name"; break;
+						case MIDI_LYRIC: name = "Lyric"; break;
+						case MIDI_TEXT_MARKER: name = "Text marker"; break;
+						case MIDI_SEQUENCE_NUMBER: name = "Sequence number"; printable = false; break;
+						case MIDI_CHANNEL_PREFIX_OR_PORT: name = "Channel prefix or port"; printable = false; break;
+						case MIDI_CUE_POINT: name = "Cue point"; break;
+						case MIDI_CHANNEL_PREFIX: name = "Channel prefix"; printable = false; break;
+						case MIDI_SEQUENCER_SPECIFIC: name = "Sequencer specific"; printable = false; break;
+						case MIDI_SMPTE_OFFSET: name = "SMPTE offset"; printable = false; break;
+							
+						case MIDI_SET_TEMPO:
+						{
+							int m0 = j->getMetaMessage()[0];
+							int m1 = j->getMetaMessage()[1];
+							int m2 = j->getMetaMessage()[2];
+							long tempo = (((m0 << 8) + m1) << 8) + m2;
+							
+							cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl;
+							midiEvents.tempo = 60000000.0 / double(tempo);
+							midiEvents.period = double(tempo)/1000.0;
+							
+							printf("period double is %f\n", midiEvents.period);
+						}
+							break;
+							
+						case MIDI_TIME_SIGNATURE:
+						{
+							int numerator = j->getMetaMessage()[0];
+							int denominator = 1 << (int)j->getMetaMessage()[1];
+							
+							cout << t << ": Time signature: " << numerator << "/" << denominator << endl;
+						}
+							
+						case MIDI_KEY_SIGNATURE:
+						{
+							int accidentals = j->getMetaMessage()[0];
+							int isMinor = j->getMetaMessage()[1];
+							bool isSharp = accidentals < 0 ? false : true;
+							accidentals = accidentals < 0 ? -accidentals : accidentals;
+							cout << t << ": Key signature: " << accidentals << " "
+							<< (isSharp ?
+								(accidentals > 1 ? "sharps" : "sharp") :
+								(accidentals > 1 ? "flats" : "flat"))
+							<< (isMinor ? ", minor" : ", major") << endl;
+						}
+							
+					}
+					
+					
+					if (name != "") {
+						if (printable) {
+							cout << t << ": File meta event: code " << code
+							<< ": " << name << ": \"" << j->getMetaMessage()
+							<< "\"" << endl;
+						} else {
+							cout << t << ": File meta event: code " << code
+							<< ": " << name << ": ";
+							for (int k = 0; k < j->getMetaMessage().length(); ++k) {
+								cout << (int)j->getMetaMessage()[k] << " ";
+							}
+						}
+					}
+					continue;
+				}
+				
+				switch (j->getMessageType()) {
+						
+					case MIDI_NOTE_ON:
+						cout << t << ": Note: channel " << ch
+						<< " duration " << j->getDuration()
+						<< " pitch " << j->getPitch()
+						<< " velocity " << j->getVelocity() 
+						<< "event time " << midiEvents.getEventTimeMillis(t) << endl;
+						v.clear();
+						v.push_back(t);
+						v.push_back(j->getPitch());
+						v.push_back(j->getVelocity());
+						v.push_back(j->getDuration());
+						midiEvents.recordedNoteOnMatrix.push_back(v);
+						midiEvents.recordedEventTimes.push_back(midiEvents.getEventTimeMillis(t));
+						break;
+						
+					case MIDI_POLY_AFTERTOUCH:
+						cout << t << ": Polyphonic aftertouch: channel " << ch
+						<< " pitch " << j->getPitch()
+						<< " pressure " << j->getData2() << endl;
+						break;
+						
+					case MIDI_CTRL_CHANGE:
+					{
+						int controller = j->getData1();
+						string name;
+						switch (controller) {
+							case MIDI_CONTROLLER_BANK_MSB: name = "Bank select MSB"; break;
+							case MIDI_CONTROLLER_VOLUME: name = "Volume"; break;
+							case MIDI_CONTROLLER_BANK_LSB: name = "Bank select LSB"; break;
+							case MIDI_CONTROLLER_MODULATION: name = "Modulation wheel"; break;
+							case MIDI_CONTROLLER_PAN: name = "Pan"; break;
+							case MIDI_CONTROLLER_SUSTAIN: name = "Sustain"; break;
+							case MIDI_CONTROLLER_RESONANCE: name = "Resonance"; break;
+							case MIDI_CONTROLLER_RELEASE: name = "Release"; break;
+							case MIDI_CONTROLLER_ATTACK: name = "Attack"; break;
+							case MIDI_CONTROLLER_FILTER: name = "Filter"; break;
+							case MIDI_CONTROLLER_REVERB: name = "Reverb"; break;
+							case MIDI_CONTROLLER_CHORUS: name = "Chorus"; break;
+							case MIDI_CONTROLLER_NRPN_1: name = "NRPN 1"; break;
+							case MIDI_CONTROLLER_NRPN_2: name = "NRPN 2"; break;
+							case MIDI_CONTROLLER_RPN_1: name = "RPN 1"; break;
+							case MIDI_CONTROLLER_RPN_2: name = "RPN 2"; break;
+							case MIDI_CONTROLLER_SOUNDS_OFF: name = "All sounds off"; break;
+							case MIDI_CONTROLLER_RESET: name = "Reset"; break;
+							case MIDI_CONTROLLER_LOCAL: name = "Local"; break;
+							case MIDI_CONTROLLER_ALL_NOTES_OFF: name = "All notes off"; break;
+						}
+						cout << t << ": Controller change: channel " << ch
+						<< " controller " << j->getData1();
+						if (name != "") cout << " (" << name << ")";
+						cout << " value " << j->getData2() << endl;
+					}
+						break;
+						
+					case MIDI_PROG_CHANGE:
+						cout << t << ": Program change: channel " << ch
+						<< " program " << j->getData1() << endl;
+						break;
+						
+					case MIDI_CHNL_AFTERTOUCH:
+						cout << t << ": Channel aftertouch: channel " << ch
+						<< " pressure " << j->getData1() << endl;
+						break;
+						
+					case MIDI_PITCH_BEND:
+						cout << t << ": Pitch bend: channel " << ch
+						<< " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl;
+						break;
+						
+					case MIDI_SYSTEM_EXCLUSIVE:
+						cout << t << ": System exclusive: code "
+						<< (int)j->getMessageType() << " message length " <<
+						j->getMetaMessage().length() << endl;
+						break;
+						
+						
+				}
+				
+				
+			}
+			
+			
+		}
+		
+	//}
+	
+	
+	
+
+}//end cannam midi main
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testApp.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,77 @@
+#ifndef _TEST_APP
+#define _TEST_APP
+
+
+//midieventholder - newMidiEvents() sent there
+//create cannamMidiLoader for cannamMainfunction
+
+
+//check new prior offset function - how is used?
+
+
+
+//check the widening function - adding decay noise
+//ticksperscreen could be better as millis per screen
+
+
+
+
+
+#include "ofMain.h"
+
+#include "MIDIFileReader.h"
+#include "ofxFileDialogOSX.h"
+#include "drawMidiNotes.h"
+#include "DynamicBayesianArray.h"
+
+#include <iostream>
+#include "midiEventHolder.h"
+
+#include "ofxOsc.h"
+#define PORT 12121
+
+using namespace std;
+using namespace MIDIConstants;
+
+class testApp : public ofBaseApp{
+
+	public:
+		void setup();
+		void update();
+		void draw();
+
+		void keyPressed  (int key);
+		void keyReleased(int key);
+		void mouseMoved(int x, int y );
+		void mouseDragged(int x, int y, int button);
+		void mousePressed(int x, int y, int button);
+		void mouseReleased(int x, int y, int button);
+		void windowResized(int w, int h);
+
+	void startPlaying();
+	void stopPlaying();
+	bool getFilenameFromDialogBox(string* fileNameToSave);
+
+	typedef std::vector<int> IntVector;
+	typedef std::vector<double> DoubleVector;
+//	typedef std::vector<IntVector> IntMatrix;	
+	IntVector v;
+
+	midiEventHolder midiEvents;
+	
+	int cannamMainFunction();
+	string midiFileName;
+
+	bool playing;
+	//drawMidiNotes drawer;
+	
+//	BayesianArrayStructure bayesStruct;
+	
+	int screenWidth, screenHeight;
+	
+private:
+	ofxOscReceiver	receiver;
+	
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/untitled.h	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,12 @@
+/*
+ *  untitled.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 18/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "ofMain.h"
+
+class Double
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/workingNotes.rtf	Tue Aug 16 11:29:59 2011 +0100
@@ -0,0 +1,19 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0
+\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
+
+\f0\fs24 \cf0 BUGS:\
+When prior and posterior etc are split off the screen, it doesn't find the right indices for them. Are we writing the correct prior vector? constrained limits?\
+\
+\
+using best estimate continually - good in the new note on function?\
+\
++ + + + + + + + + \
+\
+best estimate locked to map so need to free\
+\
+need to do relative tempo estimates\
+\
+}
\ No newline at end of file