Arduino MIDI Library Version 3.2
/Users/franky/Documents/Dropbox/SVN/embedded/toolbox/libraries/MIDILib/trunk/Arduino/MIDI/MIDI.h
Go to the documentation of this file.
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_