mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 1:9db0e321a9f4 1 /*
kenjiArai 1:9db0e321a9f4 2 * Copyright (c) 2018-2019, Arm Limited and affiliates.
kenjiArai 1:9db0e321a9f4 3 * SPDX-License-Identifier: Apache-2.0
kenjiArai 1:9db0e321a9f4 4 *
kenjiArai 1:9db0e321a9f4 5 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 1:9db0e321a9f4 6 * you may not use this file except in compliance with the License.
kenjiArai 1:9db0e321a9f4 7 * You may obtain a copy of the License at
kenjiArai 1:9db0e321a9f4 8 *
kenjiArai 1:9db0e321a9f4 9 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 1:9db0e321a9f4 10 *
kenjiArai 1:9db0e321a9f4 11 * Unless required by applicable law or agreed to in writing, software
kenjiArai 1:9db0e321a9f4 12 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 1:9db0e321a9f4 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 1:9db0e321a9f4 14 * See the License for the specific language governing permissions and
kenjiArai 1:9db0e321a9f4 15 * limitations under the License.
kenjiArai 1:9db0e321a9f4 16 */
kenjiArai 1:9db0e321a9f4 17
kenjiArai 1:9db0e321a9f4 18 #ifndef MIDIMESSAGE_H
kenjiArai 1:9db0e321a9f4 19 #define MIDIMESSAGE_H
kenjiArai 1:9db0e321a9f4 20
kenjiArai 1:9db0e321a9f4 21 #include <stdint.h>
kenjiArai 1:9db0e321a9f4 22
kenjiArai 1:9db0e321a9f4 23 #define MAX_MIDI_MESSAGE_SIZE 256 // Max message size. SysEx can be up to 65536 but 256 should be fine for most usage
kenjiArai 1:9db0e321a9f4 24
kenjiArai 1:9db0e321a9f4 25 // MIDI Message Format
kenjiArai 1:9db0e321a9f4 26 //
kenjiArai 1:9db0e321a9f4 27 // [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
kenjiArai 1:9db0e321a9f4 28 //
kenjiArai 1:9db0e321a9f4 29 // MIDI Data Messages (Channel Specific)
kenjiArai 1:9db0e321a9f4 30 //
kenjiArai 1:9db0e321a9f4 31 // Message msg n m
kenjiArai 1:9db0e321a9f4 32 // ---------------------------------------------
kenjiArai 1:9db0e321a9f4 33 // Note Off 0x8 Key Velocity
kenjiArai 1:9db0e321a9f4 34 // Note On 0x9 Key Velocity
kenjiArai 1:9db0e321a9f4 35 // Polyphonic Aftertouch 0xA Key Pressure
kenjiArai 1:9db0e321a9f4 36 // Control Change 0xB Controller Value
kenjiArai 1:9db0e321a9f4 37 // Program Change 0xC Program -
kenjiArai 1:9db0e321a9f4 38 // Channel Aftertouch 0xD Pressure -
kenjiArai 1:9db0e321a9f4 39 // Pitch Wheel 0xE LSB MSB
kenjiArai 1:9db0e321a9f4 40
kenjiArai 1:9db0e321a9f4 41 #define CABLE_NUM (0<<4)
kenjiArai 1:9db0e321a9f4 42
kenjiArai 1:9db0e321a9f4 43
kenjiArai 1:9db0e321a9f4 44 /**
kenjiArai 1:9db0e321a9f4 45 * \defgroup drivers_MIDIMessage MIDIMessage class
kenjiArai 1:9db0e321a9f4 46 * \ingroup drivers-internal-api-usb
kenjiArai 1:9db0e321a9f4 47 * @{
kenjiArai 1:9db0e321a9f4 48 */
kenjiArai 1:9db0e321a9f4 49
kenjiArai 1:9db0e321a9f4 50 /** A MIDI message container */
kenjiArai 1:9db0e321a9f4 51 class MIDIMessage {
kenjiArai 1:9db0e321a9f4 52 public:
kenjiArai 1:9db0e321a9f4 53
kenjiArai 1:9db0e321a9f4 54 MIDIMessage() : data(new uint8_t[MAX_MIDI_MESSAGE_SIZE + 1]), length(0) {}
kenjiArai 1:9db0e321a9f4 55
kenjiArai 1:9db0e321a9f4 56 MIDIMessage(uint8_t *buf) : data(new uint8_t[MAX_MIDI_MESSAGE_SIZE + 1]), length(0)
kenjiArai 1:9db0e321a9f4 57 {
kenjiArai 1:9db0e321a9f4 58 for (int i = 0; i < 4; i++) {
kenjiArai 1:9db0e321a9f4 59 data[i] = buf[i];
kenjiArai 1:9db0e321a9f4 60 }
kenjiArai 1:9db0e321a9f4 61 }
kenjiArai 1:9db0e321a9f4 62
kenjiArai 1:9db0e321a9f4 63 /**
kenjiArai 1:9db0e321a9f4 64 * Copy constructor
kenjiArai 1:9db0e321a9f4 65 */
kenjiArai 1:9db0e321a9f4 66 MIDIMessage(const MIDIMessage &other)
kenjiArai 1:9db0e321a9f4 67 {
kenjiArai 1:9db0e321a9f4 68 *this = other;
kenjiArai 1:9db0e321a9f4 69 }
kenjiArai 1:9db0e321a9f4 70
kenjiArai 1:9db0e321a9f4 71 /**
kenjiArai 1:9db0e321a9f4 72 * Assignment operator
kenjiArai 1:9db0e321a9f4 73 */
kenjiArai 1:9db0e321a9f4 74 MIDIMessage &operator=(const MIDIMessage &other)
kenjiArai 1:9db0e321a9f4 75 {
kenjiArai 1:9db0e321a9f4 76 length = other.length;
kenjiArai 1:9db0e321a9f4 77 for (int i = 0; i < length; i++) {
kenjiArai 1:9db0e321a9f4 78 data[i] = other.data[i];
kenjiArai 1:9db0e321a9f4 79 }
kenjiArai 1:9db0e321a9f4 80
kenjiArai 1:9db0e321a9f4 81 return *this;
kenjiArai 1:9db0e321a9f4 82 }
kenjiArai 1:9db0e321a9f4 83
kenjiArai 1:9db0e321a9f4 84 ~MIDIMessage()
kenjiArai 1:9db0e321a9f4 85 {
kenjiArai 1:9db0e321a9f4 86 delete[] data;
kenjiArai 1:9db0e321a9f4 87 }
kenjiArai 1:9db0e321a9f4 88
kenjiArai 1:9db0e321a9f4 89 /**
kenjiArai 1:9db0e321a9f4 90 * Set this MIDIMessage to a raw MIDI message
kenjiArai 1:9db0e321a9f4 91 *
kenjiArai 1:9db0e321a9f4 92 * @param buf is a true MIDI message (not USBMidi message)
kenjiArai 1:9db0e321a9f4 93 * @param buf_len size of message
kenjiArai 1:9db0e321a9f4 94 */
kenjiArai 1:9db0e321a9f4 95 void from_raw(uint8_t *buf, int buf_len)
kenjiArai 1:9db0e321a9f4 96 {
kenjiArai 1:9db0e321a9f4 97 length = buf_len + 1;
kenjiArai 1:9db0e321a9f4 98 if (length > MAX_MIDI_MESSAGE_SIZE) {
kenjiArai 1:9db0e321a9f4 99 // Message is too big
kenjiArai 1:9db0e321a9f4 100 length = 0;
kenjiArai 1:9db0e321a9f4 101 return;
kenjiArai 1:9db0e321a9f4 102 }
kenjiArai 1:9db0e321a9f4 103
kenjiArai 1:9db0e321a9f4 104 // first byte keeped for retro-compatibility
kenjiArai 1:9db0e321a9f4 105 data[0] = CABLE_NUM | 0x08;
kenjiArai 1:9db0e321a9f4 106
kenjiArai 1:9db0e321a9f4 107 for (int i = 0; i < buf_len; i++) {
kenjiArai 1:9db0e321a9f4 108 data[i + 1] = buf[i];
kenjiArai 1:9db0e321a9f4 109 }
kenjiArai 1:9db0e321a9f4 110 }
kenjiArai 1:9db0e321a9f4 111
kenjiArai 1:9db0e321a9f4 112 // create messages
kenjiArai 1:9db0e321a9f4 113
kenjiArai 1:9db0e321a9f4 114 /** Create a NoteOff message
kenjiArai 1:9db0e321a9f4 115 * @param key Key ID
kenjiArai 1:9db0e321a9f4 116 * @param velocity Key velocity (0-127, default = 127)
kenjiArai 1:9db0e321a9f4 117 * @param channel Key channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 118 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 119 */
kenjiArai 1:9db0e321a9f4 120 static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0)
kenjiArai 1:9db0e321a9f4 121 {
kenjiArai 1:9db0e321a9f4 122 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 123 msg.data[0] = CABLE_NUM | 0x08;
kenjiArai 1:9db0e321a9f4 124 msg.data[1] = 0x80 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 125 msg.data[2] = key & 0x7F;
kenjiArai 1:9db0e321a9f4 126 msg.data[3] = velocity & 0x7F;
kenjiArai 1:9db0e321a9f4 127 msg.length = 4;
kenjiArai 1:9db0e321a9f4 128 return msg;
kenjiArai 1:9db0e321a9f4 129 }
kenjiArai 1:9db0e321a9f4 130
kenjiArai 1:9db0e321a9f4 131 /** Create a NoteOn message
kenjiArai 1:9db0e321a9f4 132 * @param key Key ID
kenjiArai 1:9db0e321a9f4 133 * @param velocity Key velocity (0-127, default = 127)
kenjiArai 1:9db0e321a9f4 134 * @param channel Key channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 135 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 136 */
kenjiArai 1:9db0e321a9f4 137 static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0)
kenjiArai 1:9db0e321a9f4 138 {
kenjiArai 1:9db0e321a9f4 139 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 140 msg.data[0] = CABLE_NUM | 0x09;
kenjiArai 1:9db0e321a9f4 141 msg.data[1] = 0x90 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 142 msg.data[2] = key & 0x7F;
kenjiArai 1:9db0e321a9f4 143 msg.data[3] = velocity & 0x7F;
kenjiArai 1:9db0e321a9f4 144 msg.length = 4;
kenjiArai 1:9db0e321a9f4 145 return msg;
kenjiArai 1:9db0e321a9f4 146 }
kenjiArai 1:9db0e321a9f4 147
kenjiArai 1:9db0e321a9f4 148 /** Create a PolyPhonic Aftertouch message
kenjiArai 1:9db0e321a9f4 149 * @param key Key ID
kenjiArai 1:9db0e321a9f4 150 * @param pressure Aftertouch pressure (0-127)
kenjiArai 1:9db0e321a9f4 151 * @param channel Key channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 152 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 153 */
kenjiArai 1:9db0e321a9f4 154 static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0)
kenjiArai 1:9db0e321a9f4 155 {
kenjiArai 1:9db0e321a9f4 156 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 157 msg.data[0] = CABLE_NUM | 0x0A;
kenjiArai 1:9db0e321a9f4 158 msg.data[1] = 0xA0 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 159 msg.data[2] = key & 0x7F;
kenjiArai 1:9db0e321a9f4 160 msg.data[3] = pressure & 0x7F;
kenjiArai 1:9db0e321a9f4 161 msg.length = 4;
kenjiArai 1:9db0e321a9f4 162 return msg;
kenjiArai 1:9db0e321a9f4 163 }
kenjiArai 1:9db0e321a9f4 164
kenjiArai 1:9db0e321a9f4 165 /** Create a Control Change message
kenjiArai 1:9db0e321a9f4 166 * @param control Controller ID
kenjiArai 1:9db0e321a9f4 167 * @param value Controller value (0-127)
kenjiArai 1:9db0e321a9f4 168 * @param channel Controller channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 169 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 170 */
kenjiArai 1:9db0e321a9f4 171 static MIDIMessage ControlChange(int control, int value, int channel = 0)
kenjiArai 1:9db0e321a9f4 172 {
kenjiArai 1:9db0e321a9f4 173 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 174 msg.data[0] = CABLE_NUM | 0x0B;
kenjiArai 1:9db0e321a9f4 175 msg.data[1] = 0xB0 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 176 msg.data[2] = control & 0x7F;
kenjiArai 1:9db0e321a9f4 177 msg.data[3] = value & 0x7F;
kenjiArai 1:9db0e321a9f4 178 msg.length = 4;
kenjiArai 1:9db0e321a9f4 179 return msg;
kenjiArai 1:9db0e321a9f4 180 }
kenjiArai 1:9db0e321a9f4 181
kenjiArai 1:9db0e321a9f4 182 /** Create a Program Change message
kenjiArai 1:9db0e321a9f4 183 * @param program Program ID
kenjiArai 1:9db0e321a9f4 184 * @param channel Channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 185 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 186 */
kenjiArai 1:9db0e321a9f4 187 static MIDIMessage ProgramChange(int program, int channel = 0)
kenjiArai 1:9db0e321a9f4 188 {
kenjiArai 1:9db0e321a9f4 189 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 190 msg.data[0] = CABLE_NUM | 0x0C;
kenjiArai 1:9db0e321a9f4 191 msg.data[1] = 0xC0 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 192 msg.data[2] = program & 0x7F;
kenjiArai 1:9db0e321a9f4 193 msg.data[3] = 0x00;
kenjiArai 1:9db0e321a9f4 194 msg.length = 4;
kenjiArai 1:9db0e321a9f4 195 return msg;
kenjiArai 1:9db0e321a9f4 196 }
kenjiArai 1:9db0e321a9f4 197
kenjiArai 1:9db0e321a9f4 198 /** Create a Channel Aftertouch message
kenjiArai 1:9db0e321a9f4 199 * @param pressure Pressure
kenjiArai 1:9db0e321a9f4 200 * @param channel Key channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 201 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 202 */
kenjiArai 1:9db0e321a9f4 203 static MIDIMessage ChannelAftertouch(int pressure, int channel = 0)
kenjiArai 1:9db0e321a9f4 204 {
kenjiArai 1:9db0e321a9f4 205 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 206 msg.data[0] = CABLE_NUM | 0x0D;
kenjiArai 1:9db0e321a9f4 207 msg.data[1] = 0xD0 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 208 msg.data[2] = pressure & 0x7F;
kenjiArai 1:9db0e321a9f4 209 msg.data[3] = 0x00;
kenjiArai 1:9db0e321a9f4 210 msg.length = 4;
kenjiArai 1:9db0e321a9f4 211 return msg;
kenjiArai 1:9db0e321a9f4 212 }
kenjiArai 1:9db0e321a9f4 213
kenjiArai 1:9db0e321a9f4 214 /** Create a Pitch Wheel message
kenjiArai 1:9db0e321a9f4 215 * @param pitch Pitch (-8192 - 8191, default = 0)
kenjiArai 1:9db0e321a9f4 216 * @param channel Channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 217 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 218 */
kenjiArai 1:9db0e321a9f4 219 static MIDIMessage PitchWheel(int pitch = 0, int channel = 0)
kenjiArai 1:9db0e321a9f4 220 {
kenjiArai 1:9db0e321a9f4 221 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 222 int p = pitch + 8192; // 0 - 16383, 8192 is center
kenjiArai 1:9db0e321a9f4 223 msg.data[0] = CABLE_NUM | 0x0E;
kenjiArai 1:9db0e321a9f4 224 msg.data[1] = 0xE0 | (channel & 0x0F);
kenjiArai 1:9db0e321a9f4 225 msg.data[2] = p & 0x7F;
kenjiArai 1:9db0e321a9f4 226 msg.data[3] = (p >> 7) & 0x7F;
kenjiArai 1:9db0e321a9f4 227 msg.length = 4;
kenjiArai 1:9db0e321a9f4 228 return msg;
kenjiArai 1:9db0e321a9f4 229 }
kenjiArai 1:9db0e321a9f4 230
kenjiArai 1:9db0e321a9f4 231 /** Create an All Notes Off message
kenjiArai 1:9db0e321a9f4 232 * @param channel Channel (0-15, default 0)
kenjiArai 1:9db0e321a9f4 233 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 234 */
kenjiArai 1:9db0e321a9f4 235 static MIDIMessage AllNotesOff(int channel = 0)
kenjiArai 1:9db0e321a9f4 236 {
kenjiArai 1:9db0e321a9f4 237 return ControlChange(123, 0, channel);
kenjiArai 1:9db0e321a9f4 238 }
kenjiArai 1:9db0e321a9f4 239
kenjiArai 1:9db0e321a9f4 240 /** Create a SysEx message
kenjiArai 1:9db0e321a9f4 241 * @param data SysEx data (including 0xF0 .. 0xF7)
kenjiArai 1:9db0e321a9f4 242 * @param len SysEx data length
kenjiArai 1:9db0e321a9f4 243 * @returns A MIDIMessage
kenjiArai 1:9db0e321a9f4 244 */
kenjiArai 1:9db0e321a9f4 245 static MIDIMessage SysEx(uint8_t *data, int len)
kenjiArai 1:9db0e321a9f4 246 {
kenjiArai 1:9db0e321a9f4 247 MIDIMessage msg;
kenjiArai 1:9db0e321a9f4 248 msg.from_raw(data, len);
kenjiArai 1:9db0e321a9f4 249 return msg;
kenjiArai 1:9db0e321a9f4 250 }
kenjiArai 1:9db0e321a9f4 251
kenjiArai 1:9db0e321a9f4 252 // decode messages
kenjiArai 1:9db0e321a9f4 253
kenjiArai 1:9db0e321a9f4 254 /** MIDI Message Types */
kenjiArai 1:9db0e321a9f4 255 enum MIDIMessageType {
kenjiArai 1:9db0e321a9f4 256 ErrorType,
kenjiArai 1:9db0e321a9f4 257 NoteOffType,
kenjiArai 1:9db0e321a9f4 258 NoteOnType,
kenjiArai 1:9db0e321a9f4 259 PolyphonicAftertouchType,
kenjiArai 1:9db0e321a9f4 260 ControlChangeType,
kenjiArai 1:9db0e321a9f4 261 ProgramChangeType,
kenjiArai 1:9db0e321a9f4 262 ChannelAftertouchType,
kenjiArai 1:9db0e321a9f4 263 PitchWheelType,
kenjiArai 1:9db0e321a9f4 264 ResetAllControllersType,
kenjiArai 1:9db0e321a9f4 265 AllNotesOffType,
kenjiArai 1:9db0e321a9f4 266 SysExType
kenjiArai 1:9db0e321a9f4 267 };
kenjiArai 1:9db0e321a9f4 268
kenjiArai 1:9db0e321a9f4 269 /** Read the message type
kenjiArai 1:9db0e321a9f4 270 *
kenjiArai 1:9db0e321a9f4 271 * @returns MIDIMessageType
kenjiArai 1:9db0e321a9f4 272 */
kenjiArai 1:9db0e321a9f4 273 MIDIMessageType type()
kenjiArai 1:9db0e321a9f4 274 {
kenjiArai 1:9db0e321a9f4 275 MIDIMessageType message_type;
kenjiArai 1:9db0e321a9f4 276 uint8_t min_size;
kenjiArai 1:9db0e321a9f4 277 switch ((data[1] >> 4) & 0xF) {
kenjiArai 1:9db0e321a9f4 278 case 0x8:
kenjiArai 1:9db0e321a9f4 279 // message, channel
kenjiArai 1:9db0e321a9f4 280 // key
kenjiArai 1:9db0e321a9f4 281 // velocity
kenjiArai 1:9db0e321a9f4 282 min_size = 3;
kenjiArai 1:9db0e321a9f4 283 message_type = NoteOffType;
kenjiArai 1:9db0e321a9f4 284 break;
kenjiArai 1:9db0e321a9f4 285 case 0x9:
kenjiArai 1:9db0e321a9f4 286 // message, channel
kenjiArai 1:9db0e321a9f4 287 // key
kenjiArai 1:9db0e321a9f4 288 // velocity
kenjiArai 1:9db0e321a9f4 289 min_size = 3;
kenjiArai 1:9db0e321a9f4 290 message_type = NoteOnType;
kenjiArai 1:9db0e321a9f4 291 break;
kenjiArai 1:9db0e321a9f4 292 case 0xA:
kenjiArai 1:9db0e321a9f4 293 // message, channel
kenjiArai 1:9db0e321a9f4 294 // key
kenjiArai 1:9db0e321a9f4 295 // pressure
kenjiArai 1:9db0e321a9f4 296 min_size = 3;
kenjiArai 1:9db0e321a9f4 297 message_type = PolyphonicAftertouchType;
kenjiArai 1:9db0e321a9f4 298 break;
kenjiArai 1:9db0e321a9f4 299 case 0xB:
kenjiArai 1:9db0e321a9f4 300 // message, channel
kenjiArai 1:9db0e321a9f4 301 // controller
kenjiArai 1:9db0e321a9f4 302 min_size = 2;
kenjiArai 1:9db0e321a9f4 303 if ((data[2] & 0x7F) < 120) { // standard controllers
kenjiArai 1:9db0e321a9f4 304 message_type = ControlChangeType;
kenjiArai 1:9db0e321a9f4 305 } else if ((data[2] & 0x7F) == 121) {
kenjiArai 1:9db0e321a9f4 306 message_type = ResetAllControllersType;
kenjiArai 1:9db0e321a9f4 307 } else if ((data[2] & 0x7F) == 123) {
kenjiArai 1:9db0e321a9f4 308 message_type = AllNotesOffType;
kenjiArai 1:9db0e321a9f4 309 } else {
kenjiArai 1:9db0e321a9f4 310 message_type = ErrorType; // unsupported atm
kenjiArai 1:9db0e321a9f4 311 }
kenjiArai 1:9db0e321a9f4 312 break;
kenjiArai 1:9db0e321a9f4 313 case 0xC:
kenjiArai 1:9db0e321a9f4 314 // message, channel
kenjiArai 1:9db0e321a9f4 315 // program
kenjiArai 1:9db0e321a9f4 316 min_size = 2;
kenjiArai 1:9db0e321a9f4 317 message_type = ProgramChangeType;
kenjiArai 1:9db0e321a9f4 318 break;
kenjiArai 1:9db0e321a9f4 319 case 0xD:
kenjiArai 1:9db0e321a9f4 320 // message, channel
kenjiArai 1:9db0e321a9f4 321 // pressure
kenjiArai 1:9db0e321a9f4 322 min_size = 2;
kenjiArai 1:9db0e321a9f4 323 message_type = ChannelAftertouchType;
kenjiArai 1:9db0e321a9f4 324 break;
kenjiArai 1:9db0e321a9f4 325 case 0xE:
kenjiArai 1:9db0e321a9f4 326 // message, channel
kenjiArai 1:9db0e321a9f4 327 // pitch lsb
kenjiArai 1:9db0e321a9f4 328 // pitch msb
kenjiArai 1:9db0e321a9f4 329 min_size = 3;
kenjiArai 1:9db0e321a9f4 330 message_type = PitchWheelType;
kenjiArai 1:9db0e321a9f4 331 break;
kenjiArai 1:9db0e321a9f4 332 case 0xF:
kenjiArai 1:9db0e321a9f4 333 min_size = 2;
kenjiArai 1:9db0e321a9f4 334 message_type = SysExType;
kenjiArai 1:9db0e321a9f4 335 break;
kenjiArai 1:9db0e321a9f4 336 default:
kenjiArai 1:9db0e321a9f4 337 message_type = ErrorType;
kenjiArai 1:9db0e321a9f4 338 break;
kenjiArai 1:9db0e321a9f4 339 }
kenjiArai 1:9db0e321a9f4 340
kenjiArai 1:9db0e321a9f4 341
kenjiArai 1:9db0e321a9f4 342 if (length < min_size) {
kenjiArai 1:9db0e321a9f4 343 // too small to be a valid message
kenjiArai 1:9db0e321a9f4 344 message_type = ErrorType;
kenjiArai 1:9db0e321a9f4 345 }
kenjiArai 1:9db0e321a9f4 346 return message_type;
kenjiArai 1:9db0e321a9f4 347 }
kenjiArai 1:9db0e321a9f4 348
kenjiArai 1:9db0e321a9f4 349 /**
kenjiArai 1:9db0e321a9f4 350 * Read the channel number
kenjiArai 1:9db0e321a9f4 351 *
kenjiArai 1:9db0e321a9f4 352 * @return channel number or -1 on error
kenjiArai 1:9db0e321a9f4 353 */
kenjiArai 1:9db0e321a9f4 354
kenjiArai 1:9db0e321a9f4 355 int channel()
kenjiArai 1:9db0e321a9f4 356 {
kenjiArai 1:9db0e321a9f4 357 return (data[1] & 0x0F);
kenjiArai 1:9db0e321a9f4 358 }
kenjiArai 1:9db0e321a9f4 359
kenjiArai 1:9db0e321a9f4 360 /**
kenjiArai 1:9db0e321a9f4 361 * Read the key ID
kenjiArai 1:9db0e321a9f4 362 *
kenjiArai 1:9db0e321a9f4 363 * @return key ID or -1 on error
kenjiArai 1:9db0e321a9f4 364 */
kenjiArai 1:9db0e321a9f4 365 int key()
kenjiArai 1:9db0e321a9f4 366 {
kenjiArai 1:9db0e321a9f4 367 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 368 if ((msg_type != NoteOffType) &&
kenjiArai 1:9db0e321a9f4 369 (msg_type != NoteOnType) &&
kenjiArai 1:9db0e321a9f4 370 (msg_type != PolyphonicAftertouchType)) {
kenjiArai 1:9db0e321a9f4 371 return -1;
kenjiArai 1:9db0e321a9f4 372 }
kenjiArai 1:9db0e321a9f4 373
kenjiArai 1:9db0e321a9f4 374 return data[2] & 0x7F;
kenjiArai 1:9db0e321a9f4 375 }
kenjiArai 1:9db0e321a9f4 376
kenjiArai 1:9db0e321a9f4 377 /**
kenjiArai 1:9db0e321a9f4 378 * Read the velocity
kenjiArai 1:9db0e321a9f4 379 *
kenjiArai 1:9db0e321a9f4 380 * @return velocity or -1 on error
kenjiArai 1:9db0e321a9f4 381 */
kenjiArai 1:9db0e321a9f4 382 int velocity()
kenjiArai 1:9db0e321a9f4 383 {
kenjiArai 1:9db0e321a9f4 384 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 385 if ((msg_type != NoteOffType) &&
kenjiArai 1:9db0e321a9f4 386 (msg_type != NoteOnType)) {
kenjiArai 1:9db0e321a9f4 387 return -1;
kenjiArai 1:9db0e321a9f4 388 }
kenjiArai 1:9db0e321a9f4 389
kenjiArai 1:9db0e321a9f4 390 return data[3] & 0x7F;
kenjiArai 1:9db0e321a9f4 391 }
kenjiArai 1:9db0e321a9f4 392
kenjiArai 1:9db0e321a9f4 393 /**
kenjiArai 1:9db0e321a9f4 394 * Read the controller value
kenjiArai 1:9db0e321a9f4 395 *
kenjiArai 1:9db0e321a9f4 396 * @return controller value or -1 on error
kenjiArai 1:9db0e321a9f4 397 */
kenjiArai 1:9db0e321a9f4 398 int value()
kenjiArai 1:9db0e321a9f4 399 {
kenjiArai 1:9db0e321a9f4 400 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 401 if ((msg_type != ControlChangeType) &&
kenjiArai 1:9db0e321a9f4 402 (msg_type != ResetAllControllersType) &&
kenjiArai 1:9db0e321a9f4 403 (msg_type != AllNotesOffType)) {
kenjiArai 1:9db0e321a9f4 404 return -1;
kenjiArai 1:9db0e321a9f4 405 }
kenjiArai 1:9db0e321a9f4 406
kenjiArai 1:9db0e321a9f4 407 return data[3] & 0x7F;
kenjiArai 1:9db0e321a9f4 408 }
kenjiArai 1:9db0e321a9f4 409
kenjiArai 1:9db0e321a9f4 410 /**
kenjiArai 1:9db0e321a9f4 411 * Read the aftertouch pressure
kenjiArai 1:9db0e321a9f4 412 *
kenjiArai 1:9db0e321a9f4 413 * @return aftertouch pressure or -1 on error
kenjiArai 1:9db0e321a9f4 414 */
kenjiArai 1:9db0e321a9f4 415 int pressure()
kenjiArai 1:9db0e321a9f4 416 {
kenjiArai 1:9db0e321a9f4 417 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 418 if ((msg_type != PolyphonicAftertouchType) &&
kenjiArai 1:9db0e321a9f4 419 (msg_type != ChannelAftertouchType)) {
kenjiArai 1:9db0e321a9f4 420 return -1;
kenjiArai 1:9db0e321a9f4 421 }
kenjiArai 1:9db0e321a9f4 422
kenjiArai 1:9db0e321a9f4 423 if (type() == PolyphonicAftertouchType) {
kenjiArai 1:9db0e321a9f4 424 return data[3] & 0x7F;
kenjiArai 1:9db0e321a9f4 425 } else {
kenjiArai 1:9db0e321a9f4 426 return data[2] & 0x7F;
kenjiArai 1:9db0e321a9f4 427 }
kenjiArai 1:9db0e321a9f4 428 }
kenjiArai 1:9db0e321a9f4 429
kenjiArai 1:9db0e321a9f4 430 /**
kenjiArai 1:9db0e321a9f4 431 * Read the controller number
kenjiArai 1:9db0e321a9f4 432 *
kenjiArai 1:9db0e321a9f4 433 * @return controller number or -1 on error
kenjiArai 1:9db0e321a9f4 434 */
kenjiArai 1:9db0e321a9f4 435 int controller()
kenjiArai 1:9db0e321a9f4 436 {
kenjiArai 1:9db0e321a9f4 437 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 438 if ((msg_type != ControlChangeType) &&
kenjiArai 1:9db0e321a9f4 439 (msg_type != ResetAllControllersType) &&
kenjiArai 1:9db0e321a9f4 440 (msg_type != AllNotesOffType)) {
kenjiArai 1:9db0e321a9f4 441 return -1;
kenjiArai 1:9db0e321a9f4 442 }
kenjiArai 1:9db0e321a9f4 443
kenjiArai 1:9db0e321a9f4 444 return data[2] & 0x7F;
kenjiArai 1:9db0e321a9f4 445 }
kenjiArai 1:9db0e321a9f4 446
kenjiArai 1:9db0e321a9f4 447 /**
kenjiArai 1:9db0e321a9f4 448 * Read the program number
kenjiArai 1:9db0e321a9f4 449 *
kenjiArai 1:9db0e321a9f4 450 * @return program number or -1 on error
kenjiArai 1:9db0e321a9f4 451 */
kenjiArai 1:9db0e321a9f4 452 int program()
kenjiArai 1:9db0e321a9f4 453 {
kenjiArai 1:9db0e321a9f4 454 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 455 if (msg_type != ProgramChangeType) {
kenjiArai 1:9db0e321a9f4 456 return -1;
kenjiArai 1:9db0e321a9f4 457 }
kenjiArai 1:9db0e321a9f4 458
kenjiArai 1:9db0e321a9f4 459 return data[2] & 0x7F;
kenjiArai 1:9db0e321a9f4 460 }
kenjiArai 1:9db0e321a9f4 461
kenjiArai 1:9db0e321a9f4 462 /**
kenjiArai 1:9db0e321a9f4 463 * Read the pitch value
kenjiArai 1:9db0e321a9f4 464 *
kenjiArai 1:9db0e321a9f4 465 * @return pitch value or -1 on error
kenjiArai 1:9db0e321a9f4 466 */
kenjiArai 1:9db0e321a9f4 467 int pitch()
kenjiArai 1:9db0e321a9f4 468 {
kenjiArai 1:9db0e321a9f4 469 MIDIMessageType msg_type = type();
kenjiArai 1:9db0e321a9f4 470 if (msg_type != PitchWheelType) {
kenjiArai 1:9db0e321a9f4 471 return -1;
kenjiArai 1:9db0e321a9f4 472 }
kenjiArai 1:9db0e321a9f4 473
kenjiArai 1:9db0e321a9f4 474 int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F);
kenjiArai 1:9db0e321a9f4 475 return p - 8192; // 0 - 16383, 8192 is center
kenjiArai 1:9db0e321a9f4 476 }
kenjiArai 1:9db0e321a9f4 477
kenjiArai 1:9db0e321a9f4 478 uint8_t *data;
kenjiArai 1:9db0e321a9f4 479 uint16_t length;
kenjiArai 1:9db0e321a9f4 480 };
kenjiArai 1:9db0e321a9f4 481
kenjiArai 1:9db0e321a9f4 482 /** @}*/
kenjiArai 1:9db0e321a9f4 483
kenjiArai 1:9db0e321a9f4 484 #endif