Fork of the official USBDevice library

Fork of USBDevice by mbed official

Committer:
screamer
Date:
Fri Apr 28 17:01:10 2017 +0000
Branch:
device-files
Revision:
76:f0fd8d911b24
Parent:
73:8d28a0cb7b43
Changed the layout of USBDevice implementation for various targets to match mbed-os/targets. This also reduces the amount of files being compiled as USBDevice code for other targets is not compiled.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 73:8d28a0cb7b43 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
screamer 73:8d28a0cb7b43 2 *
screamer 73:8d28a0cb7b43 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
screamer 73:8d28a0cb7b43 4 * and associated documentation files (the "Software"), to deal in the Software without
screamer 73:8d28a0cb7b43 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
screamer 73:8d28a0cb7b43 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
screamer 73:8d28a0cb7b43 7 * Software is furnished to do so, subject to the following conditions:
screamer 73:8d28a0cb7b43 8 *
screamer 73:8d28a0cb7b43 9 * The above copyright notice and this permission notice shall be included in all copies or
screamer 73:8d28a0cb7b43 10 * substantial portions of the Software.
screamer 73:8d28a0cb7b43 11 *
screamer 73:8d28a0cb7b43 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
screamer 73:8d28a0cb7b43 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
screamer 73:8d28a0cb7b43 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
screamer 73:8d28a0cb7b43 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
screamer 73:8d28a0cb7b43 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
screamer 73:8d28a0cb7b43 17 */
screamer 73:8d28a0cb7b43 18
screamer 73:8d28a0cb7b43 19 #ifndef MIDIMESSAGE_H
screamer 73:8d28a0cb7b43 20 #define MIDIMESSAGE_H
screamer 73:8d28a0cb7b43 21
screamer 73:8d28a0cb7b43 22 #include "mbed.h"
screamer 73:8d28a0cb7b43 23
screamer 73:8d28a0cb7b43 24 #define MAX_MIDI_MESSAGE_SIZE 256 // Max message size. SysEx can be up to 65536 but 256 should be fine for most usage
screamer 73:8d28a0cb7b43 25
screamer 73:8d28a0cb7b43 26 // MIDI Message Format
screamer 73:8d28a0cb7b43 27 //
screamer 73:8d28a0cb7b43 28 // [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
screamer 73:8d28a0cb7b43 29 //
screamer 73:8d28a0cb7b43 30 // MIDI Data Messages (Channel Specific)
screamer 73:8d28a0cb7b43 31 //
screamer 73:8d28a0cb7b43 32 // Message msg n m
screamer 73:8d28a0cb7b43 33 // ---------------------------------------------
screamer 73:8d28a0cb7b43 34 // Note Off 0x8 Key Velocity
screamer 73:8d28a0cb7b43 35 // Note On 0x9 Key Velocity
screamer 73:8d28a0cb7b43 36 // Polyphonic Aftertouch 0xA Key Pressure
screamer 73:8d28a0cb7b43 37 // Control Change 0xB Controller Value
screamer 73:8d28a0cb7b43 38 // Program Change 0xC Program -
screamer 73:8d28a0cb7b43 39 // Channel Aftertouch 0xD Pressure -
screamer 73:8d28a0cb7b43 40 // Pitch Wheel 0xE LSB MSB
screamer 73:8d28a0cb7b43 41
screamer 73:8d28a0cb7b43 42 #define CABLE_NUM (0<<4)
screamer 73:8d28a0cb7b43 43
screamer 73:8d28a0cb7b43 44 /** A MIDI message container */
screamer 73:8d28a0cb7b43 45 class MIDIMessage {
screamer 73:8d28a0cb7b43 46 public:
screamer 73:8d28a0cb7b43 47 MIDIMessage() : length(4) {}
screamer 73:8d28a0cb7b43 48
screamer 73:8d28a0cb7b43 49 MIDIMessage(uint8_t *buf) : length(4) {
screamer 73:8d28a0cb7b43 50 for (int i = 0; i < 4; i++)
screamer 73:8d28a0cb7b43 51 data[i] = buf[i];
screamer 73:8d28a0cb7b43 52 }
screamer 73:8d28a0cb7b43 53
screamer 73:8d28a0cb7b43 54 // New constructor, buf is a true MIDI message (not USBMidi message) and buf_len true message length.
screamer 73:8d28a0cb7b43 55 MIDIMessage(uint8_t *buf, int buf_len) {
screamer 73:8d28a0cb7b43 56 length=buf_len+1;
screamer 73:8d28a0cb7b43 57 // first byte keeped for retro-compatibility
screamer 73:8d28a0cb7b43 58 data[0]=0;
screamer 73:8d28a0cb7b43 59
screamer 73:8d28a0cb7b43 60 for (int i = 0; i < buf_len; i++)
screamer 73:8d28a0cb7b43 61 data[i+1] = buf[i];
screamer 73:8d28a0cb7b43 62 }
screamer 73:8d28a0cb7b43 63
screamer 73:8d28a0cb7b43 64 // create messages
screamer 73:8d28a0cb7b43 65
screamer 73:8d28a0cb7b43 66 /** Create a NoteOff message
screamer 73:8d28a0cb7b43 67 * @param key Key ID
screamer 73:8d28a0cb7b43 68 * @param velocity Key velocity (0-127, default = 127)
screamer 73:8d28a0cb7b43 69 * @param channel Key channel (0-15, default 0)
screamer 73:8d28a0cb7b43 70 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 71 */
screamer 73:8d28a0cb7b43 72 static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) {
screamer 73:8d28a0cb7b43 73 MIDIMessage msg;
screamer 73:8d28a0cb7b43 74 msg.data[0] = CABLE_NUM | 0x08;
screamer 73:8d28a0cb7b43 75 msg.data[1] = 0x80 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 76 msg.data[2] = key & 0x7F;
screamer 73:8d28a0cb7b43 77 msg.data[3] = velocity & 0x7F;
screamer 73:8d28a0cb7b43 78 return msg;
screamer 73:8d28a0cb7b43 79 }
screamer 73:8d28a0cb7b43 80
screamer 73:8d28a0cb7b43 81 /** Create a NoteOn message
screamer 73:8d28a0cb7b43 82 * @param key Key ID
screamer 73:8d28a0cb7b43 83 * @param velocity Key velocity (0-127, default = 127)
screamer 73:8d28a0cb7b43 84 * @param channel Key channel (0-15, default 0)
screamer 73:8d28a0cb7b43 85 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 86 */
screamer 73:8d28a0cb7b43 87 static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) {
screamer 73:8d28a0cb7b43 88 MIDIMessage msg;
screamer 73:8d28a0cb7b43 89 msg.data[0] = CABLE_NUM | 0x09;
screamer 73:8d28a0cb7b43 90 msg.data[1] = 0x90 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 91 msg.data[2] = key & 0x7F;
screamer 73:8d28a0cb7b43 92 msg.data[3] = velocity & 0x7F;
screamer 73:8d28a0cb7b43 93 return msg;
screamer 73:8d28a0cb7b43 94 }
screamer 73:8d28a0cb7b43 95
screamer 73:8d28a0cb7b43 96 /** Create a PolyPhonic Aftertouch message
screamer 73:8d28a0cb7b43 97 * @param key Key ID
screamer 73:8d28a0cb7b43 98 * @param pressure Aftertouch pressure (0-127)
screamer 73:8d28a0cb7b43 99 * @param channel Key channel (0-15, default 0)
screamer 73:8d28a0cb7b43 100 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 101 */
screamer 73:8d28a0cb7b43 102 static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) {
screamer 73:8d28a0cb7b43 103 MIDIMessage msg;
screamer 73:8d28a0cb7b43 104 msg.data[0] = CABLE_NUM | 0x0A;
screamer 73:8d28a0cb7b43 105 msg.data[1] = 0xA0 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 106 msg.data[2] = key & 0x7F;
screamer 73:8d28a0cb7b43 107 msg.data[3] = pressure & 0x7F;
screamer 73:8d28a0cb7b43 108 return msg;
screamer 73:8d28a0cb7b43 109 }
screamer 73:8d28a0cb7b43 110
screamer 73:8d28a0cb7b43 111 /** Create a Control Change message
screamer 73:8d28a0cb7b43 112 * @param control Controller ID
screamer 73:8d28a0cb7b43 113 * @param value Controller value (0-127)
screamer 73:8d28a0cb7b43 114 * @param channel Controller channel (0-15, default 0)
screamer 73:8d28a0cb7b43 115 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 116 */
screamer 73:8d28a0cb7b43 117 static MIDIMessage ControlChange(int control, int value, int channel = 0) {
screamer 73:8d28a0cb7b43 118 MIDIMessage msg;
screamer 73:8d28a0cb7b43 119 msg.data[0] = CABLE_NUM | 0x0B;
screamer 73:8d28a0cb7b43 120 msg.data[1] = 0xB0 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 121 msg.data[2] = control & 0x7F;
screamer 73:8d28a0cb7b43 122 msg.data[3] = value & 0x7F;
screamer 73:8d28a0cb7b43 123 return msg;
screamer 73:8d28a0cb7b43 124 }
screamer 73:8d28a0cb7b43 125
screamer 73:8d28a0cb7b43 126 /** Create a Program Change message
screamer 73:8d28a0cb7b43 127 * @param program Program ID
screamer 73:8d28a0cb7b43 128 * @param channel Channel (0-15, default 0)
screamer 73:8d28a0cb7b43 129 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 130 */
screamer 73:8d28a0cb7b43 131 static MIDIMessage ProgramChange(int program, int channel = 0) {
screamer 73:8d28a0cb7b43 132 MIDIMessage msg;
screamer 73:8d28a0cb7b43 133 msg.data[0] = CABLE_NUM | 0x0C;
screamer 73:8d28a0cb7b43 134 msg.data[1] = 0xC0 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 135 msg.data[2] = program & 0x7F;
screamer 73:8d28a0cb7b43 136 msg.data[3] = 0x00;
screamer 73:8d28a0cb7b43 137 return msg;
screamer 73:8d28a0cb7b43 138 }
screamer 73:8d28a0cb7b43 139
screamer 73:8d28a0cb7b43 140 /** Create a Channel Aftertouch message
screamer 73:8d28a0cb7b43 141 * @param pressure Pressure
screamer 73:8d28a0cb7b43 142 * @param channel Key channel (0-15, default 0)
screamer 73:8d28a0cb7b43 143 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 144 */
screamer 73:8d28a0cb7b43 145 static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) {
screamer 73:8d28a0cb7b43 146 MIDIMessage msg;
screamer 73:8d28a0cb7b43 147 msg.data[0] = CABLE_NUM | 0x0D;
screamer 73:8d28a0cb7b43 148 msg.data[1] = 0xD0 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 149 msg.data[2] = pressure & 0x7F;
screamer 73:8d28a0cb7b43 150 msg.data[3] = 0x00;
screamer 73:8d28a0cb7b43 151 return msg;
screamer 73:8d28a0cb7b43 152 }
screamer 73:8d28a0cb7b43 153
screamer 73:8d28a0cb7b43 154 /** Create a Pitch Wheel message
screamer 73:8d28a0cb7b43 155 * @param pitch Pitch (-8192 - 8191, default = 0)
screamer 73:8d28a0cb7b43 156 * @param channel Channel (0-15, default 0)
screamer 73:8d28a0cb7b43 157 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 158 */
screamer 73:8d28a0cb7b43 159 static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) {
screamer 73:8d28a0cb7b43 160 MIDIMessage msg;
screamer 73:8d28a0cb7b43 161 int p = pitch + 8192; // 0 - 16383, 8192 is center
screamer 73:8d28a0cb7b43 162 msg.data[0] = CABLE_NUM | 0x0E;
screamer 73:8d28a0cb7b43 163 msg.data[1] = 0xE0 | (channel & 0x0F);
screamer 73:8d28a0cb7b43 164 msg.data[2] = p & 0x7F;
screamer 73:8d28a0cb7b43 165 msg.data[3] = (p >> 7) & 0x7F;
screamer 73:8d28a0cb7b43 166 return msg;
screamer 73:8d28a0cb7b43 167 }
screamer 73:8d28a0cb7b43 168
screamer 73:8d28a0cb7b43 169 /** Create an All Notes Off message
screamer 73:8d28a0cb7b43 170 * @param channel Channel (0-15, default 0)
screamer 73:8d28a0cb7b43 171 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 172 */
screamer 73:8d28a0cb7b43 173 static MIDIMessage AllNotesOff(int channel = 0) {
screamer 73:8d28a0cb7b43 174 return ControlChange(123, 0, channel);
screamer 73:8d28a0cb7b43 175 }
screamer 73:8d28a0cb7b43 176
screamer 73:8d28a0cb7b43 177 /** Create a SysEx message
screamer 73:8d28a0cb7b43 178 * @param data SysEx data (including 0xF0 .. 0xF7)
screamer 73:8d28a0cb7b43 179 * @param len SysEx data length
screamer 73:8d28a0cb7b43 180 * @returns A MIDIMessage
screamer 73:8d28a0cb7b43 181 */
screamer 73:8d28a0cb7b43 182 static MIDIMessage SysEx(uint8_t *data, int len) {
screamer 73:8d28a0cb7b43 183 MIDIMessage msg=MIDIMessage(data,len);
screamer 73:8d28a0cb7b43 184 return msg;
screamer 73:8d28a0cb7b43 185 }
screamer 73:8d28a0cb7b43 186
screamer 73:8d28a0cb7b43 187 // decode messages
screamer 73:8d28a0cb7b43 188
screamer 73:8d28a0cb7b43 189 /** MIDI Message Types */
screamer 73:8d28a0cb7b43 190 enum MIDIMessageType {
screamer 73:8d28a0cb7b43 191 ErrorType,
screamer 73:8d28a0cb7b43 192 NoteOffType,
screamer 73:8d28a0cb7b43 193 NoteOnType,
screamer 73:8d28a0cb7b43 194 PolyphonicAftertouchType,
screamer 73:8d28a0cb7b43 195 ControlChangeType,
screamer 73:8d28a0cb7b43 196 ProgramChangeType,
screamer 73:8d28a0cb7b43 197 ChannelAftertouchType,
screamer 73:8d28a0cb7b43 198 PitchWheelType,
screamer 73:8d28a0cb7b43 199 AllNotesOffType,
screamer 73:8d28a0cb7b43 200 SysExType
screamer 73:8d28a0cb7b43 201 };
screamer 73:8d28a0cb7b43 202
screamer 73:8d28a0cb7b43 203 /** Read the message type
screamer 73:8d28a0cb7b43 204 * @returns MIDIMessageType
screamer 73:8d28a0cb7b43 205 */
screamer 73:8d28a0cb7b43 206 MIDIMessageType type() {
screamer 73:8d28a0cb7b43 207 switch((data[1] >> 4) & 0xF) {
screamer 73:8d28a0cb7b43 208 case 0x8: return NoteOffType;
screamer 73:8d28a0cb7b43 209 case 0x9: return NoteOnType;
screamer 73:8d28a0cb7b43 210 case 0xA: return PolyphonicAftertouchType;
screamer 73:8d28a0cb7b43 211 case 0xB:
screamer 73:8d28a0cb7b43 212 if(controller() < 120) { // standard controllers
screamer 73:8d28a0cb7b43 213 return ControlChangeType;
screamer 73:8d28a0cb7b43 214 } else if(controller() == 123) {
screamer 73:8d28a0cb7b43 215 return AllNotesOffType;
screamer 73:8d28a0cb7b43 216 } else {
screamer 73:8d28a0cb7b43 217 return ErrorType; // unsupported atm
screamer 73:8d28a0cb7b43 218 }
screamer 73:8d28a0cb7b43 219 case 0xC: return ProgramChangeType;
screamer 73:8d28a0cb7b43 220 case 0xD: return ChannelAftertouchType;
screamer 73:8d28a0cb7b43 221 case 0xE: return PitchWheelType;
screamer 73:8d28a0cb7b43 222 case 0xF: return SysExType;
screamer 73:8d28a0cb7b43 223 default: return ErrorType;
screamer 73:8d28a0cb7b43 224 }
screamer 73:8d28a0cb7b43 225 }
screamer 73:8d28a0cb7b43 226
screamer 73:8d28a0cb7b43 227 /** Read the channel number */
screamer 73:8d28a0cb7b43 228 int channel() {
screamer 73:8d28a0cb7b43 229 return (data[1] & 0x0F);
screamer 73:8d28a0cb7b43 230 }
screamer 73:8d28a0cb7b43 231
screamer 73:8d28a0cb7b43 232 /** Read the key ID */
screamer 73:8d28a0cb7b43 233 int key() {
screamer 73:8d28a0cb7b43 234 return (data[2] & 0x7F);
screamer 73:8d28a0cb7b43 235 }
screamer 73:8d28a0cb7b43 236
screamer 73:8d28a0cb7b43 237 /** Read the velocity */
screamer 73:8d28a0cb7b43 238 int velocity() {
screamer 73:8d28a0cb7b43 239 return (data[3] & 0x7F);
screamer 73:8d28a0cb7b43 240 }
screamer 73:8d28a0cb7b43 241
screamer 73:8d28a0cb7b43 242 /** Read the controller value */
screamer 73:8d28a0cb7b43 243 int value() {
screamer 73:8d28a0cb7b43 244 return (data[3] & 0x7F);
screamer 73:8d28a0cb7b43 245 }
screamer 73:8d28a0cb7b43 246
screamer 73:8d28a0cb7b43 247 /** Read the aftertouch pressure */
screamer 73:8d28a0cb7b43 248 int pressure() {
screamer 73:8d28a0cb7b43 249 if(type() == PolyphonicAftertouchType) {
screamer 73:8d28a0cb7b43 250 return (data[3] & 0x7F);
screamer 73:8d28a0cb7b43 251 } else {
screamer 73:8d28a0cb7b43 252 return (data[2] & 0x7F);
screamer 73:8d28a0cb7b43 253 }
screamer 73:8d28a0cb7b43 254 }
screamer 73:8d28a0cb7b43 255
screamer 73:8d28a0cb7b43 256 /** Read the controller number */
screamer 73:8d28a0cb7b43 257 int controller() {
screamer 73:8d28a0cb7b43 258 return (data[2] & 0x7F);
screamer 73:8d28a0cb7b43 259 }
screamer 73:8d28a0cb7b43 260
screamer 73:8d28a0cb7b43 261 /** Read the program number */
screamer 73:8d28a0cb7b43 262 int program() {
screamer 73:8d28a0cb7b43 263 return (data[2] & 0x7F);
screamer 73:8d28a0cb7b43 264 }
screamer 73:8d28a0cb7b43 265
screamer 73:8d28a0cb7b43 266 /** Read the pitch value */
screamer 73:8d28a0cb7b43 267 int pitch() {
screamer 73:8d28a0cb7b43 268 int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F);
screamer 73:8d28a0cb7b43 269 return p - 8192; // 0 - 16383, 8192 is center
screamer 73:8d28a0cb7b43 270 }
screamer 73:8d28a0cb7b43 271
screamer 73:8d28a0cb7b43 272 uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
screamer 73:8d28a0cb7b43 273 uint8_t length;
screamer 73:8d28a0cb7b43 274 };
screamer 73:8d28a0cb7b43 275
screamer 73:8d28a0cb7b43 276 #endif