Version of USBDevice that works for KL25Z on Mbed OS2.
Fork of USBDevice by
Diff: USBMIDI/USBMIDI.cpp
- Revision:
- 48:03f8e580579a
- Parent:
- 47:a0cd9646ecd1
- Child:
- 50:a3c50882f2c5
diff -r a0cd9646ecd1 -r 03f8e580579a USBMIDI/USBMIDI.cpp --- 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.