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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MIDI.h Source File

MIDI.h

Go to the documentation of this file.
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_