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 USBMIDI by
MIDIMessage.h
00001 /* @license The MIT License 00002 * Copyright (c) 2011 mux, simon 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 #ifndef MBED_MIDIMESSAGE_H 00024 #define MBED_MIDIMESSAGE_H 00025 00026 #include "mbed.h" 00027 00028 // MIDI Message Format 00029 // 00030 // [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ] 00031 // 00032 // MIDI Data Messages (Channel Specific) 00033 // 00034 // Message msg n m 00035 // --------------------------------------------- 00036 // Note Off 0x8 Key Velocity 00037 // Note On 0x9 Key Velocity 00038 // Polyphonic Aftertouch 0xA Key Pressure 00039 // Control Change 0xB Controller Value 00040 // Program Change 0xC Program - 00041 // Channel Aftertouch 0xD Pressure - 00042 // Pitch Wheel 0xE LSB MSB 00043 00044 #define CABLE_NUM (0<<4) 00045 00046 /** A MIDI message container */ 00047 class MIDIMessage { 00048 public: 00049 MIDIMessage() {} 00050 00051 MIDIMessage(uint8_t *buf) { 00052 *((uint32_t *)data) = *((uint32_t *)buf); 00053 } 00054 00055 // create messages 00056 00057 /** Create a NoteOff message 00058 * @param key Key ID 00059 * @param velocity Key velocity (0-127, default = 127) 00060 * @param channel Key channel (0-15, default 0) 00061 * @returns A MIDIMessage 00062 */ 00063 static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) { 00064 MIDIMessage msg; 00065 msg.data[0] = CABLE_NUM | 0x08; 00066 msg.data[1] = 0x80 | (channel & 0x0F); 00067 msg.data[2] = key & 0x7F; 00068 msg.data[3] = velocity & 0x7F; 00069 return msg; 00070 } 00071 00072 /** Create a NoteOn message 00073 * @param key Key ID 00074 * @param velocity Key velocity (0-127, default = 127) 00075 * @param channel Key channel (0-15, default 0) 00076 * @returns A MIDIMessage 00077 */ 00078 static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) { 00079 MIDIMessage msg; 00080 msg.data[0] = CABLE_NUM | 0x09; 00081 msg.data[1] = 0x90 | (channel & 0x0F); 00082 msg.data[2] = key & 0x7F; 00083 msg.data[3] = velocity & 0x7F; 00084 return msg; 00085 } 00086 00087 /** Create a PolyPhonic Aftertouch message 00088 * @param key Key ID 00089 * @param pressure Aftertouch pressure (0-127) 00090 * @param channel Key channel (0-15, default 0) 00091 * @returns A MIDIMessage 00092 */ 00093 static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) { 00094 MIDIMessage msg; 00095 msg.data[0] = CABLE_NUM | 0x0A; 00096 msg.data[1] = 0xA0 | (channel & 0x0F); 00097 msg.data[2] = key & 0x7F; 00098 msg.data[3] = pressure & 0x7F; 00099 return msg; 00100 } 00101 00102 /** Create a Control Change message 00103 * @param control Controller ID 00104 * @param value Controller value (0-127) 00105 * @param channel Controller channel (0-15, default 0) 00106 * @returns A MIDIMessage 00107 */ 00108 static MIDIMessage ControlChange(int control, int value, int channel = 0) { 00109 MIDIMessage msg; 00110 msg.data[0] = CABLE_NUM | 0x0B; 00111 msg.data[1] = 0xB0 | (channel & 0x0F); 00112 msg.data[2] = control & 0x7F; 00113 msg.data[3] = value & 0x7F; 00114 return msg; 00115 } 00116 00117 /** Create a Program Change message 00118 * @param program Program ID 00119 * @param channel Channel (0-15, default 0) 00120 * @returns A MIDIMessage 00121 */ 00122 static MIDIMessage ProgramChange(int program, int channel = 0) { 00123 MIDIMessage msg; 00124 msg.data[0] = CABLE_NUM | 0x0C; 00125 msg.data[1] = 0xC0 | (channel & 0x0F); 00126 msg.data[2] = program & 0x7F; 00127 msg.data[3] = 0x00; 00128 return msg; 00129 } 00130 00131 /** Create a Channel Aftertouch message 00132 * @param pressure Pressure 00133 * @param channel Key channel (0-15, default 0) 00134 * @returns A MIDIMessage 00135 */ 00136 static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) { 00137 MIDIMessage msg; 00138 msg.data[0] = CABLE_NUM | 0x0D; 00139 msg.data[1] = 0xD0 | (channel & 0x0F); 00140 msg.data[2] = pressure & 0x7F; 00141 msg.data[3] = 0x00; 00142 return msg; 00143 } 00144 00145 /** Create a Pitch Wheel message 00146 * @param pitch Pitch (-8192 - 8191, default = 0) 00147 * @param channel Channel (0-15, default 0) 00148 * @returns A MIDIMessage 00149 */ 00150 static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) { 00151 MIDIMessage msg; 00152 int p = pitch + 8192; // 0 - 16383, 8192 is center 00153 msg.data[0] = CABLE_NUM | 0x0E; 00154 msg.data[1] = 0xE0 | (channel & 0x0F); 00155 msg.data[2] = p & 0x7F; 00156 msg.data[3] = (p >> 7) & 0x7F; 00157 return msg; 00158 } 00159 00160 /** Create an All Notes Off message 00161 * @param channel Channel (0-15, default 0) 00162 * @returns A MIDIMessage 00163 */ 00164 static MIDIMessage AllNotesOff(int channel = 0) { 00165 return ControlChange(123, 0, channel); 00166 } 00167 00168 // decode messages 00169 00170 /** MIDI Message Types */ 00171 enum MIDIMessageType { 00172 ErrorType, 00173 NoteOffType, 00174 NoteOnType, 00175 PolyphonicAftertouchType, 00176 ControlChangeType, 00177 ProgramChangeType, 00178 ChannelAftertouchType, 00179 PitchWheelType, 00180 AllNotesOffType, 00181 MTCType, 00182 ClockType, 00183 StartType, 00184 ContinueType, 00185 StopType 00186 }; 00187 00188 /** Read the message type 00189 * @returns MIDIMessageType 00190 */ 00191 MIDIMessageType type() { 00192 switch((data[1] >> 4) & 0xF) { 00193 case 0x8: return NoteOffType; 00194 case 0x9: return NoteOnType; 00195 case 0xA: return PolyphonicAftertouchType; 00196 case 0xB: 00197 if(controller() < 120) { // standard controllers 00198 return ControlChangeType; 00199 } else if(controller() == 123) { 00200 return AllNotesOffType; 00201 } else { 00202 return ErrorType; // unsupported atm 00203 } 00204 case 0xC: return ProgramChangeType; 00205 case 0xD: return ChannelAftertouchType; 00206 case 0xE: return PitchWheelType; 00207 case 0xF: //MIDI CLOCK 00208 switch(data[1] & 0x0F){ 00209 case 0x01: return MTCType; 00210 case 0x08: return ClockType; 00211 case 0x0A: return StartType; 00212 case 0x0B: return ContinueType; 00213 case 0x0C: return StopType; 00214 default: return ErrorType; 00215 } 00216 default: return ErrorType; 00217 } 00218 } 00219 00220 /** Read the channel number */ 00221 int channel() { 00222 return (data[1] & 0x0F); 00223 } 00224 00225 /** Read the key ID */ 00226 int key() { 00227 return (data[2] & 0x7F); 00228 } 00229 00230 /** Read the velocity */ 00231 int velocity() { 00232 return (data[3] & 0x7F); 00233 } 00234 00235 /** Read the controller value */ 00236 int value() { 00237 return (data[3] & 0x7F); 00238 } 00239 00240 /** Read the aftertouch pressure */ 00241 int pressure() { 00242 if(type() == PolyphonicAftertouchType) { 00243 return (data[3] & 0x7F); 00244 } else { 00245 return (data[2] & 0x7F); 00246 } 00247 } 00248 00249 /** Read the controller number */ 00250 int controller() { 00251 return (data[2] & 0x7F); 00252 } 00253 00254 /** Read the program number */ 00255 int program() { 00256 return (data[2] & 0x7F); 00257 } 00258 00259 /** Read the pitch value */ 00260 int pitch() { 00261 int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F); 00262 return p - 8192; // 0 - 16383, 8192 is center 00263 } 00264 00265 00266 00267 uint8_t data[4]; 00268 }; 00269 00270 #endif
Generated on Tue Jul 12 2022 23:30:37 by
