Shigeki KOMATSU / Mbed 2 deprecated OSCTransceiver

Dependencies:   EthernetNetIf mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OSCTransceiver.cpp Source File

OSCTransceiver.cpp

00001 // 
00002 // OSC Transceiver(Sender/Receiver)
00003 //
00004 // date: 2011/1/11
00005 // version: 0.7
00006 // written by: xshige
00007 //
00008 // please find OSC Sender/Receiver test program at the bottom of this file
00009 //
00010 // please refer to: http://opensoundcontrol.org/introduction-osc for OSC(Open Sound Control)
00011 /*
00012   The followings are supported:
00013 
00014     Transport Type: 
00015       UDP
00016 
00017     Features: 
00018      Packet Parsing (Client)
00019      Packet Construction (Server)
00020      Bundle NOT Support
00021      Timetag NOT Support
00022 
00023     Type Support: 
00024      i: int32
00025      b: blob
00026      s: string
00027      f: float32
00028      m: MIDI message(port id, status byte, data1, data2) // I don't know the detail
00029  
00030 */
00031 
00032 
00033 #include "mbed.h"
00034 #include "EthernetNetIf.h"
00035 #include "UDPSocket.h"
00036 
00037 //#define DHCP
00038 //#define LED
00039 //int ledsOSC;
00040 
00041 #define INPUT_PORT 57130
00042 #define OUTPUT_PORT 12000
00043 // setup your mbed IP address
00044 Host sendHost(IpAddr(192, 168, 0, 7), OUTPUT_PORT, NULL); // Send Port
00045 Host recHost(IpAddr(192, 168, 0, 7), INPUT_PORT, NULL);  // Receive Port
00046 UDPSocket udpRec,udpSend;
00047 
00048 #ifdef DHCP
00049 EthernetNetIf eth;
00050 #else
00051 EthernetNetIf eth(
00052   IpAddr(192,168,0,25), //IP Address
00053   IpAddr(255,255,255,0), //Network Mask
00054   IpAddr(192,168,0,1), //Gateway
00055   IpAddr(192,168,0,1)  //DNS
00056 );
00057 #endif
00058 
00059 
00060 //--- OSC related stuff ---
00061 int putOSCmsg(char *packet , union OSCarg *msg); // makes packet from OSC message and returns packet size
00062 void getOSCmsg(char *packet , union OSCarg *msg); // makes OSC message from packet
00063 
00064 union OSCarg {
00065 // char*, int and float are assumed four bytes
00066         char *address;
00067         char *typeTag;
00068         int i;
00069         float f;
00070         char *s;
00071         struct {
00072             int len; // is "int i"
00073             char *p;
00074         } blob;
00075         char m[4];  // for MIDI
00076         char _b[4]; // endian conversion temp variable
00077 };
00078 
00079 int putOSCmsg(char *packet , union OSCarg *msg){
00080     char *p, *s, *d, *typeTag; char c;
00081 
00082     p=packet;
00083     d=p;
00084     s=msg[0].address; // address
00085     for(int i=0; i<strlen(msg[0].address); i++) *d++ = *s++;
00086     *d=0; // terminator
00087     p += 4*(strlen(msg[1].address)/4+1);
00088     // 
00089     s=msg[1].typeTag;
00090     d=p;
00091     for(int i=0; i<strlen(msg[1].typeTag); i++) *d++ = *s++; 
00092     *d=0; // terminator   
00093     p += 4*(strlen(msg[1].s)/4+1);
00094     //
00095     typeTag=msg[1].s+1; // skip ','
00096     for(int n=0; n<strlen(typeTag); n++){
00097         c = typeTag[n];
00098         if (('s'==c)) {
00099             s=msg[n+2].s;
00100             d=p;
00101             for(int i=0; i<strlen(msg[n+2].s); i++) *d++ = *s++;
00102             *d=0; // terminater    
00103             p += 4*(strlen(msg[n+2].s)/4+1);
00104         } else if (('i'==c)||('f'==c)) {
00105             // chang endian (little to big)
00106             p[0]=msg[n+2]._b[3]; 
00107             p[1]=msg[n+2]._b[2]; 
00108             p[2]=msg[n+2]._b[1];
00109             p[3]=msg[n+2]._b[0];
00110             p +=4;  
00111         } else if ('b'==c) {
00112             // chang endian (little to big)
00113             // put length of blog
00114             p[0]=msg[n+2]._b[3]; 
00115             p[1]=msg[n+2]._b[2]; 
00116             p[2]=msg[n+2]._b[1];
00117             p[3]=msg[n+2]._b[0];
00118             p +=4;  
00119             // get ponter of blog (copy to msg[n].blog.p)
00120             s=msg[n+2].blob.p;
00121             d=p;
00122             for(int i=0; i<msg[n+2].blob.len; i++) *d++ = *s++;    
00123             p += 4*(msg[n+2].blob.len/4+1);       
00124         } else if ('m'==c) {
00125             // get midi data (copy to msg[n].m[])
00126             p[0]=msg[n+2].m[0]; 
00127             p[1]=msg[n+2].m[1]; 
00128             p[2]=msg[n+2].m[2];
00129             p[3]=msg[n+2].m[3];
00130             p +=4;  
00131         } else {
00132             printf("*** Not Supported TypeTag:%s ****\n",typeTag);
00133         }
00134     };
00135     return (p-packet); // return packet size    
00136 }
00137 
00138 void getOSCmsg(char *packet , union OSCarg *msg){
00139 // Caution: the returned result points to packet as blobs or strings (not newly allocatd)
00140     char *p, *typeTag; char c;
00141         
00142     msg[0].address = packet; // address
00143     msg[1].typeTag = packet+4*(strlen(msg[0].s)/4+1);//typeTag
00144     typeTag=msg[1].s+1; // skip ','
00145     p= msg[1].s+4*(strlen(msg[1].s)/4+1);
00146     for(int n=0; n<strlen(typeTag); n++){
00147         c = typeTag[n];
00148         if (('s'==c)) {
00149             msg[n+2].s=p;
00150             p += 4*(strlen(msg[n+2].s)/4+1);
00151         } else if (('i'==c)||('f'==c)) {
00152             // chang endian (big to little)
00153             msg[n+2]._b[3]=p[0]; 
00154             msg[n+2]._b[2]=p[1]; 
00155             msg[n+2]._b[1]=p[2];
00156             msg[n+2]._b[0]=p[3];
00157             p +=4;  
00158         } else if ('b'==c) {
00159             // chang endian (big to little)
00160             // get lenth of blog (copy to msg[n].blog.len)
00161             msg[n+2]._b[3]=p[0]; 
00162             msg[n+2]._b[2]=p[1]; 
00163             msg[n+2]._b[1]=p[2];
00164             msg[n+2]._b[0]=p[3];
00165             p +=4;
00166             // get ponter of blog (copy to msg[n].blog.p)
00167             msg[n+2].blob.p=p;
00168             p += 4*(msg[n+2].blob.len/4+1);       
00169         } else if ('m'==c) {
00170             // get midi data (copy to msg[n].m[])
00171             msg[n+2].m[0]=p[0]; 
00172             msg[n+2].m[1]=p[1]; 
00173             msg[n+2].m[2]=p[2];
00174             msg[n+2].m[3]=p[3];
00175             p +=4;  
00176         } else {
00177             printf("*** Not Supported TypeTag:%s ****\n",typeTag);
00178         }
00179     };
00180     
00181 }
00182 //-------------------------------------------
00183 
00184 void onUDPSocketEvent(UDPSocketEvent e)
00185 {
00186   union OSCarg msg[10];
00187 
00188   switch(e)
00189   {
00190   case UDPSOCKET_READABLE: //The only event for now
00191     char buf[256] = {0};
00192     Host host;
00193     while( int len = udpRec.recvfrom( buf, 256, &host ) )
00194     {
00195       if( len <= 0 )
00196         break;
00197       printf("\r\nFrom %d.%d.%d.%d:\r\n", 
00198       host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]);
00199       
00200       getOSCmsg(buf,msg);
00201 
00202       // address pattern samples
00203       if (strcmp(msg[0].address,"/test")==0) {
00204         printf("OSCmsg: %s %s %d %f %s %d\n", 
00205             msg[0].address, msg[1].typeTag,msg[2].i, msg[3].f, msg[4].s, msg[5].blob.len);
00206         printf("blob content:\n");
00207         char *p=msg[5].blob.p;
00208         for(int n=0; n<msg[5].blob.len; p++,n++) printf(" %02X",(unsigned char)(*p));
00209         printf("\n");
00210         break;
00211       }
00212       if (strcmp(msg[0].address,"/kb/m")==0) {
00213         printf("OSCmsg: %s %s %d %d %d\n", 
00214             msg[0].address, msg[1].typeTag,msg[2].i, msg[3].i, msg[4].i);
00215         break;
00216       }
00217       if (strcmp(msg[0].address,"/cc/m")==0) {
00218         printf("OSCmsg: %s %s %d %d %d\n", 
00219             msg[0].address, msg[1].typeTag,msg[2].i, msg[3].i, msg[4].i);
00220         break;
00221       }
00222       if (strcmp(msg[0].address,"/1/fader1")==0) {
00223         printf("OSCmsg: %s %s %f\n", 
00224             msg[0].address, msg[1].typeTag,msg[2].f);
00225         break;
00226       }
00227       if (strcmp(msg[0].address,"/1/knob1")==0) {
00228         printf("OSCmsg: %s %s %f\n", 
00229             msg[0].address, msg[1].typeTag, msg[2].f);
00230         break;
00231       } 
00232       if (strcmp(msg[0].address,"/1/butt/A1")==0) {
00233         printf("OSCmsg: %s %s %i\n", 
00234             msg[0].address, msg[1].typeTag, msg[2].i);
00235         break;
00236       }
00237       if (strcmp(msg[0].address,"/1/butt/B1")==0) {
00238         printf("OSCmsg: %s %s %i\n", 
00239             msg[0].address, msg[1].typeTag, msg[2].i);
00240         break;
00241       }
00242       if (strcmp(msg[0].address,"/mouse/dragged")==0) {
00243         printf("OSCmsg: %s %s %i %i\n", 
00244             msg[0].address, msg[1].typeTag, msg[2].i, msg[3].i);
00245         break;
00246       }
00247       if (strcmp(msg[0].address,"/mouse/pressed")==0) {
00248         printf("OSCmsg: %s %s %i %i\n", 
00249             msg[0].address, msg[1].typeTag, msg[2].i, msg[3].i);
00250         break;
00251       }
00252       if (strcmp(msg[0].address,"/1/xy")==0) {
00253         printf("OSCmsg: %s %s %f %f %d\n", 
00254             msg[0].address, msg[1].typeTag, msg[2].f, msg[3].f, msg[4].i);
00255 #ifdef LED
00256         ledsOSC=16*msg[2].f;
00257 #endif
00258         break;
00259       }
00260       printf("undefined OSCmsg:%s %s\n",msg[0].address, msg[1].typeTag);
00261     } // while
00262     break;
00263   } // case
00264 }
00265 
00266 #ifdef LED
00267 BusOut myleds(LED1, LED2, LED3, LED4);
00268 #endif
00269 
00270 
00271 int counter=1; // for test
00272 void sendTestOSCmsg(){
00273     char packet[128]; int len;
00274     
00275     union OSCarg outmsg[10];
00276     char bb[17]={0x00, 0x01, 0x10, 0x20,0x30,0x40,0x50,0x60,0x7F,0x80,0x90,0xA0,0xB0,0xC0,0xD0,0xE0,0xFF};
00277     // setup OSC message
00278     outmsg[0].address="/test2";
00279     outmsg[1].typeTag=",ifsb";
00280     outmsg[2].i=counter; counter++;
00281     outmsg[3].f=34.55*counter;
00282     outmsg[4].s="Hello! Everything is going right?";
00283     outmsg[5].blob.len=sizeof(bb);
00284     outmsg[5].blob.p=bb;
00285     // make packet from OSC message
00286     len=putOSCmsg(packet,outmsg);
00287        
00288     // send it
00289      udpSend.sendto(packet, len, &sendHost );
00290 
00291 //debug code
00292 #if 0
00293     union OSCarg msg[10]; //debug
00294     getOSCmsg(packet,msg);
00295     if (strcmp(msg[0].address,"/test2")==0) {
00296         printf("\nsend packet debugging:\n");
00297         printf("OSCmsg: %s %s %d %f %s %d\n", 
00298             msg[0].address, msg[1].typeTag,msg[2].i, msg[3].f, msg[4].s, msg[5].blob.len);
00299         printf("blob content:\n");
00300         char *p=msg[5].blob.p;
00301         for(int n=0; n<msg[5].blob.len; p++,n++) printf(" %02X",(unsigned char)(*p));
00302         printf("\n");
00303     }
00304 #endif
00305 }
00306 
00307 
00308 int main() {
00309 // make debug port Fast
00310    Serial pc(USBTX, USBRX);
00311 //    pc.baud(9600);
00312     pc.baud(115200);
00313 //  pc.baud(230400);
00314 
00315   printf("Setting up...\r\n");
00316   EthernetErr ethErr = eth.setup();
00317   if(ethErr)
00318   {
00319     printf("Error %d in setup.\r\n", ethErr);
00320     return -1;
00321   }
00322   printf("Setup OK\r\n");
00323   
00324 
00325   // setup receiver
00326   udpRec.setOnEvent(&onUDPSocketEvent);
00327   udpRec.bind(recHost);
00328   
00329   
00330   Timer tmr;
00331   tmr.start();
00332   while(true)
00333   {
00334     Net::poll();
00335     if(tmr.read() > 2)
00336     {
00337       tmr.reset();
00338       sendTestOSCmsg();
00339     }
00340     
00341 //   sendTestOSCmsg();
00342     
00343 #ifdef LED
00344     myleds=ledsOSC%16;
00345 #endif
00346   } 
00347 }
00348 
00349 //----------------------------------------------------------------------------------------------------------
00350 /*
00351 //
00352 // OSC Sender/Receiver test
00353 //
00354 // written in: processing(refer to: http://processing.org/)
00355 //
00356 // this program is based on oscP5plug in examples of oscP5 lib.
00357 //
00358 // please install oscP5 lib
00359 // you can download this from: http://www.sojamo.de/libraries/oscP5/
00360  
00361 import oscP5.*;
00362 import netP5.*;
00363 
00364 // change them to fit your environment
00365 int INPUT_PORT=12000; // receive port
00366 int OUTPUT_PORT=57130; // send port
00367 String remoteIP="192.168.0.25"; // mbed IP address
00368 
00369 OscP5 oscP5;
00370 NetAddress remoteHost;
00371 
00372 void setup() {
00373   size(400,400);
00374   // setup receiver
00375   oscP5 = new OscP5(this,INPUT_PORT);
00376   // setup mbed IP & sender
00377   remoteHost = new NetAddress(remoteIP,OUTPUT_PORT);
00378   
00379   // setup OSC message address for receiving
00380   oscP5.plug(this,"received_test2","/test2");
00381   
00382   // send test message
00383   sendTestMsg();
00384 }
00385 
00386 public void received_test2(int a1, float a2, String a3, byte[] a4) {
00387   println("\nreceived /test2 "+a1+", "+a2+" "+a3);
00388   println("Blob contents:");
00389   for(int n=0; n<a4.length; n++) print(" "+hex(a4[n]));
00390   println();  
00391 }
00392 
00393 void draw() {
00394   background(0);
00395 }
00396 
00397 void sendTestMsg() {        
00398   OscMessage oscMsg= oscP5.newMsg("/test");
00399   oscMsg.add(mouseY);
00400   oscMsg.add(54.32);
00401   oscMsg.add("Can you chatch this?"); 
00402   // add a byte blob to the osc message
00403   oscMsg.add(
00404      new byte[] {0x00, 0x01, 0x10, 0x20,0x30,0x40,0x50,0x60,0x7F,
00405        -128,-1,(byte)0x80,(byte)0x90,(byte)0xA0,(byte)0xB0,(byte)0xC0,
00406      (byte)0xD0,(byte)0xE0,(byte)0xFF});
00407  // 0x80,0x90,0xFE,0xFF etc do not work because byte is 127 thru -128.
00408  // so do it like: (byte)0xFF
00409   oscP5.send(oscMsg, remoteHost); 
00410 }
00411 
00412 void mousePressed() {
00413   OscMessage myMessage = new OscMessage("/mouse/pressed");
00414   myMessage.add(mouseX); // add an int to the osc message
00415   myMessage.add(mouseY); // add a second int to the osc message
00416   // send the message
00417   oscP5.send(myMessage, remoteHost);
00418  // 
00419   sendTestMsg();
00420 }
00421 
00422 void mouseDragged() { 
00423   OscMessage oscMsg= oscP5.newMsg("/mouse/dragged");
00424   oscMsg.add(mouseX);
00425   oscMsg.add(mouseY);
00426   oscP5.send(oscMsg, remoteHost); 
00427 //
00428   oscMsg= oscP5.newMsg("/1/xy");
00429   oscMsg.add(mouseX*1.0/width);
00430   oscMsg.add(mouseY*1.0/height);
00431   oscMsg.add(1); // button status:pressed
00432   oscP5.send(oscMsg, remoteHost); 
00433 }
00434 
00435 void mouseReleased() {        
00436   OscMessage oscMsg= oscP5.newMsg("/1/xy");
00437   oscMsg.add(mouseX*1.0/width);
00438   oscMsg.add(mouseY*1.0/height);
00439   oscMsg.add(0); // button status:released
00440   oscP5.send(oscMsg, remoteHost); 
00441 }
00442 
00443 // incoming osc message are forwarded to the oscEvent method.
00444 void oscEvent(OscMessage theOscMessage) {
00445   // with theOscMessage.isPlugged() you check if the osc message has already been
00446   // forwarded to a plugged method. if theOscMessage.isPlugged()==true, it has already 
00447   // been forwared to another method in your sketch. theOscMessage.isPlugged() can 
00448   // be used for double posting but is not required.
00449   //  
00450   if(theOscMessage.isPlugged()==false) {
00451   // print the address pattern and the typetag of the received OscMessage
00452   println("### received an osc message.");
00453   println("### addrpattern\t"+theOscMessage.addrPattern());
00454   println("### typetag\t"+theOscMessage.typetag());
00455   }
00456 }
00457 
00458 */
00459 //----------------------------------------------------------------------------------------------------------