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

Files at this revision

API Documentation at this revision

Comitter:
xshige
Date:
Tue Jan 11 13:49:57 2011 +0000
Commit message:

Changed in this revision

EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
OSCTransceiver.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Tue Jan 11 13:49:57 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /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());
+  }
+}
+
+*/
+//----------------------------------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Jan 11 13:49:57 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9114680c05da