ADC using MODDMA and then sending the sampled value encapsulated in an OSC message

Dependencies:   EthernetNetIf mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbedOSC.cpp Source File

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     //&#12496;&#12483;&#12501;&#12449;&#21021;&#26399;&#20516;
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 }