X-TOUCH to djay bridge

Dependencies:   mbed mbed-rtos FATFileSystem

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