Peter Barrett氏のBlueUSBにMIDI USB HOST機能を加えたサンプルプログラムです。KORG nanoKEYなどのUSB MIDIストリームをシリアルMIDI(Serial TX p9)にブリッジします。動作確認はKORG nanoKEY、AKAI LPK-25、EDIROL PC-50のみです。

Dependencies:   mbed

Revision:
0:79620c558b0c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MidiUSB.cpp	Fri May 11 10:05:40 2012 +0000
@@ -0,0 +1,136 @@
+
+/*
+Copyright (c) 2012 RadioJunkBox
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "mbed.h"
+#include "USBHost.h"
+#include "Utils.h"
+
+#define MIDIEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
+u8 ms_buf[255];  // MIDI Streaming Buffer
+
+// Ring Buffer
+#define         BUFSIZE             32      // size of ring buffer (ex 4,8,16,32...)
+int             gPtr_buf_in, gPtr_buf_out;
+unsigned char   gRxBuf[BUFSIZE];
+
+// Serial MIDI Port
+#define         MIDI_RATE           31250   // 31.25kbps
+Serial          gMIDI(p9,p10);
+Ticker          gTickerMIDI;
+
+// Transmit to Serial MIDI Port
+void TxSerialMidi()
+{
+    unsigned char rb;
+
+    // ring buffer empty?
+    if(gPtr_buf_in != gPtr_buf_out)
+    {
+        // get 1byte from ring buffer
+        gPtr_buf_out++;
+        gPtr_buf_out &= (BUFSIZE - 1);
+        rb = gRxBuf[gPtr_buf_out];
+        gMIDI.putc(rb);
+    }      
+}
+
+// Intialize Serial MIDI Port  
+void InitSerialMIDI()
+{
+    gPtr_buf_in = gPtr_buf_out = 0;
+    gMIDI.baud(MIDI_RATE);
+    gTickerMIDI.attach_us(&TxSerialMidi, 500);  // 500us
+}
+
+//  Received MIDI Steram
+void MidiEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
+{
+    int i;
+    int ptr = 0;
+
+    while((data[ptr] != 0) && (ptr < len))
+    {        
+        // printf("MIDI %02X %02X %02X",device,status,len);
+        // printfBytes("",data,4);
+        for( i = 1; i<4; i++)
+        {
+            gPtr_buf_in++;
+            gPtr_buf_in &= (BUFSIZE - 1);
+            gRxBuf[gPtr_buf_in] = data[ptr+i];
+        }
+        ptr+=4;
+    }
+    USBBulkTransfer(device,endpoint,data,len,MidiEventCallback,userData);
+}
+
+//  Add MIDI Interface
+void AddMidiInterface(int device, InterfaceDescriptor* id, EndpointDescriptor* ed,int len)
+{
+    if ((ed->bmAttributes & 3) != ENDPOINT_BULK || !(ed->bEndpointAddress & 0x80))
+        return;
+    
+    // Make bulk enpoints for MIDI devices
+    u32 evt = MIDIEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol);
+    u8* dst = ms_buf;
+
+    if(dst)
+    {
+        // printf("Add Midi Interface %02X %08X\r\n",ed->bEndpointAddress,evt);
+        USBBulkTransfer(device,ed->bEndpointAddress,dst,len,MidiEventCallback,(void*)evt);
+    }
+}
+
+//  Detected Midi Device
+int OnMidiInsert(int device)
+{
+    u8 buffer[255];
+    int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
+    if (err < 0)
+        return err;
+
+    int len = buffer[2] | (buffer[3] << 8);
+    u8* d = buffer;
+    u8* end = d + len;
+
+    // printf("OnMidiInsert %02X %02X\r\n",device,len);
+
+    while (d < end)
+    {
+        if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
+        {
+            InterfaceDescriptor* id = (InterfaceDescriptor*)d;
+            d += d[0];
+            while (d < end)
+            {
+                    if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
+                    {
+                        // printfBytes("MIDI Endpoint",d,d[0]);
+                        AddMidiInterface(device,id,(EndpointDescriptor*)d,d[4]);
+                    }
+                    d += d[0];
+            }
+        }
+        d += d[0];
+    }
+    return 0;
+}