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

Dependencies:   mbed

Committer:
radiojunkbox
Date:
Fri May 11 10:05:40 2012 +0000
Revision:
0:79620c558b0c
Rev. 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
radiojunkbox 0:79620c558b0c 1
radiojunkbox 0:79620c558b0c 2 /*
radiojunkbox 0:79620c558b0c 3 Copyright (c) 2012 RadioJunkBox
radiojunkbox 0:79620c558b0c 4
radiojunkbox 0:79620c558b0c 5 Permission is hereby granted, free of charge, to any person obtaining a copy
radiojunkbox 0:79620c558b0c 6 of this software and associated documentation files (the "Software"), to deal
radiojunkbox 0:79620c558b0c 7 in the Software without restriction, including without limitation the rights
radiojunkbox 0:79620c558b0c 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
radiojunkbox 0:79620c558b0c 9 copies of the Software, and to permit persons to whom the Software is
radiojunkbox 0:79620c558b0c 10 furnished to do so, subject to the following conditions:
radiojunkbox 0:79620c558b0c 11
radiojunkbox 0:79620c558b0c 12 The above copyright notice and this permission notice shall be included in
radiojunkbox 0:79620c558b0c 13 all copies or substantial portions of the Software.
radiojunkbox 0:79620c558b0c 14
radiojunkbox 0:79620c558b0c 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
radiojunkbox 0:79620c558b0c 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
radiojunkbox 0:79620c558b0c 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
radiojunkbox 0:79620c558b0c 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
radiojunkbox 0:79620c558b0c 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
radiojunkbox 0:79620c558b0c 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
radiojunkbox 0:79620c558b0c 21 THE SOFTWARE.
radiojunkbox 0:79620c558b0c 22 */
radiojunkbox 0:79620c558b0c 23
radiojunkbox 0:79620c558b0c 24 #include "mbed.h"
radiojunkbox 0:79620c558b0c 25 #include "USBHost.h"
radiojunkbox 0:79620c558b0c 26 #include "Utils.h"
radiojunkbox 0:79620c558b0c 27
radiojunkbox 0:79620c558b0c 28 #define MIDIEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
radiojunkbox 0:79620c558b0c 29 u8 ms_buf[255]; // MIDI Streaming Buffer
radiojunkbox 0:79620c558b0c 30
radiojunkbox 0:79620c558b0c 31 // Ring Buffer
radiojunkbox 0:79620c558b0c 32 #define BUFSIZE 32 // size of ring buffer (ex 4,8,16,32...)
radiojunkbox 0:79620c558b0c 33 int gPtr_buf_in, gPtr_buf_out;
radiojunkbox 0:79620c558b0c 34 unsigned char gRxBuf[BUFSIZE];
radiojunkbox 0:79620c558b0c 35
radiojunkbox 0:79620c558b0c 36 // Serial MIDI Port
radiojunkbox 0:79620c558b0c 37 #define MIDI_RATE 31250 // 31.25kbps
radiojunkbox 0:79620c558b0c 38 Serial gMIDI(p9,p10);
radiojunkbox 0:79620c558b0c 39 Ticker gTickerMIDI;
radiojunkbox 0:79620c558b0c 40
radiojunkbox 0:79620c558b0c 41 // Transmit to Serial MIDI Port
radiojunkbox 0:79620c558b0c 42 void TxSerialMidi()
radiojunkbox 0:79620c558b0c 43 {
radiojunkbox 0:79620c558b0c 44 unsigned char rb;
radiojunkbox 0:79620c558b0c 45
radiojunkbox 0:79620c558b0c 46 // ring buffer empty?
radiojunkbox 0:79620c558b0c 47 if(gPtr_buf_in != gPtr_buf_out)
radiojunkbox 0:79620c558b0c 48 {
radiojunkbox 0:79620c558b0c 49 // get 1byte from ring buffer
radiojunkbox 0:79620c558b0c 50 gPtr_buf_out++;
radiojunkbox 0:79620c558b0c 51 gPtr_buf_out &= (BUFSIZE - 1);
radiojunkbox 0:79620c558b0c 52 rb = gRxBuf[gPtr_buf_out];
radiojunkbox 0:79620c558b0c 53 gMIDI.putc(rb);
radiojunkbox 0:79620c558b0c 54 }
radiojunkbox 0:79620c558b0c 55 }
radiojunkbox 0:79620c558b0c 56
radiojunkbox 0:79620c558b0c 57 // Intialize Serial MIDI Port
radiojunkbox 0:79620c558b0c 58 void InitSerialMIDI()
radiojunkbox 0:79620c558b0c 59 {
radiojunkbox 0:79620c558b0c 60 gPtr_buf_in = gPtr_buf_out = 0;
radiojunkbox 0:79620c558b0c 61 gMIDI.baud(MIDI_RATE);
radiojunkbox 0:79620c558b0c 62 gTickerMIDI.attach_us(&TxSerialMidi, 500); // 500us
radiojunkbox 0:79620c558b0c 63 }
radiojunkbox 0:79620c558b0c 64
radiojunkbox 0:79620c558b0c 65 // Received MIDI Steram
radiojunkbox 0:79620c558b0c 66 void MidiEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
radiojunkbox 0:79620c558b0c 67 {
radiojunkbox 0:79620c558b0c 68 int i;
radiojunkbox 0:79620c558b0c 69 int ptr = 0;
radiojunkbox 0:79620c558b0c 70
radiojunkbox 0:79620c558b0c 71 while((data[ptr] != 0) && (ptr < len))
radiojunkbox 0:79620c558b0c 72 {
radiojunkbox 0:79620c558b0c 73 // printf("MIDI %02X %02X %02X",device,status,len);
radiojunkbox 0:79620c558b0c 74 // printfBytes("",data,4);
radiojunkbox 0:79620c558b0c 75 for( i = 1; i<4; i++)
radiojunkbox 0:79620c558b0c 76 {
radiojunkbox 0:79620c558b0c 77 gPtr_buf_in++;
radiojunkbox 0:79620c558b0c 78 gPtr_buf_in &= (BUFSIZE - 1);
radiojunkbox 0:79620c558b0c 79 gRxBuf[gPtr_buf_in] = data[ptr+i];
radiojunkbox 0:79620c558b0c 80 }
radiojunkbox 0:79620c558b0c 81 ptr+=4;
radiojunkbox 0:79620c558b0c 82 }
radiojunkbox 0:79620c558b0c 83 USBBulkTransfer(device,endpoint,data,len,MidiEventCallback,userData);
radiojunkbox 0:79620c558b0c 84 }
radiojunkbox 0:79620c558b0c 85
radiojunkbox 0:79620c558b0c 86 // Add MIDI Interface
radiojunkbox 0:79620c558b0c 87 void AddMidiInterface(int device, InterfaceDescriptor* id, EndpointDescriptor* ed,int len)
radiojunkbox 0:79620c558b0c 88 {
radiojunkbox 0:79620c558b0c 89 if ((ed->bmAttributes & 3) != ENDPOINT_BULK || !(ed->bEndpointAddress & 0x80))
radiojunkbox 0:79620c558b0c 90 return;
radiojunkbox 0:79620c558b0c 91
radiojunkbox 0:79620c558b0c 92 // Make bulk enpoints for MIDI devices
radiojunkbox 0:79620c558b0c 93 u32 evt = MIDIEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol);
radiojunkbox 0:79620c558b0c 94 u8* dst = ms_buf;
radiojunkbox 0:79620c558b0c 95
radiojunkbox 0:79620c558b0c 96 if(dst)
radiojunkbox 0:79620c558b0c 97 {
radiojunkbox 0:79620c558b0c 98 // printf("Add Midi Interface %02X %08X\r\n",ed->bEndpointAddress,evt);
radiojunkbox 0:79620c558b0c 99 USBBulkTransfer(device,ed->bEndpointAddress,dst,len,MidiEventCallback,(void*)evt);
radiojunkbox 0:79620c558b0c 100 }
radiojunkbox 0:79620c558b0c 101 }
radiojunkbox 0:79620c558b0c 102
radiojunkbox 0:79620c558b0c 103 // Detected Midi Device
radiojunkbox 0:79620c558b0c 104 int OnMidiInsert(int device)
radiojunkbox 0:79620c558b0c 105 {
radiojunkbox 0:79620c558b0c 106 u8 buffer[255];
radiojunkbox 0:79620c558b0c 107 int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
radiojunkbox 0:79620c558b0c 108 if (err < 0)
radiojunkbox 0:79620c558b0c 109 return err;
radiojunkbox 0:79620c558b0c 110
radiojunkbox 0:79620c558b0c 111 int len = buffer[2] | (buffer[3] << 8);
radiojunkbox 0:79620c558b0c 112 u8* d = buffer;
radiojunkbox 0:79620c558b0c 113 u8* end = d + len;
radiojunkbox 0:79620c558b0c 114
radiojunkbox 0:79620c558b0c 115 // printf("OnMidiInsert %02X %02X\r\n",device,len);
radiojunkbox 0:79620c558b0c 116
radiojunkbox 0:79620c558b0c 117 while (d < end)
radiojunkbox 0:79620c558b0c 118 {
radiojunkbox 0:79620c558b0c 119 if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
radiojunkbox 0:79620c558b0c 120 {
radiojunkbox 0:79620c558b0c 121 InterfaceDescriptor* id = (InterfaceDescriptor*)d;
radiojunkbox 0:79620c558b0c 122 d += d[0];
radiojunkbox 0:79620c558b0c 123 while (d < end)
radiojunkbox 0:79620c558b0c 124 {
radiojunkbox 0:79620c558b0c 125 if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
radiojunkbox 0:79620c558b0c 126 {
radiojunkbox 0:79620c558b0c 127 // printfBytes("MIDI Endpoint",d,d[0]);
radiojunkbox 0:79620c558b0c 128 AddMidiInterface(device,id,(EndpointDescriptor*)d,d[4]);
radiojunkbox 0:79620c558b0c 129 }
radiojunkbox 0:79620c558b0c 130 d += d[0];
radiojunkbox 0:79620c558b0c 131 }
radiojunkbox 0:79620c558b0c 132 }
radiojunkbox 0:79620c558b0c 133 d += d[0];
radiojunkbox 0:79620c558b0c 134 }
radiojunkbox 0:79620c558b0c 135 return 0;
radiojunkbox 0:79620c558b0c 136 }