Peter Barrett氏のBlueUSBにMIDI USB HOST機能を加えたサンプルプログラムです。KORG nanoKEYなどのUSB MIDIストリームをシリアルMIDI(Serial TX p9)にブリッジします。動作確認はKORG nanoKEY、AKAI LPK-25、EDIROL PC-50のみです。
MidiUSB.cpp
00001 00002 /* 00003 Copyright (c) 2012 RadioJunkBox 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "mbed.h" 00025 #include "USBHost.h" 00026 #include "Utils.h" 00027 00028 #define MIDIEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol) 00029 u8 ms_buf[255]; // MIDI Streaming Buffer 00030 00031 // Ring Buffer 00032 #define BUFSIZE 32 // size of ring buffer (ex 4,8,16,32...) 00033 int gPtr_buf_in, gPtr_buf_out; 00034 unsigned char gRxBuf[BUFSIZE]; 00035 00036 // Serial MIDI Port 00037 #define MIDI_RATE 31250 // 31.25kbps 00038 Serial gMIDI(p9,p10); 00039 Ticker gTickerMIDI; 00040 00041 // Transmit to Serial MIDI Port 00042 void TxSerialMidi() 00043 { 00044 unsigned char rb; 00045 00046 // ring buffer empty? 00047 if(gPtr_buf_in != gPtr_buf_out) 00048 { 00049 // get 1byte from ring buffer 00050 gPtr_buf_out++; 00051 gPtr_buf_out &= (BUFSIZE - 1); 00052 rb = gRxBuf[gPtr_buf_out]; 00053 gMIDI.putc(rb); 00054 } 00055 } 00056 00057 // Intialize Serial MIDI Port 00058 void InitSerialMIDI() 00059 { 00060 gPtr_buf_in = gPtr_buf_out = 0; 00061 gMIDI.baud(MIDI_RATE); 00062 gTickerMIDI.attach_us(&TxSerialMidi, 500); // 500us 00063 } 00064 00065 // Received MIDI Steram 00066 void MidiEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData) 00067 { 00068 int i; 00069 int ptr = 0; 00070 00071 while((data[ptr] != 0) && (ptr < len)) 00072 { 00073 // printf("MIDI %02X %02X %02X",device,status,len); 00074 // printfBytes("",data,4); 00075 for( i = 1; i<4; i++) 00076 { 00077 gPtr_buf_in++; 00078 gPtr_buf_in &= (BUFSIZE - 1); 00079 gRxBuf[gPtr_buf_in] = data[ptr+i]; 00080 } 00081 ptr+=4; 00082 } 00083 USBBulkTransfer(device,endpoint,data,len,MidiEventCallback,userData); 00084 } 00085 00086 // Add MIDI Interface 00087 void AddMidiInterface(int device, InterfaceDescriptor* id, EndpointDescriptor* ed,int len) 00088 { 00089 if ((ed->bmAttributes & 3) != ENDPOINT_BULK || !(ed->bEndpointAddress & 0x80)) 00090 return; 00091 00092 // Make bulk enpoints for MIDI devices 00093 u32 evt = MIDIEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol); 00094 u8* dst = ms_buf; 00095 00096 if(dst) 00097 { 00098 // printf("Add Midi Interface %02X %08X\r\n",ed->bEndpointAddress,evt); 00099 USBBulkTransfer(device,ed->bEndpointAddress,dst,len,MidiEventCallback,(void*)evt); 00100 } 00101 } 00102 00103 // Detected Midi Device 00104 int OnMidiInsert(int device) 00105 { 00106 u8 buffer[255]; 00107 int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255); 00108 if (err < 0) 00109 return err; 00110 00111 int len = buffer[2] | (buffer[3] << 8); 00112 u8* d = buffer; 00113 u8* end = d + len; 00114 00115 // printf("OnMidiInsert %02X %02X\r\n",device,len); 00116 00117 while (d < end) 00118 { 00119 if (d[1] == DESCRIPTOR_TYPE_INTERFACE) 00120 { 00121 InterfaceDescriptor* id = (InterfaceDescriptor*)d; 00122 d += d[0]; 00123 while (d < end) 00124 { 00125 if (d[1] == DESCRIPTOR_TYPE_ENDPOINT) 00126 { 00127 // printfBytes("MIDI Endpoint",d,d[0]); 00128 AddMidiInterface(device,id,(EndpointDescriptor*)d,d[4]); 00129 } 00130 d += d[0]; 00131 } 00132 } 00133 d += d[0]; 00134 } 00135 return 0; 00136 }
Generated on Wed Jul 13 2022 17:48:05 by
1.7.2