A library to send and receive MIDI messages over USB using the default USB-MIDI drivers on Win/Mac
Fork of USBMIDI by
MIDIMessage.h@0:56b095524cf2, 2011-02-06 (annotated)
- Committer:
- simon
- Date:
- Sun Feb 06 17:26:29 2011 +0000
- Revision:
- 0:56b095524cf2
- Child:
- 1:ff74eabe02cd
Who changed what in which revision?
User | Revision | Line number | New 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 |