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
OSCTransceiver.cpp
- Committer:
- xshige
- Date:
- 2011-01-11
- Revision:
- 0:a11a5771a1a9
File content as of revision 0:a11a5771a1a9:
// // 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()); } } */ //----------------------------------------------------------------------------------------------------------