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
--- /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