Fork of, triyin to rewrite for mbed 5. WIP not yet finished but working. ----------------------- An Open Sound Control library for the mbed, created to be compatible with Recotana's OSCClass library (http://recotana.com) for the Arduino with Ethernet shield. It also uses parts of the OSC Transceiver(Sender/Receiver) code by xshige written by: Alvaro Cassinelli, October 2011 tweaked by: Toby Harris / *spark audio-visual, March 2012

Committer:
ibiltari
Date:
Sat Dec 08 02:16:38 2018 +0100
Revision:
12:f2c792ac1aca
Parent:
10:936c3afce828
Child:
13:c2fe6b720f94
Match!!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ibiltari 7:98280cef1c4f 1 /* mbed OSC Library
Ibiltari 7:98280cef1c4f 2 This is an Open Sound Control library for the mbed, created to be compatible with Recotana's OSCClass library (http://recotana.com) for the
Ibiltari 7:98280cef1c4f 3 Arduino with Ethernet shield. It also uses parts of the OSC Transceiver(Sender/Receiver) code by xshige
Ibiltari 7:98280cef1c4f 4 written by: Alvaro Cassinelli, October 2011
Ibiltari 7:98280cef1c4f 5 tweaked by: Toby Harris / *spark audio-visual, March 2012
Ibiltari 7:98280cef1c4f 6
Ibiltari 7:98280cef1c4f 7 This library is free software; you can redistribute it and/or
Ibiltari 7:98280cef1c4f 8 modify it under the terms of the GNU Lesser General Public
Ibiltari 7:98280cef1c4f 9 License version 2.1 as published by the Free Software Foundation.
Ibiltari 7:98280cef1c4f 10 Open Sound Control http://opensoundcontrol.org/
Ibiltari 7:98280cef1c4f 11 */
Ibiltari 7:98280cef1c4f 12
Ibiltari 7:98280cef1c4f 13 #ifndef mbedOSC_h
Ibiltari 7:98280cef1c4f 14 #define mbedOSC_h
Ibiltari 7:98280cef1c4f 15
Ibiltari 7:98280cef1c4f 16 #include "mbed.h"
Ibiltari 7:98280cef1c4f 17 #include "EthernetInterface.h"
Ibiltari 7:98280cef1c4f 18 #include "UDPSocket.h"
Ibiltari 7:98280cef1c4f 19 #include "OSCData.h"
Ibiltari 7:98280cef1c4f 20
Ibiltari 7:98280cef1c4f 21 class OSCMessage
Ibiltari 7:98280cef1c4f 22 {
Ibiltari 7:98280cef1c4f 23
Ibiltari 7:98280cef1c4f 24 private:
Ibiltari 7:98280cef1c4f 25
Ibiltari 7:98280cef1c4f 26 //friends
Ibiltari 7:98280cef1c4f 27 friend class OSCBundle;
Ibiltari 7:98280cef1c4f 28
Ibiltari 7:98280cef1c4f 29
Ibiltari 7:98280cef1c4f 30 /*=============================================================================
Ibiltari 7:98280cef1c4f 31 PRIVATE VARIABLES
Ibiltari 7:98280cef1c4f 32 =============================================================================*/
Ibiltari 7:98280cef1c4f 33
Ibiltari 7:98280cef1c4f 34 //the address
Ibiltari 7:98280cef1c4f 35 char * address;
Ibiltari 7:98280cef1c4f 36
Ibiltari 7:98280cef1c4f 37 //the data
Ibiltari 7:98280cef1c4f 38 OSCData ** data;
Ibiltari 7:98280cef1c4f 39
Ibiltari 7:98280cef1c4f 40 //the number of OSCData in the data array
Ibiltari 7:98280cef1c4f 41 int dataCount;
Ibiltari 7:98280cef1c4f 42
Ibiltari 7:98280cef1c4f 43 //error codes for potential runtime problems
Ibiltari 7:98280cef1c4f 44 OSCErrorCode error;
Ibiltari 7:98280cef1c4f 45
Ibiltari 7:98280cef1c4f 46 /*=============================================================================
Ibiltari 7:98280cef1c4f 47 DECODING INCOMING BYTES
Ibiltari 7:98280cef1c4f 48 =============================================================================*/
Ibiltari 7:98280cef1c4f 49
Ibiltari 7:98280cef1c4f 50 //the decoding states for incoming bytes
Ibiltari 7:98280cef1c4f 51 enum DecodeState {
Ibiltari 7:98280cef1c4f 52 STANDBY,
Ibiltari 7:98280cef1c4f 53 ADDRESS,
Ibiltari 7:98280cef1c4f 54 ADDRESS_PADDING,
Ibiltari 7:98280cef1c4f 55 TYPES,
Ibiltari 7:98280cef1c4f 56 TYPES_PADDING,
Ibiltari 7:98280cef1c4f 57 DATA,
Ibiltari 7:98280cef1c4f 58 DATA_PADDING,
Ibiltari 7:98280cef1c4f 59 DONE,
Ibiltari 7:98280cef1c4f 60 } decodeState;
Ibiltari 7:98280cef1c4f 61
Ibiltari 7:98280cef1c4f 62 //stores incoming bytes until they can be decoded
Ibiltari 7:98280cef1c4f 63 uint8_t * incomingBuffer;
Ibiltari 7:98280cef1c4f 64 int incomingBufferSize; // how many bytes are stored
Ibiltari 7:98280cef1c4f 65 int incomingBufferFree; // how many bytes are allocated but unused
Ibiltari 7:98280cef1c4f 66
Ibiltari 7:98280cef1c4f 67 //adds a byte to the buffer
Ibiltari 7:98280cef1c4f 68 void addToIncomingBuffer(uint8_t);
Ibiltari 7:98280cef1c4f 69 //clears the incoming buffer
Ibiltari 7:98280cef1c4f 70 void clearIncomingBuffer();
Ibiltari 7:98280cef1c4f 71
Ibiltari 7:98280cef1c4f 72 //decoding function
Ibiltari 7:98280cef1c4f 73 void decode(uint8_t);
Ibiltari 7:98280cef1c4f 74 void decodeAddress();
Ibiltari 7:98280cef1c4f 75 void decodeType(uint8_t);
Ibiltari 7:98280cef1c4f 76 void decodeData(uint8_t);
Ibiltari 7:98280cef1c4f 77
Ibiltari 7:98280cef1c4f 78 /*=============================================================================
Ibiltari 7:98280cef1c4f 79 HELPER FUNCTIONS
Ibiltari 7:98280cef1c4f 80 =============================================================================*/
Ibiltari 7:98280cef1c4f 81
Ibiltari 7:98280cef1c4f 82 void setupMessage();
Ibiltari 7:98280cef1c4f 83
Ibiltari 7:98280cef1c4f 84 //compares the OSCData's type char to a test char
Ibiltari 7:98280cef1c4f 85 bool testType(int position, char type);
Ibiltari 7:98280cef1c4f 86
Ibiltari 7:98280cef1c4f 87 //returns the number of bytes to pad to make it 4-bit aligned
Ibiltari 7:98280cef1c4f 88 int padSize(int bytes);
Ibiltari 7:98280cef1c4f 89
Ibiltari 7:98280cef1c4f 90 public:
Ibiltari 7:98280cef1c4f 91
Ibiltari 7:98280cef1c4f 92 //returns the OSCData at that position
Ibiltari 7:98280cef1c4f 93 OSCData * getOSCData(int);
Ibiltari 7:98280cef1c4f 94
Ibiltari 7:98280cef1c4f 95 /*=============================================================================
Ibiltari 7:98280cef1c4f 96 CONSTRUCTORS / DESTRUCTOR
Ibiltari 7:98280cef1c4f 97 =============================================================================*/
Ibiltari 7:98280cef1c4f 98
Ibiltari 7:98280cef1c4f 99 //new constructor needs an address
Ibiltari 7:98280cef1c4f 100 OSCMessage (const char * _address);
Ibiltari 7:98280cef1c4f 101 //no address
Ibiltari 7:98280cef1c4f 102 //placeholder since it's invalide OSC
Ibiltari 7:98280cef1c4f 103 OSCMessage();
Ibiltari 7:98280cef1c4f 104
Ibiltari 7:98280cef1c4f 105 //can optionally accept all of the data after the address
Ibiltari 7:98280cef1c4f 106 //OSCMessage(const char * _address, char * types, ... );
Ibiltari 7:98280cef1c4f 107 //created from another OSCMessage
Ibiltari 7:98280cef1c4f 108 OSCMessage (OSCMessage *);
Ibiltari 7:98280cef1c4f 109
Ibiltari 7:98280cef1c4f 110 //DESTRUCTOR
Ibiltari 7:98280cef1c4f 111 ~OSCMessage();
Ibiltari 7:98280cef1c4f 112
Ibiltari 7:98280cef1c4f 113 //empties all of the data
Ibiltari 7:98280cef1c4f 114 OSCMessage& empty();
Ibiltari 7:98280cef1c4f 115
Ibiltari 9:e4528f622bcc 116 void copy(OSCMessage * msg);
Ibiltari 9:e4528f622bcc 117
Ibiltari 9:e4528f622bcc 118
Ibiltari 7:98280cef1c4f 119 /*=============================================================================
Ibiltari 7:98280cef1c4f 120 SETTING DATA
Ibiltari 7:98280cef1c4f 121 =============================================================================*/
Ibiltari 7:98280cef1c4f 122
Ibiltari 7:98280cef1c4f 123 //returns the OSCMessage so that multiple 'add's can be strung together
Ibiltari 7:98280cef1c4f 124 template <typename T>
Ibiltari 7:98280cef1c4f 125 OSCMessage& add(T datum){
Ibiltari 7:98280cef1c4f 126 //make a piece of data
Ibiltari 7:98280cef1c4f 127 OSCData * d = new OSCData(datum);
Ibiltari 7:98280cef1c4f 128 //check if it has any errors
Ibiltari 7:98280cef1c4f 129 if (d->error == ALLOCFAILED){
Ibiltari 7:98280cef1c4f 130 error = ALLOCFAILED;
Ibiltari 7:98280cef1c4f 131 } else {
Ibiltari 7:98280cef1c4f 132 //resize the data array
Ibiltari 7:98280cef1c4f 133 OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1));
Ibiltari 7:98280cef1c4f 134 if (dataMem == NULL){
Ibiltari 7:98280cef1c4f 135 error = ALLOCFAILED;
Ibiltari 7:98280cef1c4f 136 } else {
Ibiltari 7:98280cef1c4f 137 data = dataMem;
Ibiltari 7:98280cef1c4f 138 //add data to the end of the array
Ibiltari 7:98280cef1c4f 139 data[dataCount] = d;
Ibiltari 7:98280cef1c4f 140 //increment the data size
Ibiltari 7:98280cef1c4f 141 dataCount++;
Ibiltari 7:98280cef1c4f 142 }
Ibiltari 7:98280cef1c4f 143 }
Ibiltari 7:98280cef1c4f 144 return *this;
Ibiltari 7:98280cef1c4f 145 }
Ibiltari 10:936c3afce828 146
Ibiltari 7:98280cef1c4f 147 //blob specific add
Ibiltari 7:98280cef1c4f 148 OSCMessage& add(uint8_t * blob, int length){
Ibiltari 7:98280cef1c4f 149 //make a piece of data
Ibiltari 7:98280cef1c4f 150 OSCData * d = new OSCData(blob, length);
Ibiltari 7:98280cef1c4f 151 //check if it has any errors
Ibiltari 7:98280cef1c4f 152 if (d->error == ALLOCFAILED){
Ibiltari 7:98280cef1c4f 153 error = ALLOCFAILED;
Ibiltari 7:98280cef1c4f 154 } else {
Ibiltari 7:98280cef1c4f 155 //resize the data array
Ibiltari 7:98280cef1c4f 156 OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1));
Ibiltari 7:98280cef1c4f 157 if (dataMem == NULL){
Ibiltari 7:98280cef1c4f 158 error = ALLOCFAILED;
Ibiltari 7:98280cef1c4f 159 } else {
Ibiltari 7:98280cef1c4f 160 data = dataMem;
Ibiltari 7:98280cef1c4f 161 //add data to the end of the array
Ibiltari 7:98280cef1c4f 162 data[dataCount] = d;
Ibiltari 7:98280cef1c4f 163 //increment the data size
Ibiltari 7:98280cef1c4f 164 dataCount++;
Ibiltari 7:98280cef1c4f 165 }
Ibiltari 7:98280cef1c4f 166 }
Ibiltari 7:98280cef1c4f 167 return *this;
Ibiltari 7:98280cef1c4f 168 }
Ibiltari 10:936c3afce828 169
Ibiltari 7:98280cef1c4f 170 //sets the data at a position
Ibiltari 7:98280cef1c4f 171 template <typename T>
Ibiltari 7:98280cef1c4f 172 OSCMessage& set(int position, T datum){
Ibiltari 7:98280cef1c4f 173 if (position < dataCount){
Ibiltari 7:98280cef1c4f 174 //replace the OSCData with a new one
Ibiltari 7:98280cef1c4f 175 OSCData * oldDatum = getOSCData(position);
Ibiltari 7:98280cef1c4f 176 //destroy the old one
Ibiltari 7:98280cef1c4f 177 delete oldDatum;
Ibiltari 7:98280cef1c4f 178 //make a new one
Ibiltari 7:98280cef1c4f 179 OSCData * newDatum = new OSCData(datum);
Ibiltari 7:98280cef1c4f 180 //test if there was an error
Ibiltari 7:98280cef1c4f 181 if (newDatum->error == ALLOCFAILED){
Ibiltari 7:98280cef1c4f 182 error = ALLOCFAILED;
Ibiltari 7:98280cef1c4f 183 } else {
Ibiltari 7:98280cef1c4f 184 //otherwise, put it in the data array
Ibiltari 7:98280cef1c4f 185 data[position] = newDatum;
Ibiltari 7:98280cef1c4f 186 }
Ibiltari 7:98280cef1c4f 187 } else if (position == (dataCount)){
Ibiltari 7:98280cef1c4f 188 //add the data to the end
Ibiltari 7:98280cef1c4f 189 add(datum);
Ibiltari 7:98280cef1c4f 190 } else {
Ibiltari 7:98280cef1c4f 191 //else out of bounds error
Ibiltari 7:98280cef1c4f 192 error = INDEX_OUT_OF_BOUNDS;
Ibiltari 7:98280cef1c4f 193 }
Ibiltari 7:98280cef1c4f 194 return *this;
Ibiltari 7:98280cef1c4f 195 }
Ibiltari 10:936c3afce828 196
Ibiltari 7:98280cef1c4f 197 //blob specific setter
Ibiltari 7:98280cef1c4f 198 OSCMessage& set(int position, uint8_t * blob, int length){
Ibiltari 7:98280cef1c4f 199 if (position < dataCount){
Ibiltari 7:98280cef1c4f 200 //replace the OSCData with a new one
Ibiltari 7:98280cef1c4f 201 OSCData * oldDatum = getOSCData(position);
Ibiltari 7:98280cef1c4f 202 //destroy the old one
Ibiltari 7:98280cef1c4f 203 delete oldDatum;
Ibiltari 7:98280cef1c4f 204 //make a new one
Ibiltari 7:98280cef1c4f 205 OSCData * newDatum = new OSCData(blob, length);
Ibiltari 7:98280cef1c4f 206 //test if there was an error
Ibiltari 7:98280cef1c4f 207 if (newDatum->error == ALLOCFAILED){
Ibiltari 7:98280cef1c4f 208 error = ALLOCFAILED;
Ibiltari 7:98280cef1c4f 209 } else {
Ibiltari 7:98280cef1c4f 210 //otherwise, put it in the data array
Ibiltari 7:98280cef1c4f 211 data[position] = newDatum;
Ibiltari 7:98280cef1c4f 212 }
Ibiltari 7:98280cef1c4f 213 } else if (position == (dataCount)){
Ibiltari 7:98280cef1c4f 214 //add the data to the end
Ibiltari 7:98280cef1c4f 215 add(blob, length);
Ibiltari 7:98280cef1c4f 216 } else {
Ibiltari 7:98280cef1c4f 217 //else out of bounds error
Ibiltari 7:98280cef1c4f 218 error = INDEX_OUT_OF_BOUNDS;
Ibiltari 7:98280cef1c4f 219 }
Ibiltari 7:98280cef1c4f 220 return *this;
Ibiltari 7:98280cef1c4f 221 }
Ibiltari 10:936c3afce828 222
Ibiltari 7:98280cef1c4f 223 OSCMessage& setAddress(const char *);
Ibiltari 7:98280cef1c4f 224
Ibiltari 7:98280cef1c4f 225 /*=============================================================================
Ibiltari 7:98280cef1c4f 226 GETTING DATA
Ibiltari 7:98280cef1c4f 227
Ibiltari 7:98280cef1c4f 228 getters take a position as an argument
Ibiltari 7:98280cef1c4f 229 =============================================================================*/
Ibiltari 7:98280cef1c4f 230
Ibiltari 7:98280cef1c4f 231 int32_t getInt(int);
Ibiltari 7:98280cef1c4f 232 // osctime_t getTime(int); // TODO: implement timming
Ibiltari 7:98280cef1c4f 233
Ibiltari 7:98280cef1c4f 234 float getFloat(int);
Ibiltari 7:98280cef1c4f 235 double getDouble(int);
Ibiltari 7:98280cef1c4f 236 bool getBoolean(int);
Ibiltari 7:98280cef1c4f 237
Ibiltari 7:98280cef1c4f 238 //return the copied string's length
Ibiltari 7:98280cef1c4f 239 int getString(int, char *);
Ibiltari 7:98280cef1c4f 240 //check that it won't overflow the passed buffer's size with a third argument
Ibiltari 7:98280cef1c4f 241 int getString(int, char *, int);
Ibiltari 7:98280cef1c4f 242 //offset and size can be defined in order to only query a part of the string
Ibiltari 7:98280cef1c4f 243 int getString(int, char *, int, int, int);
Ibiltari 7:98280cef1c4f 244
Ibiltari 7:98280cef1c4f 245 //returns the number of unsigned int8's copied into the buffer
Ibiltari 7:98280cef1c4f 246 int getBlob(int, uint8_t *);
Ibiltari 7:98280cef1c4f 247 //check that it won't overflow the passed buffer's size with a third argument
Ibiltari 7:98280cef1c4f 248 int getBlob(int, uint8_t *, int);
Ibiltari 7:98280cef1c4f 249 //offset and size can be defined in order to only query a part of the blob's content
Ibiltari 7:98280cef1c4f 250 int getBlob(int, uint8_t *, int, int, int);
Ibiltari 7:98280cef1c4f 251
Ibiltari 7:98280cef1c4f 252
Ibiltari 7:98280cef1c4f 253 // returns the length of blob
Ibiltari 7:98280cef1c4f 254 uint32_t getBlobLength(int position);
Ibiltari 7:98280cef1c4f 255
Ibiltari 7:98280cef1c4f 256 //returns the number of bytes of the data at that position
Ibiltari 7:98280cef1c4f 257 int getDataLength(int);
Ibiltari 7:98280cef1c4f 258
Ibiltari 7:98280cef1c4f 259 //returns the type at the position
Ibiltari 7:98280cef1c4f 260 char getType(int);
Ibiltari 7:98280cef1c4f 261
Ibiltari 7:98280cef1c4f 262 //put the address in the buffer
Ibiltari 7:98280cef1c4f 263 const char * getAddress( int offset = 0);
Ibiltari 7:98280cef1c4f 264 int getAddress(char * buffer, int offset, int len);
Ibiltari 7:98280cef1c4f 265
Ibiltari 7:98280cef1c4f 266 // TODO: int getAddressLength(int offset = 0);
Ibiltari 7:98280cef1c4f 267
Ibiltari 7:98280cef1c4f 268
Ibiltari 7:98280cef1c4f 269 /*=============================================================================
Ibiltari 7:98280cef1c4f 270 TESTING DATA
Ibiltari 7:98280cef1c4f 271
Ibiltari 7:98280cef1c4f 272 testers take a position as an argument
Ibiltari 7:98280cef1c4f 273 =============================================================================*/
Ibiltari 7:98280cef1c4f 274
Ibiltari 7:98280cef1c4f 275 bool isInt(int);
Ibiltari 7:98280cef1c4f 276 bool isFloat(int);
Ibiltari 7:98280cef1c4f 277 bool isBlob(int);
Ibiltari 7:98280cef1c4f 278 bool isChar(int);
Ibiltari 7:98280cef1c4f 279 bool isString(int);
Ibiltari 7:98280cef1c4f 280 bool isDouble(int);
Ibiltari 7:98280cef1c4f 281 bool isBoolean(int);
Ibiltari 7:98280cef1c4f 282 bool isTime(int);
Ibiltari 7:98280cef1c4f 283
Ibiltari 7:98280cef1c4f 284 /*=============================================================================
Ibiltari 7:98280cef1c4f 285 PATTERN MATCHING
Ibiltari 7:98280cef1c4f 286 =============================================================================*/
ibiltari 12:f2c792ac1aca 287
Ibiltari 7:98280cef1c4f 288 //match the pattern against the address
Ibiltari 7:98280cef1c4f 289 //returns true only for a complete match
Ibiltari 7:98280cef1c4f 290 bool fullMatch( const char * pattern, int = 0);
Ibiltari 7:98280cef1c4f 291
Ibiltari 7:98280cef1c4f 292 //returns the number of characters matched in the address
Ibiltari 7:98280cef1c4f 293 int match( const char * pattern, int = 0);
Ibiltari 7:98280cef1c4f 294
Ibiltari 7:98280cef1c4f 295 //calls the function with the message as the arg if it was a full match
Ibiltari 7:98280cef1c4f 296 bool dispatch(const char * pattern, void (*callback)(OSCMessage &), int = 0);
Ibiltari 7:98280cef1c4f 297
Ibiltari 7:98280cef1c4f 298 //like dispatch, but allows for partial matches
Ibiltari 7:98280cef1c4f 299 //the address match offset is sent as an argument to the callback
Ibiltari 7:98280cef1c4f 300 //also room for an option address offset to allow for multiple nested routes
Ibiltari 7:98280cef1c4f 301 bool route(const char * pattern, void (*callback)(OSCMessage &, int), int = 0);
Ibiltari 7:98280cef1c4f 302
ibiltari 12:f2c792ac1aca 303
Ibiltari 7:98280cef1c4f 304
Ibiltari 7:98280cef1c4f 305 /*=============================================================================
Ibiltari 7:98280cef1c4f 306 SIZE
Ibiltari 7:98280cef1c4f 307 =============================================================================*/
Ibiltari 7:98280cef1c4f 308
Ibiltari 7:98280cef1c4f 309 //the number of data that the message contains
Ibiltari 7:98280cef1c4f 310 int size();
Ibiltari 7:98280cef1c4f 311
Ibiltari 7:98280cef1c4f 312 //computes the number of bytes the OSCMessage occupies if everything is 32-bit aligned
Ibiltari 7:98280cef1c4f 313 int bytes();
Ibiltari 7:98280cef1c4f 314
Ibiltari 7:98280cef1c4f 315 /*=============================================================================
Ibiltari 7:98280cef1c4f 316 TRANSMISSION
Ibiltari 7:98280cef1c4f 317 =============================================================================*/
Ibiltari 7:98280cef1c4f 318
Ibiltari 7:98280cef1c4f 319 //send the message
Ibiltari 10:936c3afce828 320 OSCMessage& send(UDPSocket &p, const char *host, uint16_t port);
Ibiltari 10:936c3afce828 321
Ibiltari 7:98280cef1c4f 322
Ibiltari 7:98280cef1c4f 323 //fill the message from a byte stream
Ibiltari 7:98280cef1c4f 324 OSCMessage& fill(uint8_t);
Ibiltari 7:98280cef1c4f 325 OSCMessage& fill(uint8_t *, int);
Ibiltari 7:98280cef1c4f 326
Ibiltari 7:98280cef1c4f 327 /*=============================================================================
Ibiltari 7:98280cef1c4f 328 ERROR
Ibiltari 7:98280cef1c4f 329 =============================================================================*/
Ibiltari 7:98280cef1c4f 330
Ibiltari 7:98280cef1c4f 331 bool hasError();
Ibiltari 7:98280cef1c4f 332
Ibiltari 7:98280cef1c4f 333 OSCErrorCode getError();
Ibiltari 7:98280cef1c4f 334
Ibiltari 7:98280cef1c4f 335 };
Ibiltari 7:98280cef1c4f 336
Ibiltari 7:98280cef1c4f 337
Ibiltari 7:98280cef1c4f 338 #endif