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