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
main.cpp
- Committer:
- xshige
- Date:
- 2010-09-20
- Revision:
- 0:189db48772ae
File content as of revision 0:189db48772ae:
// 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