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.
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.