Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBMIDI.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 #include "USBMIDI.h" 00021 00022 00023 USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) 00024 : USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true) 00025 { 00026 midi_evt = NULL; 00027 USBDevice::connect(); 00028 } 00029 00030 // write plain MIDIMessage that will be converted to USBMidi event packet 00031 void USBMIDI::write(MIDIMessage m) { 00032 // first byte keeped for retro-compatibility 00033 for(int p=1; p < m.length; p+=3) { 00034 uint8_t buf[4]; 00035 // Midi message to USBMidi event packet 00036 buf[0]=m.data[1] >> 4; 00037 // SysEx 00038 if(buf[0] == 0xF) { 00039 if((m.length - p) > 3) { 00040 // SysEx start or continue 00041 buf[0]=0x4; 00042 } else { 00043 switch(m.length - p) { 00044 case 1: 00045 // SysEx end with one byte 00046 buf[0]=0x5; 00047 break; 00048 case 2: 00049 // SysEx end with two bytes 00050 buf[0]=0x6; 00051 break; 00052 case 3: 00053 // SysEx end with three bytes 00054 buf[0]=0x7; 00055 break; 00056 } 00057 } 00058 } 00059 buf[1]=m.data[p]; 00060 00061 if(p+1 < m.length) 00062 buf[2]=m.data[p+1]; 00063 else 00064 buf[2]=0; 00065 00066 if(p+2 < m.length) 00067 buf[3]=m.data[p+2]; 00068 else 00069 buf[3]=0; 00070 00071 USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK); 00072 } 00073 } 00074 00075 00076 void USBMIDI::attach(void (*fptr)(MIDIMessage)) { 00077 midi_evt = fptr; 00078 } 00079 00080 bool USBMIDI::EPBULK_OUT_callback() { 00081 uint8_t buf[64]; 00082 uint32_t len; 00083 readEP(EPBULK_OUT, buf, &len, 64); 00084 00085 if (midi_evt != NULL) { 00086 for (uint32_t i=0; i<len; i+=4) { 00087 uint8_t data_read; 00088 data_end=true; 00089 switch(buf[i]) { 00090 case 0x2: 00091 // Two-bytes System Common Message - undefined in USBMidi 1.0 00092 data_read=2; 00093 break; 00094 case 0x4: 00095 // SysEx start or continue 00096 data_end=false; 00097 data_read=3; 00098 break; 00099 case 0x5: 00100 // Single-byte System Common Message or SysEx end with one byte 00101 data_read=1; 00102 break; 00103 case 0x6: 00104 // SysEx end with two bytes 00105 data_read=2; 00106 break; 00107 case 0xC: 00108 // Program change 00109 data_read=2; 00110 break; 00111 case 0xD: 00112 // Channel pressure 00113 data_read=2; 00114 break; 00115 case 0xF: 00116 // Single byte 00117 data_read=1; 00118 break; 00119 default: 00120 // Others three-bytes messages 00121 data_read=3; 00122 break; 00123 } 00124 00125 for(uint8_t j=1;j<data_read+1;j++) { 00126 data[cur_data]=buf[i+j]; 00127 cur_data++; 00128 } 00129 00130 if(data_end) { 00131 midi_evt(MIDIMessage(data,cur_data)); 00132 cur_data=0; 00133 } 00134 } 00135 } 00136 00137 // We reactivate the endpoint to receive next characters 00138 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00139 return true; 00140 } 00141 00142 // Called in ISR context 00143 // Set configuration. Return false if the 00144 // configuration is not supported. 00145 bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) { 00146 if (configuration != DEFAULT_CONFIGURATION) { 00147 return false; 00148 } 00149 00150 // Configure endpoints > 0 00151 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); 00152 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00153 00154 // We activate the endpoint to be able to receive data 00155 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00156 return true; 00157 } 00158 00159 00160 const uint8_t * USBMIDI::stringIinterfaceDesc() { 00161 static const uint8_t stringIinterfaceDescriptor[] = { 00162 0x0c, //bLength 00163 STRING_DESCRIPTOR, //bDescriptorType 0x03 00164 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio 00165 }; 00166 return stringIinterfaceDescriptor; 00167 } 00168 00169 const uint8_t * USBMIDI::stringIproductDesc() { 00170 static const uint8_t stringIproductDescriptor[] = { 00171 0x16, //bLength 00172 STRING_DESCRIPTOR, //bDescriptorType 0x03 00173 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio 00174 }; 00175 return stringIproductDescriptor; 00176 } 00177 00178 00179 const uint8_t * USBMIDI::configurationDesc() { 00180 static const uint8_t configDescriptor[] = { 00181 // configuration descriptor 00182 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, 00183 00184 // The Audio Interface Collection 00185 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor 00186 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor 00187 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors 00188 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor 00189 00190 // MIDI IN JACKS 00191 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, 00192 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, 00193 00194 // MIDI OUT JACKS 00195 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 00196 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00, 00197 00198 // OUT endpoint descriptor 00199 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 00200 0x05, 0x25, 0x01, 0x01, 0x01, 00201 00202 // IN endpoint descriptor 00203 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 00204 0x05, 0x25, 0x01, 0x01, 0x03, 00205 }; 00206 return configDescriptor; 00207 }
Generated on Tue Jul 12 2022 13:31:53 by
