OSC meeseage tranceiver(Sender/Receiver) for Sparkfun CC3000 WiFi Shield. Supports the following boards: FRDM-KL25Z,ST Nucleo F401RE,ST Nucleo F030R8,LPCXpresso1549,Seeduino-Arch-Pro.
Dependencies: cc3000_hostdriver_mbedsocket mbed
OSCmsgCodec.cpp
- Committer:
- xshige
- Date:
- 2014-09-03
- Revision:
- 1:e62251d890c1
- Parent:
- 0:eadd1c588343
File content as of revision 1:e62251d890c1:
/*
<----------------------------------------------------------------------------------
OSC message Codec(encoder/decoder)
version: 1.3 (2014/ 8/31) encoder bufix(enoceder returns byte length)
version: 1.2 (2014/ 8/30) decoder bufix
version: 1.1 (2013/11/20) support BIG_ENDIAN by #define
version: 1.0 (2013/11/10)
Copyright (C) 2011,2013,2014 S.Komatsu
released under the MIT License: http://mbed.org/license/mit
please refer to: http://opensoundcontrol.org/introduction-osc for OSC(Open Sound Control)
The followings are supported:
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
Change Log:
Bug(string length is not correct in encoding) Fix on 2013/11/10 (v0.9 -> v1.0)
>----------------------------------------------------------------------------------
*/
#include "OSCmsgCodec.h"
//#define BIG_ENDIAN
int lenAlign4B(int len) {
if ((len % 4) == 0) {return len; }
else {return len+4-(len % 4);}
}
int encOSCmsg(char *packet , union OSCarg *msg){
// *** important notice ***
// output buffer must be cleared before call this
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[0].address)+1)/4+1);
p += lenAlign4B(strlen(msg[0].address)+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)+1)/4+1);
p += lenAlign4B(strlen(msg[1].typeTag)+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)+1)/4+1);
p += lenAlign4B(strlen(msg[n+2].s)+1);
}
else if (('i'==c)||('f'==c)) {
#ifdef BIG_ENDIAN
// no change endian (big to big)
p[0]=msg[n+2]._b[0];
p[1]=msg[n+2]._b[1];
p[2]=msg[n+2]._b[2];
p[3]=msg[n+2]._b[3];
#else
// change 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];
#endif
p +=4;
}
else if ('b'==c) {
// put length of blog
#ifdef BIG_ENDIAN
// no change endian (big to big)
p[0]=msg[n+2]._b[0];
p[1]=msg[n+2]._b[1];
p[2]=msg[n+2]._b[2];
p[3]=msg[n+2]._b[3];
#else
// change 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];
#endif
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
// bugfix 2014/8/31
return sizeof(char)*(p-packet); // return byte length
};
void decOSCmsg(char *packet , union OSCarg *msg){
// Caution: the returned result points to packet as blobs or strings (not newly allocatd)
char *p, *typeTag;
char c; int n;
msg[0].address = packet; // address
msg[1].typeTag = packet+4*((strlen(msg[0].s)+1)/4+1);//typeTag
typeTag=msg[1].s+1; // skip ','
// bugfix 2014/8/30
if (strlen(typeTag)%2 == 0) p= msg[1].s+4*((strlen(msg[1].s)+1)/4);
else p= msg[1].s+4*((strlen(msg[1].s)+1)/4+1);
for(n=0; n<strlen(typeTag); n++){
c = typeTag[n];
if (('s'==c)) {
msg[n+2].s=p;
//p += 4*((strlen(msg[n+2].s)+1)/4+1);
p += lenAlign4B(strlen(msg[n+2].s)+1);
}
else if (('i'==c)||('f'==c)) {
#ifdef BIG_ENDIAN
// no change endian (big to big)
msg[n+2]._b[0]=p[0];
msg[n+2]._b[1]=p[1];
msg[n+2]._b[2]=p[2];
msg[n+2]._b[3]=p[3];
#else
// change 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];
#endif
p +=4;
}
else if ('b'==c) {
// get lenth of blog (copy to msg[n].blog.len)
#ifdef BIG_ENDIAN
// no change endian (big to big)
msg[n+2]._b[0]=p[0];
msg[n+2]._b[1]=p[1];
msg[n+2]._b[2]=p[2];
msg[n+2]._b[3]=p[3];
#else
// change 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];
#endif
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);
p += lenAlign4B(msg[n+2].blob.len+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);
}
};
};