USB device stack
Dependents: blinky_max32630fthr FTHR_USB_serial FTHR_OLED HSP_RPC_GUI_3_0_1 ... more
Fork of USBDevice by
Diff: USBMIDI/USBMIDI.cpp
- Revision:
- 48:03f8e580579a
- Parent:
- 47:a0cd9646ecd1
- Child:
- 50:a3c50882f2c5
--- a/USBMIDI/USBMIDI.cpp Wed Apr 08 07:46:23 2015 +0100
+++ b/USBMIDI/USBMIDI.cpp Thu Apr 16 11:00:20 2015 +0100
@@ -25,8 +25,49 @@
USBDevice::connect();
}
+// write plain MIDIMessage that will be converted to USBMidi event packet
void USBMIDI::write(MIDIMessage m) {
- USBDevice::write(EPBULK_IN, m.data, 4, MAX_PACKET_SIZE_EPBULK);
+ // first byte keeped for retro-compatibility
+ for(int p=1; p < m.length; p+=3) {
+ uint8_t buf[4];
+ // Midi message to USBMidi event packet
+ buf[0]=m.data[1] >> 4;
+ // SysEx
+ if(buf[0] == 0xF) {
+ if((m.length - p) > 3) {
+ // SysEx start or continue
+ buf[0]=0x4;
+ } else {
+ switch(m.length - p) {
+ case 1:
+ // SysEx end with one byte
+ buf[0]=0x5;
+ break;
+ case 2:
+ // SysEx end with two bytes
+ buf[0]=0x6;
+ break;
+ case 3:
+ // SysEx end with three bytes
+ buf[0]=0x7;
+ break;
+ }
+ }
+ }
+ buf[1]=m.data[p];
+
+ if(p+1 < m.length)
+ buf[2]=m.data[p+1];
+ else
+ buf[2]=0;
+
+ if(p+2 < m.length)
+ buf[3]=m.data[p+2];
+ else
+ buf[3]=0;
+
+ USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
+ }
}
@@ -34,16 +75,61 @@
midi_evt = fptr;
}
-
bool USBMIDI::EPBULK_OUT_callback() {
uint8_t buf[64];
uint32_t len;
readEP(EPBULK_OUT, buf, &len, 64);
if (midi_evt != NULL) {
- for (uint32_t i=0; i<len; i+=4) {
- midi_evt(MIDIMessage(buf+i));
- }
+ for (uint32_t i=0; i<len; i+=4) {
+ uint8_t data_read;
+ data_end=true;
+ switch(buf[i]) {
+ case 0x2:
+ // Two-bytes System Common Message - undefined in USBMidi 1.0
+ data_read=2;
+ break;
+ case 0x4:
+ // SysEx start or continue
+ data_end=false;
+ data_read=3;
+ break;
+ case 0x5:
+ // Single-byte System Common Message or SysEx end with one byte
+ data_read=1;
+ break;
+ case 0x6:
+ // SysEx end with two bytes
+ data_read=2;
+ break;
+ case 0xC:
+ // Program change
+ data_read=2;
+ break;
+ case 0xD:
+ // Channel pressure
+ data_read=2;
+ break;
+ case 0xF:
+ // Single byte
+ data_read=1;
+ break;
+ default:
+ // Others three-bytes messages
+ data_read=3;
+ break;
+ }
+
+ for(uint8_t j=1;j<data_read+1;j++) {
+ data[cur_data]=buf[i+j];
+ cur_data++;
+ }
+
+ if(data_end) {
+ midi_evt(MIDIMessage(data,cur_data));
+ cur_data=0;
+ }
+ }
}
// We reactivate the endpoint to receive next characters
@@ -51,8 +137,6 @@
return true;
}
-
-
// Called in ISR context
// Set configuration. Return false if the
// configuration is not supported.
