MIDIoIP test This test program controls blinking of Four LEDs by Knob#1/slider#1/key of KORG nano Kontrol/Key, and needs midi_bridge.c on linux to transfer MIDI data to mbed (over PC-serial or IP packet)
Dependencies: EthernetNetIf mbed
Revision 0:189db48772ae, committed 2010-09-20
- Comitter:
- xshige
- Date:
- Mon Sep 20 13:18:42 2010 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 189db48772ae EthernetNetIf.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetNetIf.lib Mon Sep 20 13:18:42 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
diff -r 000000000000 -r 189db48772ae main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Sep 20 13:18:42 2010 +0000 @@ -0,0 +1,508 @@ + +// MIDI over IP/serial test (MIDIoIP_test) + +// This test program controls blinking of Four LEDs +// by Knob#1/slider#1/key of KORG nano Kontrol/Key, +// and needs midi_bridge.c on linux to trasfer MIDI data +// to mbed (over PC-serial or IP packet) +// +// Note: +// midi_bridge.c is included in this file as comment. +// + +// written by: xshige +// 2010/9/20 + + +//#define SERIAL_MIDI // get MIDI data from PC serial +#define UDP_MIDI // get MIDI data from IP packet(UDP) + +#include "mbed.h" +#include "EthernetNetIf.h" +#include "UDPSocket.h" + +EthernetNetIf eth; +#if 0 +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 + +UDPSocket udp; + + +//------------------------------------------------- + +class RingBuffer +{ + protected: + unsigned char *buffer; + int buffersize; + int rp; // read index + int wp; // write index + int num; // how many bytes you have in buffer + + public: + RingBuffer(int bufsiz) + { + buffersize = bufsiz; + + buffer = new unsigned char[buffersize]; + // memset(buffer, 0, sizeof(char) * buffersize); + + // reset pointer to make empty + rp = 0; + wp = 0; + // zero byte in buffer + num = 0; + }; + + ~RingBuffer(void) + { + delete[] buffer; + }; + + int GetByte(unsigned char *cp); + int PutByte(unsigned char c); + int IsEmpty(void); + int IsNumBytes(void); +}; + + +int RingBuffer::GetByte(unsigned char *cp ) +{ + if( rp != wp ) { // not empty + *cp = buffer[rp]; + rp = (rp + 1) % buffersize; + num--; + return 0; + } else { // empty + num = 0; + return -1; + } +} + + +int RingBuffer::PutByte(unsigned char c ) +{ + int next = (wp + 1) % buffersize; + if( next == rp ) { + printf("*** Buffer Full ***\r\n" ); +// printf("*");//debug + return -1; + } + buffer[wp] = c; + wp = next; + num++; + return 0; +} + + +int RingBuffer::IsEmpty(void) +{ + return (rp==wp)?(true):(false); +} + +int RingBuffer::IsNumBytes(void) +{ + return num; +} + +//----------------- + +// create RingBuffer +RingBuffer UDPbuf(64); + +void onUDPSocketEvent(UDPSocketEvent e) +{ + switch(e) + { + case UDPSOCKET_READABLE: //The only event for now + char buf[64] = {0}; + Host host; + while( int len = udp.recvfrom( buf, 63, &host ) ) + { + if( len <= 0 ) break; + for(int i=0;i<len;i++) { + UDPbuf.PutByte(buf[i]); + } +// printf("\r\nFrom %d.%d.%d.%d\r\n", +// host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]); //debug +// printf("len:%d\r\n",len); // debug + } + break; + } +} + +DigitalOut led1(LED1, "led1"); +DigitalOut led2(LED2, "led2"); +DigitalOut led3(LED3, "led3"); +DigitalOut led4(LED4, "led4"); + +BusOut myleds(LED1, LED2, LED3, LED4); + +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"); + +//Host broadcast(IpAddr(192, 168, 0,255), 12345, NULL); // local broadcast over router +//Host multicast(IpAddr(239, 192, 1, 100), 50000, NULL); // Join multicast group on port 50000 +Host broadcast(IpAddr(255, 255, 255,255), 8888, NULL); // broadcast in a router + + udp.setOnEvent(&onUDPSocketEvent); + + udp.bind(broadcast); + + Timer tmr; + tmr.start(); + +#ifdef SERIAL_MIDI + printf("Serial MIDI enable\r\n"); +#else + printf("Serial MIDI disable\r\n"); +#endif + + +#ifdef UDP_MIDI + printf("IP MIDI enable\r\n"); +#else + printf("IP MIDI disable\r\n"); +#endif + + + while(true) + { + Net::poll(); + int velocity,MIDIch,pitch; + // +#ifdef SERIAL_MIDI + if(pc.readable()) { + int c; + c=pc.getc(); // get 1st byte + printf("Received:%02X\r\n",c); + MIDIch=c&0x0F; + c=c&0xF0; + if (0xB0==c) { + c=pc.getc(); + printf("Received:%02X\r\n",c); + if (0x0E==c) { // Knob#1 on KORG Kontrol (SCENE#1) + c=pc.getc(); // get volume + printf("Received:%02X\r\n",c); + // MIDI controls LEDs + myleds=(15*c)/127; + } + if (0x02==c) { // Slider#1 on KORG Kontrol (SCENE#1) + c=pc.getc(); // get volume + printf("Received:%02X\r\n",c); + // MIDI controls LEDs + myleds=(15*c)/127; + } + } // if (0xB0==c) + if (0x90==c) { // Note On + c=pc.getc(); // get Note# + printf("Received:%02X\r\n",c); + // Note# controls LEDs + myleds=(c%0x10); + c=pc.getc(); // get Velocity + printf("Received:%02X\r\n",c); + velocity=c; + } + if (0x80==c) { // Note Off + c=pc.getc(); // get Note# + printf("Received:%02X\r\n",c); + // Note# controls LEDs + myleds=(c%0x10); + c=pc.getc(); // get Velocity + printf("Received:%02X\r\n",c); + // Velocity(at Note On) controls LEDs + myleds=(15*velocity)/127; + } + if (0xE0==c) { // Pich Bend + c=pc.getc(); // get LSB + printf("Received:%02X\r\n",c); + if (0xE0==c) c=pc.getc(); // re-get for error recover + pitch=(c&0x7F); + c=pc.getc(); // get MSB + printf("Received:%02X\r\n",c); + pitch+=((c&0x7F)<<7);pitch-=8192; + printf("Pitch Bend:%d\r\n",pitch); + + } + } // pc.readable +#endif // ifdef SERIAL_MIDI +#ifdef UDP_MIDI + // get MIDI data in UDP packet + if(UDPbuf.IsNumBytes()>3) { + unsigned char uc; + UDPbuf.GetByte(&uc); // get 1st byte + printf("\r\nFrom Net:%02X\r\n",uc); + MIDIch=uc&0x0F; + uc=uc&0xF0; + if (0xB0==uc) { + UDPbuf.GetByte(&uc); + if (0xB0==uc) UDPbuf.GetByte(&uc); // re-get for error recover + printf("From Net:%02X\r\n",uc); + if (0x0E==uc) { // Knob#1 on KORG Kontrol (SCENE#1) + UDPbuf.GetByte(&uc); // get volume + printf("From Net:%02X\r\n",uc); + // MIDI controls LEDs + myleds=(15*uc)/127; + } + if (0x02==uc) { // Slider#1 on KORG Kontrol (SCENE#1) + UDPbuf.GetByte(&uc); // get volume + printf("From Net:%02X\r\n",uc); + // MIDI controls LEDs + myleds=(15*uc)/127; + } + } // if (0xB0==uc) + if (0x90==uc) { // Note On + UDPbuf.GetByte(&uc); // get Note# + printf("From Net:%02X\r\n",uc); + // Note# controls LEDs + myleds=(uc%0x10); + UDPbuf.GetByte(&uc); // get Velocity + printf("From Net:%02X\r\n",uc); + velocity=uc; + } + if (0x80==uc) { // Note Off + UDPbuf.GetByte(&uc); // get Note# + printf("From Net:%02X\r\n",uc); + // Note# controls LEDs + myleds=(uc%0x10); + UDPbuf.GetByte(&uc); // get Velocity + printf("From Net:%02X\r\n",uc); + // Velocity(at Note On) controls LEDs + myleds=(15*velocity)/127; + } + if (0xE0==uc) { // Pich Bend + UDPbuf.GetByte(&uc); // get LSB + if (0xE0==uc) UDPbuf.GetByte(&uc); // re-get for error recover + printf("From Net:%02X\r\n",uc); + pitch=(uc&0x7F); + UDPbuf.GetByte(&uc); // get MSB + printf("From Net:%02X\r\n",uc); + pitch+=((uc&0x7F)<<7);pitch-=8192; + printf("Pitch Bend From Net:%d\r\n",pitch); + } + } // if !UDPbuf.IsNumBytes() +#endif // ifdef UDP_MIDI +// + if(tmr.read() > 0.5) { + tmr.reset(); + + // blink to indicate alive + led1=!led1; + } + } // while(true) +} + +//--------------------------------------------------------------------------- +#if 0 +/* +midi_bridge.c + +How to Compile: +gcc midi_bridge.c -o midi_bridge + +How to execute(on linux): +<connet USB-MIDI devices and mbed USB to PC> +midi_bridge[Enter] +init serial between mbed and PC +init serial for USB-MIDI +Connected on /dev/mid2 +Connected on /dev/mid3 +Setting up... +[..\fwk\if\eth\EthernetNetIf.cpp:setup@86] HW Addr is : 00:02:f7:f0:4f:9d. +[..\fwk\if\eth\EthernetNetIf.cpp:setup@99] DHCP Started, waiting for IP... +[..\fwk\if\eth\EthernetNetIf.cpp:setup@142] Connected, IP : 192.168.0.2 +Setup OK +Serial MIDI disable +IP MIDI enable +<move knob#1> +B0 +0E +35 + +From Net:B0 +From Net:0E +From Net:36 +B0 +0E +34 + +From Net:B0 +From Net:0E +From Net:35 +.... + +*/ + + +//---- + +// MIDI bridge among USB-MIDI, PC-serial, and IP-packet +// +// written by:xshige + +// v0.5 2010/9/18 +// (implemented path: USB-MIDI to PC-serial, USB-MIDI to IP-packet) + +#include <stdio.h> +#include <stdlib.h> + +//#include <io.h> +#include <fcntl.h> + +#include <unistd.h> +#include <termios.h> +#include <signal.h> +#include <errno.h> + +// socket +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + + +#define max(a,b) ((a) > (b) ? (a) : (b)) + +int main(void) +{ + // init socket + int sock; + struct sockaddr_in addr; + int yes = 1; + sock = socket(AF_INET, SOCK_DGRAM, 0); + addr.sin_family = AF_INET; +// ******* IP setup ******* + addr.sin_port = htons(8888); // port# +//addr.sin_port = htons(50000); // port# +//addr.sin_addr.s_addr = inet_addr("239.192.1.100"); //Join multicast group on port 50000 + addr.sin_addr.s_addr = inet_addr("255.255.255.255"); // broadcast in a router +//addr.sin_addr.s_addr = inet_addr("192.168.0.255"); // local broadcast over routers +//memo: multicast IP 224.0.0.1 hosts in the subnet +// ************************* + // + setsockopt(sock, + SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes)); + + // *** serial for mbed *** + printf("init serial between mbed and PC\n"); + struct termios options; + int fdt=open("/dev/ttyACM0",O_RDWR|O_NOCTTY|O_NONBLOCK); + if (fdt == -1) { + perror("open_port: Unable to open port between mbed and PC - "); + } + // Get the current options for the port... + tcgetattr(fdt, &options); + // Set the baud rates to 1115200 bps for mbed + cfsetispeed(&options, B115200); + cfsetospeed(&options, B115200); + // No parity (8N1) + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + // Set the new options for the port... + tcsetattr(fdt, TCSANOW, &options); + + // *** serial for MIDI *** + printf("init serial for USB-MIDI\n"); + int fdm2=open("/dev/midi2", O_RDONLY|O_NONBLOCK); + int fdm3=open("/dev/midi3", O_RDONLY|O_NONBLOCK); + int fdm4=open("/dev/midi4", O_RDONLY|O_NONBLOCK); + if (fdm2 != -1) printf("Connected on /dev/mid2\n"); + if (fdm3 != -1) printf("Connected on /dev/mid3\n"); + if (fdm4 != -1) printf("Connected on /dev/mid4\n"); + + // Init FDs for Select + int maxfd=-1; + fd_set fds,readfds; + struct timeval timeout; + // Init the read FD set + FD_ZERO(&readfds); + FD_SET(fdt, &readfds); + if (fdm2 != -1) FD_SET(fdm2, &readfds); + if (fdm3 != -1) FD_SET(fdm3, &readfds); + if (fdm4 != -1) FD_SET(fdm4, &readfds); + // get max fd + maxfd=max(maxfd,fdt); + if (fdm2 != -1) maxfd=max(maxfd,fdm2); + if (fdm3 != -1) maxfd=max(maxfd,fdm3); + if (fdm4 != -1) maxfd=max(maxfd,fdm4); + maxfd=maxfd+1; +// printf("FDs:%d %d %d %d\n",fdt,fdm2,fdm3,fdm4); // debug +// printf("maxfd:%d\n",maxfd); // debug + + unsigned char cs,cm; + while(1) { + // init FDs for the select at everytime + memcpy(&fds, &readfds, sizeof(fd_set)); + // Init the timeout structure + timeout.tv_sec = 3600; // set one hour for timeout + timeout.tv_usec = 0; + // Do the select + int n = select(maxfd, &fds, NULL, NULL, &timeout); + if (n == 0) { + puts("*** TIMEOUT *** "); + } else { + // + // for /dev/midi2 + if (fdm2 != -1) + if (FD_ISSET(fdm2,&fds)) if (read(fdm2,&cm,1) == 1) { + // readable + printf("%02X\n",cm); // display MIDI in HEX on console + write(fdt,&cm,1); // USB-MIDI to mbed + sendto(sock,&cm,1, // USB-MIDI to IP network + 0, (struct sockaddr *)&addr, sizeof(addr)); + } + // for /dev/midi3 + if (fdm3 != -1) + if (FD_ISSET(fdm3,&fds)) if (read(fdm3,&cm,1) == 1) { + // readable + printf("%02X\n",cm); // display MIDI in HEX on console + write(fdt,&cm,1); // USB-MIDI to mbed + sendto(sock,&cm,1, // USB-MIDI to IP network + 0, (struct sockaddr *)&addr, sizeof(addr)); + + + } + // for /dev/midi4 + if (fdm4 != -1) + if (FD_ISSET(fdm4,&fds)) if (read(fdm4,&cm,1) == 1) { + // readable + printf("%02X\n",cm); // display MIDI in HEX on console + write(fdt,&cm,1); // USB-MIDI to mbed + sendto(sock,&cm,1, // USB-MIDI to IP network + 0, (struct sockaddr *)&addr, sizeof(addr)); + + + } + // for /dev/ttyACM0 + if (FD_ISSET(fdt,&fds)) if (read(fdt,&cs,1) == 1) { + // readable on mbed + putchar(cs); // display to console + //write(fdm2,&cs,1); // mbed to USB-MIDI + } + }// if else + + } // while +} +#endif
diff -r 000000000000 -r 189db48772ae mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Sep 20 13:18:42 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e