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
mbedOSC.cpp
00001 /* 00002 mbedOSC.cpp 00003 */ 00004 00005 #include "mbed.h" 00006 #include "mbedOSC.h" 00007 #include "stdarg.h" 00008 00009 OSCMessage::OSCMessage() { 00010 // Initialize host address and port by default (as if this where the receiver message): 00011 // host=new Host(IpAddr(10, 0, 0, 1), DEFAULT_RECEIVE_PORT, NULL); 00012 } 00013 00014 void OSCMessage::setPort(uint16_t _port){ 00015 host.setPort(_port); 00016 } 00017 00018 00019 void OSCMessage::setIp(uint8_t *_ip){ 00020 host.setIp(IpAddr(_ip[0], _ip[1], _ip[2], _ip[3])); 00021 } 00022 00023 00024 00025 void OSCMessage::setIp( uint8_t _ip1, 00026 uint8_t _ip2, 00027 uint8_t _ip3, 00028 uint8_t _ip4 ){ 00029 00030 host.setIp(IpAddr(_ip1, _ip2, _ip3, _ip4)); 00031 } 00032 00033 const IpAddr& OSCMessage::getIp(){ 00034 return host.getIp(); 00035 } 00036 00037 00038 const int& OSCMessage::getPort(){ 00039 return host.getPort(); 00040 } 00041 00042 00043 00044 uint8_t OSCMessage::getAddressNum(){ 00045 00046 return addressNum; 00047 } 00048 00049 00050 uint8_t OSCMessage::getArgNum(){ 00051 00052 return argNum; 00053 } 00054 00055 00056 00057 char * OSCMessage::getAddress(uint8_t _index){ 00058 if(_index>MAX_ADDRESS) _index=MAX_ADDRESS-1; 00059 return address[_index]; 00060 00061 } 00062 00063 00064 00065 char * OSCMessage::getTopAddress(){ 00066 00067 return getAddress(0); 00068 00069 } 00070 00071 00072 char * OSCMessage::getSubAddress(){ 00073 00074 return getAddress(1); 00075 00076 } 00077 00078 00079 char OSCMessage::getTypeTag(uint8_t _index){ 00080 if(_index>MAX_ARG) _index=MAX_ARG-1; 00081 return typeTag[_index]; 00082 } 00083 00084 00085 int32_t OSCMessage::getArgInt(uint8_t _index){ 00086 int32_t *value; 00087 if(_index > argNum) _index=argNum; 00088 value = (int32_t *)arg[_index]; // cast to int32_t 00089 return *value; 00090 } 00091 00092 00093 double OSCMessage::getArgFloat(uint8_t _index){ 00094 float *value; 00095 if(_index > argNum) _index=argNum; 00096 value = (float *)arg[_index]; // cast to float not double for correct parsing on mbed! 00097 return *value; 00098 } 00099 00100 00101 void OSCMessage::setTopAddress(char *_address){ 00102 address[0]=_address; 00103 address[1]=0; 00104 addressNum=1; // Note: this "erases" the subaddress! (is this a good idea?) 00105 } 00106 00107 00108 void OSCMessage::setSubAddress(char *_address){ 00109 address[1]=_address; 00110 addressNum=2; // Note: this assumes the top address was already set! 00111 } 00112 00113 00114 00115 void OSCMessage::setAddress(char *_topAddress,char *_subAddress){ 00116 setTopAddress(_topAddress); 00117 setSubAddress(_subAddress); 00118 addressNum=2; // (unnecessary...) 00119 } 00120 00121 00122 void OSCMessage::setAddress(uint8_t _index, char *_address){ 00123 if(_index>MAX_ADDRESS) _index=MAX_ADDRESS-1; 00124 address[_index]=_address; 00125 addressNum=_index+1; 00126 } 00127 00128 00129 00130 void OSCMessage::setArgs(char *types,...){ 00131 00132 va_list argList; 00133 00134 argNum = strlen(types); 00135 if(argNum>MAX_ARG) argNum=MAX_ARG-1; 00136 00137 va_start( argList, types ); 00138 for(uint8_t i=0 ; i < argNum ; i++){ 00139 00140 typeTag[i]=types[i]; 00141 00142 switch(types[i]) { 00143 case 'i': 00144 arg[i]=(uint32_t *)va_arg(argList, uint32_t *); 00145 break; 00146 case 'f': 00147 arg[i]=va_arg(argList, double *); 00148 break; 00149 } 00150 } 00151 } 00152 00153 // ================================================================================================================================================ 00154 // ==================================== OSCClass for sending and receiving OSC messages using UDP protocol ======================================= 00155 // ================================================================================================================================================ 00156 //The class define an object wrapping the UDP functions to send and receive OSC messages 00157 00158 OSCClass::OSCClass(){ 00159 udpRec.setOnEvent(this, &OSCClass::onUDPSocketEvent); 00160 newMessage=false; 00161 } 00162 00163 OSCClass::~OSCClass(){ 00164 udpSend.resetOnEvent(); 00165 udpRec.close(); 00166 } 00167 00168 OSCClass::OSCClass(OSCMessage *_mes){ 00169 udpRec.setOnEvent(this, &OSCClass::onUDPSocketEvent); 00170 receiverMessage = _mes; // note: receiverMessage MUST be a pointer to the message, because we will modify things in it 00171 newMessage=false; 00172 } 00173 00174 void OSCClass::begin() 00175 { 00176 // setup receiver udp socket: 00177 udpRec.bind(receiverMessage->host); 00178 } 00179 00180 00181 void OSCClass::begin(uint16_t _recievePort) 00182 { 00183 receiverMessage->host.setPort(_recievePort); 00184 // setup receiver udp socket: 00185 udpRec.bind(receiverMessage->host); 00186 } 00187 00188 00189 void OSCClass::setReceiveMessage(OSCMessage *_mes){ 00190 receiverMessage = _mes; 00191 } 00192 00193 void OSCClass::onUDPSocketEvent(UDPSocketEvent e) 00194 { 00195 switch(e) 00196 { 00197 case UDPSOCKET_READABLE: //The only event for now 00198 //char buf[256] = {0}; 00199 Host auxhost; 00200 buflength = udpRec.recvfrom( rcvBuff, 256, &auxhost ); // QUESTION: auxhost should be equal to the receiver host I guess... 00201 if ( buflength > 0 ) { 00202 //printf("\r\nFrom %d.%d.%d.%d:\r\n", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]); 00203 decodePacket(receiverMessage); // convert to OSC message, and save it in receiverMessage 00204 newMessage=true; 00205 00206 messageReceivedCallback.call(); 00207 } 00208 break; 00209 } 00210 } 00211 00212 /* 00213 Decode UDP packet and save it in the OSCMessage structure 00214 */ 00215 void OSCClass::decodePacket( OSCMessage *_mes) { 00216 00217 //uint16_t lenBuff; 00218 uint8_t d; 00219 uint8_t messagePos=0; 00220 uint8_t adrCount=0; 00221 uint8_t adrMesPos=0; 00222 uint8_t packetCount=0; 00223 uint8_t packetPos=4; 00224 00225 00226 //W5100.writeSn(socketNo, SnIR, SnIR::RECV); 00227 //lenBuff=recvfrom(socketNo, rcvBuff, 1, receiverMessage->ip, &receiverMessage->port); 00228 00229 receiverMessage->address[0]=tempAddress[0]; 00230 00231 //(1) address process start ========================================= 00232 do{ 00233 d=rcvBuff[messagePos]; 00234 00235 00236 if( (d=='/') && (messagePos>0) ){ 00237 00238 if(adrCount<MAX_ADDRESS){ 00239 tempAddress[adrCount][adrMesPos]=0; 00240 00241 adrCount++; 00242 adrMesPos=0; 00243 00244 receiverMessage->address[adrCount]=tempAddress[adrCount]; 00245 } 00246 00247 } 00248 00249 if(adrCount<MAX_ADDRESS){ 00250 //Added this in to remove the slashes out of final output 00251 if(d!='/'){ 00252 tempAddress[adrCount][adrMesPos]=d; 00253 00254 if(packetCount>3) { 00255 packetCount=0; 00256 packetPos+=4; 00257 } 00258 00259 adrMesPos++; 00260 } 00261 } 00262 messagePos++; 00263 packetCount++; 00264 00265 }while(d!=0); 00266 00267 00268 if(adrCount<MAX_ADDRESS) adrCount++; 00269 receiverMessage->addressNum=adrCount; 00270 00271 messagePos=packetPos; 00272 00273 //(2) type tag process starts ========================================= 00274 packetCount=0; 00275 packetPos+=4; 00276 00277 uint8_t typeTagPos=0; 00278 uint8_t tempArgNum=0; 00279 00280 while(rcvBuff[messagePos]!=0 ){ 00281 00282 if(rcvBuff[messagePos] != ',') { 00283 00284 if(typeTagPos<MAX_ARG){ 00285 receiverMessage->typeTag[tempArgNum]=rcvBuff[messagePos]; 00286 tempArgNum++; 00287 } 00288 typeTagPos++; 00289 00290 } 00291 00292 packetCount++; 00293 00294 if(packetCount>3) { 00295 packetCount=0; 00296 packetPos+=4; 00297 } 00298 00299 messagePos++; 00300 } 00301 00302 receiverMessage->argNum=tempArgNum; 00303 00304 messagePos=packetPos; 00305 00306 //(3) tempArg process starts ========================================= 00307 for(int i=0;i<tempArgNum;i++){ 00308 00309 adrMesPos=3; 00310 00311 receiverMessage->arg[i]=tempArg[i]; 00312 00313 for(int j=0;j<4;j++){ 00314 00315 tempArg[i][adrMesPos]=rcvBuff[messagePos]; 00316 00317 messagePos++; 00318 adrMesPos--; 00319 } 00320 00321 } 00322 00323 00324 } 00325 00326 00327 00328 OSCMessage * OSCClass::getMessage(){ 00329 newMessage=false; // this indicate the user READ the message 00330 return receiverMessage; 00331 } 00332 00333 00334 void OSCClass::sendOsc( OSCMessage *_mes ) 00335 { 00336 uint8_t lengthEnd; 00337 uint8_t lengthStart; 00338 char buff[128]; 00339 00340 sendContainer = _mes; 00341 00342 //バッファ初期値 00343 buff[0]=0; 00344 00345 //1) Add name spaces: 00346 for(int i=0;i<sendContainer->addressNum;i++){ 00347 00348 strcat(buff,sendContainer->address[i]); // note: an address is for instance: "/test" (including the "/") 00349 00350 } 00351 00352 // pad with 0s to align in multiples of 4: 00353 lengthStart=strlen(buff); 00354 lengthEnd=lengthStart+(4-(lengthStart%4)); 00355 for(int i=lengthStart ; i<lengthEnd; i++){ 00356 buff[i]=0; 00357 } 00358 00359 lengthStart=lengthEnd; 00360 00361 //2) Add TypeTag: 00362 buff[lengthEnd++]=','; // Note: type tag is for instance: ",if" 00363 for(int i=0;i<sendContainer->argNum;i++){ 00364 buff[lengthEnd++]=sendContainer->typeTag[i]; 00365 } 00366 00367 // pad with 0s to align in multiples of 4: 00368 lengthStart=lengthEnd; 00369 lengthEnd=lengthStart+(4-(lengthStart%4)); 00370 for(int i=lengthStart ; i<lengthEnd; i++){ 00371 buff[i]=0; 00372 } 00373 00374 //3) add argument values (Note: here only big endian): 00375 uint8_t *v; 00376 for(int i=0;i<sendContainer->argNum;i++){ 00377 uint8_t valuePos=3; 00378 v=(uint8_t *)sendContainer->arg[i]; 00379 00380 buff[lengthEnd++]=v[valuePos--]; 00381 buff[lengthEnd++]=v[valuePos--]; 00382 buff[lengthEnd++]=v[valuePos--]; 00383 buff[lengthEnd++]=v[valuePos]; 00384 00385 } 00386 00387 //4) Send udp packet: 00388 //sendto( socketNo, (uint8_t *)buff, lengthEnd, sendContainer->ip, sendContainer->port ); 00389 udpSend.sendto(buff , lengthEnd, &(sendContainer->host)); 00390 } 00391 00392 00393 /* 00394 flush a receive buffer 00395 void OSCClass::flush() { 00396 while ( available() ){} 00397 } 00398 */ 00399 00400 00401 void OSCClass::stop() { 00402 //close( socketNo ); 00403 udpSend.resetOnEvent(); // disables callback 00404 } 00405 00406
Generated on Wed Jul 13 2022 04:37:12 by 1.7.2