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

Files at this revision

API Documentation at this revision

Comitter:
xshige
Date:
Mon Sep 20 13:18:42 2010 +0000
Commit message:

Changed in this revision

EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /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
--- /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