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_STM32F103 by
Revision 48:03f8e580579a, committed 2015-04-16
- Comitter:
- mbed_official
- Date:
- Thu Apr 16 11:00:20 2015 +0100
- Parent:
- 47:a0cd9646ecd1
- Child:
- 49:bee5808e91e3
- Commit message:
- Synchronized with git revision 1b9e8d686fd7448739e56182eb1f7cc0634667b5
Full URL: https://github.com/mbedmicro/mbed/commit/1b9e8d686fd7448739e56182eb1f7cc0634667b5/
Add SysEx to USBMIDI device
Changed in this revision
--- a/USBMIDI/MIDIMessage.h Wed Apr 08 07:46:23 2015 +0100
+++ b/USBMIDI/MIDIMessage.h Thu Apr 16 11:00:20 2015 +0100
@@ -21,6 +21,8 @@
#include "mbed.h"
+#define MAX_MIDI_MESSAGE_SIZE 256 // Max message size. SysEx can be up to 65536 but 256 should be fine for most usage
+
// MIDI Message Format
//
// [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
@@ -49,6 +51,16 @@
data[i] = buf[i];
}
+ // New constructor, buf is a true MIDI message (not USBMidi message) and buf_len true message length.
+ MIDIMessage(uint8_t *buf, int buf_len) {
+ length=buf_len+1;
+ // first byte keeped for retro-compatibility
+ data[0]=0;
+
+ for (int i = 0; i < buf_len; i++)
+ data[i+1] = buf[i];
+ }
+
// create messages
/** Create a NoteOff message
@@ -162,6 +174,16 @@
return ControlChange(123, 0, channel);
}
+ /** Create a SysEx message
+ * @param data SysEx data (including 0xF0 .. 0xF7)
+ * @param len SysEx data length
+ * @returns A MIDIMessage
+ */
+ static MIDIMessage SysEx(uint8_t *data, int len) {
+ MIDIMessage msg=MIDIMessage(data,len);
+ return msg;
+ }
+
// decode messages
/** MIDI Message Types */
@@ -174,7 +196,8 @@
ProgramChangeType,
ChannelAftertouchType,
PitchWheelType,
- AllNotesOffType
+ AllNotesOffType,
+ SysExType
};
/** Read the message type
@@ -196,6 +219,7 @@
case 0xC: return ProgramChangeType;
case 0xD: return ChannelAftertouchType;
case 0xE: return PitchWheelType;
+ case 0xF: return SysExType;
default: return ErrorType;
}
}
@@ -245,7 +269,8 @@
return p - 8192; // 0 - 16383, 8192 is center
}
- uint8_t data[4];
+ uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
+ uint8_t length=4;
};
#endif
--- 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.
--- a/USBMIDI/USBMIDI.h Wed Apr 08 07:46:23 2015 +0100
+++ b/USBMIDI/USBMIDI.h Thu Apr 16 11:00:20 2015 +0100
@@ -102,8 +102,11 @@
virtual uint8_t * configurationDesc();
private:
+ uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
+ uint8_t cur_data=0;
+ bool data_end = true;
+
void (*midi_evt)(MIDIMessage);
-
};
#endif
