Arduino MIDI Library Version 3.2
|
00001 00011 #ifndef LIB_MIDI_H_ 00012 #define LIB_MIDI_H_ 00013 00014 #include <inttypes.h> 00015 00016 00017 /* 00018 ############################################################### 00019 # # 00020 # CONFIGURATION AREA # 00021 # # 00022 # Here are a few settings you can change to customize # 00023 # the library for your own project. You can for example # 00024 # choose to compile only parts of it so you gain flash # 00025 # space and optimise the speed of your sketch. # 00026 # # 00027 ############################################################### 00028 */ 00029 00030 00031 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. 00032 #define COMPILE_MIDI_OUT 1 // Set this setting to 1 to use the MIDI output. 00033 #define COMPILE_MIDI_THRU 1 // Set this setting to 1 to use the MIDI Soft Thru feature 00034 // Please note that the Thru will work only when both COMPILE_MIDI_IN and COMPILE_MIDI_OUT set to 1. 00035 00036 00037 #define USE_SERIAL_PORT Serial // Change the number (to Serial1 for example) if you want 00038 // to use a different serial port for MIDI I/O. 00039 00040 00041 #define USE_RUNNING_STATUS 1 // Running status enables short messages when sending multiple values 00042 // of the same type and channel. 00043 // Set to 0 if you have troubles with controlling you hardware. 00044 00045 00046 #define USE_CALLBACKS 1 // Set this to 1 if you want to use callback handlers (to bind your functions to the library). 00047 // To use the callbacks, you need to have COMPILE_MIDI_IN set to 1 00048 00049 #define USE_1BYTE_PARSING 1 // Each call to MIDI.read will only parse one byte (might be faster). 00050 00051 00052 // END OF CONFIGURATION AREA 00053 // (do not modify anything under this line unless you know what you are doing) 00054 00055 00056 #define MIDI_BAUDRATE 31250 00057 00058 #define MIDI_CHANNEL_OMNI 0 00059 #define MIDI_CHANNEL_OFF 17 // and over 00060 00061 #define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes. 00062 00064 typedef uint8_t byte; 00065 typedef uint16_t word; 00066 00068 enum kMIDIType { 00069 NoteOff = 0x80, 00070 NoteOn = 0x90, 00071 AfterTouchPoly = 0xA0, 00072 ControlChange = 0xB0, 00073 ProgramChange = 0xC0, 00074 AfterTouchChannel = 0xD0, 00075 PitchBend = 0xE0, 00076 SystemExclusive = 0xF0, 00077 TimeCodeQuarterFrame = 0xF1, 00078 SongPosition = 0xF2, 00079 SongSelect = 0xF3, 00080 TuneRequest = 0xF6, 00081 Clock = 0xF8, 00082 Start = 0xFA, 00083 Continue = 0xFB, 00084 Stop = 0xFC, 00085 ActiveSensing = 0xFE, 00086 SystemReset = 0xFF, 00087 InvalidType = 0x00 00088 }; 00089 00091 enum kThruFilterMode { 00092 Off = 0, 00093 Full = 1, 00094 SameChannel = 2, 00095 DifferentChannel = 3 00096 }; 00097 00098 00100 struct midimsg { 00102 byte channel; 00104 kMIDIType type; 00106 byte data1; 00108 byte data2; 00110 byte sysex_array[MIDI_SYSEX_ARRAY_SIZE]; 00112 bool valid; 00113 }; 00114 00115 00116 00117 00122 class MIDI_Class { 00123 00124 00125 public: 00126 // Constructor and Destructor 00127 MIDI_Class(); 00128 ~MIDI_Class(); 00129 00130 00131 void begin(const byte inChannel = 1); 00132 00133 00134 00135 00136 /* ####### OUTPUT COMPILATION BLOCK ####### */ 00137 #if COMPILE_MIDI_OUT 00138 00139 public: 00140 00141 void sendNoteOn(byte NoteNumber,byte Velocity,byte Channel); 00142 void sendNoteOff(byte NoteNumber,byte Velocity,byte Channel); 00143 void sendProgramChange(byte ProgramNumber,byte Channel); 00144 void sendControlChange(byte ControlNumber, byte ControlValue,byte Channel); 00145 void sendPitchBend(int PitchValue,byte Channel); 00146 void sendPitchBend(unsigned int PitchValue,byte Channel); 00147 void sendPitchBend(double PitchValue,byte Channel); 00148 void sendPolyPressure(byte NoteNumber,byte Pressure,byte Channel); 00149 void sendAfterTouch(byte Pressure,byte Channel); 00150 void sendSysEx(int length, const byte *const array,bool ArrayContainsBoundaries = false); 00151 void sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble); 00152 void sendTimeCodeQuarterFrame(byte data); 00153 void sendSongPosition(unsigned int Beats); 00154 void sendSongSelect(byte SongNumber); 00155 void sendTuneRequest(); 00156 void sendRealTime(kMIDIType Type); 00157 00158 void send(kMIDIType type, byte param1, byte param2, byte channel); 00159 00160 private: 00161 00162 const byte genstatus(const kMIDIType inType,const byte inChannel) const; 00163 00164 00165 // Attributes 00166 #if USE_RUNNING_STATUS 00167 byte mRunningStatus_TX; 00168 #endif // USE_RUNNING_STATUS 00169 00170 #endif // COMPILE_MIDI_OUT 00171 00172 00173 00174 /* ####### INPUT COMPILATION BLOCK ####### */ 00175 #if COMPILE_MIDI_IN 00176 00177 public: 00178 00179 bool read(); 00180 bool read(const byte Channel); 00181 00182 // Getters 00183 kMIDIType getType() const; 00184 byte getChannel() const; 00185 byte getData1() const; 00186 byte getData2() const; 00187 const byte * getSysExArray() const; 00188 unsigned int getSysExArrayLength() const; 00189 bool check() const; 00190 00191 byte getInputChannel() const 00192 { 00193 return mInputChannel; 00194 } 00195 00196 // Setters 00197 void setInputChannel(const byte Channel); 00198 00203 static inline const kMIDIType getTypeFromStatusByte(const byte inStatus) 00204 { 00205 if ((inStatus < 0x80) 00206 || (inStatus == 0xF4) 00207 || (inStatus == 0xF5) 00208 || (inStatus == 0xF9) 00209 || (inStatus == 0xFD)) return InvalidType; // data bytes and undefined. 00210 if (inStatus < 0xF0) return (kMIDIType)(inStatus & 0xF0); // Channel message, remove channel nibble. 00211 else return (kMIDIType)inStatus; 00212 } 00213 00214 00215 #if USE_CALLBACKS 00216 00217 void setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)); 00218 void setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)); 00219 void setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)); 00220 void setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)); 00221 void setHandleProgramChange(void (*fptr)(byte channel, byte number)); 00222 void setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)); 00223 void setHandlePitchBend(void (*fptr)(byte channel, int bend)); 00224 void setHandleSystemExclusive(void (*fptr)(byte * array, byte size)); 00225 void setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)); 00226 void setHandleSongPosition(void (*fptr)(unsigned int beats)); 00227 void setHandleSongSelect(void (*fptr)(byte songnumber)); 00228 void setHandleTuneRequest(void (*fptr)(void)); 00229 void setHandleClock(void (*fptr)(void)); 00230 void setHandleStart(void (*fptr)(void)); 00231 void setHandleContinue(void (*fptr)(void)); 00232 void setHandleStop(void (*fptr)(void)); 00233 void setHandleActiveSensing(void (*fptr)(void)); 00234 void setHandleSystemReset(void (*fptr)(void)); 00235 00236 void disconnectCallbackFromType(kMIDIType Type); 00237 00238 #endif // USE_CALLBACKS 00239 00240 00241 private: 00242 00243 bool input_filter(byte inChannel); 00244 bool parse(byte inChannel); 00245 void reset_input_attributes(); 00246 00247 // Attributes 00248 byte mRunningStatus_RX; 00249 byte mInputChannel; 00250 00251 byte mPendingMessage[MIDI_SYSEX_ARRAY_SIZE]; 00252 unsigned int mPendingMessageExpectedLenght; 00253 unsigned int mPendingMessageIndex; // Extended to unsigned int for larger sysex payloads. 00254 00255 midimsg mMessage; 00256 00257 #if USE_CALLBACKS 00258 00259 void launchCallback(); 00260 00261 void (*mNoteOffCallback)(byte channel, byte note, byte velocity); 00262 void (*mNoteOnCallback)(byte channel, byte note, byte velocity); 00263 void (*mAfterTouchPolyCallback)(byte channel, byte note, byte velocity); 00264 void (*mControlChangeCallback)(byte channel, byte, byte); 00265 void (*mProgramChangeCallback)(byte channel, byte); 00266 void (*mAfterTouchChannelCallback)(byte channel, byte); 00267 void (*mPitchBendCallback)(byte channel, int); 00268 void (*mSystemExclusiveCallback)(byte * array, byte size); 00269 void (*mTimeCodeQuarterFrameCallback)(byte data); 00270 void (*mSongPositionCallback)(unsigned int beats); 00271 void (*mSongSelectCallback)(byte songnumber); 00272 void (*mTuneRequestCallback)(void); 00273 void (*mClockCallback)(void); 00274 void (*mStartCallback)(void); 00275 void (*mContinueCallback)(void); 00276 void (*mStopCallback)(void); 00277 void (*mActiveSensingCallback)(void); 00278 void (*mSystemResetCallback)(void); 00279 00280 #endif // USE_CALLBACKS 00281 00282 00283 #endif // COMPILE_MIDI_IN 00284 00285 00286 /* ####### THRU COMPILATION BLOCK ####### */ 00287 #if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU) // Thru 00288 00289 public: 00290 00291 // Getters 00292 kThruFilterMode getFilterMode() const { return mThruFilterMode; } 00293 bool getThruState() const { return mThruActivated; } 00294 00295 00296 // Setters 00297 void turnThruOn(kThruFilterMode inThruFilterMode = Full); 00298 void turnThruOff(); 00299 00300 void setThruFilterMode(const kThruFilterMode inThruFilterMode); 00301 00302 00303 private: 00304 00305 void thru_filter(byte inChannel); 00306 00307 bool mThruActivated; 00308 kThruFilterMode mThruFilterMode; 00309 00310 #endif // Thru 00311 00312 }; 00313 00314 extern MIDI_Class MIDI; 00315 00316 #endif // LIB_MIDI_H_