ADC using MODDMA and then sending the sampled value encapsulated in an OSC message
Dependencies: EthernetNetIf mbed
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 double *value; 00095 if(_index > argNum) _index=argNum; 00096 value = (double *)arg[_index]; 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 00155 // ================================================================================================================================================ 00156 // ==================================== OSCClass for sending and receiving OSC messages using UDP protocol ======================================= 00157 // ================================================================================================================================================ 00158 //The class define an object wrapping the UDP functions to send and receive OSC messages 00159 00160 OSCClass::OSCClass(){ 00161 udpRec.setOnEvent(this, &OSCClass::onUDPSocketEvent); 00162 newMessage=false; 00163 } 00164 00165 OSCClass::OSCClass(OSCMessage *_mes){ 00166 udpRec.setOnEvent(this, &OSCClass::onUDPSocketEvent); 00167 receiverMessage = _mes; // note: receiverMessage MUST be a pointer to the message, because we will modify things in it 00168 newMessage=false; 00169 } 00170 00171 void OSCClass::begin() 00172 { 00173 // setup receiver udp socket: 00174 udpRec.bind(receiverMessage->host); 00175 } 00176 00177 00178 void OSCClass::begin(uint16_t _recievePort) 00179 { 00180 receiverMessage->host.setPort(_recievePort); 00181 // setup receiver udp socket: 00182 udpRec.bind(receiverMessage->host); 00183 } 00184 00185 00186 void OSCClass::setReceiveMessage(OSCMessage *_mes){ 00187 receiverMessage = _mes; 00188 } 00189 00190 void OSCClass::onUDPSocketEvent(UDPSocketEvent e) 00191 { 00192 switch(e) 00193 { 00194 case UDPSOCKET_READABLE: //The only event for now 00195 //char buf[256] = {0}; 00196 Host auxhost; 00197 buflength = udpRec.recvfrom( rcvBuff, 256, &auxhost ); // QUESTION: auxhost should be equal to the receiver host I guess... 00198 if ( buflength > 0 ) { 00199 //printf("\r\nFrom %d.%d.%d.%d:\r\n", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]); 00200 decodePacket(receiverMessage); // convert to OSC message, and save it in receiverMessage 00201 newMessage=true; 00202 00203 messageReceivedCallback.call(); 00204 } 00205 break; 00206 } 00207 } 00208 00209 /* 00210 Decode UDP packet and save it in the OSCMessage structure 00211 */ 00212 void OSCClass::decodePacket( OSCMessage *_mes) { 00213 00214 //uint16_t lenBuff; 00215 uint8_t d; 00216 uint8_t messagePos=0; 00217 uint8_t adrCount=0; 00218 uint8_t adrMesPos=0; 00219 uint8_t packetCount=0; 00220 uint8_t packetPos=4; 00221 00222 00223 //W5100.writeSn(socketNo, SnIR, SnIR::RECV); 00224 //lenBuff=recvfrom(socketNo, rcvBuff, 1, receiverMessage->ip, &receiverMessage->port); 00225 00226 receiverMessage->address[0]=tempAddress[0]; 00227 00228 //(1) address process start ========================================= 00229 do{ 00230 d=rcvBuff[messagePos]; 00231 00232 00233 if( (d=='/') && (messagePos>0) ){ 00234 00235 if(adrCount<MAX_ADDRESS){ 00236 tempAddress[adrCount][adrMesPos]=0; 00237 00238 adrCount++; 00239 adrMesPos=0; 00240 00241 receiverMessage->address[adrCount]=tempAddress[adrCount]; 00242 } 00243 00244 } 00245 00246 if(adrCount<MAX_ADDRESS){ 00247 //Added this in to remove the slashes out of final output 00248 if(d!='/'){ 00249 tempAddress[adrCount][adrMesPos]=d; 00250 00251 if(packetCount>3) { 00252 packetCount=0; 00253 packetPos+=4; 00254 } 00255 00256 adrMesPos++; 00257 } 00258 } 00259 messagePos++; 00260 packetCount++; 00261 00262 }while(d!=0); 00263 00264 00265 if(adrCount<MAX_ADDRESS) adrCount++; 00266 receiverMessage->addressNum=adrCount; 00267 00268 messagePos=packetPos; 00269 00270 //(2) type tag process starts ========================================= 00271 packetCount=0; 00272 packetPos+=4; 00273 00274 uint8_t typeTagPos=0; 00275 uint8_t tempArgNum=0; 00276 00277 while(rcvBuff[messagePos]!=0 ){ 00278 00279 if(rcvBuff[messagePos] != ',') { 00280 00281 if(typeTagPos<MAX_ARG){ 00282 receiverMessage->typeTag[tempArgNum]=rcvBuff[messagePos]; 00283 tempArgNum++; 00284 } 00285 typeTagPos++; 00286 00287 } 00288 00289 packetCount++; 00290 00291 if(packetCount>3) { 00292 packetCount=0; 00293 packetPos+=4; 00294 } 00295 00296 messagePos++; 00297 } 00298 00299 receiverMessage->argNum=tempArgNum; 00300 00301 messagePos=packetPos; 00302 00303 //(3) tempArg process starts ========================================= 00304 for(int i=0;i<tempArgNum;i++){ 00305 00306 adrMesPos=3; 00307 00308 receiverMessage->arg[i]=tempArg[i]; 00309 00310 for(int j=0;j<4;j++){ 00311 00312 tempArg[i][adrMesPos]=rcvBuff[messagePos]; 00313 00314 messagePos++; 00315 adrMesPos--; 00316 } 00317 00318 } 00319 00320 00321 } 00322 00323 00324 00325 OSCMessage * OSCClass::getMessage(){ 00326 newMessage=false; // this indicate the user READ the message 00327 return receiverMessage; 00328 } 00329 00330 00331 void OSCClass::sendOsc( OSCMessage *_mes ) 00332 { 00333 uint8_t lengthEnd; 00334 uint8_t lengthStart; 00335 char buff[128]; 00336 00337 sendContainer = _mes; 00338 00339 //バッファ初期値 00340 buff[0]=0; 00341 00342 //1) Add name spaces: 00343 for(int i=0;i<sendContainer->addressNum;i++){ 00344 00345 strcat(buff,sendContainer->address[i]); // note: an address is for instance: "/test" (including the "/") 00346 00347 } 00348 00349 // pad with 0s to align in multiples of 4: 00350 lengthStart=strlen(buff); 00351 lengthEnd=lengthStart+(4-(lengthStart%4)); 00352 for(int i=lengthStart ; i<lengthEnd; i++){ 00353 buff[i]=0; 00354 } 00355 00356 lengthStart=lengthEnd; 00357 00358 //2) Add TypeTag: 00359 buff[lengthEnd++]=','; // Note: type tag is for instance: ",if" 00360 for(int i=0;i<sendContainer->argNum;i++){ 00361 buff[lengthEnd++]=sendContainer->typeTag[i]; 00362 } 00363 00364 // pad with 0s to align in multiples of 4: 00365 lengthStart=lengthEnd; 00366 lengthEnd=lengthStart+(4-(lengthStart%4)); 00367 for(int i=lengthStart ; i<lengthEnd; i++){ 00368 buff[i]=0; 00369 } 00370 00371 //3) add argument values (Note: here only big endian): 00372 uint8_t *v; 00373 for(int i=0;i<sendContainer->argNum;i++){ 00374 uint8_t valuePos=3; 00375 v=(uint8_t *)sendContainer->arg[i]; 00376 00377 buff[lengthEnd++]=v[valuePos--]; 00378 buff[lengthEnd++]=v[valuePos--]; 00379 buff[lengthEnd++]=v[valuePos--]; 00380 buff[lengthEnd++]=v[valuePos]; 00381 00382 } 00383 00384 //4) Send udp packet: 00385 //sendto( socketNo, (uint8_t *)buff, lengthEnd, sendContainer->ip, sendContainer->port ); 00386 udpSend.sendto(buff , lengthEnd, &(sendContainer->host)); 00387 } 00388 00389 00390 /* 00391 flush a receive buffer 00392 void OSCClass::flush() { 00393 while ( available() ){} 00394 } 00395 */ 00396 00397 00398 void OSCClass::stop() { 00399 //close( socketNo ); 00400 udpSend.resetOnEvent(); // disables callback 00401 }
Generated on Tue Jul 12 2022 21:52:12 by 1.7.2