aboutsummaryrefslogtreecommitdiff
path: root/libOSC
diff options
context:
space:
mode:
Diffstat (limited to 'libOSC')
-rw-r--r--libOSC/LIBOSC.00194
-rw-r--r--libOSC/LIBOSC.002100
-rw-r--r--libOSC/LIBOSC.DSP100
-rw-r--r--libOSC/LIBOSC.DSW29
-rw-r--r--libOSC/LIBOSC.PLG29
-rw-r--r--libOSC/Makefile21
-rw-r--r--libOSC/OSC-client.c473
-rw-r--r--libOSC/OSC-client.c.pre-htonl303
-rw-r--r--libOSC/OSC-client.h181
-rw-r--r--libOSC/OSC-timetag.c175
-rw-r--r--libOSC/OSC-timetag.h93
-rw-r--r--libOSC/test_OSC.c149
-rw-r--r--libOSC/test_OSC_timeTag.c36
13 files changed, 1783 insertions, 0 deletions
diff --git a/libOSC/LIBOSC.001 b/libOSC/LIBOSC.001
new file mode 100644
index 0000000..d1b40cc
--- /dev/null
+++ b/libOSC/LIBOSC.001
@@ -0,0 +1,94 @@
+# Microsoft Developer Studio Project File - Name="LIBOSC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=LIBOSC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "LIBOSC.MAK".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "LIBOSC.MAK" CFG="LIBOSC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "LIBOSC - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "LIBOSC - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF "$(CFG)" == "LIBOSC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "LIBOSC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "LIBOSC - Win32 Release"
+# Name "LIBOSC - Win32 Debug"
+# Begin Source File
+
+SOURCE=".\OSC-client.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-client.h"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-timetag.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-timetag.h"
+# End Source File
+# End Target
+# End Project
diff --git a/libOSC/LIBOSC.002 b/libOSC/LIBOSC.002
new file mode 100644
index 0000000..d2c0fe8
--- /dev/null
+++ b/libOSC/LIBOSC.002
@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Project File - Name="LIBOSC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=LIBOSC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "LIBOSC.MAK".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "LIBOSC.MAK" CFG="LIBOSC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "LIBOSC - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "LIBOSC - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF "$(CFG)" == "LIBOSC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../pd/src" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\..\pd\lib\LIBOSC.lib"
+
+!ELSEIF "$(CFG)" == "LIBOSC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /I "../../pd/src" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "LIBOSC - Win32 Release"
+# Name "LIBOSC - Win32 Debug"
+# Begin Source File
+
+SOURCE=".\OSC-client.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-client.h"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-timetag.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-timetag.h"
+# End Source File
+# End Target
+# End Project
diff --git a/libOSC/LIBOSC.DSP b/libOSC/LIBOSC.DSP
new file mode 100644
index 0000000..99e661a
--- /dev/null
+++ b/libOSC/LIBOSC.DSP
@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Project File - Name="LIBOSC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=LIBOSC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "LIBOSC.MAK".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "LIBOSC.MAK" CFG="LIBOSC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "LIBOSC - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "LIBOSC - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "LIBOSC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../pd/src" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\..\pd\lib\LIBOSC.lib"
+
+!ELSEIF "$(CFG)" == "LIBOSC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /I "../../pd/src" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "LIBOSC - Win32 Release"
+# Name "LIBOSC - Win32 Debug"
+# Begin Source File
+
+SOURCE=".\OSC-client.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-client.h"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-timetag.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\OSC-timetag.h"
+# End Source File
+# End Target
+# End Project
diff --git a/libOSC/LIBOSC.DSW b/libOSC/LIBOSC.DSW
new file mode 100644
index 0000000..ef47907
--- /dev/null
+++ b/libOSC/LIBOSC.DSW
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "LIBOSC"=.\LIBOSC.DSP - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/libOSC/LIBOSC.PLG b/libOSC/LIBOSC.PLG
new file mode 100644
index 0000000..d011835
--- /dev/null
+++ b/libOSC/LIBOSC.PLG
@@ -0,0 +1,29 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: LIBOSC - Win32 Release--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\gustav\LOCALS~1\Temp\RSPB.tmp" with contents
+[
+/nologo /ML /W3 /GX /O2 /I "../../pd/src" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"Release/LIBOSC.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
+"D:\pd\OSC\LIBOSC\OSC-client.c"
+"D:\pd\OSC\LIBOSC\OSC-timetag.c"
+]
+Creating command line "cl.exe @C:\DOCUME~1\gustav\LOCALS~1\Temp\RSPB.tmp"
+Creating command line "link.exe -lib /nologo /out:"..\..\..\pd\lib\LIBOSC.lib" ".\Release\OSC-client.obj" ".\Release\OSC-timetag.obj" "
+<h3>Output Window</h3>
+Compiling...
+OSC-client.c
+OSC-timetag.c
+Creating library...
+
+
+
+<h3>Results</h3>
+LIBOSC.lib - 0 error(s), 0 warning(s)
+</pre>
+</body>
+</html>
diff --git a/libOSC/Makefile b/libOSC/Makefile
new file mode 100644
index 0000000..6261b37
--- /dev/null
+++ b/libOSC/Makefile
@@ -0,0 +1,21 @@
+CFLAGS= -O2
+LIB=libOSC.a
+
+LIBOBJS= ${LIB}(OSC-client.o) ${LIB}(OSC-timetag.o)
+
+all: ${LIBOBJS}
+
+.c.a:
+ ${CC} -c ${CFLAGS} $<
+ ${AR} ${ARFLAGS} $@ $*.o
+ rm -f $*.o
+
+test_OSC: test_OSC.o ${LIB}
+ cc -o test_OSC test_OSC.o ${LIB}
+
+test_OSC_timeTag: test_OSC_timeTag.o OSC-timetag.o
+ cc -o test_OSC_timeTag test_OSC_timeTag.o OSC-timetag.o
+
+
+clean:
+ rm -f ${LIB} *.o
diff --git a/libOSC/OSC-client.c b/libOSC/OSC-client.c
new file mode 100644
index 0000000..27b07d0
--- /dev/null
+++ b/libOSC/OSC-client.c
@@ -0,0 +1,473 @@
+/*
+Copyright (c) 1996. The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for educational, research, and not-for-profit purposes, without
+fee and without a signed licensing agreement, is hereby granted, provided that
+the above copyright notice, this paragraph and the following two paragraphs
+appear in all copies, modifications, and distributions. Contact The Office of
+Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
+CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
+
+Written by Matt Wright, The Center for New Music and Audio Technologies,
+University of California, Berkeley.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
+ DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
+ REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+
+/*
+ Author: Matt Wright
+ Version 2.2: Calls htonl in the right places 20000620
+ Version 2.3: Gets typed messages right.
+ */
+
+/*
+ pd
+ -------------
+
+ raf@interaccess.com:
+ rev. for Win32 build (verified under Win-2ooo) 11-April-2002
+
+*/
+
+/* Here are the possible values of the state field: */
+
+#define EMPTY 0 /* Nothing written to packet yet */
+#define ONE_MSG_ARGS 1 /* Packet has a single message; gathering arguments */
+#define NEED_COUNT 2 /* Just opened a bundle; must write message name or
+ open another bundle */
+#define GET_ARGS 3 /* Getting arguments to a message. If we see a message
+ name or a bundle open/close then the current message
+ will end. */
+#define DONE 4 /* All open bundles have been closed, so can't write
+ anything else */
+
+#ifdef WIN32
+ #include <winsock2.h>
+ #include <io.h>
+ #include <stdio.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+#endif
+
+
+#include "OSC-client.h"
+
+char *OSC_errorMessage;
+
+#ifndef WIN32
+ static int strlen(char *s);
+#endif
+static int OSC_padString(char *dest, char *str);
+static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str);
+static int OSC_WritePadding(char *dest, int i);
+static int CheckTypeTag(OSCbuf *buf, char expectedType);
+
+void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) {
+ buf->buffer = byteArray;
+ buf->size = size;
+ OSC_resetBuffer(buf);
+}
+
+void OSC_resetBuffer(OSCbuf *buf) {
+ buf->bufptr = buf->buffer;
+ buf->state = EMPTY;
+ buf->bundleDepth = 0;
+ buf->prevCounts[0] = 0;
+ buf->gettingFirstUntypedArg = 0;
+ buf->typeStringPtr = 0;
+}
+
+int OSC_isBufferEmpty(OSCbuf *buf) {
+ return buf->bufptr == buf->buffer;
+}
+
+int OSC_freeSpaceInBuffer(OSCbuf *buf) {
+ return buf->size - (buf->bufptr - buf->buffer);
+}
+
+int OSC_isBufferDone(OSCbuf *buf) {
+ return (buf->state == DONE || buf->state == ONE_MSG_ARGS);
+}
+
+char *OSC_getPacket(OSCbuf *buf) {
+#ifdef ERROR_CHECK_GETPACKET
+ if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
+ return buf->buffer;
+ } else {
+ OSC_errorMessage = "Packet has unterminated bundles";
+ return 0;
+ }
+#else
+ return buf->buffer;
+#endif
+}
+
+int OSC_packetSize(OSCbuf *buf) {
+#ifdef ERROR_CHECK_PACKETSIZE
+ if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
+ return (buf->bufptr - buf->buffer);
+ } else {
+ OSC_errorMessage = "Packet has unterminated bundles";
+ return 0;
+ }
+#else
+ return (buf->bufptr - buf->buffer);
+#endif
+}
+
+#define CheckOverflow(buf, bytesNeeded) { \
+ if ((bytesNeeded) > OSC_freeSpaceInBuffer(buf)) { \
+ OSC_errorMessage = "buffer overflow"; \
+ return 1; \
+ } \
+}
+
+static void PatchMessageSize(OSCbuf *buf) {
+ int4byte size;
+ size = buf->bufptr - ((char *) buf->thisMsgSize) - 4;
+ *(buf->thisMsgSize) = htonl(size);
+}
+
+int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt) {
+ if (buf->state == ONE_MSG_ARGS) {
+ OSC_errorMessage = "Can't open a bundle in a one-message packet";
+ return 3;
+ }
+
+ if (buf->state == DONE) {
+ OSC_errorMessage = "This packet is finished; can't open a new bundle";
+ return 4;
+ }
+
+ if (++(buf->bundleDepth) >= MAX_BUNDLE_NESTING) {
+ OSC_errorMessage = "Bundles nested too deeply; change MAX_BUNDLE_NESTING in OpenSoundControl.h";
+ return 2;
+ }
+
+ if (CheckTypeTag(buf, '\0')) return 9;
+
+ if (buf->state == GET_ARGS) {
+ PatchMessageSize(buf);
+ }
+
+ if (buf->state == EMPTY) {
+ /* Need 16 bytes for "#bundle" and time tag */
+ CheckOverflow(buf, 16);
+ } else {
+ /* This bundle is inside another bundle, so we need to leave
+ a blank size count for the size of this current bundle. */
+ CheckOverflow(buf, 20);
+ *((int4byte *)buf->bufptr) = 0xaaaaaaaa;
+ buf->prevCounts[buf->bundleDepth] = (int4byte *)buf->bufptr;
+
+ buf->bufptr += 4;
+ }
+
+ buf->bufptr += OSC_padString(buf->bufptr, "#bundle");
+
+
+ *((OSCTimeTag *) buf->bufptr) = tt;
+
+ if (htonl(1) != 1) {
+ /* Byte swap the 8-byte integer time tag */
+ int4byte *intp = (int4byte *)buf->bufptr;
+ intp[0] = htonl(intp[0]);
+ intp[1] = htonl(intp[1]);
+
+#ifdef HAS8BYTEINT
+ { /* tt is a 64-bit int so we have to swap the two 32-bit words.
+ (Otherwise tt is a struct of two 32-bit words, and even though
+ each word was wrong-endian, they were in the right order
+ in the struct.) */
+ int4byte temp = intp[0];
+ intp[0] = intp[1];
+ intp[1] = temp;
+ }
+#endif
+ }
+
+ buf->bufptr += sizeof(OSCTimeTag);
+
+ buf->state = NEED_COUNT;
+
+ buf->gettingFirstUntypedArg = 0;
+ buf->typeStringPtr = 0;
+ return 0;
+}
+
+
+int OSC_closeBundle(OSCbuf *buf) {
+ if (buf->bundleDepth == 0) {
+ /* This handles EMPTY, ONE_MSG, ARGS, and DONE */
+ OSC_errorMessage = "Can't close bundle; no bundle is open!";
+ return 5;
+ }
+
+ if (CheckTypeTag(buf, '\0')) return 9;
+
+ if (buf->state == GET_ARGS) {
+ PatchMessageSize(buf);
+ }
+
+ if (buf->bundleDepth == 1) {
+ /* Closing the last bundle: No bundle size to patch */
+ buf->state = DONE;
+ } else {
+ /* Closing a sub-bundle: patch bundle size */
+ int size = buf->bufptr - ((char *) buf->prevCounts[buf->bundleDepth]) - 4;
+ *(buf->prevCounts[buf->bundleDepth]) = htonl(size);
+ buf->state = NEED_COUNT;
+ }
+
+ --buf->bundleDepth;
+ buf->gettingFirstUntypedArg = 0;
+ buf->typeStringPtr = 0;
+ return 0;
+}
+
+
+int OSC_closeAllBundles(OSCbuf *buf) {
+ if (buf->bundleDepth == 0) {
+ /* This handles EMPTY, ONE_MSG, ARGS, and DONE */
+ OSC_errorMessage = "Can't close all bundles; no bundle is open!";
+ return 6;
+ }
+
+ if (CheckTypeTag(buf, '\0')) return 9;
+
+ while (buf->bundleDepth > 0) {
+ OSC_closeBundle(buf);
+ }
+ buf->typeStringPtr = 0;
+ return 0;
+}
+
+int OSC_writeAddress(OSCbuf *buf, char *name) {
+ int4byte paddedLength;
+
+ if (buf->state == ONE_MSG_ARGS) {
+ OSC_errorMessage = "This packet is not a bundle, so you can't write another address";
+ return 7;
+ }
+
+ if (buf->state == DONE) {
+ OSC_errorMessage = "This packet is finished; can't write another address";
+ return 8;
+ }
+
+ if (CheckTypeTag(buf, '\0')) return 9;
+
+ paddedLength = OSC_effectiveStringLength(name);
+
+ if (buf->state == EMPTY) {
+ /* This will be a one-message packet, so no sizes to worry about */
+ CheckOverflow(buf, paddedLength);
+ buf->state = ONE_MSG_ARGS;
+ } else {
+ /* GET_ARGS or NEED_COUNT */
+ CheckOverflow(buf, 4+paddedLength);
+ if (buf->state == GET_ARGS) {
+ /* Close the old message */
+ PatchMessageSize(buf);
+ }
+ buf->thisMsgSize = (int4byte *)buf->bufptr;
+ *(buf->thisMsgSize) = 0xbbbbbbbb;
+ buf->bufptr += 4;
+ buf->state = GET_ARGS;
+ }
+
+ /* Now write the name */
+ buf->bufptr += OSC_padString(buf->bufptr, name);
+ buf->typeStringPtr = 0;
+ buf->gettingFirstUntypedArg = 1;
+
+ return 0;
+}
+
+int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types) {
+ int result;
+ int4byte paddedLength;
+
+ if (CheckTypeTag(buf, '\0')) return 9;
+
+ result = OSC_writeAddress(buf, name);
+
+ if (result) return result;
+
+ paddedLength = OSC_effectiveStringLength(types);
+
+ CheckOverflow(buf, paddedLength);
+
+ buf->typeStringPtr = buf->bufptr + 1; /* skip comma */
+ buf->bufptr += OSC_padString(buf->bufptr, types);
+
+ buf->gettingFirstUntypedArg = 0;
+ return 0;
+}
+
+static int CheckTypeTag(OSCbuf *buf, char expectedType) {
+ if (buf->typeStringPtr) {
+ if (*(buf->typeStringPtr) != expectedType) {
+ if (expectedType == '\0') {
+ OSC_errorMessage =
+ "According to the type tag I expected more arguments.";
+ } else if (*(buf->typeStringPtr) == '\0') {
+ OSC_errorMessage =
+ "According to the type tag I didn't expect any more arguments.";
+ } else {
+ OSC_errorMessage =
+ "According to the type tag I expected an argument of a different type.";
+ printf("* Expected %c, string now %s\n", expectedType, buf->typeStringPtr);
+ }
+ return 9;
+ }
+ ++(buf->typeStringPtr);
+ }
+ return 0;
+}
+
+
+int OSC_writeFloatArg(OSCbuf *buf, float arg) {
+ int4byte *intp;
+ //int result;
+
+ CheckOverflow(buf, 4);
+
+ if (CheckTypeTag(buf, 'f')) return 9;
+
+ /* Pretend arg is a long int so we can use htonl() */
+ intp = ((int4byte *) &arg);
+ *((int4byte *) buf->bufptr) = htonl(*intp);
+
+ buf->bufptr += 4;
+
+ buf->gettingFirstUntypedArg = 0;
+ return 0;
+}
+
+
+
+int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args) {
+ int i;
+ int4byte *intp;
+
+ CheckOverflow(buf, 4 * numFloats);
+
+ /* Pretend args are long ints so we can use htonl() */
+ intp = ((int4byte *) args);
+
+ for (i = 0; i < numFloats; i++) {
+ if (CheckTypeTag(buf, 'f')) return 9;
+ *((int4byte *) buf->bufptr) = htonl(intp[i]);
+ buf->bufptr += 4;
+ }
+
+ buf->gettingFirstUntypedArg = 0;
+ return 0;
+}
+
+int OSC_writeIntArg(OSCbuf *buf, int4byte arg) {
+ CheckOverflow(buf, 4);
+ if (CheckTypeTag(buf, 'i')) return 9;
+
+ *((int4byte *) buf->bufptr) = htonl(arg);
+ buf->bufptr += 4;
+
+ buf->gettingFirstUntypedArg = 0;
+ return 0;
+}
+
+int OSC_writeStringArg(OSCbuf *buf, char *arg) {
+ int len;
+
+ if (CheckTypeTag(buf, 's')) return 9;
+
+ len = OSC_effectiveStringLength(arg);
+
+ if (buf->gettingFirstUntypedArg && arg[0] == ',') {
+ /* This un-type-tagged message starts with a string
+ that starts with a comma, so we have to escape it
+ (with a double comma) so it won't look like a type
+ tag string. */
+
+ CheckOverflow(buf, len+4); /* Too conservative */
+ buf->bufptr +=
+ OSC_padStringWithAnExtraStupidComma(buf->bufptr, arg);
+
+ } else {
+ CheckOverflow(buf, len);
+ buf->bufptr += OSC_padString(buf->bufptr, arg);
+ }
+
+ buf->gettingFirstUntypedArg = 0;
+ return 0;
+
+}
+
+/* String utilities */
+
+#ifndef WIN32
+static int strlen(char *s) {
+ int i;
+ for (i=0; s[i] != '\0'; i++) /* Do nothing */ ;
+ return i;
+}
+#endif
+
+#define STRING_ALIGN_PAD 4
+int OSC_effectiveStringLength(char *string) {
+ int len = strlen(string) + 1; /* We need space for the null char. */
+
+ /* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */
+ if ((len % STRING_ALIGN_PAD) != 0) {
+ len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD);
+ }
+ return len;
+}
+
+static int OSC_padString(char *dest, char *str) {
+ int i;
+
+ for (i = 0; str[i] != '\0'; i++) {
+ dest[i] = str[i];
+ }
+
+ return OSC_WritePadding(dest, i);
+}
+
+static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str) {
+ int i;
+
+ dest[0] = ',';
+ for (i = 0; str[i] != '\0'; i++) {
+ dest[i+1] = str[i];
+ }
+
+ return OSC_WritePadding(dest, i+1);
+}
+
+static int OSC_WritePadding(char *dest, int i) {
+ dest[i] = '\0';
+ i++;
+
+ for (; (i % STRING_ALIGN_PAD) != 0; i++) {
+ dest[i] = '\0';
+ }
+
+ return i;
+}
diff --git a/libOSC/OSC-client.c.pre-htonl b/libOSC/OSC-client.c.pre-htonl
new file mode 100644
index 0000000..6aebfe2
--- /dev/null
+++ b/libOSC/OSC-client.c.pre-htonl
@@ -0,0 +1,303 @@
+/*
+Copyright (c) 1996. The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for educational, research, and not-for-profit purposes, without
+fee and without a signed licensing agreement, is hereby granted, provided that
+the above copyright notice, this paragraph and the following two paragraphs
+appear in all copies, modifications, and distributions. Contact The Office of
+Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
+CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
+
+Written by Matt Wright, The Center for New Music and Audio Technologies,
+University of California, Berkeley.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
+ DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
+ REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+
+/*
+ Author: Matt Wright
+ Version 2.1
+ */
+
+
+/* Here are the possible values of the state field: */
+
+#define EMPTY 0 /* Nothing written to packet yet */
+#define ONE_MSG_ARGS 1 /* Packet has a single message; gathering arguments */
+#define NEED_COUNT 2 /* Just opened a bundle; must write message name or
+ open another bundle */
+#define GET_ARGS 3 /* Getting arguments to a message. If we see a message
+ name or a bundle open/close then the current message
+ will end. */
+#define DONE 4 /* All open bundles have been closed, so can't write
+ anything else */
+
+#include "OSC-client.h"
+
+char *OSC_errorMessage;
+
+
+static int strlen(char *s);
+static int OSC_padString(char *dest, char *str);
+
+void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) {
+ buf->buffer = byteArray;
+ buf->size = size;
+ OSC_resetBuffer(buf);
+}
+
+void OSC_resetBuffer(OSCbuf *buf) {
+ buf->bufptr = buf->buffer;
+ buf->state = EMPTY;
+ buf->bundleDepth = 0;
+ buf->prevCounts[0] = 0;
+}
+
+int OSC_isBufferEmpty(OSCbuf *buf) {
+ return buf->bufptr == buf->buffer;
+}
+
+int OSC_freeSpaceInBuffer(OSCbuf *buf) {
+ return buf->size - (buf->bufptr - buf->buffer);
+}
+
+int OSC_isBufferDone(OSCbuf *buf) {
+ return (buf->state == DONE || buf->state == ONE_MSG_ARGS);
+}
+
+char *OSC_getPacket(OSCbuf *buf) {
+#ifdef ERROR_CHECK_GETPACKET
+ if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
+ return buf->buffer;
+ } else {
+ OSC_errorMessage = "Packet has unterminated bundles";
+ return 0;
+ }
+#else
+ return buf->buffer;
+#endif
+}
+
+int OSC_packetSize(OSCbuf *buf) {
+#ifdef ERROR_CHECK_PACKETSIZE
+ if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
+ return (buf->bufptr - buf->buffer);
+ } else {
+ OSC_errorMessage = "Packet has unterminated bundles";
+ return 0;
+ }
+#else
+ return (buf->bufptr - buf->buffer);
+#endif
+}
+
+#define CheckOverflow(buf, bytesNeeded) { \
+ if ((bytesNeeded) > OSC_freeSpaceInBuffer(buf)) { \
+ OSC_errorMessage = "buffer overflow"; \
+ return 1; \
+ } \
+}
+
+static void PatchMessageSize(OSCbuf *buf) {
+ int4byte size;
+ size = buf->bufptr - ((char *) buf->thisMsgSize) - 4;
+ *(buf->thisMsgSize) = size;
+}
+
+int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt) {
+ if (buf->state == ONE_MSG_ARGS) {
+ OSC_errorMessage = "Can't open a bundle in a one-message packet";
+ return 3;
+ }
+
+ if (buf->state == DONE) {
+ OSC_errorMessage = "This packet is finished; can't open a new bundle";
+ return 4;
+ }
+
+ if (++(buf->bundleDepth) >= MAX_BUNDLE_NESTING) {
+ OSC_errorMessage = "Bundles nested too deeply; change MAX_BUNDLE_NESTING in OpenSoundControl.h";
+ return 2;
+ }
+
+ if (buf->state == GET_ARGS) {
+ PatchMessageSize(buf);
+ }
+
+ if (buf->state == EMPTY) {
+ /* Need 16 bytes for "#bundle" and time tag */
+ CheckOverflow(buf, 16);
+ } else {
+ /* This bundle is inside another bundle, so we need to leave
+ a blank size count for the size of this current bundle. */
+ CheckOverflow(buf, 20);
+ *((int4byte *)buf->bufptr) = 0xaaaaaaaa;
+ buf->prevCounts[buf->bundleDepth] = (int4byte *)buf->bufptr;
+
+ buf->bufptr += 4;
+ }
+
+ buf->bufptr += OSC_padString(buf->bufptr, "#bundle");
+ *((OSCTimeTag *) buf->bufptr) = tt;
+ buf->bufptr += sizeof(OSCTimeTag);
+
+ buf->state = NEED_COUNT;
+ return 0;
+}
+
+
+int OSC_closeBundle(OSCbuf *buf) {
+ if (buf->bundleDepth == 0) {
+ /* This handles EMPTY, ONE_MSG, ARGS, and DONE */
+ OSC_errorMessage = "Can't close bundle; no bundle is open!";
+ return 5;
+ }
+
+ if (buf->state == GET_ARGS) {
+ PatchMessageSize(buf);
+ }
+
+ if (buf->bundleDepth == 1) {
+ /* Closing the last bundle: No bundle size to patch */
+ buf->state = DONE;
+ } else {
+ /* Closing a sub-bundle: patch bundle size */
+ int size = buf->bufptr - ((char *) buf->prevCounts[buf->bundleDepth]) - 4;
+ *(buf->prevCounts[buf->bundleDepth]) = size;
+ buf->state = NEED_COUNT;
+ }
+
+ --buf->bundleDepth;
+ return 0;
+}
+
+
+int OSC_closeAllBundles(OSCbuf *buf) {
+ if (buf->bundleDepth == 0) {
+ /* This handles EMPTY, ONE_MSG, ARGS, and DONE */
+ OSC_errorMessage = "Can't close all bundles; no bundle is open!";
+ return 6;
+ }
+
+ while (buf->bundleDepth > 0) {
+ OSC_closeBundle(buf);
+ }
+ return 0;
+}
+
+int OSC_writeAddress(OSCbuf *buf, char *name) {
+ int4byte paddedLength;
+
+ if (buf->state == ONE_MSG_ARGS) {
+ OSC_errorMessage = "This packet is not a bundle, so you can't write another address";
+ return 7;
+ }
+
+ if (buf->state == DONE) {
+ OSC_errorMessage = "This packet is finished; can't write another address";
+ return 8;
+ }
+
+ paddedLength = OSC_effectiveStringLength(name);
+
+ if (buf->state == EMPTY) {
+ /* This will be a one-message packet, so no sizes to worry about */
+ CheckOverflow(buf, paddedLength);
+ buf->state = ONE_MSG_ARGS;
+ } else {
+ /* GET_ARGS or NEED_COUNT */
+ CheckOverflow(buf, 4+paddedLength);
+ if (buf->state == GET_ARGS) {
+ /* Close the old message */
+ PatchMessageSize(buf);
+ }
+ buf->thisMsgSize = (int4byte *)buf->bufptr;
+ *(buf->thisMsgSize) = 0xbbbbbbbb;
+ buf->bufptr += 4;
+ buf->state = GET_ARGS;
+ }
+
+ /* Now write the name */
+ buf->bufptr += OSC_padString(buf->bufptr, name);
+ return 0;
+}
+
+int OSC_writeFloatArg(OSCbuf *buf, float arg) {
+ CheckOverflow(buf, 4);
+ *((float *) buf->bufptr) = arg;
+ buf->bufptr += 4;
+ return 0;
+}
+
+int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args) {
+ int i;
+ CheckOverflow(buf, 4 * numFloats);
+ for (i = 0; i < numFloats; i++) {
+ *((float *) buf->bufptr) = args[i];
+ buf->bufptr += 4;
+ }
+ return 0;
+}
+
+int OSC_writeIntArg(OSCbuf *buf, int4byte arg) {
+ CheckOverflow(buf, 4);
+ *((int4byte *) buf->bufptr) = arg;
+ buf->bufptr += 4;
+ return 0;
+}
+
+int OSC_writeStringArg(OSCbuf *buf, char *arg) {
+ CheckOverflow(buf, OSC_effectiveStringLength(arg));
+ buf->bufptr += OSC_padString(buf->bufptr, arg);
+ return 0;
+}
+
+/* String utilities */
+
+static int strlen(char *s) {
+ int i;
+ for (i=0; s[i] != '\0'; i++) /* Do nothing */ ;
+ return i;
+}
+
+#define STRING_ALIGN_PAD 4
+int OSC_effectiveStringLength(char *string) {
+ int len = strlen(string) + 1; /* We need space for the null char. */
+
+ /* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */
+ if ((len % STRING_ALIGN_PAD) != 0) {
+ len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD);
+ }
+ return len;
+}
+
+static int OSC_padString(char *dest, char *str) {
+ int i;
+
+ for (i = 0; str[i] != '\0'; i++) {
+ dest[i] = str[i];
+ }
+
+ dest[i] = '\0';
+ i++;
+
+ for (; (i % STRING_ALIGN_PAD) != 0; i++) {
+ dest[i] = '\0';
+ }
+
+ return i;
+}
+
diff --git a/libOSC/OSC-client.h b/libOSC/OSC-client.h
new file mode 100644
index 0000000..b1fd833
--- /dev/null
+++ b/libOSC/OSC-client.h
@@ -0,0 +1,181 @@
+/*
+Copyright (c) 1996,1997. The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for educational, research, and not-for-profit purposes, without
+fee and without a signed licensing agreement, is hereby granted, provided that
+the above copyright notice, this paragraph and the following two paragraphs
+appear in all copies, modifications, and distributions. Contact The Office of
+Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
+CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
+
+Written by Matt Wright, The Center for New Music and Audio Technologies,
+University of California, Berkeley.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
+ DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
+ REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/*
+
+ OSC-client.h: library for constructing OpenSoundControl messages.
+ Derived from SynthControl.h
+ Author: Matt Wright
+ Version 0.1: 6/13/97
+ Version 0.2: 7/21/2000: Support for type-tagged messages
+
+
+ General notes:
+
+ This library abstracts away the data format for the OpenSoundControl
+ protocol. Users of this library can construct OpenSoundControl packets
+ with a function call interface instead of knowing how to lay out the bits.
+
+ All issues of memory allocation are deferred to the user of this library.
+ There are two data structures that the user must allocate. The first
+ is the actual buffer that the message will be written into. This buffer
+ can be any size, but if it's too small there's a possibility that it
+ will become overfull. The other data structure is called an OSCbuf,
+ and it holds all the state used by the library as it's constructing
+ a buffer.
+
+ All procedures that have the possibility of an error condition return int,
+ with 0 indicating no error and nonzero indicating an error. The variable
+ OSC_errorMessage will be set to point to a string containing an error
+ message explaining what the problem is.
+
+*/
+
+
+#include "OSC-timetag.h"
+
+/* The int4byte type has to be a 4-byte integer. You may have to
+ change this to long or something else on your system. */
+#ifdef __MWERKS__
+ /* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is
+ always 4 bytes */
+ typedef long int4byte;
+#else
+ typedef int int4byte;
+#endif
+
+/* The maximum depth of bundles within bundles within bundles within...
+ This is the size of a static array. If you exceed this limit you'll
+ get an error message. */
+#define MAX_BUNDLE_NESTING 32
+
+
+/* Don't ever manipulate the data in the OSCbuf struct directly. (It's
+ declared here in the header file only so your program will be able to
+ declare variables of type OSCbuf and have the right amount of memory
+ be allocated.) */
+
+typedef struct OSCbuf_struct {
+ char *buffer; /* The buffer to hold the OSC packet */
+ int size; /* Size of the buffer */
+ char *bufptr; /* Current position as we fill the buffer */
+ int state; /* State of partially-constructed message */
+ int4byte *thisMsgSize; /* Pointer to count field before
+ currently-being-written message */
+ int4byte *prevCounts[MAX_BUNDLE_NESTING];
+ /* Pointers to count field before each currently
+ open bundle */
+ int bundleDepth; /* How many sub-sub-bundles are we in now? */
+ char *typeStringPtr; /* This pointer advances through the type
+ tag string as you add arguments. */
+ int gettingFirstUntypedArg; /* nonzero if this message doesn't have
+ a type tag and we're waiting for the 1st arg */
+} OSCbuf;
+
+
+
+/* Initialize the given OSCbuf. The user of this module must pass in the
+ block of memory that this OSCbuf will use for a buffer, and the number of
+ bytes in that block. (It's the user's job to allocate the memory because
+ you do it differently in different systems.) */
+void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray);
+
+
+/* Reset the given OSCbuf. Do this after you send out the contents of
+ the buffer and want to start writing new data into it. */
+void OSC_resetBuffer(OSCbuf *buf);
+
+
+/* Is the buffer empty? (I.e., would it be stupid to send the buffer
+ contents to the synth?) */
+int OSC_isBufferEmpty(OSCbuf *buf);
+
+
+/* How much space is left in the buffer? */
+int OSC_freeSpaceInBuffer(OSCbuf *buf);
+
+/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */
+int OSC_isBufferDone(OSCbuf *buf);
+
+/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone()
+ returns true), call these two procedures to get the OSC packet that's been
+ assembled and its size in bytes. (And then call OSC_resetBuffer() if you
+ want to re-use this OSCbuf for the next packet.) */
+char *OSC_getPacket(OSCbuf *buf);
+int OSC_packetSize(OSCbuf *buf);
+
+
+
+/* Here's the basic model for building up OSC messages in an OSCbuf:
+
+ - Make sure the OSCbuf has been initialized with OSC_initBuffer().
+
+ - To open a bundle, call OSC_openBundle(). You can then write
+ messages or open new bundles within the bundle you opened.
+ Call OSC_closeBundle() to close the bundle. Note that a packet
+ does not have to have a bundle; it can instead consist of just a
+ single message.
+
+
+ - For each message you want to send:
+
+ - Call OSC_writeAddress() with the name of your message. (In
+ addition to writing your message name into the buffer, this
+ procedure will also leave space for the size count of this message.)
+
+ - Alternately, call OSC_writeAddressAndTypes() with the name of
+ your message and with a type string listing the types of all the
+ arguments you will be putting in this message.
+
+ - Now write each of the arguments into the buffer, by calling one of:
+ OSC_writeFloatArg()
+ OSC_writeFloatArgs()
+ OSC_writeIntArg()
+ OSC_writeStringArg()
+
+ - Now your message is complete; you can send out the buffer or you can
+ add another message to it.
+*/
+
+int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt);
+int OSC_closeBundle(OSCbuf *buf);
+int OSC_closeAllBundles(OSCbuf *buf);
+
+int OSC_writeAddress(OSCbuf *buf, char *name);
+int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types);
+int OSC_writeFloatArg(OSCbuf *buf, float arg);
+int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args);
+int OSC_writeIntArg(OSCbuf *buf, int4byte arg);
+int OSC_writeStringArg(OSCbuf *buf, char *arg);
+
+extern char *OSC_errorMessage;
+
+/* How many bytes will be needed in the OSC format to hold the given
+ string? The length of the string, plus the null char, plus any padding
+ needed for 4-byte alignment. */
+int OSC_effectiveStringLength(char *string);
diff --git a/libOSC/OSC-timetag.c b/libOSC/OSC-timetag.c
new file mode 100644
index 0000000..639eae9
--- /dev/null
+++ b/libOSC/OSC-timetag.c
@@ -0,0 +1,175 @@
+/*
+Copyright (c) 1998. The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for educational, research, and not-for-profit purposes, without
+fee and without a signed licensing agreement, is hereby granted, provided that
+the above copyright notice, this paragraph and the following two paragraphs
+appear in all copies, modifications, and distributions. Contact The Office of
+Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
+CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
+
+Written by Matt Wright, The Center for New Music and Audio Technologies,
+University of California, Berkeley.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
+ DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
+ REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ ENHANCEMENTS, OR MODIFICATIONS.
+
+The OpenSound Control WWW page is
+ http://www.cnmat.berkeley.edu/OpenSoundControl
+*/
+
+/*
+
+ OSC_timeTag.c: library for manipulating OSC time tags
+ Matt Wright, 5/29/97
+
+ Version 0.2 (9/11/98): cleaned up so no explicit type names in the .c file.
+
+*/
+
+#include "OSC-timetag.h"
+
+
+#ifdef HAS8BYTEINT
+#define TWO_TO_THE_32_FLOAT 4294967296.0f
+
+OSCTimeTag OSCTT_Immediately(void) {
+ return (OSCTimeTag) 1;
+}
+
+OSCTimeTag OSCTT_BiggestPossibleTimeTag(void) {
+ return (OSCTimeTag) 0xffffffffffffffff;
+}
+
+OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) {
+ int64 offset = (int64) (secondsOffset * TWO_TO_THE_32_FLOAT);
+
+/* printf("* OSCTT_PlusSeconds %llx plus %f seconds (i.e., %lld offset) is %llx\n", original,
+ secondsOffset, offset, original + offset); */
+
+ return original + offset;
+}
+
+int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right) {
+#if 0
+ printf("***** OSCTT_Compare(%llx, %llx): %d\n", left, right,
+ (left<right) ? -1 : ((left == right) ? 0 : 1));
+#endif
+ if (left < right) {
+ return -1;
+ } else if (left == right) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+#ifdef __sgi
+#include <sys/time.h>
+
+#define SECONDS_FROM_1900_to_1970 2208988800 /* 17 leap years */
+#define TWO_TO_THE_32_OVER_ONE_MILLION 4295
+
+
+OSCTimeTag OSCTT_CurrentTime(void) {
+ uint64 result;
+ uint32 usecOffset;
+ struct timeval tv;
+ struct timezone tz;
+
+ BSDgettimeofday(&tv, &tz);
+
+ /* First get the seconds right */
+ result = (unsigned) SECONDS_FROM_1900_to_1970 +
+ (unsigned) tv.tv_sec -
+ (unsigned) 60 * tz.tz_minuteswest +
+ (unsigned) (tz.tz_dsttime ? 3600 : 0);
+
+#if 0
+ /* No timezone, no DST version ... */
+ result = (unsigned) SECONDS_FROM_1900_to_1970 +
+ (unsigned) tv.tv_sec;
+#endif
+
+
+ /* make seconds the high-order 32 bits */
+ result = result << 32;
+
+ /* Now get the fractional part. */
+ usecOffset = (unsigned) tv.tv_usec * (unsigned) TWO_TO_THE_32_OVER_ONE_MILLION;
+ /* printf("** %ld microsec is offset %x\n", tv.tv_usec, usecOffset); */
+
+ result += usecOffset;
+
+/* printf("* OSCTT_CurrentTime is %llx\n", result); */
+ return result;
+}
+
+#else /* __sgi */
+
+/* Instead of asking your operating system what time it is, it might be
+ clever to find out the current time at the instant your application
+ starts audio processing, and then keep track of the number of samples
+ output to know how much time has passed. */
+
+/* Loser version for systems that have no ability to tell the current time: */
+OSCTimeTag OSCTT_CurrentTime(void) {
+ return (OSCTimeTag) 1;
+}
+
+#endif /* __sgi */
+
+
+#else /* Not HAS8BYTEINT */
+
+OSCTimeTag OSCTT_CurrentTime(void) {
+ OSCTimeTag result;
+ result.seconds = 0;
+ result.fraction = 1;
+ return result;
+}
+
+OSCTimeTag OSCTT_BiggestPossibleTimeTag(void) {
+ OSCTimeTag result;
+ result.seconds = 0xffffffff;
+ result.fraction = 0xffffffff;
+ return result;
+}
+
+OSCTimeTag OSCTT_Immediately(void) {
+ OSCTimeTag result;
+ result.seconds = 0;
+ result.fraction = 1;
+ return result;
+}
+
+OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) {
+ OSCTimeTag result;
+ result.seconds = 0;
+ result.fraction = 1;
+ return result;
+}
+
+int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right) {
+ /* Untested! */
+ int highResult = left.seconds - right.seconds;
+
+ if (highResult != 0) return highResult;
+
+ return left.fraction - right.fraction;
+}
+
+
+#endif /* HAS8BYTEINT */
+
diff --git a/libOSC/OSC-timetag.h b/libOSC/OSC-timetag.h
new file mode 100644
index 0000000..3ce693a
--- /dev/null
+++ b/libOSC/OSC-timetag.h
@@ -0,0 +1,93 @@
+/*
+Copyright (c) 1998. The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for educational, research, and not-for-profit purposes, without
+fee and without a signed licensing agreement, is hereby granted, provided that
+the above copyright notice, this paragraph and the following two paragraphs
+appear in all copies, modifications, and distributions. Contact The Office of
+Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
+CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
+
+Written by Matt Wright, The Center for New Music and Audio Technologies,
+University of California, Berkeley.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
+ DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
+ REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ ENHANCEMENTS, OR MODIFICATIONS.
+
+The OpenSound Control WWW page is
+ http://www.cnmat.berkeley.edu/OpenSoundControl
+*/
+
+/*
+ OSC_timeTag.h: library for manipulating OSC time tags
+ Matt Wright, 5/29/97
+
+ Time tags in OSC have the same format as in NTP: 64 bit fixed point, with the
+ top 32 bits giving number of seconds sinve midnight 1/1/1900 and the bottom
+ 32 bits giving fractional parts of a second. We represent this by a 64-bit
+ unsigned long if possible, or else a struct.
+
+ NB: On many architectures with 64-bit ints, it's illegal (like maybe a bus error)
+ to dereference a pointer to a 64-bit int that's not 64-bit aligned.
+*/
+
+#ifndef OSC_TIMETAG
+#define OSC_TIMETAG
+
+#ifdef __sgi
+ #define HAS8BYTEINT
+ /* You may have to change this typedef if there's some other
+ way to specify 64 bit ints on your system */
+ typedef long long int64;
+ typedef unsigned long long uint64;
+ typedef unsigned long uint32;
+#else
+ /* You may have to redefine this typedef if ints on your system
+ aren't 32 bits. */
+ typedef unsigned int uint32;
+#endif
+
+
+#ifdef HAS8BYTEINT
+ typedef uint64 OSCTimeTag;
+#else
+ typedef struct {
+ uint32 seconds;
+ uint32 fraction;
+ } OSCTimeTag;
+#endif
+
+
+
+/* Return a time tag representing the current time (as of when this
+ procedure is called). */
+OSCTimeTag OSCTT_CurrentTime(void);
+
+/* Return the time tag 0x0000000000000001, indicating to the receiving device
+ that it should process the message immediately. */
+OSCTimeTag OSCTT_Immediately(void);
+
+/* Return the time tag 0xffffffffffffffff, a time so far in the future that
+ it's effectively infinity. */
+OSCTimeTag OSCTT_BiggestPossibleTimeTag(void);
+
+/* Given a time tag and a number of seconds to add to the time tag, return
+ the new time tag */
+OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset);
+
+/* Compare two time tags. Return negative if first is < second, 0 if
+ they're equal, and positive if first > second. */
+int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right);
+
+#endif /* OSC_TIMETAG */
diff --git a/libOSC/test_OSC.c b/libOSC/test_OSC.c
new file mode 100644
index 0000000..4593ec6
--- /dev/null
+++ b/libOSC/test_OSC.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997 Regents of the University of California.
+ * All rights reserved.
+ *
+ * The name of the University may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
+ * IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/*
+ test_OSC.c
+ Trivial program to test OpenSoundControl.[ch]
+
+ Matt Wright 6/2/97
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#include "OpenSoundControl.h"
+
+#define SIZE 10000
+
+void PrintBuf(OSCbuf *b) {
+ printf("Buffer is %sempty.\n", OSC_isBufferEmpty(b) ? "" : "not ");
+ printf("%d bytes free in buffer\n", OSC_freeSpaceInBuffer(b));
+ printf("Buffer is %sready to send\n", OSC_isBufferDone(b) ?"":"not ");
+
+ printf("Buffer: bufptr %p, state %d, thisMsgSize %p, bundleDepth %d\n"
+ "prevCounts[%d] %p\n", b->bufptr, b->state, b->thisMsgSize,
+ b->bundleDepth, b->bundleDepth, b->prevCounts[b->bundleDepth]);
+}
+
+void PrintPacket(OSCbuf *b) {
+ char *p = OSC_getPacket(b);
+ int size = OSC_packetSize(b);
+ unsigned int *intp;
+ int i;
+
+ printf("PrintPacket: packet at %p, size %d\n", p, size);
+ if (p == 0 || size == 0) return;
+
+ printf("Hex version:");
+ for (i = 0, intp = (unsigned int *)p; i < size; i += 4, intp++) {
+ if (i % 40 == 0) printf("\n");
+ printf("%x ", *intp);
+ }
+
+ printf("\n\nString version:");
+ for (i = 0; i < size; i++) {
+ if (i % 40 == 0) printf("\n");
+ if (isprint(p[i])) {
+ printf("%c", p[i]);
+ } else {
+ printf("\\%x", p[i] & 0x000000ff);
+ }
+ }
+ printf("\n");
+}
+
+
+main() {
+ OSCbuf myBuf;
+ OSCbuf *b = &myBuf;
+ char bytes[SIZE];
+ OSCTimeTag tt;
+
+ printf("OSC_initBuffer\n");
+ OSC_initBuffer(b, SIZE, bytes);
+
+ PrintBuf(b);
+
+ printf("Testing one-message packet\n");
+ if (OSC_writeAddress(b, "/blah/bleh/singlemessage")) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeFloatArg(b, 1.23456f)) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ {
+ float floatarray[10];
+ int i;
+ for (i = 0; i < 10; ++i) {
+ floatarray[i] = i * 10.0f;
+ }
+ if (OSC_writeFloatArgs(b, 10, floatarray)) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+ }
+
+ if (OSC_writeIntArg(b, 123456)) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeStringArg(b, "This is a cool string, dude.")) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ PrintBuf(b);
+ PrintPacket(b);
+
+ printf("Resetting\n");
+ OSC_resetBuffer(b);
+
+ printf("Testing time tags\n");
+ tt = OSCTT_CurrentTime();
+ printf("Time now is %llx\n", tt);
+
+ printf("Testing bundles\n");
+ if (OSC_openBundle(b, tt)) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeAddress(b, "/a/hello")) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeIntArg(b, 16)) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeIntArg(b, 32)) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_openBundle(b, OSCTT_PlusSeconds(tt, 1.0f))) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeAddress(b, "/b/hello")) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ if (OSC_writeAddress(b, "/c/hello")) {
+ printf("** ERROR: %s\n", OSC_errorMessage);
+ }
+
+ OSC_closeAllBundles(b);
+
+ PrintBuf(b);
+ PrintPacket(b);
+}
+
+
+
diff --git a/libOSC/test_OSC_timeTag.c b/libOSC/test_OSC_timeTag.c
new file mode 100644
index 0000000..8a1cabf
--- /dev/null
+++ b/libOSC/test_OSC_timeTag.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1997 Regents of the University of California.
+ * All rights reserved.
+ *
+ * The name of the University may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
+ * IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/*
+ test_OSC_timeTag.c
+ Matt Wright, 5/30/97
+*/
+
+#include <stdio.h>
+#include "OSC_timeTag.h"
+
+main() {
+ OSCTimeTag now, later;
+
+ now = OSCTT_CurrentTime();
+ printf("Now it's %llu (0x%llx)\n", now, now);
+
+ printf("Immediately would be %llu (0x%llx)\n", OSCTT_Immediately(),
+ OSCTT_Immediately());
+
+ later = OSCTT_PlusSeconds(now, 1.0f);
+ printf("One second from now would be %llu (0x%llx)\n", later, later);
+
+ now = OSCTT_CurrentTime();
+ printf("And *now* it's %llu (0x%llx)\n", now, now);
+}
+