Arduino MIDI Library Version 3.1.1
|
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 00050 // END OF CONFIGURATION AREA 00051 // (do not modify anything under this line unless you know what you are doing) 00052 00053 00054 #define MIDI_BAUDRATE 31250 00055 00056 #define MIDI_CHANNEL_OMNI 0 00057 #define MIDI_CHANNEL_OFF 17 // and over 00058 00059 #define MIDI_SYSEX_ARRAY_SIZE 255 00060 00062 typedef uint8_t byte; 00063 typedef uint16_t word; 00064 00066 enum kMIDIType { 00067 NoteOff = 0x80, 00068 NoteOn = 0x90, 00069 AfterTouchPoly = 0xA0, 00070 ControlChange = 0xB0, 00071 ProgramChange = 0xC0, 00072 AfterTouchChannel = 0xD0, 00073 PitchBend = 0xE0, 00074 SystemExclusive = 0xF0, 00075 TimeCodeQuarterFrame = 0xF1, 00076 SongPosition = 0xF2, 00077 SongSelect = 0xF3, 00078 TuneRequest = 0xF6, 00079 Clock = 0xF8, 00080 Start = 0xFA, 00081 Continue = 0xFB, 00082 Stop = 0xFC, 00083 ActiveSensing = 0xFE, 00084 SystemReset = 0xFF, 00085 InvalidType = 0x00 00086 }; 00087 00089 enum kThruFilterMode { 00090 Off = 0, 00091 Full = 1, 00092 SameChannel = 2, 00093 DifferentChannel = 3 00094 }; 00095 00096 00098 struct midimsg { 00100 byte channel; 00102 kMIDIType type; 00104 byte data1; 00106 byte data2; 00108 byte sysex_array[MIDI_SYSEX_ARRAY_SIZE]; 00110 bool valid; 00111 }; 00112 00113 00114 00115 00120 class MIDI_Class { 00121 00122 00123 public: 00124 // Constructor and Destructor 00125 MIDI_Class(); 00126 ~MIDI_Class(); 00127 00128 00129 void begin(const byte inChannel = 1); 00130 00131 00132 00133 00134 /* ####### OUTPUT COMPILATION BLOCK ####### */ 00135 #if COMPILE_MIDI_OUT 00136 00137 public: 00138 00139 void sendNoteOn(byte NoteNumber,byte Velocity,byte Channel); 00140 void sendNoteOff(byte NoteNumber,byte Velocity,byte Channel); 00141 void sendProgramChange(byte ProgramNumber,byte Channel); 00142 void sendControlChange(byte ControlNumber, byte ControlValue,byte Channel); 00143 void sendPitchBend(int PitchValue,byte Channel); 00144 void sendPitchBend(unsigned int PitchValue,byte Channel); 00145 void sendPitchBend(double PitchValue,byte Channel); 00146 void sendPolyPressure(byte NoteNumber,byte Pressure,byte Channel); 00147 void sendAfterTouch(byte Pressure,byte Channel); 00148 void sendSysEx(byte length, byte * array,bool ArrayContainsBoundaries = false); 00149 void sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble); 00150 void sendTimeCodeQuarterFrame(byte data); 00151 void sendSongPosition(unsigned int Beats); 00152 void sendSongSelect(byte SongNumber); 00153 void sendTuneRequest(); 00154 void sendRealTime(kMIDIType Type); 00155 00156 void send(kMIDIType type, byte param1, byte param2, byte channel); 00157 00158 private: 00159 00160 const byte genstatus(const kMIDIType inType,const byte inChannel); 00161 00162 00163 // Attributes 00164 #if USE_RUNNING_STATUS 00165 byte mRunningStatus_TX; 00166 #endif // USE_RUNNING_STATUS 00167 00168 #endif // COMPILE_MIDI_OUT 00169 00170 00171 00172 /* ####### INPUT COMPILATION BLOCK ####### */ 00173 #if COMPILE_MIDI_IN 00174 00175 public: 00176 00177 bool read(); 00178 bool read(const byte Channel); 00179 00180 // Getters 00181 kMIDIType getType(); 00182 byte getChannel(); 00183 byte getData1(); 00184 byte getData2(); 00185 byte * getSysExArray(); 00186 bool check(); 00187 00188 byte getInputChannel() { return mInputChannel; } 00189 00190 // Setters 00191 void setInputChannel(const byte Channel); 00192 00197 static inline const kMIDIType getTypeFromStatusByte(const byte inStatus) { 00198 if ((inStatus < 0x80) 00199 || (inStatus == 0xF4) 00200 || (inStatus == 0xF5) 00201 || (inStatus == 0xF9) 00202 || (inStatus == 0xFD)) return InvalidType; // data bytes and undefined. 00203 if (inStatus < 0xF0) return (kMIDIType)(inStatus & 0xF0); // Channel message, remove channel nibble. 00204 else return (kMIDIType)inStatus; 00205 } 00206 00207 00208 #if USE_CALLBACKS 00209 00210 void setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)); 00211 void setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)); 00212 void setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)); 00213 void setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)); 00214 void setHandleProgramChange(void (*fptr)(byte channel, byte number)); 00215 void setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)); 00216 void setHandlePitchBend(void (*fptr)(byte channel, int bend)); 00217 void setHandleSystemExclusive(void (*fptr)(byte * array, byte size)); 00218 void setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)); 00219 void setHandleSongPosition(void (*fptr)(unsigned int beats)); 00220 void setHandleSongSelect(void (*fptr)(byte songnumber)); 00221 void setHandleTuneRequest(void (*fptr)(void)); 00222 void setHandleClock(void (*fptr)(void)); 00223 void setHandleStart(void (*fptr)(void)); 00224 void setHandleContinue(void (*fptr)(void)); 00225 void setHandleStop(void (*fptr)(void)); 00226 void setHandleActiveSensing(void (*fptr)(void)); 00227 void setHandleSystemReset(void (*fptr)(void)); 00228 00229 void disconnectCallbackFromType(kMIDIType Type); 00230 00231 #endif // USE_CALLBACKS 00232 00233 00234 private: 00235 00236 bool input_filter(byte inChannel); 00237 bool parse(byte inChannel); 00238 void reset_input_attributes(); 00239 00240 // Attributes 00241 byte mRunningStatus_RX; 00242 byte mInputChannel; 00243 00244 byte mPendingMessage[MIDI_SYSEX_ARRAY_SIZE]; 00245 byte mPendingMessageExpectedLenght; 00246 byte mPendingMessageIndex; 00247 00248 midimsg mMessage; 00249 00250 #if USE_CALLBACKS 00251 00252 void launchCallback(); 00253 00254 void (*mNoteOffCallback)(byte channel, byte note, byte velocity); 00255 void (*mNoteOnCallback)(byte channel, byte note, byte velocity); 00256 void (*mAfterTouchPolyCallback)(byte channel, byte note, byte velocity); 00257 void (*mControlChangeCallback)(byte channel, byte, byte); 00258 void (*mProgramChangeCallback)(byte channel, byte); 00259 void (*mAfterTouchChannelCallback)(byte channel, byte); 00260 void (*mPitchBendCallback)(byte channel, int); 00261 void (*mSystemExclusiveCallback)(byte * array, byte size); 00262 void (*mTimeCodeQuarterFrameCallback)(byte data); 00263 void (*mSongPositionCallback)(unsigned int beats); 00264 void (*mSongSelectCallback)(byte songnumber); 00265 void (*mTuneRequestCallback)(void); 00266 void (*mClockCallback)(void); 00267 void (*mStartCallback)(void); 00268 void (*mContinueCallback)(void); 00269 void (*mStopCallback)(void); 00270 void (*mActiveSensingCallback)(void); 00271 void (*mSystemResetCallback)(void); 00272 00273 #endif // USE_CALLBACKS 00274 00275 00276 #endif // COMPILE_MIDI_IN 00277 00278 00279 /* ####### THRU COMPILATION BLOCK ####### */ 00280 #if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU) // Thru 00281 00282 public: 00283 00284 // Getters 00285 kThruFilterMode getFilterMode() { return mThruFilterMode; } 00286 bool getThruState() { return mThruActivated; } 00287 00288 00289 // Setters 00290 void turnThruOn(kThruFilterMode inThruFilterMode = Full); 00291 void turnThruOff(); 00292 00293 void setThruFilterMode(const kThruFilterMode inThruFilterMode); 00294 00295 00296 private: 00297 00298 void thru_filter(byte inChannel); 00299 00300 bool mThruActivated; 00301 kThruFilterMode mThruFilterMode; 00302 00303 #endif // Thru 00304 00305 }; 00306 00307 extern MIDI_Class MIDI; 00308 00309 #endif // LIB_MIDI_H_