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
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 }; 00182 00183 /** Read the message type 00184 * @returns MIDIMessageType 00185 */ 00186 MIDIMessageType type() { 00187 switch((data[1] >> 4) & 0xF) { 00188 case 0x8: return NoteOffType; 00189 case 0x9: return NoteOnType; 00190 case 0xA: return PolyphonicAftertouchType; 00191 case 0xB: 00192 if(controller() < 120) { // standard controllers 00193 return ControlChangeType; 00194 } else if(controller() == 123) { 00195 return AllNotesOffType; 00196 } else { 00197 return ErrorType; // unsupported atm 00198 } 00199 case 0xC: return ProgramChangeType; 00200 case 0xD: return ChannelAftertouchType; 00201 case 0xE: return PitchWheelType; 00202 default: return ErrorType; 00203 } 00204 } 00205 00206 /** Read the channel number */ 00207 int channel() { 00208 return (data[1] & 0x0F); 00209 } 00210 00211 /** Read the key ID */ 00212 int key() { 00213 return (data[2] & 0x7F); 00214 } 00215 00216 /** Read the velocity */ 00217 int velocity() { 00218 return (data[3] & 0x7F); 00219 } 00220 00221 /** Read the controller value */ 00222 int value() { 00223 return (data[3] & 0x7F); 00224 } 00225 00226 /** Read the aftertouch pressure */ 00227 int pressure() { 00228 if(type() == PolyphonicAftertouchType) { 00229 return (data[3] & 0x7F); 00230 } else { 00231 return (data[2] & 0x7F); 00232 } 00233 } 00234 00235 /** Read the controller number */ 00236 int controller() { 00237 return (data[2] & 0x7F); 00238 } 00239 00240 /** Read the program number */ 00241 int program() { 00242 return (data[2] & 0x7F); 00243 } 00244 00245 /** Read the pitch value */ 00246 int pitch() { 00247 int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F); 00248 return p - 8192; // 0 - 16383, 8192 is center 00249 } 00250 00251 uint8_t data[4]; 00252 }; 00253 00254 #endif
Generated on Tue Jul 12 2022 16:19:58 by 1.7.2