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

Dependencies:   NetServices mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbedOSC.h Source File

mbedOSC.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 "EthernetNetIf.h"
00018 #include "UDPSocket.h"
00019 
00020 // setup IP of destination (computer):
00021 #define DEFAULT_SEND_PORT 12000
00022 //Host sendHost(IpAddr(10, 0, 0, 1), DEFAULT_SEND_PORT, NULL); // Send Port
00023 // set IP of origin of UDP packets - the mbed acts as a SERVER here, and needs to bind the socket to the "client" (the computer)
00024 #define DEFAULT_RECEIVE_PORT 57130
00025 //Host recHost(IpAddr(10, 0, 0, 1), DEFAULT_RECEIVE_PORT, NULL);  // Receive Port
00026 //UDPSocket udpRec,udpSend;
00027 
00028 
00029 #define MAX_ADDRESS    2
00030 #define MAX_ARG        2
00031 
00032 #define TYPE_INT    1
00033 #define TYPE_FLOAT    2
00034 
00035 
00036 /** Container class for OSC messages (receiving or sending)
00037  @note mbedOSC version 0.1 Specification (similar to Recotana's OSCClass library)
00038  Example of an OSC message: "/mbed/test1, if 50 32.4"
00039  ie. "Address TypeTag Args"
00040  Address : max 2
00041     "/ard"
00042     "/ard/output"
00043     --address[0]="/ard"       :max 15character
00044     --address[1]="/output"    :max 15character
00045  TypeTag : max 2
00046     "i" - long or unsigned long
00047     "f" - double
00048  arg    :    max 2
00049  (Note: The byte string as seen here is not sent as UDP packet directly - there are no spaces, and arguments are in binary, BIG ENDIAN)
00050 */
00051 class OSCMessage{
00052     
00053     private:
00054     
00055         char        *address[MAX_ADDRESS]; // these are strings (as char*)
00056         uint8_t         addressNum; // current number of addresses in the message (ex: "/ard/test" --> the number of the addresses is 2)
00057     
00058         char         typeTag[MAX_ARG];
00059     
00060         void        *arg[MAX_ARG];
00061         uint8_t         argNum;
00062     
00063         // Information about the connection:    
00064         //uint8_t         ip[4];            
00065         //uint16_t     port;
00066         Host host; 
00067     
00068     public:
00069         /** Create a container for an OSC message to be received or sent */
00070         OSCMessage();
00071 
00072         /** Return the IpAddr object */   
00073         const IpAddr& getIp();
00074         /** Return the port */
00075         const int&     getPort();
00076     
00077 /** Gets the address string of the OSC message
00078  *
00079  * @param[in] _index The index of the address string (byte)
00080  * @return pointer of the address string (char *)
00081  * @note ex. "/ard/test"<br>
00082  * getAddress(0) = "/ard"<br>
00083  * getAddress(1) = "/test"
00084  * @attention It is maximum number of the addresses is 2<br>
00085  * In this case "/ard/test1/test2"<br>
00086  * ignore it after "/test2"
00087  */
00088         char        *getAddress(uint8_t _index);    //retturn address
00089         
00090 /** Gets the TopAddress string of the OSC message (this is just the address with index 0)
00091  @return pointer of the TopAddress string (char *), i.e. address[0]
00092  Example: In the case "/ard/test", getTopAddress() = "/ard" (WITH the slash "/") 
00093  */        
00094         char        *getTopAddress();    //return address[0] :"/ard"
00095 
00096 /**
00097  Gets the "SubAddress" string of the OSC message (this is just the address with index 1)
00098  @return pointer of the SubAddress string (char *), i.e. address[1]
00099  Example: in the case "/ard/test", getSubAddress() = "/test" (WITH the slash "/") 
00100  */
00101         char        *getSubAddress();    //return address[1] :"/test"
00102 
00103 /**
00104  Gets the number of the OSC message address
00105  @return number of the OSC message address (byte)
00106  Examples: "/ard"      --> the number of the addresses is 1
00107            "/ard/test" --> the number of the addresses is 2
00108  Attention: the maximum number of addresses is 2 (MAX_ADDRESS)
00109 */
00110         uint8_t         getAddressNum();    //return 2        
00111     
00112 /**
00113  Gets the TypeTag string (with index) of the OSC message
00114  @param[in] _index The index of the TypeTag string (byte)
00115  @return: TypeTag char (char)
00116  Example: in the case of a total typetag string equal to "if", getTypeTag(0) = 'i' and getTypeTag(1) = 'f'
00117  Attention: MAX_ARG is maximum number of the args, if the index argument is larger, it will be constrained to this max. 
00118  */
00119         char         getTypeTag(uint8_t _index);    //_index=0 ->'i'
00120                                                     //_index=1 ->'f'
00121 
00122 /**
00123  Gets the number of the OSC message args
00124  @return number of the args (byte)
00125  Example: "i" 123 --> number of the OSC message args is 1
00126           "if" 123 54.24 --> number of the OSC message args is 2
00127  Attention: the maximum number of args is 2 (MAX_ARG)
00128  */
00129         uint8_t         getArgNum();    //return 2
00130     
00131 /**
00132  Get the args of the OSC message with an integer value
00133  @param[in] _index An int or uint8_t corresponding to the index of the args (byte)
00134  @return: integer value (long, or int32_t)
00135  Example: in the case "if" 123 54.24, getArgInt(0) = 123
00136  Noe: "i" is integer, but the return type is "long"
00137  Note: When a index is bigger than the number of the args, it is set to the number of the args
00138  */
00139         int32_t         getArgInt(uint8_t _index);        //_index=0 -> 123
00140 
00141 /**
00142  Get the args of the OSC message with a float value
00143  @param[in] _index The index of the args
00144  @return: float value (double)
00145  note: In this case "if" 123 54.24, getArgFloat(1) = 54.24
00146  attention: arg declared as float, but return value cast as "double"
00147  attention: When index is bigger than the number of the args, it is set to the number of the args
00148  */
00149         double         getArgFloat(uint8_t _index);    //_index=1 -> 54.21
00150     
00151     
00152 /**
00153  Set TopAddress string of OSC Message 
00154  @param[in] _address A string pointer for the TopAddress String (char *). NOTE: is this a good idea? why not pass as const, and do allocation here?
00155  Example: if the complete address string is "/ard/test", we set the topaddress as follows: char top[]="/ard" (allocation done here!), then setTopAddress(top)
00156  */
00157         void setTopAddress(char *_address);        //set address[0]
00158 
00159 /**
00160  Set SubAddress string of the OSC Message
00161  @param[in] _address A string pointer for the SubAddress String (char *)
00162  Example:  if the complete address string is "/ard/test", we set the subaddress as follows: char sub[]="/test" (allocation done here!), then setSubAddress(sub)
00163  Attention: we should call first setTopAddress, and then setSubAddress. The order is important. This does not seems like a good idea...
00164  */
00165         void setSubAddress(char *_address);        //set address[1]
00166 
00167 /**
00168  Set the complete Address string of the OSC Message (top and sub addresses)
00169  @param[in] _topAddress, _subAddress The string pointers to top and sub addresses (char *)
00170  Example: in the case "/ard/test", we need to do: char top[]="/ard", char sub[]="/test", and then setAddress(top,sub)
00171  Reminder: in this implementation, the maximum number of addresses is MAX_ADDRESS=2
00172  */
00173         void setAddress(char *_topAddress,     
00174                         char *_subAddress);
00175 
00176 /**
00177  Set address string using index (here 0 or 1)
00178  Example: "/ard/test", char adr[]="/ard", setAddress(0,adr), char adr2[]="/test", setAddress(1,adr)
00179  */
00180         void setAddress(uint8_t _index,        //set 0,address[0]
00181                         char *_address);    
00182                                             //set 1,address[1]
00183 
00184 /**
00185  Set IP Address of the OSC Message (for SENDING messages - for receiving this will be done when receiving something ) 
00186  @param[in] _ip Pointer of IP Address array (byte *)
00187  Example: IP=192.168.0.99, then we have to do: ip[]={192,168,0,1}, then setIp(ip)
00188  */    
00189         void setIp( uint8_t *_ip );    //set ip
00190 
00191 /**
00192  Set IP Address to the OSC Message container (not through pointer)
00193  Example: IP=192.168.0.99 => setIp(192,168,0,99)
00194  */    
00195         void setIp(uint8_t _ip1,    //set(192,
00196                    uint8_t _ip2,    //      168,
00197                    uint8_t _ip3,    //    0,
00198                    uint8_t _ip4);    //    100)
00199 
00200         /*
00201          Set PortNo for the OSC Message
00202          @param[in] _port PortNo (unsigned int)
00203          @return None
00204          */
00205         void setPort( uint16_t _port );
00206     
00207 /**
00208  Set TypeTag and args to the OSC Message container
00209  @param[in] types TypeTag string "i"(integer) or"f"(float) (char *)
00210  @param[in] ... Pointer of the Args(variable argument) ..
00211  @Example: 
00212  (1) integer 123: (NOTE: integers are LONG)
00213  long v1=123; sendMes.setArgs("i",&v1)
00214  (2)integer:123 and float:52.14
00215  long v1=123; double v2=52.14; sendMes.setArgs("if",&v1,&v2)
00216  Attention: in this implementation, the maximum number of the args is 2
00217  (if setArgs("iff",&v1,&v2,&v3), data is ignored after &v3)
00218  */
00219         void setArgs( char *types , ... );    //set ("if",&v1,&v2)
00220     
00221         friend class OSCClass;
00222     
00223 };
00224 
00225 
00226 
00227 /* ====================================  OSCClass for sending and receiving OSC messages using UDP protocol ===================================== */
00228 
00229 #include "UDPSocket.h"
00230 
00231 /** Wraps the UDP functions to send and receive OSC messages */
00232 class OSCClass {
00233     
00234 private:
00235     
00236     UDPSocket udpRec,udpSend;
00237     char   rcvBuff[256]; // raw buffer for UDP packets (udpRec.recvfrom( buf, 256, &host ) ))
00238     int   buflength;
00239     
00240     OSCMessage *receiverMessage;
00241     OSCMessage *sendContainer;
00242     
00243     char         tempAddress[MAX_ADDRESS][16];
00244     uint8_t      tempArg[MAX_ARG][4];    
00245     
00246     void onUDPSocketEvent(UDPSocketEvent e);
00247     
00248     void decodePacket( OSCMessage *_mes); // makes OSC message from packet
00249 
00250 public:
00251     
00252     friend class UDPSocket;
00253     
00254     /** Create an object to send and receive OSC messages */
00255     OSCClass();
00256     
00257 /**
00258  This sets "binds" the received message to the receiver container of the communication object
00259  @param[in] _mes A pointer to the "receiveing" OSC message (OSCMessage *)
00260  */
00261     OSCClass(OSCMessage *_mes); // set the receiver message container
00262         
00263 /**
00264  This initializes the OSC communication object with default receiving port (DEFAULT_REC_PORT) 
00265  */
00266     void begin();
00267 
00268 /**
00269  Initialize an OSC object with arbitrary listening port
00270  @param[in] _recievePort The listening ("receiving") Port No (unsigned int)
00271  */
00272     void begin(uint16_t _recievePort);
00273 
00274 /**
00275  Stop OSC communication (in fact, only the receiver - the server side)
00276  */
00277     void stop();
00278     
00279 /**
00280  Returns whether there is new OSC data in the receiver message container.
00281  */
00282     bool newMessage;
00283 
00284 /**
00285  Set a OSC receive message container
00286  @param[in] _mes Pointer to the OSC receive message container (OSCMessage *)
00287  */
00288     void setReceiveMessage( OSCMessage *_mes ); //set receive OSCmessage container (note: the message has a "host" object from which we get the upd packets)
00289 
00290 /**
00291  Get the received OSC message (note: this is another way to access the message directly from the OSCClass object).
00292  The advantage is that we will signal that we read the message, and will be able to query if a NEW message arrived
00293  (Alternatively, one could have a function pointer to pass to the OSC object, that will be called each time a new packet is received: TO DO) 
00294  */
00295     OSCMessage    *getMessage();    //return received OSCmessage    
00296     
00297 /**
00298  Send an OSC Message (message contain the host ip and port where the message data has to be sent)
00299  @param[in] _mes Pointer to the OSC message container (OSCMessage *)
00300  */
00301     void sendOsc( OSCMessage *_mes ); //set&send OSCmessage (note: it will be sent to the host defined in the message container)
00302 
00303 /**
00304  A function pointer to be set by host program that will be called on receipt of an OSC message
00305  @code
00306  osc.messageReceivedCallback.attach(&processOSC);
00307  @endcode
00308  */
00309     FunctionPointer messageReceivedCallback;
00310 };
00311 
00312 #endif