(uncpomplete) port of the cnmat osc library for Arduino/Teensy. Upstream url: https://github.com/CNMAT/OSC

(uncpomplete) port of the cnmat osc library for Arduino/Teensy. Upstream url: https://github.com/CNMAT/OSC

Compiles, but not Tested in any kind. OSCMessage::send(); and OSCBundle::send() don't work/are commented out due to Platform specifics I first have to figure out.

Readme

Committer:
aspeteRakete
Date:
Fri May 16 22:10:49 2014 +0000
Revision:
1:18009e3041ea
Child:
2:61caa2495215
OSCMessage Portiert: ::send(Print &p) derzeit auskommentiert.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aspeteRakete 1:18009e3041ea 1 /*
aspeteRakete 1:18009e3041ea 2 Written by Yotam Mann, The Center for New Music and Audio Technologies,
aspeteRakete 1:18009e3041ea 3 University of California, Berkeley. Copyright (c) 2012, The Regents of
aspeteRakete 1:18009e3041ea 4 the University of California (Regents).
aspeteRakete 1:18009e3041ea 5
aspeteRakete 1:18009e3041ea 6 Permission to use, copy, modify, distribute, and distribute modified versions
aspeteRakete 1:18009e3041ea 7 of this software and its documentation without fee and without a signed
aspeteRakete 1:18009e3041ea 8 licensing agreement, is hereby granted, provided that the above copyright
aspeteRakete 1:18009e3041ea 9 notice, this paragraph and the following two paragraphs appear in all copies,
aspeteRakete 1:18009e3041ea 10 modifications, and distributions.
aspeteRakete 1:18009e3041ea 11
aspeteRakete 1:18009e3041ea 12 IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
aspeteRakete 1:18009e3041ea 13 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
aspeteRakete 1:18009e3041ea 14 OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
aspeteRakete 1:18009e3041ea 15 BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
aspeteRakete 1:18009e3041ea 16
aspeteRakete 1:18009e3041ea 17 REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
aspeteRakete 1:18009e3041ea 18 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
aspeteRakete 1:18009e3041ea 19 PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
aspeteRakete 1:18009e3041ea 20 HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
aspeteRakete 1:18009e3041ea 21 MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
aspeteRakete 1:18009e3041ea 22
aspeteRakete 1:18009e3041ea 23 For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu
aspeteRakete 1:18009e3041ea 24 */
aspeteRakete 1:18009e3041ea 25
aspeteRakete 1:18009e3041ea 26 #ifndef OSCMESSAGE_h
aspeteRakete 1:18009e3041ea 27 #define OSCMESSAGE_h
aspeteRakete 1:18009e3041ea 28
aspeteRakete 1:18009e3041ea 29 #include "OSCData.h"
aspeteRakete 1:18009e3041ea 30 //#include <Print.h>
aspeteRakete 1:18009e3041ea 31
aspeteRakete 1:18009e3041ea 32
aspeteRakete 1:18009e3041ea 33 class OSCMessage
aspeteRakete 1:18009e3041ea 34 {
aspeteRakete 1:18009e3041ea 35
aspeteRakete 1:18009e3041ea 36 private:
aspeteRakete 1:18009e3041ea 37
aspeteRakete 1:18009e3041ea 38 //friends
aspeteRakete 1:18009e3041ea 39 friend class OSCBundle;
aspeteRakete 1:18009e3041ea 40
aspeteRakete 1:18009e3041ea 41
aspeteRakete 1:18009e3041ea 42 /*=============================================================================
aspeteRakete 1:18009e3041ea 43 PRIVATE VARIABLES
aspeteRakete 1:18009e3041ea 44 =============================================================================*/
aspeteRakete 1:18009e3041ea 45
aspeteRakete 1:18009e3041ea 46 //the address
aspeteRakete 1:18009e3041ea 47 char * address;
aspeteRakete 1:18009e3041ea 48
aspeteRakete 1:18009e3041ea 49 //the data
aspeteRakete 1:18009e3041ea 50 OSCData ** data;
aspeteRakete 1:18009e3041ea 51
aspeteRakete 1:18009e3041ea 52 //the number of OSCData in the data array
aspeteRakete 1:18009e3041ea 53 int dataCount;
aspeteRakete 1:18009e3041ea 54
aspeteRakete 1:18009e3041ea 55 //error codes for potential runtime problems
aspeteRakete 1:18009e3041ea 56 OSCErrorCode error;
aspeteRakete 1:18009e3041ea 57
aspeteRakete 1:18009e3041ea 58 /*=============================================================================
aspeteRakete 1:18009e3041ea 59 DECODING INCOMING BYTES
aspeteRakete 1:18009e3041ea 60 =============================================================================*/
aspeteRakete 1:18009e3041ea 61
aspeteRakete 1:18009e3041ea 62 //the decoding states for incoming bytes
aspeteRakete 1:18009e3041ea 63 enum DecodeState {
aspeteRakete 1:18009e3041ea 64 STANDBY,
aspeteRakete 1:18009e3041ea 65 ADDRESS,
aspeteRakete 1:18009e3041ea 66 ADDRESS_PADDING,
aspeteRakete 1:18009e3041ea 67 TYPES,
aspeteRakete 1:18009e3041ea 68 TYPES_PADDING,
aspeteRakete 1:18009e3041ea 69 DATA,
aspeteRakete 1:18009e3041ea 70 DATA_PADDING,
aspeteRakete 1:18009e3041ea 71 DONE,
aspeteRakete 1:18009e3041ea 72 } decodeState;
aspeteRakete 1:18009e3041ea 73
aspeteRakete 1:18009e3041ea 74 //stores incoming bytes until they can be decoded
aspeteRakete 1:18009e3041ea 75 uint8_t * incomingBuffer;
aspeteRakete 1:18009e3041ea 76 int incomingBufferSize; // how many bytes are stored
aspeteRakete 1:18009e3041ea 77 int incomingBufferFree; // how many bytes are allocated but unused
aspeteRakete 1:18009e3041ea 78
aspeteRakete 1:18009e3041ea 79 //adds a byte to the buffer
aspeteRakete 1:18009e3041ea 80 void addToIncomingBuffer(uint8_t);
aspeteRakete 1:18009e3041ea 81 //clears the incoming buffer
aspeteRakete 1:18009e3041ea 82 void clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 83
aspeteRakete 1:18009e3041ea 84 //decoding function
aspeteRakete 1:18009e3041ea 85 void decode(uint8_t);
aspeteRakete 1:18009e3041ea 86 void decodeAddress();
aspeteRakete 1:18009e3041ea 87 void decodeType(uint8_t);
aspeteRakete 1:18009e3041ea 88 void decodeData(uint8_t);
aspeteRakete 1:18009e3041ea 89
aspeteRakete 1:18009e3041ea 90 /*=============================================================================
aspeteRakete 1:18009e3041ea 91 HELPER FUNCTIONS
aspeteRakete 1:18009e3041ea 92 =============================================================================*/
aspeteRakete 1:18009e3041ea 93
aspeteRakete 1:18009e3041ea 94 void setupMessage();
aspeteRakete 1:18009e3041ea 95
aspeteRakete 1:18009e3041ea 96 //compares the OSCData's type char to a test char
aspeteRakete 1:18009e3041ea 97 bool testType(int position, char type);
aspeteRakete 1:18009e3041ea 98
aspeteRakete 1:18009e3041ea 99 //returns the number of bytes to pad to make it 4-bit aligned
aspeteRakete 1:18009e3041ea 100 // int padSize(int bytes);
aspeteRakete 1:18009e3041ea 101
aspeteRakete 1:18009e3041ea 102 public:
aspeteRakete 1:18009e3041ea 103
aspeteRakete 1:18009e3041ea 104 //returns the OSCData at that position
aspeteRakete 1:18009e3041ea 105 OSCData * getOSCData(int);
aspeteRakete 1:18009e3041ea 106
aspeteRakete 1:18009e3041ea 107 /*=============================================================================
aspeteRakete 1:18009e3041ea 108 CONSTRUCTORS / DESTRUCTOR
aspeteRakete 1:18009e3041ea 109 =============================================================================*/
aspeteRakete 1:18009e3041ea 110
aspeteRakete 1:18009e3041ea 111 //new constructor needs an address
aspeteRakete 1:18009e3041ea 112 OSCMessage (const char * _address);
aspeteRakete 1:18009e3041ea 113 //no address
aspeteRakete 1:18009e3041ea 114 //placeholder since it's invalide OSC
aspeteRakete 1:18009e3041ea 115 OSCMessage();
aspeteRakete 1:18009e3041ea 116
aspeteRakete 1:18009e3041ea 117 //can optionally accept all of the data after the address
aspeteRakete 1:18009e3041ea 118 //OSCMessage(const char * _address, char * types, ... );
aspeteRakete 1:18009e3041ea 119 //created from another OSCMessage
aspeteRakete 1:18009e3041ea 120 OSCMessage (OSCMessage *);
aspeteRakete 1:18009e3041ea 121
aspeteRakete 1:18009e3041ea 122 //DESTRUCTOR
aspeteRakete 1:18009e3041ea 123 ~OSCMessage();
aspeteRakete 1:18009e3041ea 124
aspeteRakete 1:18009e3041ea 125 //empties all of the data
aspeteRakete 1:18009e3041ea 126 void empty();
aspeteRakete 1:18009e3041ea 127
aspeteRakete 1:18009e3041ea 128 /*=============================================================================
aspeteRakete 1:18009e3041ea 129 SETTING DATA
aspeteRakete 1:18009e3041ea 130 =============================================================================*/
aspeteRakete 1:18009e3041ea 131
aspeteRakete 1:18009e3041ea 132 //returns the OSCMessage so that multiple 'add's can be strung together
aspeteRakete 1:18009e3041ea 133 template <typename T>
aspeteRakete 1:18009e3041ea 134 OSCMessage& add(T datum){
aspeteRakete 1:18009e3041ea 135 //make a piece of data
aspeteRakete 1:18009e3041ea 136 OSCData * d = new OSCData(datum);
aspeteRakete 1:18009e3041ea 137 //check if it has any errors
aspeteRakete 1:18009e3041ea 138 if (d->error == ALLOCFAILED){
aspeteRakete 1:18009e3041ea 139 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 140 } else {
aspeteRakete 1:18009e3041ea 141 //resize the data array
aspeteRakete 1:18009e3041ea 142 OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1));
aspeteRakete 1:18009e3041ea 143 if (dataMem == NULL){
aspeteRakete 1:18009e3041ea 144 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 145 } else {
aspeteRakete 1:18009e3041ea 146 data = dataMem;
aspeteRakete 1:18009e3041ea 147 //add data to the end of the array
aspeteRakete 1:18009e3041ea 148 data[dataCount] = d;
aspeteRakete 1:18009e3041ea 149 //increment the data size
aspeteRakete 1:18009e3041ea 150 dataCount++;
aspeteRakete 1:18009e3041ea 151 }
aspeteRakete 1:18009e3041ea 152 }
aspeteRakete 1:18009e3041ea 153 return *this;
aspeteRakete 1:18009e3041ea 154 }
aspeteRakete 1:18009e3041ea 155
aspeteRakete 1:18009e3041ea 156 //blob specific add
aspeteRakete 1:18009e3041ea 157 OSCMessage& add(uint8_t * blob, int length){
aspeteRakete 1:18009e3041ea 158 //make a piece of data
aspeteRakete 1:18009e3041ea 159 OSCData * d = new OSCData(blob, length);
aspeteRakete 1:18009e3041ea 160 //check if it has any errors
aspeteRakete 1:18009e3041ea 161 if (d->error == ALLOCFAILED){
aspeteRakete 1:18009e3041ea 162 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 163 } else {
aspeteRakete 1:18009e3041ea 164 //resize the data array
aspeteRakete 1:18009e3041ea 165 OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1));
aspeteRakete 1:18009e3041ea 166 if (dataMem == NULL){
aspeteRakete 1:18009e3041ea 167 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 168 } else {
aspeteRakete 1:18009e3041ea 169 data = dataMem;
aspeteRakete 1:18009e3041ea 170 //add data to the end of the array
aspeteRakete 1:18009e3041ea 171 data[dataCount] = d;
aspeteRakete 1:18009e3041ea 172 //increment the data size
aspeteRakete 1:18009e3041ea 173 dataCount++;
aspeteRakete 1:18009e3041ea 174 }
aspeteRakete 1:18009e3041ea 175 }
aspeteRakete 1:18009e3041ea 176 return *this;
aspeteRakete 1:18009e3041ea 177 }
aspeteRakete 1:18009e3041ea 178
aspeteRakete 1:18009e3041ea 179 //sets the data at a position
aspeteRakete 1:18009e3041ea 180 template <typename T>
aspeteRakete 1:18009e3041ea 181 void set(int position, T datum){
aspeteRakete 1:18009e3041ea 182 if (position < dataCount){
aspeteRakete 1:18009e3041ea 183 //replace the OSCData with a new one
aspeteRakete 1:18009e3041ea 184 OSCData * oldDatum = getOSCData(position);
aspeteRakete 1:18009e3041ea 185 //destroy the old one
aspeteRakete 1:18009e3041ea 186 delete oldDatum;
aspeteRakete 1:18009e3041ea 187 //make a new one
aspeteRakete 1:18009e3041ea 188 OSCData * newDatum = new OSCData(datum);
aspeteRakete 1:18009e3041ea 189 //test if there was an error
aspeteRakete 1:18009e3041ea 190 if (newDatum->error == ALLOCFAILED){
aspeteRakete 1:18009e3041ea 191 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 192 } else {
aspeteRakete 1:18009e3041ea 193 //otherwise, put it in the data array
aspeteRakete 1:18009e3041ea 194 data[position] = newDatum;
aspeteRakete 1:18009e3041ea 195 }
aspeteRakete 1:18009e3041ea 196 } else if (position == (dataCount)){
aspeteRakete 1:18009e3041ea 197 //add the data to the end
aspeteRakete 1:18009e3041ea 198 add(datum);
aspeteRakete 1:18009e3041ea 199 } else {
aspeteRakete 1:18009e3041ea 200 //else out of bounds error
aspeteRakete 1:18009e3041ea 201 error = INDEX_OUT_OF_BOUNDS;
aspeteRakete 1:18009e3041ea 202 }
aspeteRakete 1:18009e3041ea 203 }
aspeteRakete 1:18009e3041ea 204
aspeteRakete 1:18009e3041ea 205 //blob specific setter
aspeteRakete 1:18009e3041ea 206 void set(int position, uint8_t * blob, int length){
aspeteRakete 1:18009e3041ea 207 if (position < dataCount){
aspeteRakete 1:18009e3041ea 208 //replace the OSCData with a new one
aspeteRakete 1:18009e3041ea 209 OSCData * oldDatum = getOSCData(position);
aspeteRakete 1:18009e3041ea 210 //destroy the old one
aspeteRakete 1:18009e3041ea 211 delete oldDatum;
aspeteRakete 1:18009e3041ea 212 //make a new one
aspeteRakete 1:18009e3041ea 213 OSCData * newDatum = new OSCData(blob, length);
aspeteRakete 1:18009e3041ea 214 //test if there was an error
aspeteRakete 1:18009e3041ea 215 if (newDatum->error == ALLOCFAILED){
aspeteRakete 1:18009e3041ea 216 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 217 } else {
aspeteRakete 1:18009e3041ea 218 //otherwise, put it in the data array
aspeteRakete 1:18009e3041ea 219 data[position] = newDatum;
aspeteRakete 1:18009e3041ea 220 }
aspeteRakete 1:18009e3041ea 221 } else if (position == (dataCount)){
aspeteRakete 1:18009e3041ea 222 //add the data to the end
aspeteRakete 1:18009e3041ea 223 add(blob, length);
aspeteRakete 1:18009e3041ea 224 } else {
aspeteRakete 1:18009e3041ea 225 //else out of bounds error
aspeteRakete 1:18009e3041ea 226 error = INDEX_OUT_OF_BOUNDS;
aspeteRakete 1:18009e3041ea 227 }
aspeteRakete 1:18009e3041ea 228 }
aspeteRakete 1:18009e3041ea 229
aspeteRakete 1:18009e3041ea 230 void setAddress(const char *);
aspeteRakete 1:18009e3041ea 231
aspeteRakete 1:18009e3041ea 232 /*=============================================================================
aspeteRakete 1:18009e3041ea 233 GETTING DATA
aspeteRakete 1:18009e3041ea 234
aspeteRakete 1:18009e3041ea 235 getters take a position as an argument
aspeteRakete 1:18009e3041ea 236 =============================================================================*/
aspeteRakete 1:18009e3041ea 237
aspeteRakete 1:18009e3041ea 238 int32_t getInt(int);
aspeteRakete 1:18009e3041ea 239 uint64_t getTime(int);
aspeteRakete 1:18009e3041ea 240
aspeteRakete 1:18009e3041ea 241 float getFloat(int);
aspeteRakete 1:18009e3041ea 242 double getDouble(int);
aspeteRakete 1:18009e3041ea 243 bool getBoolean(int);
aspeteRakete 1:18009e3041ea 244
aspeteRakete 1:18009e3041ea 245 //return the copied string's length
aspeteRakete 1:18009e3041ea 246 int getString(int, char *, int);
aspeteRakete 1:18009e3041ea 247 //returns the number of unsigned int8's copied into the buffer
aspeteRakete 1:18009e3041ea 248 int getBlob(int, uint8_t *, int);
aspeteRakete 1:18009e3041ea 249
aspeteRakete 1:18009e3041ea 250 //returns the number of bytes of the data at that position
aspeteRakete 1:18009e3041ea 251 int getDataLength(int);
aspeteRakete 1:18009e3041ea 252
aspeteRakete 1:18009e3041ea 253 //returns the type at the position
aspeteRakete 1:18009e3041ea 254 char getType(int);
aspeteRakete 1:18009e3041ea 255
aspeteRakete 1:18009e3041ea 256 //put the address in the buffer
aspeteRakete 1:18009e3041ea 257 int getAddress(char * buffer, int offset = 0);
aspeteRakete 1:18009e3041ea 258 int getAddress(char * buffer, int offset, int len);
aspeteRakete 1:18009e3041ea 259
aspeteRakete 1:18009e3041ea 260 // TODO: int getAddressLength(int offset = 0);
aspeteRakete 1:18009e3041ea 261
aspeteRakete 1:18009e3041ea 262
aspeteRakete 1:18009e3041ea 263 /*=============================================================================
aspeteRakete 1:18009e3041ea 264 TESTING DATA
aspeteRakete 1:18009e3041ea 265
aspeteRakete 1:18009e3041ea 266 testers take a position as an argument
aspeteRakete 1:18009e3041ea 267 =============================================================================*/
aspeteRakete 1:18009e3041ea 268
aspeteRakete 1:18009e3041ea 269 bool isInt(int);
aspeteRakete 1:18009e3041ea 270 bool isFloat(int);
aspeteRakete 1:18009e3041ea 271 bool isBlob(int);
aspeteRakete 1:18009e3041ea 272 bool isChar(int);
aspeteRakete 1:18009e3041ea 273 bool isString(int);
aspeteRakete 1:18009e3041ea 274 bool isDouble(int);
aspeteRakete 1:18009e3041ea 275 bool isBoolean(int);
aspeteRakete 1:18009e3041ea 276 bool isTime(int);
aspeteRakete 1:18009e3041ea 277
aspeteRakete 1:18009e3041ea 278 /*=============================================================================
aspeteRakete 1:18009e3041ea 279 PATTERN MATCHING
aspeteRakete 1:18009e3041ea 280 =============================================================================*/
aspeteRakete 1:18009e3041ea 281
aspeteRakete 1:18009e3041ea 282 //match the pattern against the address
aspeteRakete 1:18009e3041ea 283 //returns true only for a complete match
aspeteRakete 1:18009e3041ea 284 bool fullMatch( const char * pattern, int = 0);
aspeteRakete 1:18009e3041ea 285
aspeteRakete 1:18009e3041ea 286 //returns the number of characters matched in the address
aspeteRakete 1:18009e3041ea 287 int match( const char * pattern, int = 0);
aspeteRakete 1:18009e3041ea 288
aspeteRakete 1:18009e3041ea 289 //calls the function with the message as the arg if it was a full match
aspeteRakete 1:18009e3041ea 290 bool dispatch(const char * pattern, void (*callback)(OSCMessage &), int = 0);
aspeteRakete 1:18009e3041ea 291
aspeteRakete 1:18009e3041ea 292 //like dispatch, but allows for partial matches
aspeteRakete 1:18009e3041ea 293 //the address match offset is sent as an argument to the callback
aspeteRakete 1:18009e3041ea 294 //also room for an option address offset to allow for multiple nested routes
aspeteRakete 1:18009e3041ea 295 bool route(const char * pattern, void (*callback)(OSCMessage &, int), int = 0);
aspeteRakete 1:18009e3041ea 296
aspeteRakete 1:18009e3041ea 297
aspeteRakete 1:18009e3041ea 298
aspeteRakete 1:18009e3041ea 299 /*=============================================================================
aspeteRakete 1:18009e3041ea 300 SIZE
aspeteRakete 1:18009e3041ea 301 =============================================================================*/
aspeteRakete 1:18009e3041ea 302
aspeteRakete 1:18009e3041ea 303 //the number of data that the message contains
aspeteRakete 1:18009e3041ea 304 int size();
aspeteRakete 1:18009e3041ea 305
aspeteRakete 1:18009e3041ea 306 //computes the number of bytes the OSCMessage occupies if everything is 32-bit aligned
aspeteRakete 1:18009e3041ea 307 int bytes();
aspeteRakete 1:18009e3041ea 308
aspeteRakete 1:18009e3041ea 309 /*=============================================================================
aspeteRakete 1:18009e3041ea 310 TRANSMISSION
aspeteRakete 1:18009e3041ea 311 =============================================================================*/
aspeteRakete 1:18009e3041ea 312
aspeteRakete 1:18009e3041ea 313 //send the message
aspeteRakete 1:18009e3041ea 314 // void send(Print &p);
aspeteRakete 1:18009e3041ea 315
aspeteRakete 1:18009e3041ea 316 //fill the message from a byte stream
aspeteRakete 1:18009e3041ea 317 void fill(uint8_t);
aspeteRakete 1:18009e3041ea 318 void fill(uint8_t *, int);
aspeteRakete 1:18009e3041ea 319
aspeteRakete 1:18009e3041ea 320 /*=============================================================================
aspeteRakete 1:18009e3041ea 321 ERROR
aspeteRakete 1:18009e3041ea 322 =============================================================================*/
aspeteRakete 1:18009e3041ea 323
aspeteRakete 1:18009e3041ea 324 bool hasError();
aspeteRakete 1:18009e3041ea 325
aspeteRakete 1:18009e3041ea 326 OSCErrorCode getError();
aspeteRakete 1:18009e3041ea 327
aspeteRakete 1:18009e3041ea 328 };
aspeteRakete 1:18009e3041ea 329
aspeteRakete 1:18009e3041ea 330 #endif