KAMUI OSC-CV Example refer to OSCReceiver by xshige http://mbed.org/users/xshige/programs/OSCReceiver/
Dependencies: NetServices TextLCD mbed
Revision 0:eabe87e89290, committed 2012-05-06
- Comitter:
- radiojunkbox
- Date:
- Sun May 06 07:17:59 2012 +0000
- Commit message:
- Rev. 1.0
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NetServices.lib Sun May 06 07:17:59 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/segundo/code/NetServices/#4e2468d7d5cb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OSCReceiver.cpp Sun May 06 07:17:59 2012 +0000 @@ -0,0 +1,235 @@ +// +// OSC Receiver +// +// date: 2011/1/10 +// version: 0.7 +// written by: xshige +// +// please find OSC Sender program at the bottom of this file +// +/* + The followings are supported: + + Transport Type: + UDP + + Features: + Packet Parsing (Client) + Not Supported: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 "OSCReceiver.h" // Add by RadioJunkBox 2012/05/16 + +/* comment out by RadioJunkBox 2012/05/16 + +#include "EthernetNetIf.h" +#include "UDPSocket.h" + +#define DHCP + +//#define INPUT_PORT 12000 +#define INPUT_PORT 12345 + +#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 --- +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 +}; +*/ +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); + } + }; + +} +//------------------------------------------- + +/* comment out RadioJunkBox 2012/05/06 + +UDPSocket udp; + + +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 = udp.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,"/osc/padx")==0) { + printf("OSCmsg: %s %s %f\n", + msg[0].address, msg[1].typeTag,msg[2].f); + break; + } + if (strcmp(msg[0].address,"/osc/pady")==0) { + printf("OSCmsg: %s %s %f\n", + msg[0].address, msg[1].typeTag, msg[2].f); + break; + } + if (strcmp(msg[0].address,"/osc/button1")==0) { + printf("OSCmsg: %s %s %i\n", + msg[0].address, msg[1].typeTag, msg[2].i); + break; + } + if (strcmp(msg[0].address,"/osc/button2")==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); + break; + } + printf("undefined OSCmsg:%s %s\n",msg[0].address, msg[1].typeTag); + } // while + break; + } // case +} + +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"); + + + // port setup +// Host recHost(IpAddr(192, 168, 0, 7), INPUT_PORT, NULL); + Host broadcast(IpAddr(eth.getIp()[0], eth.getIp()[1], eth.getIp()[2], 255), INPUT_PORT, NULL); + udp.setOnEvent(&onUDPSocketEvent); + udp.bind(broadcast); + + Timer tmr; + tmr.start(); + while(true) + { + Net::poll(); + if(tmr.read() > 5) + { + tmr.reset(); + } + } + +} +*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OSCReceiver.h Sun May 06 07:17:59 2012 +0000 @@ -0,0 +1,30 @@ +//------------------------------------------------------------- +// KAMUI OSC-CV Example +// file : OSCReceiver.h +// referred to xshige's OSCReceiver +// http://mbed.org/users/xshige/programs/OSCReceiver/ +// Copyright (C) 2012 RJB RadioJunkBox +// Released under the MIT License: http://mbed.org/license/mit +//------------------------------------------------------------- + +#ifndef MBED_OSCRECEIVER_H +#define MBED_OSCRECEIVER_H + +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 +}; + +void getOSCmsg(char *packet , union OSCarg *msg); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Sun May 06 07:17:59 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun May 06 07:17:59 2012 +0000 @@ -0,0 +1,444 @@ +//------------------------------------------------------------- +// KAMUI OSC-CV Exapmple +// referred to xshige's OSCReceiver +// http://mbed.org/users/xshige/programs/OSCReceiver/ +// Copyright (C) 2012 RJB RadioJunkBox +// Released under the MIT License: http://mbed.org/license/mit +//------------------------------------------------------------- + +#include "mbed.h" +#include "TextLCD.h" +#include "EthernetNetIf.h" +#include "UDPSocket.h" +#include "OSCReceiver.h" +#include <stdlib.h> +#include <ctype.h> +#include <math.h> + +//------------------------------------------------------------- +// Define + +#define AD5551 // 14bitDAC + +#define SPI_RATE 1000000 // 1Mbps +#define MIDI_RATE 31250 // 31.25kbps +#define BEEP_FREQ 1760.0 // 1760Hz +#define UPDATE_INTERVAL 100 // 100us +#define SW_WATCH_INTERVAL (25000/UPDATE_INTERVAL) // 25ms +#define PARAM_GLIDE 6554.0 + +#define UPDATE_MODE0 0 // Update Interval CV ch1-6 1200us, ch7,8 400us +#define UPDATE_MODE1 1 // Update Interval CV ch1-6 N/A, ch7,8 200us + +#define GATE1 0x01 +#define GATE2 0x02 +#define GATE3 0x04 +#define GATE4 0x08 + +#define SYNC1CLK 0x01 +#define SYNC1RUN 0x02 +#define SYNC2CLK 0x04 +#define SYNC2RUN 0x08 + +#define MODE_CV 0x00 +#define MODE_GATE 0x40 +#define MODE_SYNC 0x80 +#define MODE_SET_SYNC 0xC0 + +#define SW1 0x01 +#define SW2 0x02 +#define SW3 0x04 +#define SW4 0x08 +#define SYNC1CLK_IN 0x10 +#define SYNC1RUN_IN 0x20 +#define SYNC2CLK_IN 0x40 +#define GATE_IN 0x80 + +#define _ENABLE 0 +#define _DISABLE 1 + +//------------------------------------------------------------- +// Functions + +void InitKamui(void); +void UpdateCV(void); +unsigned char CheckSW(unsigned char); + +void SetCV(void); +int SetupEthNetIf(void); +void onUDPSocketEvent(UDPSocketEvent); + +//------------------------------------------------------------- +// Global Variables + +int gUpdateMode; +unsigned short gCV[8]; +unsigned char gGATE; +unsigned char gSYNC; +unsigned char gSW; + +union { + unsigned short WORD; + struct { + unsigned char L; + unsigned char H; + } BYTE; +} gDAC; + +float gGLIDE[8]; +float gOSC_CV[8]; + +//------------------------------------------------------------- +// mbed Functions + +// TextLCD +TextLCD gLCD(p23, p24, p25, p26, p29, p30); // rs, e, d4-d7 + +// SPI +SPI gSPI(p11,p12,p13); +DigitalOut gCSA(p14); +DigitalOut gCSB(p22); + +// Sirial MIDI +//Serial gMIDI(p9,p10); + +// AnalogIn +AnalogIn gAIN1(p15); // VR1 +AnalogIn gAIN2(p16); // VR2 +AnalogIn gAIN3(p17); // VR3 +AnalogIn gAIN4(p18); // VR4 +AnalogIn gAIN5(p19); // IN1 +AnalogIn gAIN6(p20); // IN2 + +// BEEP +PwmOut gBEEP(p21); + +// LED +DigitalOut gLED1(LED1); +DigitalOut gLED2(LED2); +DigitalOut gLED3(LED3); +DigitalOut gLED4(LED4); +BusOut gLEDS(LED1,LED2,LED3,LED4); + +// Ticker +Ticker gTICKER; + +// Ethernet +EthernetNetIf gEth; +UDPSocket gUdp; + +//------------------------------------------------------------- +// main + +int main() { + + int i; + int pot[4],_pot[4]; + unsigned char ch = 0; + unsigned char mode = 7; // for Intialize + unsigned char edit[4]; + int val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Initialize + for( i=0; i<4; i++) { + pot[i] = _pot[i] = 0; + edit[i] = 0; + gGLIDE[i] = 1.0 / expf(val[i]*656.0/PARAM_GLIDE); + gGLIDE[i+4] = 1.0 / expf(val[i+4]*656.0/PARAM_GLIDE); + } + gSW = SW4; // for Intialize + + InitKamui(); + if(SetupEthNetIf() == -1) + { + gBEEP.write(0.5); + wait(1); + gBEEP.write(0.0); + return -1; + } + + // loop + while(1) { + + // Ethernet Polling + Net::poll(); + + // Read pot + pot[0] = gAIN1.read_u16(); + pot[1] = gAIN2.read_u16(); + pot[2] = gAIN3.read_u16(); + pot[3] = gAIN4.read_u16(); + + // change pot amount? + if(abs(pot[ch] - _pot[ch]) > 0x2000) edit[ch] = 1; + + if(edit[ch]) { + switch(mode) { + case 0: + gGLIDE[ch] = 1.0 / expf(pot[ch]/PARAM_GLIDE); + val[ch] = pot[ch] / 656; + break; + case 1: + gGLIDE[ch+4] = 1.0 / expf(pot[ch]/PARAM_GLIDE); + val[ch+4] = pot[ch] / 656; + break; + default: + break; + } + } + + // Push Mode SW + if(gSW & SW4) { + mode++; + mode &= 0x01; + for( i=0; i<4; i++) { + _pot[i] = pot[i]; + edit[i] = 0; + } + } + gSW = 0; + + // LCD Display + gLCD.locate( 0, 1 ); + switch(mode) { + case 0: + gLCD.printf("G1-4 %02d %02d %02d %02d", + val[0], val[1], val[2], val[3]); + break; + case 1: + gLCD.printf("G5-8 %02d %02d %02d %02d", + val[4], val[5], val[6], val[7]); + break; + } + + ch++; + ch &= 0x03; + } +} + +//------------------------------------------------------------- +// Initialize KAMUI + +void InitKamui() +{ + // Init. Variables + for( int i=0; i<8; i++) { + gCV[i] = 0x8000; + } + gGATE = 0; + gSYNC = 0; + + gUpdateMode = UPDATE_MODE0; + + // Init. SPI + gCSA = _DISABLE; + gCSB = _DISABLE; + gSPI.format(8,0); + gSPI.frequency(SPI_RATE); + + // Init. Serial MIDI +// gMIDI.baud(MIDI_RATE); + + // Ticker + gTICKER.attach_us(&UpdateCV, UPDATE_INTERVAL); + + // Beep + gBEEP.period(1.0/BEEP_FREQ); + gBEEP.write(0.5); + wait(0.2); + gBEEP.write(0.0); + + // Init Display + gLCD.locate( 0, 0 ); + // 123456789ABCDEF + gLCD.printf("OSC-CV Example "); +} + +//------------------------------------------------------------- +// Update CV, GATE, SYNC + +void UpdateCV() +{ + unsigned char rcv,ch; + unsigned char ptn[] = { 0,1,6,7,2,3,6,7,4,5,6,7 }; + const int numptn = (sizeof ptn / sizeof ptn[0]) - 1; + static unsigned char cnt; + + __disable_irq(); + + // SET DAC + ch = ptn[cnt]; + if(gUpdateMode) ch |= 0x06; + +#ifdef AD5551 // 14bitDAC + gDAC.WORD = gCV[ch] >> 2; +#else + gDAC.WORD = gCV[ch]; +#endif + + gCSA = _ENABLE; + gSPI.write(gDAC.BYTE.H); + gSPI.write(gDAC.BYTE.L); + gCSA = _DISABLE; + + // GATE or SYNC OUT + if(cnt & 0x01) { + // GATE OUT + gCSB = _ENABLE; + rcv = gSPI.write(gGATE | MODE_GATE) & 0x0F; + gCSB = _DISABLE; + } + else { + // SYNC OUT + gCSB = _ENABLE; + rcv = gSPI.write(gSYNC | MODE_SYNC); + gCSB = _DISABLE; + } + + // SEL CV CHANNEL + gCSB = _ENABLE; + gSPI.write(ch); + gCSB = _DISABLE; + + cnt < numptn ? cnt++ : cnt = 0; + + __enable_irq(); + + gSW |= CheckSW(rcv); + SetCV(); +} + +//------------------------------------------------------------- +// Check SW + +unsigned char CheckSW(unsigned char c) { + + static unsigned char swbuf[2]; + static unsigned int cntsw; + unsigned char ret = 0; + + if(cntsw > SW_WATCH_INTERVAL) { + if(c &= 0x0F) { + if(!swbuf[1]) { + if( swbuf[0] == c) { + swbuf[1] = c; + ret = c; + } + else { + swbuf[0] = c; + } + } + } + else { + swbuf[1] = 0; + swbuf[0] = 0; + } + cntsw = 0; + } + cntsw++; + return ret; +} + +//------------------------------------------------------------- +// Set CV + +void SetCV() +{ + static unsigned char ch; + static float cvf[8]; + unsigned int cv; + + // Calculate CV + cvf[ch] = (gOSC_CV[ch] - cvf[ch]) * gGLIDE[ch] + cvf[ch]; + cv = (unsigned int)cvf[ch] + 0x8000; + if(cv > 0xFFFF) cv = 0xFFFF; + gCV[ch] = cv; + + ch++; + ch &= 0x07; +} + +//------------------------------------------------------------- +// Setup Ethernet port + +int SetupEthNetIf() +{ + gLCD.locate( 0, 1 ); + gLCD.printf("Setting up... "); +// printf("Setting up...\r\n"); + + EthernetErr ethErr = gEth.setup(); + if(ethErr) + { + gLCD.locate( 0, 1 ); + gLCD.printf("Error in setup."); +// printf("Error %d in setup.\r\n", ethErr); + return -1; + } +// printf("Setup OK\r\n"); + +// printf("IP address %d.%d.%d.%d\r\n", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]); + Host broadcast(IpAddr(gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], 255), 12345, NULL); + gUdp.setOnEvent(&onUDPSocketEvent); + gUdp.bind(broadcast); + + gLCD.locate( 0, 1 ); + gLCD.printf("%03d.%03d.%03d.%03d", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]); + wait(2.0); + + return 0; +} + +//------------------------------------------------------------- +// Handller receive UDP Packet + +void onUDPSocketEvent(UDPSocketEvent e) +{ + union OSCarg msg[10]; + int num; + + switch(e) + { + case UDPSOCKET_READABLE: //The only event for now + char buf[256] = {0}; + Host host; + + while( int len = gUdp.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); +// printf("OSCmsg: %s %s %f %i\r\n", +// msg[0].address, msg[1].typeTag, msg[2].f, msg[2].i); + + len = strlen(msg[0].address); + if(isdigit(msg[0].address[len-1])) num = msg[0].address[len-1] - '0' - 1; + else num = -1; + + // address pattern CV + if((strncmp(msg[0].address,"/kamui/cv",9)==0) && (num != -1)) { + + if(num > 7) break; + if(msg[1].typeTag[1] == 'f') gOSC_CV[num] = msg[2].f * 3072.0; + if(msg[1].typeTag[1] == 'i') gOSC_CV[num] = msg[2].i * 3072.0; + + break; + } + + // address pattern GATE + if((strncmp(msg[0].address,"/kamui/gate",11)==0) && (num != -1)) { + + if(num > 3) break; + if(msg[2].i) gGATE |= (0x01 << num); + else gGATE &= ~(0x01 << num); + + break; + } + + // printf("undefined OSCmsg:%s %s\r\n",msg[0].address, msg[1].typeTag); + } + break; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun May 06 07:17:59 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479