00001 /* 00002 Copyright (c) 1996,1997. The Regents of the University of California (Regents). 00003 All Rights Reserved. 00004 00005 Permission to use, copy, modify, and distribute this software and its 00006 documentation for educational, research, and not-for-profit purposes, without 00007 fee and without a signed licensing agreement, is hereby granted, provided that 00008 the above copyright notice, this paragraph and the following two paragraphs 00009 appear in all copies, modifications, and distributions. Contact The Office of 00010 Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, 00011 CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. 00012 00013 Written by Matt Wright, The Center for New Music and Audio Technologies, 00014 University of California, Berkeley. 00015 00016 IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 00017 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, 00018 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 00019 REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00020 00021 REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 00022 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00023 FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING 00024 DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 00025 REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 00026 ENHANCEMENTS, OR MODIFICATIONS. 00027 */ 00028 00029 /* 00030 00031 OSC-client.h: library for constructing OpenSoundControl messages. 00032 Derived from SynthControl.h 00033 Author: Matt Wright 00034 Version 0.1: 6/13/97 00035 Version 0.2: 7/21/2000: Support for type-tagged messages 00036 00037 00038 General notes: 00039 00040 This library abstracts away the data format for the OpenSoundControl 00041 protocol. Users of this library can construct OpenSoundControl packets 00042 with a function call interface instead of knowing how to lay out the bits. 00043 00044 All issues of memory allocation are deferred to the user of this library. 00045 There are two data structures that the user must allocate. The first 00046 is the actual buffer that the message will be written into. This buffer 00047 can be any size, but if it's too small there's a possibility that it 00048 will become overfull. The other data structure is called an OSCbuf, 00049 and it holds all the state used by the library as it's constructing 00050 a buffer. 00051 00052 All procedures that have the possibility of an error condition return int, 00053 with 0 indicating no error and nonzero indicating an error. The variable 00054 OSC_errorMessage will be set to point to a string containing an error 00055 message explaining what the problem is. 00056 00057 */ 00058 00059 00060 #include "OSC-timetag.h" 00061 #include "global.h" 00062 #include <progmem.h> 00063 00064 #ifdef ATMEL 00065 #define htonl(x) \ 00066 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ 00067 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) 00068 00069 #endif 00070 00071 /* The int4byte type has to be a 4-byte integer. You may have to 00072 change this to long or something else on your system. */ 00073 #ifdef __MWERKS__ 00074 /* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is 00075 always 4 bytes */ 00076 typedef long int4byte; 00077 #else 00078 typedef s32 int4byte; 00079 #endif 00080 00081 /* The maximum depth of bundles within bundles within bundles within... 00082 This is the size of a static array. If you exceed this limit you'll 00083 get an error message. */ 00084 #define MAX_BUNDLE_NESTING 32 00085 00086 00087 /* Don't ever manipulate the data in the OSCbuf struct directly. (It's 00088 declared here in the header file only so your program will be able to 00089 declare variables of type OSCbuf and have the right amount of memory 00090 be allocated.) */ 00091 00092 typedef struct OSCbuf_struct { 00093 char *buffer; /* The buffer to hold the OSC packet */ 00094 int size; /* Size of the buffer */ 00095 char *bufptr; /* Current position as we fill the buffer */ 00096 int state; /* State of partially-constructed message */ 00097 int4byte *thisMsgSize; /* Pointer to count field before 00098 currently-being-written message */ 00099 int4byte *prevCounts[MAX_BUNDLE_NESTING]; 00100 /* Pointers to count field before each currently 00101 open bundle */ 00102 int bundleDepth; /* How many sub-sub-bundles are we in now? */ 00103 char *typeStringPtr; /* This pointer advances through the type 00104 tag string as you add arguments. */ 00105 int gettingFirstUntypedArg; /* nonzero if this message doesn't have 00106 a type tag and we're waiting for the 1st arg */ 00107 } OSCbuf; 00108 00109 00110 00111 /* Initialize the given OSCbuf. The user of this module must pass in the 00112 block of memory that this OSCbuf will use for a buffer, and the number of 00113 bytes in that block. (It's the user's job to allocate the memory because 00114 you do it differently in different systems.) */ 00115 void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray); 00116 00117 00118 /* Reset the given OSCbuf. Do this after you send out the contents of 00119 the buffer and want to start writing new data into it. */ 00120 void OSC_resetBuffer(OSCbuf *buf); 00121 00122 00123 /* Is the buffer empty? (I.e., would it be stupid to send the buffer 00124 contents to the synth?) */ 00125 int OSC_isBufferEmpty(OSCbuf *buf); 00126 00127 00128 /* How much space is left in the buffer? */ 00129 int OSC_freeSpaceInBuffer(OSCbuf *buf); 00130 00131 /* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */ 00132 int OSC_isBufferDone(OSCbuf *buf); 00133 00134 /* When you're ready to send out the buffer (i.e., when OSC_isBufferDone() 00135 returns true), call these two procedures to get the OSC packet that's been 00136 assembled and its size in bytes. (And then call OSC_resetBuffer() if you 00137 want to re-use this OSCbuf for the next packet.) */ 00138 char *OSC_getPacket(OSCbuf *buf); 00139 int OSC_packetSize(OSCbuf *buf); 00140 00141 00142 00143 /* Here's the basic model for building up OSC messages in an OSCbuf: 00144 00145 - Make sure the OSCbuf has been initialized with OSC_initBuffer(). 00146 00147 - To open a bundle, call OSC_openBundle(). You can then write 00148 messages or open new bundles within the bundle you opened. 00149 Call OSC_closeBundle() to close the bundle. Note that a packet 00150 does not have to have a bundle; it can instead consist of just a 00151 single message. 00152 00153 00154 - For each message you want to send: 00155 00156 - Call OSC_writeAddress() with the name of your message. (In 00157 addition to writing your message name into the buffer, this 00158 procedure will also leave space for the size count of this message.) 00159 00160 - Alternately, call OSC_writeAddressAndTypes() with the name of 00161 your message and with a type string listing the types of all the 00162 arguments you will be putting in this message. 00163 00164 - Now write each of the arguments into the buffer, by calling one of: 00165 OSC_writeFloatArg() 00166 OSC_writeFloatArgs() 00167 OSC_writeIntArg() 00168 OSC_writeStringArg() 00169 00170 - Now your message is complete; you can send out the buffer or you can 00171 add another message to it. 00172 */ 00173 00174 int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt); 00175 int OSC_closeBundle(OSCbuf *buf); 00176 int OSC_closeAllBundles(OSCbuf *buf); 00177 00178 int OSC_writeAddress(OSCbuf *buf, char PROGMEM *name); 00179 int OSC_writeAddressAndTypes(OSCbuf *buf, char PROGMEM *name, char PROGMEM *types); 00180 int OSC_writeFloatArg(OSCbuf *buf, float arg); 00181 int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args); 00182 int OSC_writeIntArg(OSCbuf *buf, int4byte arg); 00183 int OSC_writeStringArg(OSCbuf *buf, char PROGMEM *arg); 00184 00185 extern char *OSC_errorMessage; 00186 00187 /* How many bytes will be needed in the OSC format to hold the given 00188 string? The length of the string, plus the null char, plus any padding 00189 needed for 4-byte alignment. */ 00190 int OSC_effectiveStringLength(char PROGMEM *string);