A library to send and receive MIDI messages over USB using the default USB-MIDI drivers on Win/Mac

Dependents:   USBMIDI_HelloWorld USBMIDI_DrumExample USBMIDI_MonoSynth MIDI_Interface_ver_1 ... more

Committer:
simon
Date:
Sun Feb 06 17:26:29 2011 +0000
Revision:
0:56b095524cf2
Child:
1:ff74eabe02cd

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:56b095524cf2 1 /* MIDI Message Format
simon 0:56b095524cf2 2 *
simon 0:56b095524cf2 3 * [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
simon 0:56b095524cf2 4 *
simon 0:56b095524cf2 5 * MIDI Data Messages (Channel Specific)
simon 0:56b095524cf2 6 *
simon 0:56b095524cf2 7 * Message msg n m
simon 0:56b095524cf2 8 * ---------------------------------------------
simon 0:56b095524cf2 9 * Note Off 0x8 Key Velocity
simon 0:56b095524cf2 10 * Note On 0x9 Key Velocity
simon 0:56b095524cf2 11 * Polyphonic Aftertouch 0xA Key Pressure
simon 0:56b095524cf2 12 * Control Change 0xB Controller Value
simon 0:56b095524cf2 13 * Program Change 0xC Program -
simon 0:56b095524cf2 14 * Channel Aftertouch 0xD Pressure -
simon 0:56b095524cf2 15 * Pitch Wheel 0xE LSB MSB
simon 0:56b095524cf2 16 */
simon 0:56b095524cf2 17
simon 0:56b095524cf2 18
simon 0:56b095524cf2 19 #ifndef MBED_MIDIMESSAGE_H
simon 0:56b095524cf2 20 #define MBED_MIDIMESSAGE_H
simon 0:56b095524cf2 21
simon 0:56b095524cf2 22 class MIDIMessage {
simon 0:56b095524cf2 23 public:
simon 0:56b095524cf2 24
simon 0:56b095524cf2 25 // create messages
simon 0:56b095524cf2 26
simon 0:56b095524cf2 27 static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) {
simon 0:56b095524cf2 28 MIDIMessage msg;
simon 0:56b095524cf2 29 msg.data[0] = 0x80 | (channel & 0x0F);
simon 0:56b095524cf2 30 msg.data[1] = key & 0x7F;
simon 0:56b095524cf2 31 msg.data[2] = velocity & 0x7F;
simon 0:56b095524cf2 32 return msg;
simon 0:56b095524cf2 33 }
simon 0:56b095524cf2 34
simon 0:56b095524cf2 35 static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) {
simon 0:56b095524cf2 36 MIDIMessage msg;
simon 0:56b095524cf2 37 msg.data[0] = 0x90 | (channel & 0x0F);
simon 0:56b095524cf2 38 msg.data[1] = key & 0x7F;
simon 0:56b095524cf2 39 msg.data[2] = velocity & 0x7F;
simon 0:56b095524cf2 40 return msg;
simon 0:56b095524cf2 41 }
simon 0:56b095524cf2 42
simon 0:56b095524cf2 43 static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) {
simon 0:56b095524cf2 44 MIDIMessage msg;
simon 0:56b095524cf2 45 msg.data[0] = 0xA0 | (channel & 0x0F);
simon 0:56b095524cf2 46 msg.data[1] = key & 0x7F;
simon 0:56b095524cf2 47 msg.data[2] = pressure & 0x7F;
simon 0:56b095524cf2 48 return msg;
simon 0:56b095524cf2 49 }
simon 0:56b095524cf2 50
simon 0:56b095524cf2 51 static MIDIMessage ControlChange(int control, int value, int channel = 0) {
simon 0:56b095524cf2 52 MIDIMessage msg;
simon 0:56b095524cf2 53 msg.data[0] = 0xB0 | (channel & 0x0F);
simon 0:56b095524cf2 54 msg.data[1] = control & 0x7F;
simon 0:56b095524cf2 55 msg.data[2] = value & 0x7F;
simon 0:56b095524cf2 56 return msg;
simon 0:56b095524cf2 57 }
simon 0:56b095524cf2 58
simon 0:56b095524cf2 59 static MIDIMessage ProgramChange(int program, int channel = 0) {
simon 0:56b095524cf2 60 MIDIMessage msg;
simon 0:56b095524cf2 61 msg.data[0] = 0xC0 | (channel & 0x0F);
simon 0:56b095524cf2 62 msg.data[1] = program & 0x7F;
simon 0:56b095524cf2 63 msg.data[2] = 0x00;
simon 0:56b095524cf2 64 return msg;
simon 0:56b095524cf2 65 }
simon 0:56b095524cf2 66
simon 0:56b095524cf2 67 static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) {
simon 0:56b095524cf2 68 MIDIMessage msg;
simon 0:56b095524cf2 69 msg.data[0] = 0xD0 | (channel & 0x0F);
simon 0:56b095524cf2 70 msg.data[1] = pressure & 0x7F;
simon 0:56b095524cf2 71 msg.data[2] = 0x00;
simon 0:56b095524cf2 72 return msg;
simon 0:56b095524cf2 73 }
simon 0:56b095524cf2 74
simon 0:56b095524cf2 75 static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) {
simon 0:56b095524cf2 76 MIDIMessage msg;
simon 0:56b095524cf2 77 int p = pitch + 8192; // 0 - 16383, 8192 is center
simon 0:56b095524cf2 78 msg.data[0] = 0xE0 | (channel & 0x0F);
simon 0:56b095524cf2 79 msg.data[1] = p & 0x7F;
simon 0:56b095524cf2 80 msg.data[2] = (p >> 7) & 0x7F;
simon 0:56b095524cf2 81 return msg;
simon 0:56b095524cf2 82 }
simon 0:56b095524cf2 83
simon 0:56b095524cf2 84 static MIDIMessage AllNotesOff(int channel = 0) {
simon 0:56b095524cf2 85 return ControlChange(123, 0, channel);
simon 0:56b095524cf2 86 }
simon 0:56b095524cf2 87
simon 0:56b095524cf2 88 // decode messages
simon 0:56b095524cf2 89 enum MIDIMessageType {
simon 0:56b095524cf2 90 ErrorType,
simon 0:56b095524cf2 91 NoteOffType,
simon 0:56b095524cf2 92 NoteOnType,
simon 0:56b095524cf2 93 PolyphonicAftertouchType,
simon 0:56b095524cf2 94 ControlChangeType,
simon 0:56b095524cf2 95 ProgramChangeType,
simon 0:56b095524cf2 96 ChannelAftertouchType,
simon 0:56b095524cf2 97 PitchWheelType,
simon 0:56b095524cf2 98 AllNotesOffType
simon 0:56b095524cf2 99 };
simon 0:56b095524cf2 100
simon 0:56b095524cf2 101 MIDIMessageType type() {
simon 0:56b095524cf2 102 switch((data[0] >> 4) & 0xF) {
simon 0:56b095524cf2 103 case 0x8: return NoteOffType;
simon 0:56b095524cf2 104 case 0x9: return NoteOnType;
simon 0:56b095524cf2 105 case 0xA: return PolyphonicAftertouchType;
simon 0:56b095524cf2 106 case 0xB:
simon 0:56b095524cf2 107 if(controller() < 120) { // standard controllers
simon 0:56b095524cf2 108 return ControlChangeType;
simon 0:56b095524cf2 109 } else if(controller() == 123) {
simon 0:56b095524cf2 110 return AllNotesOffType;
simon 0:56b095524cf2 111 } else {
simon 0:56b095524cf2 112 return ErrorType; // unsupported atm
simon 0:56b095524cf2 113 }
simon 0:56b095524cf2 114 case 0xC: return ProgramChangeType;
simon 0:56b095524cf2 115 case 0xD: return ChannelAftertouchType;
simon 0:56b095524cf2 116 case 0xE: return PitchWheelType;
simon 0:56b095524cf2 117 default: return ErrorType;
simon 0:56b095524cf2 118 }
simon 0:56b095524cf2 119 }
simon 0:56b095524cf2 120
simon 0:56b095524cf2 121 int channel() {
simon 0:56b095524cf2 122 return (data[0] & 0x0F);
simon 0:56b095524cf2 123 }
simon 0:56b095524cf2 124
simon 0:56b095524cf2 125 int key() {
simon 0:56b095524cf2 126 return (data[1] & 0x7F);
simon 0:56b095524cf2 127 }
simon 0:56b095524cf2 128
simon 0:56b095524cf2 129 int velocity() {
simon 0:56b095524cf2 130 return (data[2] & 0x7F);
simon 0:56b095524cf2 131 }
simon 0:56b095524cf2 132
simon 0:56b095524cf2 133 int value() {
simon 0:56b095524cf2 134 return (data[2] & 0x7F);
simon 0:56b095524cf2 135 }
simon 0:56b095524cf2 136
simon 0:56b095524cf2 137 int pressure() {
simon 0:56b095524cf2 138 if(type() == PolyphonicAftertouchType) {
simon 0:56b095524cf2 139 return (data[2] & 0x7F);
simon 0:56b095524cf2 140 } else {
simon 0:56b095524cf2 141 return (data[1] & 0x7F);
simon 0:56b095524cf2 142 }
simon 0:56b095524cf2 143 }
simon 0:56b095524cf2 144
simon 0:56b095524cf2 145 int controller() {
simon 0:56b095524cf2 146 return (data[1] & 0x7F);
simon 0:56b095524cf2 147 }
simon 0:56b095524cf2 148
simon 0:56b095524cf2 149 int program() {
simon 0:56b095524cf2 150 return (data[1] & 0x7F);
simon 0:56b095524cf2 151 }
simon 0:56b095524cf2 152
simon 0:56b095524cf2 153 int pitch() {
simon 0:56b095524cf2 154 int p = ((data[2] & 0x7F) << 7) | (data[1] & 0x7F);
simon 0:56b095524cf2 155 return p - 8192; // 0 - 16383, 8192 is center
simon 0:56b095524cf2 156 }
simon 0:56b095524cf2 157
simon 0:56b095524cf2 158 uint8_t data[3];
simon 0:56b095524cf2 159 };
simon 0:56b095524cf2 160
simon 0:56b095524cf2 161 #endif