00001
00011 #ifndef LIB_MIDI_H_
00012 #define LIB_MIDI_H_
00013
00014 #include <inttypes.h>
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define COMPATIBILITY_V25 1 // Enable compatibility with MIDI Library v2.5
00031
00032
00033 #define COMPFLAG_MIDI_IN 1 // Set this setting to 1 to use the MIDI input.
00034 #define COMPFLAG_MIDI_OUT 1 // Set this setting to 1 to use the MIDI output.
00035
00036
00037 #define USE_SERIAL_PORT Serial // Change the number (to Serial1 for example) if you want
00038
00039
00040
00041 #define USE_RUNNING_STATUS 1 // Running status enables short messages when sending multiple values
00042
00043
00044
00045
00046
00047
00048
00049 #if COMPATIBILITY_V25
00050 #include "Compatibility_v2.5.h"
00051 #endif
00052
00053 #define MIDI_BAUDRATE 31250
00054
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
00065 enum kMIDIType {
00066 NoteOff = 0x80,
00067 NoteOn = 0x90,
00068 AfterTouchPoly = 0xA0,
00069 ControlChange = 0xB0,
00070 ProgramChange = 0xC0,
00071 AfterTouchChannel = 0xD0,
00072 PitchBend = 0xE0,
00073 SystemExclusive = 0xF0,
00074 TimeCodeQuarterFrame = 0xF1,
00075 SongPosition = 0xF2,
00076 SongSelect = 0xF3,
00077 TuneRequest = 0xF6,
00078 Clock = 0xF8,
00079 Start = 0xFA,
00080 Continue = 0xFB,
00081 Stop = 0xFC,
00082 ActiveSensing = 0xFE,
00083 SystemReset = 0xFF,
00084 InvalidType = 0x00
00085 };
00086
00088 enum kThruFilterMode {
00089 Off = 0,
00090 Full = 1,
00091 SameChannel = 2,
00092 DifferentChannel = 3
00093 };
00094
00095
00097 struct midimsg {
00099 byte channel;
00101 kMIDIType type;
00103 byte data1;
00105 byte data2;
00107 byte sysex_array[MIDI_SYSEX_ARRAY_SIZE];
00109 bool valid;
00110 };
00111
00112
00117 class MIDI_Class {
00118
00119
00120 public:
00121
00122 MIDI_Class();
00123 ~MIDI_Class();
00124
00125
00126 void begin(const byte inChannel = 1);
00127
00128
00129
00130
00131
00132 #if COMPFLAG_MIDI_OUT
00133
00134 public:
00135
00136 void sendNoteOn(byte NoteNumber,byte Velocity,byte Channel);
00137 void sendNoteOff(byte NoteNumber,byte Velocity,byte Channel);
00138 void sendProgramChange(byte ProgramNumber,byte Channel);
00139 void sendControlChange(byte ControlNumber, byte ControlValue,byte Channel);
00140 void sendPitchBend(unsigned int PitchValue,byte Channel);
00141 void sendPitchBend(double PitchValue,byte Channel);
00142 void sendPolyPressure(byte NoteNumber,byte Pressure,byte Channel);
00143 void sendAfterTouch(byte Pressure,byte Channel);
00144 void sendSysEx(byte length, byte * array,bool ArrayContainsBoundaries = false);
00145 void sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble);
00146 void sendTimeCodeQuarterFrame(byte data);
00147 void sendSongPosition(unsigned int Beats);
00148 void sendSongSelect(byte SongNumber);
00149 void sendTuneRequest();
00150 void sendRealTime(kMIDIType Type);
00151
00152
00153 private:
00154
00155 const byte genstatus(const kMIDIType inType,const byte inChannel);
00156 void send(kMIDIType type, byte param1, byte param2, byte channel);
00157
00158
00159 #if USE_RUNNING_STATUS
00160 byte mRunningStatus_TX;
00161 #endif // USE_RUNNING_STATUS
00162
00163 #endif // COMPFLAG_MIDI_OUT
00164
00165
00166
00167
00168 #if COMPFLAG_MIDI_IN
00169
00170 public:
00171
00172 bool read();
00173 bool read(const byte Channel);
00174
00175
00176 kMIDIType getType();
00177 byte getChannel();
00178 byte getData1();
00179 byte getData2();
00180 byte * getSysExArray();
00181 bool check();
00182
00183 byte getInputChannel() { return mInputChannel; }
00184
00185
00186 void setInputChannel(const byte Channel);
00187
00188 private:
00189
00190 inline const kMIDIType getTypeFromStatusByte(const byte inStatus) {
00191 if ((inStatus < 0x80)
00192 || (inStatus == 0xF4)
00193 || (inStatus == 0xF5)
00194 || (inStatus == 0xF9)
00195 || (inStatus == 0xFD)) return InvalidType;
00196 if (inStatus < 0xF0) return (kMIDIType)(inStatus & 0xF0);
00197 else return (kMIDIType)inStatus;
00198 }
00199
00200 bool filter(byte inChannel);
00201 bool parse(byte inChannel);
00202
00203
00204
00205 byte mRunningStatus_RX;
00206 byte mInputChannel;
00207
00208 byte mPendingMessage[MIDI_SYSEX_ARRAY_SIZE];
00209 byte mPendingMessageExpectedLenght;
00210 byte mPendingMessageIndex;
00211
00212 midimsg mMessage;
00213
00214 #endif // COMPFLAG_MIDI_IN
00215
00216
00217
00218 #if (COMPFLAG_MIDI_IN && COMPFLAG_MIDI_OUT) // Thru
00219
00220 public:
00221
00222
00223 kThruFilterMode getFilterMode() { return mThruFilterMode; }
00224 bool getThruState() { return mThruActivated; }
00225
00226
00227
00228 void turnThruOn(kThruFilterMode inThruFilterMode = Full);
00229 void turnThruOff();
00230
00231 void setThruFilterMode(const byte inThruFilterMode);
00232 void setThruFilterMode(const kThruFilterMode inThruFilterMode);
00233
00234
00235 private:
00236
00237 bool mThruActivated;
00238 kThruFilterMode mThruFilterMode;
00239
00240 #endif // Thru
00241
00242 };
00243
00244 extern MIDI_Class MIDI;
00245
00246 #endif // LIB_MIDI_H_