Ported from Arduino MIDI library Orignal: http://www.arduino.cc/playground/Main/MIDILibrary use Serial (UART)
Dependents: MIDI_sample MIDI_usb_bridge MIDI_Interpreter midi-timer ... more
MIDI.h
00001 /*! 00002 * @file MIDI.h 00003 * Project MIDI Library 00004 * @brief MIDI Library for the Arduino 00005 * Version 3.2 00006 * @author Francois Best 00007 * @date 24/02/11 00008 * License GPL Forty Seven Effects - 2011 00009 */ 00010 /* 00011 * Ported for mbed by Hiroshi Suga 00012 * Orignal: http://www.arduino.cc/playground/Main/MIDILibrary 00013 */ 00014 00015 #ifndef LIB_MIDI_H_ 00016 #define LIB_MIDI_H_ 00017 00018 #include "mbed.h" 00019 00020 00021 /* 00022 ############################################################### 00023 # # 00024 # CONFIGURATION AREA # 00025 # # 00026 # Here are a few settings you can change to customize # 00027 # the library for your own project. You can for example # 00028 # choose to compile only parts of it so you gain flash # 00029 # space and optimise the speed of your sketch. # 00030 # # 00031 ############################################################### 00032 */ 00033 00034 00035 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. 00036 #define COMPILE_MIDI_OUT 1 // Set this setting to 1 to use the MIDI output. 00037 #define COMPILE_MIDI_THRU 0 // Set this setting to 1 to use the MIDI Soft Thru feature 00038 // Please note that the Thru will work only when both COMPILE_MIDI_IN and COMPILE_MIDI_OUT set to 1. 00039 00040 00041 #define USE_SERIAL_PORT _midi // Change the number (to Serial1 for example) if you want 00042 // to use a different serial port for MIDI I/O. 00043 00044 00045 #define USE_RUNNING_STATUS 1 // Running status enables short messages when sending multiple values 00046 // of the same type and channel. 00047 // Set to 0 if you have troubles with controlling you hardware. 00048 00049 00050 #define USE_CALLBACKS 1 // Set this to 1 if you want to use callback handlers (to bind your functions to the library). 00051 // To use the callbacks, you need to have COMPILE_MIDI_IN set to 1 00052 00053 #define USE_1BYTE_PARSING 1 // Each call to MIDI.read will only parse one byte (might be faster). 00054 00055 00056 // END OF CONFIGURATION AREA 00057 // (do not modify anything under this line unless you know what you are doing) 00058 00059 00060 #define MIDI_BAUDRATE 31250 00061 00062 #define MIDI_CHANNEL_OMNI 0 00063 #define MIDI_CHANNEL_OFF 17 // and over 00064 00065 #define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes. 00066 00067 /*! Type definition for practical use (because "unsigned char" is a bit long to write.. )*/ 00068 typedef uint8_t byte ; 00069 typedef uint16_t word; 00070 00071 /*! Enumeration of MIDI types */ 00072 enum kMIDIType { 00073 NoteOff = 0x80, ///< Note Off 00074 NoteOn = 0x90, ///< Note On 00075 AfterTouchPoly = 0xA0, ///< Polyphonic AfterTouch 00076 ControlChange = 0xB0, ///< Control Change / Channel Mode 00077 ProgramChange = 0xC0, ///< Program Change 00078 AfterTouchChannel = 0xD0, ///< Channel (monophonic) AfterTouch 00079 PitchBend = 0xE0, ///< Pitch Bend 00080 SystemExclusive = 0xF0, ///< System Exclusive 00081 TimeCodeQuarterFrame = 0xF1, ///< System Common - MIDI Time Code Quarter Frame 00082 SongPosition = 0xF2, ///< System Common - Song Position Pointer 00083 SongSelect = 0xF3, ///< System Common - Song Select 00084 TuneRequest = 0xF6, ///< System Common - Tune Request 00085 Clock = 0xF8, ///< System Real Time - Timing Clock 00086 Start = 0xFA, ///< System Real Time - Start 00087 Continue = 0xFB, ///< System Real Time - Continue 00088 Stop = 0xFC, ///< System Real Time - Stop 00089 ActiveSensing = 0xFE, ///< System Real Time - Active Sensing 00090 SystemReset = 0xFF, ///< System Real Time - System Reset 00091 InvalidType = 0x00 ///< For notifying errors 00092 }; 00093 00094 /*! Enumeration of Thru filter modes */ 00095 enum kThruFilterMode { 00096 Off = 0, ///< Thru disabled (nothing passes through). 00097 Full = 1, ///< Fully enabled Thru (every incoming message is sent back). 00098 SameChannel = 2, ///< Only the messages on the Input Channel will be sent back. 00099 DifferentChannel = 3 ///< All the messages but the ones on the Input Channel will be sent back. 00100 }; 00101 00102 00103 /*! The midimsg structure contains decoded data of a MIDI message read from the serial port with read() or thru(). \n */ 00104 struct midimsg { 00105 /*! The MIDI channel on which the message was recieved. \n Value goes from 1 to 16. */ 00106 byte channel ; 00107 /*! The type of the message (see the define section for types reference) */ 00108 kMIDIType type ; 00109 /*! The first data byte.\n Value goes from 0 to 127.\n */ 00110 byte data1 ; 00111 /*! The second data byte. If the message is only 2 bytes long, this one is null.\n Value goes from 0 to 127. */ 00112 byte data2 ; 00113 /*! System Exclusive dedicated byte array. \n Array length is stocked on 16 bits, in data1 (LSB) and data2 (MSB) */ 00114 byte sysex_array [MIDI_SYSEX_ARRAY_SIZE]; 00115 /*! This boolean indicates if the message is valid or not. There is no channel consideration here, validity means the message respects the MIDI norm. */ 00116 bool valid ; 00117 }; 00118 00119 00120 00121 00122 /*! \brief The main class for MIDI handling.\n 00123 See member descriptions to know how to use it, 00124 or check out the examples supplied with the library. 00125 */ 00126 class MIDI { 00127 00128 00129 public: 00130 // Constructor and Destructor 00131 MIDI(PinName p_tx, PinName p_rx); 00132 ~MIDI(); 00133 00134 00135 void begin(const byte inChannel = 1); 00136 00137 00138 00139 00140 /* ####### OUTPUT COMPILATION BLOCK ####### */ 00141 #if COMPILE_MIDI_OUT 00142 00143 public: 00144 00145 void sendNoteOn(byte NoteNumber,byte Velocity,byte Channel); 00146 void sendNoteOff(byte NoteNumber,byte Velocity,byte Channel); 00147 void sendProgramChange(byte ProgramNumber,byte Channel); 00148 void sendControlChange(byte ControlNumber, byte ControlValue,byte Channel); 00149 void sendPitchBend(int PitchValue,byte Channel); 00150 void sendPitchBend(unsigned int PitchValue,byte Channel); 00151 void sendPitchBend(double PitchValue,byte Channel); 00152 void sendPolyPressure(byte NoteNumber,byte Pressure,byte Channel); 00153 void sendAfterTouch(byte Pressure,byte Channel); 00154 void sendSysEx(int length, const byte *const array,bool ArrayContainsBoundaries = false); 00155 void sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble); 00156 void sendTimeCodeQuarterFrame(byte data); 00157 void sendSongPosition(unsigned int Beats); 00158 void sendSongSelect(byte SongNumber); 00159 void sendTuneRequest(); 00160 void sendRealTime(kMIDIType Type); 00161 00162 void send(kMIDIType type, byte param1, byte param2, byte channel); 00163 00164 private: 00165 00166 Serial _midi; 00167 byte genstatus(const kMIDIType inType,const byte inChannel) const; 00168 00169 00170 // Attributes 00171 #if USE_RUNNING_STATUS 00172 byte mRunningStatus_TX; 00173 #endif // USE_RUNNING_STATUS 00174 00175 #endif // COMPILE_MIDI_OUT 00176 00177 00178 00179 /* ####### INPUT COMPILATION BLOCK ####### */ 00180 #if COMPILE_MIDI_IN 00181 00182 public: 00183 00184 bool read(); 00185 bool read(const byte Channel); 00186 00187 // Getters 00188 kMIDIType getType() const; 00189 byte getChannel() const; 00190 byte getData1() const; 00191 byte getData2() const; 00192 const byte * getSysExArray() const; 00193 unsigned int getSysExArrayLength() const; 00194 bool check() const; 00195 00196 byte getInputChannel() const 00197 { 00198 return mInputChannel; 00199 } 00200 00201 // Setters 00202 void setInputChannel(const byte Channel); 00203 00204 /*! \brief Extract an enumerated MIDI type from a status byte. 00205 00206 This is a utility static method, used internally, made public so you can handle kMIDITypes more easily. 00207 */ 00208 static inline kMIDIType getTypeFromStatusByte(const byte inStatus) 00209 { 00210 if ((inStatus < 0x80) 00211 || (inStatus == 0xF4) 00212 || (inStatus == 0xF5) 00213 || (inStatus == 0xF9) 00214 || (inStatus == 0xFD)) return InvalidType; // data bytes and undefined. 00215 if (inStatus < 0xF0) return (kMIDIType )(inStatus & 0xF0); // Channel message, remove channel nibble. 00216 else return (kMIDIType )inStatus; 00217 } 00218 00219 00220 #if USE_CALLBACKS 00221 00222 void setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)); 00223 void setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)); 00224 void setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)); 00225 void setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)); 00226 void setHandleProgramChange(void (*fptr)(byte channel, byte number)); 00227 void setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)); 00228 void setHandlePitchBend(void (*fptr)(byte channel, int bend)); 00229 void setHandleSystemExclusive(void (*fptr)(byte * array, byte size)); 00230 void setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)); 00231 void setHandleSongPosition(void (*fptr)(unsigned int beats)); 00232 void setHandleSongSelect(void (*fptr)(byte songnumber)); 00233 void setHandleTuneRequest(void (*fptr)(void)); 00234 void setHandleClock(void (*fptr)(void)); 00235 void setHandleStart(void (*fptr)(void)); 00236 void setHandleContinue(void (*fptr)(void)); 00237 void setHandleStop(void (*fptr)(void)); 00238 void setHandleActiveSensing(void (*fptr)(void)); 00239 void setHandleSystemReset(void (*fptr)(void)); 00240 00241 void disconnectCallbackFromType(kMIDIType Type); 00242 00243 #endif // USE_CALLBACKS 00244 00245 00246 private: 00247 00248 bool input_filter(byte inChannel); 00249 bool parse(byte inChannel); 00250 void reset_input_attributes(); 00251 00252 // Attributes 00253 byte mRunningStatus_RX; 00254 byte mInputChannel; 00255 00256 byte mPendingMessage[MIDI_SYSEX_ARRAY_SIZE]; 00257 unsigned int mPendingMessageExpectedLenght; 00258 unsigned int mPendingMessageIndex; // Extended to unsigned int for larger sysex payloads. 00259 00260 midimsg mMessage; 00261 00262 #if USE_CALLBACKS 00263 00264 void launchCallback(); 00265 00266 void (*mNoteOffCallback)(byte channel, byte note, byte velocity); 00267 void (*mNoteOnCallback)(byte channel, byte note, byte velocity); 00268 void (*mAfterTouchPolyCallback)(byte channel, byte note, byte velocity); 00269 void (*mControlChangeCallback)(byte channel, byte , byte ); 00270 void (*mProgramChangeCallback)(byte channel, byte ); 00271 void (*mAfterTouchChannelCallback)(byte channel, byte ); 00272 void (*mPitchBendCallback)(byte channel, int); 00273 void (*mSystemExclusiveCallback)(byte * array, byte size); 00274 void (*mTimeCodeQuarterFrameCallback)(byte data); 00275 void (*mSongPositionCallback)(unsigned int beats); 00276 void (*mSongSelectCallback)(byte songnumber); 00277 void (*mTuneRequestCallback)(void); 00278 void (*mClockCallback)(void); 00279 void (*mStartCallback)(void); 00280 void (*mContinueCallback)(void); 00281 void (*mStopCallback)(void); 00282 void (*mActiveSensingCallback)(void); 00283 void (*mSystemResetCallback)(void); 00284 00285 #endif // USE_CALLBACKS 00286 00287 00288 #endif // COMPILE_MIDI_IN 00289 00290 00291 /* ####### THRU COMPILATION BLOCK ####### */ 00292 #if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU) // Thru 00293 00294 public: 00295 00296 // Getters 00297 kThruFilterMode getFilterMode() const { return mThruFilterMode; } 00298 bool getThruState() const { return mThruActivated; } 00299 00300 00301 // Setters 00302 void turnThruOn(kThruFilterMode inThruFilterMode = Full); 00303 void turnThruOff(); 00304 00305 void setThruFilterMode(const kThruFilterMode inThruFilterMode); 00306 00307 00308 private: 00309 00310 void thru_filter(byte inChannel); 00311 00312 bool mThruActivated; 00313 kThruFilterMode mThruFilterMode; 00314 00315 #endif // Thru 00316 00317 }; 00318 00319 #endif // LIB_MIDI_H_
Generated on Tue Jul 12 2022 20:13:45 by 1.7.2