Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
OSCMessage.h
00001 /* mbed OSC Library 00002 This is an Open Sound Control library for the mbed, created to be compatible with Recotana's OSCClass library (http://recotana.com) for the 00003 Arduino with Ethernet shield. It also uses parts of the OSC Transceiver(Sender/Receiver) code by xshige 00004 written by: Alvaro Cassinelli, October 2011 00005 tweaked by: Toby Harris / *spark audio-visual, March 2012 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License version 2.1 as published by the Free Software Foundation. 00010 Open Sound Control http://opensoundcontrol.org/ 00011 */ 00012 00013 #ifndef mbedOSC_h 00014 #define mbedOSC_h 00015 00016 #include "mbed.h" 00017 #include "EthernetInterface.h" 00018 #include "UDPSocket.h" 00019 #include "OSCData.h" 00020 00021 class OSCMessage 00022 { 00023 00024 private: 00025 00026 //friends 00027 friend class OSCBundle; 00028 00029 00030 /*============================================================================= 00031 PRIVATE VARIABLES 00032 =============================================================================*/ 00033 00034 //the address 00035 char * address; 00036 00037 //the data 00038 OSCData ** data; 00039 00040 //the number of OSCData in the data array 00041 int dataCount; 00042 00043 //error codes for potential runtime problems 00044 OSCErrorCode error; 00045 00046 /*============================================================================= 00047 DECODING INCOMING BYTES 00048 =============================================================================*/ 00049 00050 //the decoding states for incoming bytes 00051 enum DecodeState { 00052 STANDBY, 00053 ADDRESS, 00054 ADDRESS_PADDING, 00055 TYPES, 00056 TYPES_PADDING, 00057 DATA, 00058 DATA_PADDING, 00059 DONE, 00060 } decodeState; 00061 00062 //stores incoming bytes until they can be decoded 00063 uint8_t * incomingBuffer; 00064 int incomingBufferSize; // how many bytes are stored 00065 int incomingBufferFree; // how many bytes are allocated but unused 00066 00067 //adds a byte to the buffer 00068 void addToIncomingBuffer(uint8_t); 00069 //clears the incoming buffer 00070 void clearIncomingBuffer(); 00071 00072 //decoding function 00073 void decode(uint8_t); 00074 void decodeAddress(); 00075 void decodeType(uint8_t); 00076 void decodeData(uint8_t); 00077 00078 /*============================================================================= 00079 HELPER FUNCTIONS 00080 =============================================================================*/ 00081 00082 void setupMessage(); 00083 00084 //compares the OSCData's type char to a test char 00085 bool testType(int position, char type); 00086 00087 //returns the number of bytes to pad to make it 4-bit aligned 00088 int padSize(int bytes); 00089 00090 public: 00091 00092 //returns the OSCData at that position 00093 OSCData * getOSCData(int); 00094 00095 /*============================================================================= 00096 CONSTRUCTORS / DESTRUCTOR 00097 =============================================================================*/ 00098 00099 //new constructor needs an address 00100 OSCMessage (const char * _address); 00101 //no address 00102 //placeholder since it's invalide OSC 00103 OSCMessage(); 00104 00105 //can optionally accept all of the data after the address 00106 //OSCMessage(const char * _address, char * types, ... ); 00107 //created from another OSCMessage 00108 OSCMessage (OSCMessage *); 00109 00110 00111 //DESTRUCTOR 00112 ~OSCMessage(); 00113 00114 //empties all of the data 00115 OSCMessage& empty(); 00116 00117 void copy(OSCMessage * msg); 00118 00119 00120 /*============================================================================= 00121 SETTING DATA 00122 =============================================================================*/ 00123 00124 //returns the OSCMessage so that multiple 'add's can be strung together 00125 template <typename T> 00126 OSCMessage& add(T datum){ 00127 //make a piece of data 00128 OSCData * d = new OSCData(datum); 00129 //check if it has any errors 00130 if (d->error == ALLOCFAILED){ 00131 error = ALLOCFAILED; 00132 } else { 00133 //resize the data array 00134 OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1)); 00135 if (dataMem == NULL){ 00136 error = ALLOCFAILED; 00137 } else { 00138 data = dataMem; 00139 //add data to the end of the array 00140 data[dataCount] = d; 00141 //increment the data size 00142 dataCount++; 00143 } 00144 } 00145 return *this; 00146 } 00147 00148 //blob specific add 00149 OSCMessage& add(uint8_t * blob, int length){ 00150 //make a piece of data 00151 OSCData * d = new OSCData(blob, length); 00152 //check if it has any errors 00153 if (d->error == ALLOCFAILED){ 00154 error = ALLOCFAILED; 00155 } else { 00156 //resize the data array 00157 OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1)); 00158 if (dataMem == NULL){ 00159 error = ALLOCFAILED; 00160 } else { 00161 data = dataMem; 00162 //add data to the end of the array 00163 data[dataCount] = d; 00164 //increment the data size 00165 dataCount++; 00166 } 00167 } 00168 return *this; 00169 } 00170 00171 //sets the data at a position 00172 template <typename T> 00173 OSCMessage& set(int position, T datum){ 00174 if (position < dataCount){ 00175 //replace the OSCData with a new one 00176 OSCData * oldDatum = getOSCData(position); 00177 //destroy the old one 00178 delete oldDatum; 00179 //make a new one 00180 OSCData * newDatum = new OSCData(datum); 00181 //test if there was an error 00182 if (newDatum->error == ALLOCFAILED){ 00183 error = ALLOCFAILED; 00184 } else { 00185 //otherwise, put it in the data array 00186 data[position] = newDatum; 00187 } 00188 } else if (position == (dataCount)){ 00189 //add the data to the end 00190 add(datum); 00191 } else { 00192 //else out of bounds error 00193 error = INDEX_OUT_OF_BOUNDS; 00194 } 00195 return *this; 00196 } 00197 00198 //blob specific setter 00199 OSCMessage& set(int position, uint8_t * blob, int length){ 00200 if (position < dataCount){ 00201 //replace the OSCData with a new one 00202 OSCData * oldDatum = getOSCData(position); 00203 //destroy the old one 00204 delete oldDatum; 00205 //make a new one 00206 OSCData * newDatum = new OSCData(blob, length); 00207 //test if there was an error 00208 if (newDatum->error == ALLOCFAILED){ 00209 error = ALLOCFAILED; 00210 } else { 00211 //otherwise, put it in the data array 00212 data[position] = newDatum; 00213 } 00214 } else if (position == (dataCount)){ 00215 //add the data to the end 00216 add(blob, length); 00217 } else { 00218 //else out of bounds error 00219 error = INDEX_OUT_OF_BOUNDS; 00220 } 00221 return *this; 00222 } 00223 00224 OSCMessage& setAddress(const char *); 00225 00226 /*============================================================================= 00227 GETTING DATA 00228 00229 getters take a position as an argument 00230 =============================================================================*/ 00231 00232 int32_t getInt(int); 00233 osctime_t getTime(int); 00234 00235 float getFloat(int); 00236 double getDouble(int); 00237 bool getBoolean(int); 00238 00239 //return the copied string's length 00240 int getString(int, char *); 00241 //check that it won't overflow the passed buffer's size with a third argument 00242 int getString(int, char *, int); 00243 //offset and size can be defined in order to only query a part of the string 00244 int getString(int, char *, int, int, int); 00245 00246 //returns the number of unsigned int8's copied into the buffer 00247 int getBlob(int, uint8_t *); 00248 //check that it won't overflow the passed buffer's size with a third argument 00249 int getBlob(int, uint8_t *, int); 00250 //offset and size can be defined in order to only query a part of the blob's content 00251 int getBlob(int, uint8_t *, int, int, int); 00252 00253 00254 // returns the length of blob 00255 uint32_t getBlobLength(int position); 00256 00257 //returns the number of bytes of the data at that position 00258 int getDataLength(int); 00259 00260 //returns the type at the position 00261 char getType(int); 00262 00263 //put the address in the buffer 00264 const char * getAddress( int offset = 0); 00265 int getAddress(char * buffer, int offset, int len); 00266 00267 int getAddressLength(int offset = 0); 00268 00269 00270 /*============================================================================= 00271 TESTING DATA 00272 00273 testers take a position as an argument 00274 =============================================================================*/ 00275 00276 bool isInt(int); 00277 bool isFloat(int); 00278 bool isBlob(int); 00279 bool isChar(int); 00280 bool isString(int); 00281 bool isDouble(int); 00282 bool isBoolean(int); 00283 bool isTime(int); 00284 00285 /*============================================================================= 00286 PATTERN MATCHING 00287 =============================================================================*/ 00288 00289 //match the pattern against the address 00290 //returns true only for a complete match 00291 bool fullMatch( const char * pattern, int = 0); 00292 00293 //returns the number of characters matched in the address 00294 int match( const char * pattern, int = 0); 00295 00296 //calls the function with the message as the arg if it was a full match 00297 bool dispatch(const char * pattern, void (*callback)(OSCMessage &), int = 0); 00298 00299 //like dispatch, but allows for partial matches 00300 //the address match offset is sent as an argument to the callback 00301 //also room for an option address offset to allow for multiple nested routes 00302 bool route(const char * pattern, void (*callback)(OSCMessage &, int), int = 0); 00303 00304 00305 00306 /*============================================================================= 00307 SIZE 00308 =============================================================================*/ 00309 00310 //the number of data that the message contains 00311 int size(); 00312 00313 //computes the number of bytes the OSCMessage occupies if everything is 32-bit aligned 00314 int bytes(); 00315 00316 /*============================================================================= 00317 TRANSMISSION 00318 =============================================================================*/ 00319 00320 //send the message 00321 OSCMessage& send(UDPSocket &p, const SocketAddress &address); 00322 00323 00324 //fill the message from a byte stream 00325 OSCMessage& fill(uint8_t); 00326 OSCMessage& fill(uint8_t *, int); 00327 00328 /*============================================================================= 00329 ERROR 00330 =============================================================================*/ 00331 00332 bool hasError(); 00333 00334 OSCErrorCode getError(); 00335 00336 }; 00337 00338 00339 #endif
Generated on Sun Jul 24 2022 13:23:54 by
1.7.2