OSC Transceiver(Sender/Receiver) program on mbed supporting types i:int32, b:blob, s:string, f:float32, m:MIDI. Attached OSC test program(in processing). Plese refer for detail:http://opensoundcontrol.org/introduction-osc

Dependencies:   EthernetNetIf mbed

Revision:
0:a11a5771a1a9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCTransceiver.cpp	Tue Jan 11 13:49:57 2011 +0000
@@ -0,0 +1,459 @@
+// 
+// OSC Transceiver(Sender/Receiver)
+//
+// date: 2011/1/11
+// version: 0.7
+// written by: xshige
+//
+// please find OSC Sender/Receiver test program at the bottom of this file
+//
+// please refer to: http://opensoundcontrol.org/introduction-osc for OSC(Open Sound Control)
+/*
+  The followings are supported:
+
+    Transport Type: 
+      UDP
+
+    Features: 
+     Packet Parsing (Client)
+     Packet Construction (Server)
+     Bundle NOT Support
+     Timetag NOT Support
+
+    Type Support: 
+     i: int32
+     b: blob
+     s: string
+     f: float32
+     m: MIDI message(port id, status byte, data1, data2) // I don't know the detail
+ 
+*/
+
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "UDPSocket.h"
+
+//#define DHCP
+//#define LED
+//int ledsOSC;
+
+#define INPUT_PORT 57130
+#define OUTPUT_PORT 12000
+// setup your mbed IP address
+Host sendHost(IpAddr(192, 168, 0, 7), OUTPUT_PORT, NULL); // Send Port
+Host recHost(IpAddr(192, 168, 0, 7), INPUT_PORT, NULL);  // Receive Port
+UDPSocket udpRec,udpSend;
+
+#ifdef DHCP
+EthernetNetIf eth;
+#else
+EthernetNetIf eth(
+  IpAddr(192,168,0,25), //IP Address
+  IpAddr(255,255,255,0), //Network Mask
+  IpAddr(192,168,0,1), //Gateway
+  IpAddr(192,168,0,1)  //DNS
+);
+#endif
+
+
+//--- OSC related stuff ---
+int putOSCmsg(char *packet , union OSCarg *msg); // makes packet from OSC message and returns packet size
+void getOSCmsg(char *packet , union OSCarg *msg); // makes OSC message from packet
+
+union OSCarg {
+// char*, int and float are assumed four bytes
+        char *address;
+        char *typeTag;
+        int i;
+        float f;
+        char *s;
+        struct {
+            int len; // is "int i"
+            char *p;
+        } blob;
+        char m[4];  // for MIDI
+        char _b[4]; // endian conversion temp variable
+};
+
+int putOSCmsg(char *packet , union OSCarg *msg){
+    char *p, *s, *d, *typeTag; char c;
+
+    p=packet;
+    d=p;
+    s=msg[0].address; // address
+    for(int i=0; i<strlen(msg[0].address); i++) *d++ = *s++;
+    *d=0; // terminator
+    p += 4*(strlen(msg[1].address)/4+1);
+    // 
+    s=msg[1].typeTag;
+    d=p;
+    for(int i=0; i<strlen(msg[1].typeTag); i++) *d++ = *s++; 
+    *d=0; // terminator   
+    p += 4*(strlen(msg[1].s)/4+1);
+    //
+    typeTag=msg[1].s+1; // skip ','
+    for(int n=0; n<strlen(typeTag); n++){
+        c = typeTag[n];
+        if (('s'==c)) {
+            s=msg[n+2].s;
+            d=p;
+            for(int i=0; i<strlen(msg[n+2].s); i++) *d++ = *s++;
+            *d=0; // terminater    
+            p += 4*(strlen(msg[n+2].s)/4+1);
+        } else if (('i'==c)||('f'==c)) {
+            // chang endian (little to big)
+            p[0]=msg[n+2]._b[3]; 
+            p[1]=msg[n+2]._b[2]; 
+            p[2]=msg[n+2]._b[1];
+            p[3]=msg[n+2]._b[0];
+            p +=4;  
+        } else if ('b'==c) {
+            // chang endian (little to big)
+            // put length of blog
+            p[0]=msg[n+2]._b[3]; 
+            p[1]=msg[n+2]._b[2]; 
+            p[2]=msg[n+2]._b[1];
+            p[3]=msg[n+2]._b[0];
+            p +=4;  
+            // get ponter of blog (copy to msg[n].blog.p)
+            s=msg[n+2].blob.p;
+            d=p;
+            for(int i=0; i<msg[n+2].blob.len; i++) *d++ = *s++;    
+            p += 4*(msg[n+2].blob.len/4+1);       
+        } else if ('m'==c) {
+            // get midi data (copy to msg[n].m[])
+            p[0]=msg[n+2].m[0]; 
+            p[1]=msg[n+2].m[1]; 
+            p[2]=msg[n+2].m[2];
+            p[3]=msg[n+2].m[3];
+            p +=4;  
+        } else {
+            printf("*** Not Supported TypeTag:%s ****\n",typeTag);
+        }
+    };
+    return (p-packet); // return packet size    
+}
+
+void getOSCmsg(char *packet , union OSCarg *msg){
+// Caution: the returned result points to packet as blobs or strings (not newly allocatd)
+    char *p, *typeTag; char c;
+        
+    msg[0].address = packet; // address
+    msg[1].typeTag = packet+4*(strlen(msg[0].s)/4+1);//typeTag
+    typeTag=msg[1].s+1; // skip ','
+    p= msg[1].s+4*(strlen(msg[1].s)/4+1);
+    for(int n=0; n<strlen(typeTag); n++){
+        c = typeTag[n];
+        if (('s'==c)) {
+            msg[n+2].s=p;
+            p += 4*(strlen(msg[n+2].s)/4+1);
+        } else if (('i'==c)||('f'==c)) {
+            // chang endian (big to little)
+            msg[n+2]._b[3]=p[0]; 
+            msg[n+2]._b[2]=p[1]; 
+            msg[n+2]._b[1]=p[2];
+            msg[n+2]._b[0]=p[3];
+            p +=4;  
+        } else if ('b'==c) {
+            // chang endian (big to little)
+            // get lenth of blog (copy to msg[n].blog.len)
+            msg[n+2]._b[3]=p[0]; 
+            msg[n+2]._b[2]=p[1]; 
+            msg[n+2]._b[1]=p[2];
+            msg[n+2]._b[0]=p[3];
+            p +=4;
+            // get ponter of blog (copy to msg[n].blog.p)
+            msg[n+2].blob.p=p;
+            p += 4*(msg[n+2].blob.len/4+1);       
+        } else if ('m'==c) {
+            // get midi data (copy to msg[n].m[])
+            msg[n+2].m[0]=p[0]; 
+            msg[n+2].m[1]=p[1]; 
+            msg[n+2].m[2]=p[2];
+            msg[n+2].m[3]=p[3];
+            p +=4;  
+        } else {
+            printf("*** Not Supported TypeTag:%s ****\n",typeTag);
+        }
+    };
+    
+}
+//-------------------------------------------
+
+void onUDPSocketEvent(UDPSocketEvent e)
+{
+  union OSCarg msg[10];
+
+  switch(e)
+  {
+  case UDPSOCKET_READABLE: //The only event for now
+    char buf[256] = {0};
+    Host host;
+    while( int len = udpRec.recvfrom( buf, 256, &host ) )
+    {
+      if( len <= 0 )
+        break;
+      printf("\r\nFrom %d.%d.%d.%d:\r\n", 
+      host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]);
+      
+      getOSCmsg(buf,msg);
+
+      // address pattern samples
+      if (strcmp(msg[0].address,"/test")==0) {
+        printf("OSCmsg: %s %s %d %f %s %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].f, msg[4].s, msg[5].blob.len);
+        printf("blob content:\n");
+        char *p=msg[5].blob.p;
+        for(int n=0; n<msg[5].blob.len; p++,n++) printf(" %02X",(unsigned char)(*p));
+        printf("\n");
+        break;
+      }
+      if (strcmp(msg[0].address,"/kb/m")==0) {
+        printf("OSCmsg: %s %s %d %d %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].i, msg[4].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/cc/m")==0) {
+        printf("OSCmsg: %s %s %d %d %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].i, msg[4].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/1/fader1")==0) {
+        printf("OSCmsg: %s %s %f\n", 
+            msg[0].address, msg[1].typeTag,msg[2].f);
+        break;
+      }
+      if (strcmp(msg[0].address,"/1/knob1")==0) {
+        printf("OSCmsg: %s %s %f\n", 
+            msg[0].address, msg[1].typeTag, msg[2].f);
+        break;
+      } 
+      if (strcmp(msg[0].address,"/1/butt/A1")==0) {
+        printf("OSCmsg: %s %s %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/1/butt/B1")==0) {
+        printf("OSCmsg: %s %s %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/mouse/dragged")==0) {
+        printf("OSCmsg: %s %s %i %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i, msg[3].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/mouse/pressed")==0) {
+        printf("OSCmsg: %s %s %i %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i, msg[3].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/1/xy")==0) {
+        printf("OSCmsg: %s %s %f %f %d\n", 
+            msg[0].address, msg[1].typeTag, msg[2].f, msg[3].f, msg[4].i);
+#ifdef LED
+        ledsOSC=16*msg[2].f;
+#endif
+        break;
+      }
+      printf("undefined OSCmsg:%s %s\n",msg[0].address, msg[1].typeTag);
+    } // while
+    break;
+  } // case
+}
+
+#ifdef LED
+BusOut myleds(LED1, LED2, LED3, LED4);
+#endif
+
+
+int counter=1; // for test
+void sendTestOSCmsg(){
+    char packet[128]; int len;
+    
+    union OSCarg outmsg[10];
+    char bb[17]={0x00, 0x01, 0x10, 0x20,0x30,0x40,0x50,0x60,0x7F,0x80,0x90,0xA0,0xB0,0xC0,0xD0,0xE0,0xFF};
+    // setup OSC message
+    outmsg[0].address="/test2";
+    outmsg[1].typeTag=",ifsb";
+    outmsg[2].i=counter; counter++;
+    outmsg[3].f=34.55*counter;
+    outmsg[4].s="Hello! Everything is going right?";
+    outmsg[5].blob.len=sizeof(bb);
+    outmsg[5].blob.p=bb;
+    // make packet from OSC message
+    len=putOSCmsg(packet,outmsg);
+       
+    // send it
+     udpSend.sendto(packet, len, &sendHost );
+
+//debug code
+#if 0
+    union OSCarg msg[10]; //debug
+    getOSCmsg(packet,msg);
+    if (strcmp(msg[0].address,"/test2")==0) {
+        printf("\nsend packet debugging:\n");
+        printf("OSCmsg: %s %s %d %f %s %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].f, msg[4].s, msg[5].blob.len);
+        printf("blob content:\n");
+        char *p=msg[5].blob.p;
+        for(int n=0; n<msg[5].blob.len; p++,n++) printf(" %02X",(unsigned char)(*p));
+        printf("\n");
+    }
+#endif
+}
+
+
+int main() {
+// make debug port Fast
+   Serial pc(USBTX, USBRX);
+//    pc.baud(9600);
+    pc.baud(115200);
+//  pc.baud(230400);
+
+  printf("Setting up...\r\n");
+  EthernetErr ethErr = eth.setup();
+  if(ethErr)
+  {
+    printf("Error %d in setup.\r\n", ethErr);
+    return -1;
+  }
+  printf("Setup OK\r\n");
+  
+
+  // setup receiver
+  udpRec.setOnEvent(&onUDPSocketEvent);
+  udpRec.bind(recHost);
+  
+  
+  Timer tmr;
+  tmr.start();
+  while(true)
+  {
+    Net::poll();
+    if(tmr.read() > 2)
+    {
+      tmr.reset();
+      sendTestOSCmsg();
+    }
+    
+//   sendTestOSCmsg();
+    
+#ifdef LED
+    myleds=ledsOSC%16;
+#endif
+  } 
+}
+
+//----------------------------------------------------------------------------------------------------------
+/*
+//
+// OSC Sender/Receiver test
+//
+// written in: processing(refer to: http://processing.org/)
+//
+// this program is based on oscP5plug in examples of oscP5 lib.
+//
+// please install oscP5 lib
+// you can download this from: http://www.sojamo.de/libraries/oscP5/
+ 
+import oscP5.*;
+import netP5.*;
+
+// change them to fit your environment
+int INPUT_PORT=12000; // receive port
+int OUTPUT_PORT=57130; // send port
+String remoteIP="192.168.0.25"; // mbed IP address
+
+OscP5 oscP5;
+NetAddress remoteHost;
+
+void setup() {
+  size(400,400);
+  // setup receiver
+  oscP5 = new OscP5(this,INPUT_PORT);
+  // setup mbed IP & sender
+  remoteHost = new NetAddress(remoteIP,OUTPUT_PORT);
+  
+  // setup OSC message address for receiving
+  oscP5.plug(this,"received_test2","/test2");
+  
+  // send test message
+  sendTestMsg();
+}
+
+public void received_test2(int a1, float a2, String a3, byte[] a4) {
+  println("\nreceived /test2 "+a1+", "+a2+" "+a3);
+  println("Blob contents:");
+  for(int n=0; n<a4.length; n++) print(" "+hex(a4[n]));
+  println();  
+}
+
+void draw() {
+  background(0);
+}
+
+void sendTestMsg() {        
+  OscMessage oscMsg= oscP5.newMsg("/test");
+  oscMsg.add(mouseY);
+  oscMsg.add(54.32);
+  oscMsg.add("Can you chatch this?"); 
+  // add a byte blob to the osc message
+  oscMsg.add(
+     new byte[] {0x00, 0x01, 0x10, 0x20,0x30,0x40,0x50,0x60,0x7F,
+       -128,-1,(byte)0x80,(byte)0x90,(byte)0xA0,(byte)0xB0,(byte)0xC0,
+     (byte)0xD0,(byte)0xE0,(byte)0xFF});
+ // 0x80,0x90,0xFE,0xFF etc do not work because byte is 127 thru -128.
+ // so do it like: (byte)0xFF
+  oscP5.send(oscMsg, remoteHost); 
+}
+
+void mousePressed() {
+  OscMessage myMessage = new OscMessage("/mouse/pressed");
+  myMessage.add(mouseX); // add an int to the osc message
+  myMessage.add(mouseY); // add a second int to the osc message
+  // send the message
+  oscP5.send(myMessage, remoteHost);
+ // 
+  sendTestMsg();
+}
+
+void mouseDragged() { 
+  OscMessage oscMsg= oscP5.newMsg("/mouse/dragged");
+  oscMsg.add(mouseX);
+  oscMsg.add(mouseY);
+  oscP5.send(oscMsg, remoteHost); 
+//
+  oscMsg= oscP5.newMsg("/1/xy");
+  oscMsg.add(mouseX*1.0/width);
+  oscMsg.add(mouseY*1.0/height);
+  oscMsg.add(1); // button status:pressed
+  oscP5.send(oscMsg, remoteHost); 
+}
+
+void mouseReleased() {        
+  OscMessage oscMsg= oscP5.newMsg("/1/xy");
+  oscMsg.add(mouseX*1.0/width);
+  oscMsg.add(mouseY*1.0/height);
+  oscMsg.add(0); // button status:released
+  oscP5.send(oscMsg, remoteHost); 
+}
+
+// incoming osc message are forwarded to the oscEvent method.
+void oscEvent(OscMessage theOscMessage) {
+  // with theOscMessage.isPlugged() you check if the osc message has already been
+  // forwarded to a plugged method. if theOscMessage.isPlugged()==true, it has already 
+  // been forwared to another method in your sketch. theOscMessage.isPlugged() can 
+  // be used for double posting but is not required.
+  //  
+  if(theOscMessage.isPlugged()==false) {
+  // print the address pattern and the typetag of the received OscMessage
+  println("### received an osc message.");
+  println("### addrpattern\t"+theOscMessage.addrPattern());
+  println("### typetag\t"+theOscMessage.typetag());
+  }
+}
+
+*/
+//----------------------------------------------------------------------------------------------------------