Quake wip.
This commit is contained in:
parent
5a42cb006d
commit
4b8b38aeaf
258
src/MIDI.cpp
258
src/MIDI.cpp
|
|
@ -2,7 +2,7 @@
|
||||||
* @file MIDI.cpp
|
* @file MIDI.cpp
|
||||||
* Project Arduino MIDI Library
|
* Project Arduino MIDI Library
|
||||||
* @brief MIDI Library for the Arduino
|
* @brief MIDI Library for the Arduino
|
||||||
* @version 3.2
|
* @version 4.0
|
||||||
* @author Francois Best
|
* @author Francois Best
|
||||||
* @date 24/02/11
|
* @date 24/02/11
|
||||||
* license GPL Forty Seven Effects - 2011
|
* license GPL Forty Seven Effects - 2011
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "Arduino.h" // If using an old (pre-1.0) version of Arduino,
|
#include "Arduino.h" // If using an old (pre-1.0) version of Arduino,
|
||||||
// use WConstants.h instead of Arduino.h
|
// use WConstants.h instead of Arduino.h
|
||||||
|
|
||||||
#if MIDI_USE_SOFTWARE_SERIAL
|
#if MIDI_USE_SOFTWARE_SERIAL
|
||||||
|
|
||||||
// Note: Make sure the following relative path is correct.
|
// Note: Make sure the following relative path is correct.
|
||||||
|
|
@ -26,14 +27,17 @@ SoftwareSerial softSerialClass(MIDI_SOFTSERIAL_RX_PIN,
|
||||||
#endif // MIDI_USE_SOFTWARE_SERIAL
|
#endif // MIDI_USE_SOFTWARE_SERIAL
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Main instance (the class comes pre-instantiated). */
|
#if MIDI_AUTO_INSTANCIATE
|
||||||
MIDI_Class MIDI;
|
midi::MidiInterface MIDI;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Default constructor for MIDI_Class. */
|
BEGIN_MIDI_NAMESPACE
|
||||||
MIDI_Class::MIDI_Class()
|
|
||||||
|
/*! \brief Default constructor for MidiInterface. */
|
||||||
|
MidiInterface::MidiInterface()
|
||||||
{
|
{
|
||||||
#if COMPILE_MIDI_IN && USE_CALLBACKS
|
#if MIDI_BUILD_INPUT && USE_CALLBACKS
|
||||||
|
|
||||||
// Initialise callbacks to NULL pointer
|
// Initialise callbacks to NULL pointer
|
||||||
mNoteOffCallback = NULL;
|
mNoteOffCallback = NULL;
|
||||||
|
|
@ -59,11 +63,11 @@ MIDI_Class::MIDI_Class()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Default destructor for MIDI_Class.
|
/*! \brief Default destructor for MidiInterface.
|
||||||
|
|
||||||
This is not really useful for the Arduino, as it is never called...
|
This is not really useful for the Arduino, as it is never called...
|
||||||
*/
|
*/
|
||||||
MIDI_Class::~MIDI_Class()
|
MidiInterface::~MidiInterface()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -75,19 +79,19 @@ MIDI_Class::~MIDI_Class()
|
||||||
- Input channel set to 1 if no value is specified
|
- Input channel set to 1 if no value is specified
|
||||||
- Full thru mirroring
|
- Full thru mirroring
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::begin(const byte inChannel)
|
void MidiInterface::begin(const byte inChannel)
|
||||||
{
|
{
|
||||||
// Initialise the Serial port
|
// Initialise the Serial port
|
||||||
MIDI_SERIAL_PORT.begin(MIDI_BAUDRATE);
|
MIDI_SERIAL_PORT.begin(MIDI_BAUDRATE);
|
||||||
|
|
||||||
#if COMPILE_MIDI_OUT && USE_RUNNING_STATUS
|
#if MIDI_BUILD_OUTPUT && MIDI_USE_RUNNING_STATUS
|
||||||
|
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_OUT && USE_RUNNING_STATUS
|
#endif // MIDI_BUILD_OUTPUT && MIDI_USE_RUNNING_STATUS
|
||||||
|
|
||||||
|
|
||||||
#if COMPILE_MIDI_IN
|
#if MIDI_BUILD_INPUT
|
||||||
|
|
||||||
mInputChannel = inChannel;
|
mInputChannel = inChannel;
|
||||||
mRunningStatus_RX = InvalidType;
|
mRunningStatus_RX = InvalidType;
|
||||||
|
|
@ -100,10 +104,10 @@ void MIDI_Class::begin(const byte inChannel)
|
||||||
mMessage.data1 = 0;
|
mMessage.data1 = 0;
|
||||||
mMessage.data2 = 0;
|
mMessage.data2 = 0;
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_IN
|
#endif // MIDI_BUILD_INPUT
|
||||||
|
|
||||||
|
|
||||||
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU) // Thru
|
#if (MIDI_BUILD_INPUT && MIDI_BUILD_OUTPUT && MIDI_BUILD_THRU) // Thru
|
||||||
|
|
||||||
mThruFilterMode = Full;
|
mThruFilterMode = Full;
|
||||||
mThruActivated = true;
|
mThruActivated = true;
|
||||||
|
|
@ -117,14 +121,7 @@ void MIDI_Class::begin(const byte inChannel)
|
||||||
// MIDI Output
|
// MIDI Output
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
#if COMPILE_MIDI_OUT
|
#if MIDI_BUILD_OUTPUT
|
||||||
|
|
||||||
// Private method for generating a status byte from channel and type
|
|
||||||
const byte MIDI_Class::genstatus(const kMIDIType inType,
|
|
||||||
const byte inChannel) const
|
|
||||||
{
|
|
||||||
return ((byte)inType | ((inChannel-1) & 0x0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Generate and send a MIDI message from the values given.
|
/*! \brief Generate and send a MIDI message from the values given.
|
||||||
|
|
@ -138,7 +135,7 @@ const byte MIDI_Class::genstatus(const kMIDIType inType,
|
||||||
This is an internal method, use it only if you need to send raw data
|
This is an internal method, use it only if you need to send raw data
|
||||||
from your code, at your own risks.
|
from your code, at your own risks.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::send(kMIDIType type,
|
void MidiInterface::send(MidiType type,
|
||||||
byte data1,
|
byte data1,
|
||||||
byte data2,
|
byte data2,
|
||||||
byte channel)
|
byte channel)
|
||||||
|
|
@ -149,7 +146,7 @@ void MIDI_Class::send(kMIDIType type,
|
||||||
type < NoteOff)
|
type < NoteOff)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -164,7 +161,7 @@ void MIDI_Class::send(kMIDIType type,
|
||||||
|
|
||||||
byte statusbyte = genstatus(type,channel);
|
byte statusbyte = genstatus(type,channel);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
// Check Running Status
|
// Check Running Status
|
||||||
if (mRunningStatus_TX != statusbyte)
|
if (mRunningStatus_TX != statusbyte)
|
||||||
{
|
{
|
||||||
|
|
@ -198,7 +195,7 @@ void MIDI_Class::send(kMIDIType type,
|
||||||
Take a look at the values, names and frequencies of notes here:
|
Take a look at the values, names and frequencies of notes here:
|
||||||
http://www.phys.unsw.edu.au/jw/notes.html
|
http://www.phys.unsw.edu.au/jw/notes.html
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendNoteOn(byte NoteNumber,
|
void MidiInterface::sendNoteOn(byte NoteNumber,
|
||||||
byte Velocity,
|
byte Velocity,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
|
|
@ -217,7 +214,7 @@ void MIDI_Class::sendNoteOn(byte NoteNumber,
|
||||||
Take a look at the values, names and frequencies of notes here:
|
Take a look at the values, names and frequencies of notes here:
|
||||||
http://www.phys.unsw.edu.au/jw/notes.html
|
http://www.phys.unsw.edu.au/jw/notes.html
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendNoteOff(byte NoteNumber,
|
void MidiInterface::sendNoteOff(byte NoteNumber,
|
||||||
byte Velocity,
|
byte Velocity,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
|
|
@ -229,7 +226,7 @@ void MIDI_Class::sendNoteOff(byte NoteNumber,
|
||||||
\param ProgramNumber The Program to select (0 to 127).
|
\param ProgramNumber The Program to select (0 to 127).
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendProgramChange(byte ProgramNumber,
|
void MidiInterface::sendProgramChange(byte ProgramNumber,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
send(ProgramChange,ProgramNumber,0,Channel);
|
send(ProgramChange,ProgramNumber,0,Channel);
|
||||||
|
|
@ -244,7 +241,7 @@ void MIDI_Class::sendProgramChange(byte ProgramNumber,
|
||||||
See the detailed controllers numbers & description here:
|
See the detailed controllers numbers & description here:
|
||||||
http://www.somascape.org/midi/tech/spec.html#ctrlnums
|
http://www.somascape.org/midi/tech/spec.html#ctrlnums
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendControlChange(byte ControlNumber,
|
void MidiInterface::sendControlChange(byte ControlNumber,
|
||||||
byte ControlValue,
|
byte ControlValue,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
|
|
@ -257,7 +254,7 @@ void MIDI_Class::sendControlChange(byte ControlNumber,
|
||||||
\param Pressure The amount of AfterTouch to apply (0 to 127).
|
\param Pressure The amount of AfterTouch to apply (0 to 127).
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendPolyPressure(byte NoteNumber,
|
void MidiInterface::sendPolyPressure(byte NoteNumber,
|
||||||
byte Pressure,
|
byte Pressure,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
|
|
@ -269,7 +266,7 @@ void MIDI_Class::sendPolyPressure(byte NoteNumber,
|
||||||
\param Pressure The amount of AfterTouch to apply to all notes.
|
\param Pressure The amount of AfterTouch to apply to all notes.
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendAfterTouch(byte Pressure,
|
void MidiInterface::sendAfterTouch(byte Pressure,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
send(AfterTouchChannel,Pressure,0,Channel);
|
send(AfterTouchChannel,Pressure,0,Channel);
|
||||||
|
|
@ -282,7 +279,7 @@ void MIDI_Class::sendAfterTouch(byte Pressure,
|
||||||
center value is 0.
|
center value is 0.
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendPitchBend(int PitchValue,
|
void MidiInterface::sendPitchBend(int PitchValue,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
const unsigned int bend = PitchValue - MIDI_PITCHBEND_MIN;
|
const unsigned int bend = PitchValue - MIDI_PITCHBEND_MIN;
|
||||||
|
|
@ -296,7 +293,7 @@ void MIDI_Class::sendPitchBend(int PitchValue,
|
||||||
and +1.0f (max upwards bend), center value is 0.0f.
|
and +1.0f (max upwards bend), center value is 0.0f.
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendPitchBend(double PitchValue,
|
void MidiInterface::sendPitchBend(double PitchValue,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
{
|
{
|
||||||
const int pitchval = PitchValue * MIDI_PITCHBEND_MAX;
|
const int pitchval = PitchValue * MIDI_PITCHBEND_MAX;
|
||||||
|
|
@ -313,7 +310,7 @@ void MIDI_Class::sendPitchBend(double PitchValue,
|
||||||
default value for ArrayContainsBoundaries is set to 'false' for compatibility
|
default value for ArrayContainsBoundaries is set to 'false' for compatibility
|
||||||
with previous versions of the library.
|
with previous versions of the library.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendSysEx(int length,
|
void MidiInterface::sendSysEx(int length,
|
||||||
const byte *const array,
|
const byte *const array,
|
||||||
bool ArrayContainsBoundaries)
|
bool ArrayContainsBoundaries)
|
||||||
{
|
{
|
||||||
|
|
@ -332,7 +329,7 @@ void MIDI_Class::sendSysEx(int length,
|
||||||
MIDI_SERIAL_PORT.write(array[i]);
|
MIDI_SERIAL_PORT.write(array[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -343,7 +340,7 @@ void MIDI_Class::sendSysEx(int length,
|
||||||
When a MIDI unit receives this message,
|
When a MIDI unit receives this message,
|
||||||
it should tune its oscillators (if equipped with any).
|
it should tune its oscillators (if equipped with any).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendTuneRequest()
|
void MidiInterface::sendTuneRequest()
|
||||||
{
|
{
|
||||||
sendRealTime(TuneRequest);
|
sendRealTime(TuneRequest);
|
||||||
}
|
}
|
||||||
|
|
@ -355,7 +352,7 @@ void MIDI_Class::sendTuneRequest()
|
||||||
\param ValuesNibble MTC data
|
\param ValuesNibble MTC data
|
||||||
See MIDI Specification for more information.
|
See MIDI Specification for more information.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble)
|
void MidiInterface::sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble)
|
||||||
{
|
{
|
||||||
const byte data = ( ((TypeNibble & 0x07) << 4) | (ValuesNibble & 0x0F) );
|
const byte data = ( ((TypeNibble & 0x07) << 4) | (ValuesNibble & 0x0F) );
|
||||||
sendTimeCodeQuarterFrame(data);
|
sendTimeCodeQuarterFrame(data);
|
||||||
|
|
@ -368,12 +365,12 @@ void MIDI_Class::sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble)
|
||||||
\param data if you want to encode directly the nibbles in your program,
|
\param data if you want to encode directly the nibbles in your program,
|
||||||
you can send the byte here.
|
you can send the byte here.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendTimeCodeQuarterFrame(byte data)
|
void MidiInterface::sendTimeCodeQuarterFrame(byte data)
|
||||||
{
|
{
|
||||||
MIDI_SERIAL_PORT.write((byte)TimeCodeQuarterFrame);
|
MIDI_SERIAL_PORT.write((byte)TimeCodeQuarterFrame);
|
||||||
MIDI_SERIAL_PORT.write(data);
|
MIDI_SERIAL_PORT.write(data);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -382,25 +379,25 @@ void MIDI_Class::sendTimeCodeQuarterFrame(byte data)
|
||||||
/*! \brief Send a Song Position Pointer message.
|
/*! \brief Send a Song Position Pointer message.
|
||||||
\param Beats The number of beats since the start of the song.
|
\param Beats The number of beats since the start of the song.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendSongPosition(unsigned int Beats)
|
void MidiInterface::sendSongPosition(unsigned int Beats)
|
||||||
{
|
{
|
||||||
MIDI_SERIAL_PORT.write((byte)SongPosition);
|
MIDI_SERIAL_PORT.write((byte)SongPosition);
|
||||||
MIDI_SERIAL_PORT.write(Beats & 0x7F);
|
MIDI_SERIAL_PORT.write(Beats & 0x7F);
|
||||||
MIDI_SERIAL_PORT.write((Beats >> 7) & 0x7F);
|
MIDI_SERIAL_PORT.write((Beats >> 7) & 0x7F);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Song Select message */
|
/*! \brief Send a Song Select message */
|
||||||
void MIDI_Class::sendSongSelect(byte SongNumber)
|
void MidiInterface::sendSongSelect(byte SongNumber)
|
||||||
{
|
{
|
||||||
MIDI_SERIAL_PORT.write((byte)SongSelect);
|
MIDI_SERIAL_PORT.write((byte)SongSelect);
|
||||||
MIDI_SERIAL_PORT.write(SongNumber & 0x7F);
|
MIDI_SERIAL_PORT.write(SongNumber & 0x7F);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -411,9 +408,9 @@ void MIDI_Class::sendSongSelect(byte SongNumber)
|
||||||
\param Type The available Real Time types are:
|
\param Type The available Real Time types are:
|
||||||
Start, Stop, Continue, Clock, ActiveSensing and SystemReset.
|
Start, Stop, Continue, Clock, ActiveSensing and SystemReset.
|
||||||
You can also send a Tune Request with this method.
|
You can also send a Tune Request with this method.
|
||||||
@see kMIDIType
|
@see MidiType
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendRealTime(kMIDIType Type)
|
void MidiInterface::sendRealTime(MidiType Type)
|
||||||
{
|
{
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
|
|
@ -434,19 +431,19 @@ void MIDI_Class::sendRealTime(kMIDIType Type)
|
||||||
// Do not cancel Running Status for real-time messages as they can be
|
// Do not cancel Running Status for real-time messages as they can be
|
||||||
// interleaved within any message. Though, TuneRequest can be sent here,
|
// interleaved within any message. Though, TuneRequest can be sent here,
|
||||||
// and as it is a System Common message, it must reset Running Status.
|
// and as it is a System Common message, it must reset Running Status.
|
||||||
#if USE_RUNNING_STATUS
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
if (Type == TuneRequest) mRunningStatus_TX = InvalidType;
|
if (Type == TuneRequest) mRunningStatus_TX = InvalidType;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_OUT
|
#endif // MIDI_BUILD_OUTPUT
|
||||||
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// MIDI Input
|
// MIDI Input
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
#if COMPILE_MIDI_IN
|
#if MIDI_BUILD_INPUT
|
||||||
|
|
||||||
/*! \brief Read a MIDI message from the serial port
|
/*! \brief Read a MIDI message from the serial port
|
||||||
using the main input channel (see setInputChannel() for reference).
|
using the main input channel (see setInputChannel() for reference).
|
||||||
|
|
@ -456,7 +453,7 @@ void MIDI_Class::sendRealTime(kMIDIType Type)
|
||||||
If the Thru is enabled and the messages matches the filter,
|
If the Thru is enabled and the messages matches the filter,
|
||||||
it is sent back on the MIDI output.
|
it is sent back on the MIDI output.
|
||||||
*/
|
*/
|
||||||
bool MIDI_Class::read()
|
bool MidiInterface::read()
|
||||||
{
|
{
|
||||||
return read(mInputChannel);
|
return read(mInputChannel);
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +462,7 @@ bool MIDI_Class::read()
|
||||||
/*! \brief Reading/thru-ing method, the same as read()
|
/*! \brief Reading/thru-ing method, the same as read()
|
||||||
with a given input channel to read on.
|
with a given input channel to read on.
|
||||||
*/
|
*/
|
||||||
bool MIDI_Class::read(const byte inChannel)
|
bool MidiInterface::read(const byte inChannel)
|
||||||
{
|
{
|
||||||
if (inChannel >= MIDI_CHANNEL_OFF)
|
if (inChannel >= MIDI_CHANNEL_OFF)
|
||||||
return false; // MIDI Input disabled.
|
return false; // MIDI Input disabled.
|
||||||
|
|
@ -475,7 +472,7 @@ bool MIDI_Class::read(const byte inChannel)
|
||||||
if (input_filter(inChannel))
|
if (input_filter(inChannel))
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (COMPILE_MIDI_OUT && COMPILE_MIDI_THRU)
|
#if (MIDI_BUILD_OUTPUT && MIDI_BUILD_THRU)
|
||||||
thru_filter(inChannel);
|
thru_filter(inChannel);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -491,7 +488,7 @@ bool MIDI_Class::read(const byte inChannel)
|
||||||
|
|
||||||
|
|
||||||
// Private method: MIDI parser
|
// Private method: MIDI parser
|
||||||
bool MIDI_Class::parse(byte inChannel)
|
bool MidiInterface::parse(byte inChannel)
|
||||||
{
|
{
|
||||||
const byte bytes_available = MIDI_SERIAL_PORT.available();
|
const byte bytes_available = MIDI_SERIAL_PORT.available();
|
||||||
|
|
||||||
|
|
@ -662,7 +659,7 @@ bool MIDI_Class::parse(byte inChannel)
|
||||||
// This is done by leaving the pending message as is,
|
// This is done by leaving the pending message as is,
|
||||||
// it will be completed on next calls.
|
// it will be completed on next calls.
|
||||||
|
|
||||||
mMessage.type = (kMIDIType)extracted;
|
mMessage.type = (MidiType)extracted;
|
||||||
mMessage.data1 = 0;
|
mMessage.data1 = 0;
|
||||||
mMessage.data2 = 0;
|
mMessage.data2 = 0;
|
||||||
mMessage.channel = 0;
|
mMessage.channel = 0;
|
||||||
|
|
@ -779,7 +776,7 @@ bool MIDI_Class::parse(byte inChannel)
|
||||||
|
|
||||||
|
|
||||||
// Private method: check if the received message is on the listened channel
|
// Private method: check if the received message is on the listened channel
|
||||||
bool MIDI_Class::input_filter(byte inChannel)
|
bool MidiInterface::input_filter(byte inChannel)
|
||||||
{
|
{
|
||||||
// This method handles recognition of channel
|
// This method handles recognition of channel
|
||||||
// (to know if the message is destinated to the Arduino)
|
// (to know if the message is destinated to the Arduino)
|
||||||
|
|
@ -811,7 +808,7 @@ bool MIDI_Class::input_filter(byte inChannel)
|
||||||
|
|
||||||
|
|
||||||
// Private method: reset input attributes
|
// Private method: reset input attributes
|
||||||
void MIDI_Class::reset_input_attributes()
|
void MidiInterface::reset_input_attributes()
|
||||||
{
|
{
|
||||||
mPendingMessageIndex = 0;
|
mPendingMessageIndex = 0;
|
||||||
mPendingMessageExpectedLenght = 0;
|
mPendingMessageExpectedLenght = 0;
|
||||||
|
|
@ -819,102 +816,30 @@ void MIDI_Class::reset_input_attributes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
/*! \brief Get the last received message's type
|
|
||||||
|
|
||||||
Returns an enumerated type. @see kMIDIType
|
|
||||||
*/
|
|
||||||
kMIDIType MIDI_Class::getType() const
|
|
||||||
{
|
|
||||||
return mMessage.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Get the channel of the message stored in the structure.
|
|
||||||
|
|
||||||
\return Channel range is 1 to 16.
|
|
||||||
For non-channel messages, this will return 0.
|
|
||||||
*/
|
|
||||||
byte MIDI_Class::getChannel() const
|
|
||||||
{
|
|
||||||
return mMessage.channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Get the first data byte of the last received message. */
|
|
||||||
byte MIDI_Class::getData1() const
|
|
||||||
{
|
|
||||||
return mMessage.data1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Get the second data byte of the last received message. */
|
|
||||||
byte MIDI_Class::getData2() const
|
|
||||||
{
|
|
||||||
return mMessage.data2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Get the System Exclusive byte array.
|
|
||||||
|
|
||||||
@see getSysExArrayLength to get the array's length in bytes.
|
|
||||||
*/
|
|
||||||
const byte * MIDI_Class::getSysExArray() const
|
|
||||||
{
|
|
||||||
return mMessage.sysex_array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Get the lenght of the System Exclusive array.
|
|
||||||
|
|
||||||
It is coded using data1 as LSB and data2 as MSB.
|
|
||||||
\return The array's length, in bytes.
|
|
||||||
*/
|
|
||||||
unsigned int MIDI_Class::getSysExArrayLength() const
|
|
||||||
{
|
|
||||||
const unsigned int size = ((unsigned)(mMessage.data2) << 8) | mMessage.data1;
|
|
||||||
return (size > MIDI_SYSEX_ARRAY_SIZE) ? MIDI_SYSEX_ARRAY_SIZE : size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Check if a valid message is stored in the structure. */
|
|
||||||
bool MIDI_Class::check() const
|
|
||||||
{
|
|
||||||
return mMessage.valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
/*! \brief Set the value for the input MIDI channel
|
|
||||||
\param Channel the channel value. Valid values are 1 to 16,
|
|
||||||
MIDI_CHANNEL_OMNI if you want to listen to all channels,
|
|
||||||
and MIDI_CHANNEL_OFF to disable MIDI input.
|
|
||||||
*/
|
|
||||||
void MIDI_Class::setInputChannel(const byte Channel)
|
|
||||||
{
|
|
||||||
mInputChannel = Channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if USE_CALLBACKS
|
#if USE_CALLBACKS
|
||||||
|
|
||||||
void MIDI_Class::setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOffCallback = fptr; }
|
void MidiInterface::setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOffCallback = fptr; }
|
||||||
void MIDI_Class::setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOnCallback = fptr; }
|
void MidiInterface::setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOnCallback = fptr; }
|
||||||
void MIDI_Class::setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)) { mAfterTouchPolyCallback = fptr; }
|
void MidiInterface::setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)) { mAfterTouchPolyCallback = fptr; }
|
||||||
void MIDI_Class::setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)) { mControlChangeCallback = fptr; }
|
void MidiInterface::setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)) { mControlChangeCallback = fptr; }
|
||||||
void MIDI_Class::setHandleProgramChange(void (*fptr)(byte channel, byte number)) { mProgramChangeCallback = fptr; }
|
void MidiInterface::setHandleProgramChange(void (*fptr)(byte channel, byte number)) { mProgramChangeCallback = fptr; }
|
||||||
void MIDI_Class::setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)) { mAfterTouchChannelCallback = fptr; }
|
void MidiInterface::setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)) { mAfterTouchChannelCallback = fptr; }
|
||||||
void MIDI_Class::setHandlePitchBend(void (*fptr)(byte channel, int bend)) { mPitchBendCallback = fptr; }
|
void MidiInterface::setHandlePitchBend(void (*fptr)(byte channel, int bend)) { mPitchBendCallback = fptr; }
|
||||||
void MIDI_Class::setHandleSystemExclusive(void (*fptr)(byte * array, byte size)) { mSystemExclusiveCallback = fptr; }
|
void MidiInterface::setHandleSystemExclusive(void (*fptr)(byte * array, byte size)) { mSystemExclusiveCallback = fptr; }
|
||||||
void MIDI_Class::setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)) { mTimeCodeQuarterFrameCallback = fptr; }
|
void MidiInterface::setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)) { mTimeCodeQuarterFrameCallback = fptr; }
|
||||||
void MIDI_Class::setHandleSongPosition(void (*fptr)(unsigned int beats)) { mSongPositionCallback = fptr; }
|
void MidiInterface::setHandleSongPosition(void (*fptr)(unsigned int beats)) { mSongPositionCallback = fptr; }
|
||||||
void MIDI_Class::setHandleSongSelect(void (*fptr)(byte songnumber)) { mSongSelectCallback = fptr; }
|
void MidiInterface::setHandleSongSelect(void (*fptr)(byte songnumber)) { mSongSelectCallback = fptr; }
|
||||||
void MIDI_Class::setHandleTuneRequest(void (*fptr)(void)) { mTuneRequestCallback = fptr; }
|
void MidiInterface::setHandleTuneRequest(void (*fptr)(void)) { mTuneRequestCallback = fptr; }
|
||||||
void MIDI_Class::setHandleClock(void (*fptr)(void)) { mClockCallback = fptr; }
|
void MidiInterface::setHandleClock(void (*fptr)(void)) { mClockCallback = fptr; }
|
||||||
void MIDI_Class::setHandleStart(void (*fptr)(void)) { mStartCallback = fptr; }
|
void MidiInterface::setHandleStart(void (*fptr)(void)) { mStartCallback = fptr; }
|
||||||
void MIDI_Class::setHandleContinue(void (*fptr)(void)) { mContinueCallback = fptr; }
|
void MidiInterface::setHandleContinue(void (*fptr)(void)) { mContinueCallback = fptr; }
|
||||||
void MIDI_Class::setHandleStop(void (*fptr)(void)) { mStopCallback = fptr; }
|
void MidiInterface::setHandleStop(void (*fptr)(void)) { mStopCallback = fptr; }
|
||||||
void MIDI_Class::setHandleActiveSensing(void (*fptr)(void)) { mActiveSensingCallback = fptr; }
|
void MidiInterface::setHandleActiveSensing(void (*fptr)(void)) { mActiveSensingCallback = fptr; }
|
||||||
void MIDI_Class::setHandleSystemReset(void (*fptr)(void)) { mSystemResetCallback = fptr; }
|
void MidiInterface::setHandleSystemReset(void (*fptr)(void)) { mSystemResetCallback = fptr; }
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Detach an external function from the given type.
|
/*! \brief Detach an external function from the given type.
|
||||||
|
|
@ -923,7 +848,7 @@ void MIDI_Class::setHandleSystemReset(void (*fptr)(void))
|
||||||
\param Type The type of message to unbind.
|
\param Type The type of message to unbind.
|
||||||
When a message of this type is received, no function will be called.
|
When a message of this type is received, no function will be called.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::disconnectCallbackFromType(kMIDIType Type)
|
void MidiInterface::disconnectCallbackFromType(MidiType Type)
|
||||||
{
|
{
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
|
|
@ -952,7 +877,7 @@ void MIDI_Class::disconnectCallbackFromType(kMIDIType Type)
|
||||||
|
|
||||||
|
|
||||||
// Private - launch callback function based on received type.
|
// Private - launch callback function based on received type.
|
||||||
void MIDI_Class::launchCallback()
|
void MidiInterface::launchCallback()
|
||||||
{
|
{
|
||||||
// The order is mixed to allow frequent messages to trigger their callback faster.
|
// The order is mixed to allow frequent messages to trigger their callback faster.
|
||||||
switch (mMessage.type)
|
switch (mMessage.type)
|
||||||
|
|
@ -994,49 +919,18 @@ void MIDI_Class::launchCallback()
|
||||||
#endif // USE_CALLBACKS
|
#endif // USE_CALLBACKS
|
||||||
|
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_IN
|
#endif // MIDI_BUILD_INPUT
|
||||||
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// MIDI Soft Thru
|
// MIDI Soft Thru
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU)
|
#if (MIDI_BUILD_INPUT && MIDI_BUILD_OUTPUT && MIDI_BUILD_THRU)
|
||||||
|
|
||||||
/*! \brief Set the filter for thru mirroring
|
|
||||||
\param inThruFilterMode a filter mode
|
|
||||||
|
|
||||||
@see kThruFilterMode
|
|
||||||
*/
|
|
||||||
void MIDI_Class::setThruFilterMode(kThruFilterMode inThruFilterMode)
|
|
||||||
{
|
|
||||||
mThruFilterMode = inThruFilterMode;
|
|
||||||
if (mThruFilterMode != Off)
|
|
||||||
mThruActivated = true;
|
|
||||||
else
|
|
||||||
mThruActivated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Setter method: turn message mirroring on. */
|
|
||||||
void MIDI_Class::turnThruOn(kThruFilterMode inThruFilterMode)
|
|
||||||
{
|
|
||||||
mThruActivated = true;
|
|
||||||
mThruFilterMode = inThruFilterMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Setter method: turn message mirroring off. */
|
|
||||||
void MIDI_Class::turnThruOff()
|
|
||||||
{
|
|
||||||
mThruActivated = false;
|
|
||||||
mThruFilterMode = Off;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This method is called upon reception of a message
|
// This method is called upon reception of a message
|
||||||
// and takes care of Thru filtering and sending.
|
// and takes care of Thru filtering and sending.
|
||||||
void MIDI_Class::thru_filter(byte inChannel)
|
void MidiInterface::thru_filter(byte inChannel)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1142,3 +1036,5 @@ void MIDI_Class::thru_filter(byte inChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // Thru
|
#endif // Thru
|
||||||
|
|
||||||
|
END_MIDI_NAMESPACE
|
||||||
|
|
|
||||||
415
src/MIDI.h
415
src/MIDI.h
|
|
@ -2,7 +2,7 @@
|
||||||
* @file MIDI.h
|
* @file MIDI.h
|
||||||
* Project Arduino MIDI Library
|
* Project Arduino MIDI Library
|
||||||
* @brief MIDI Library for the Arduino
|
* @brief MIDI Library for the Arduino
|
||||||
* @version 3.2
|
* @version 4.0
|
||||||
* @author Francois Best
|
* @author Francois Best
|
||||||
* @date 24/02/11
|
* @date 24/02/11
|
||||||
* license GPL Forty Seven Effects - 2011
|
* license GPL Forty Seven Effects - 2011
|
||||||
|
|
@ -15,313 +15,101 @@
|
||||||
#include "midi_Settings.h"
|
#include "midi_Settings.h"
|
||||||
#include "midi_Defs.h"
|
#include "midi_Defs.h"
|
||||||
|
|
||||||
/*
|
BEGIN_MIDI_NAMESPACE
|
||||||
###############################################################
|
|
||||||
# #
|
/*! \brief The main class for MIDI handling.
|
||||||
# CONFIGURATION AREA #
|
|
||||||
# #
|
|
||||||
# Here are a few settings you can change to customize #
|
|
||||||
# the library for your own project. You can for example #
|
|
||||||
# choose to compile only parts of it so you gain flash #
|
|
||||||
# space and optimise the speed of your sketch. #
|
|
||||||
# #
|
|
||||||
###############################################################
|
|
||||||
*/
|
*/
|
||||||
|
//template<typename Uart>
|
||||||
|
class MidiInterface
|
||||||
#define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input.
|
|
||||||
#define COMPILE_MIDI_OUT 1 // Set this setting to 1 to use the MIDI output.
|
|
||||||
#define COMPILE_MIDI_THRU 1 // Set this setting to 1 to use the MIDI Soft Thru feature
|
|
||||||
// Please note that the Thru will work only when both COMPILE_MIDI_IN and COMPILE_MIDI_OUT set to 1.
|
|
||||||
|
|
||||||
|
|
||||||
#define MIDI_SERIAL_PORT Serial // Change the number (to Serial1 for example) if you want
|
|
||||||
// to use a different serial port for MIDI I/O.
|
|
||||||
|
|
||||||
#define MIDI_USE_SOFTWARE_SERIAL 0 // Set to 1 to use SoftwareSerial instead of native serial ports.
|
|
||||||
#define MIDI_SOFTSERIAL_RX_PIN 1 // This pin number will be used for MIDI Input
|
|
||||||
#define MIDI_SOFTSERIAL_TX_PIN 2 // This pin number will be used for MIDI Output.
|
|
||||||
|
|
||||||
|
|
||||||
#define USE_RUNNING_STATUS 1 // Running status enables short messages when sending multiple values
|
|
||||||
// of the same type and channel.
|
|
||||||
// Set to 0 if you have troubles controlling your hardware.
|
|
||||||
|
|
||||||
|
|
||||||
#define USE_CALLBACKS 1 // Set this to 1 if you want to use callback handlers (to bind your functions to the library).
|
|
||||||
// To use the callbacks, you need to have COMPILE_MIDI_IN set to 1
|
|
||||||
|
|
||||||
#define USE_1BYTE_PARSING 1 // Each call to MIDI.read will only parse one byte (might be faster).
|
|
||||||
|
|
||||||
|
|
||||||
// END OF CONFIGURATION AREA
|
|
||||||
// (do not modify anything under this line unless you know what you are doing)
|
|
||||||
|
|
||||||
|
|
||||||
#define MIDI_BAUDRATE 31250
|
|
||||||
|
|
||||||
#define MIDI_CHANNEL_OMNI 0
|
|
||||||
#define MIDI_CHANNEL_OFF 17 // and over
|
|
||||||
|
|
||||||
#define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes.
|
|
||||||
|
|
||||||
#define MIDI_PITCHBEND_MIN -8192
|
|
||||||
#define MIDI_PITCHBEND_MAX 8191
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! Type definition for practical use
|
|
||||||
(because "unsigned char" is a bit long to write.. )
|
|
||||||
*/
|
|
||||||
typedef uint8_t byte;
|
|
||||||
typedef uint16_t word;
|
|
||||||
|
|
||||||
|
|
||||||
/*! Enumeration of MIDI types */
|
|
||||||
enum kMIDIType
|
|
||||||
{
|
|
||||||
NoteOff = 0x80, ///< Note Off
|
|
||||||
NoteOn = 0x90, ///< Note On
|
|
||||||
AfterTouchPoly = 0xA0, ///< Polyphonic AfterTouch
|
|
||||||
ControlChange = 0xB0, ///< Control Change / Channel Mode
|
|
||||||
ProgramChange = 0xC0, ///< Program Change
|
|
||||||
AfterTouchChannel = 0xD0, ///< Channel (monophonic) AfterTouch
|
|
||||||
PitchBend = 0xE0, ///< Pitch Bend
|
|
||||||
SystemExclusive = 0xF0, ///< System Exclusive
|
|
||||||
TimeCodeQuarterFrame = 0xF1, ///< System Common - MIDI Time Code Quarter Frame
|
|
||||||
SongPosition = 0xF2, ///< System Common - Song Position Pointer
|
|
||||||
SongSelect = 0xF3, ///< System Common - Song Select
|
|
||||||
TuneRequest = 0xF6, ///< System Common - Tune Request
|
|
||||||
Clock = 0xF8, ///< System Real Time - Timing Clock
|
|
||||||
Start = 0xFA, ///< System Real Time - Start
|
|
||||||
Continue = 0xFB, ///< System Real Time - Continue
|
|
||||||
Stop = 0xFC, ///< System Real Time - Stop
|
|
||||||
ActiveSensing = 0xFE, ///< System Real Time - Active Sensing
|
|
||||||
SystemReset = 0xFF, ///< System Real Time - System Reset
|
|
||||||
InvalidType = 0x00 ///< For notifying errors
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Enumeration of Thru filter modes */
|
|
||||||
enum kThruFilterMode {
|
|
||||||
Off = 0, ///< Thru disabled (nothing passes through).
|
|
||||||
Full = 1, ///< Fully enabled Thru (every incoming message is sent back).
|
|
||||||
SameChannel = 2, ///< Only the messages on the Input Channel will be sent back.
|
|
||||||
DifferentChannel = 3 ///< All the messages but the ones on the Input Channel will be sent back.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum eMIDICCNumber
|
|
||||||
{
|
|
||||||
// High resolution Continuous Controllers MSB (+32 for LSB) ----------------
|
|
||||||
BankSelect = 0,
|
|
||||||
ModulationWheel = 1,
|
|
||||||
BreathController = 2,
|
|
||||||
// CC3 undefined
|
|
||||||
FootController = 4,
|
|
||||||
PortamentoTime = 5,
|
|
||||||
DataEntry = 6,
|
|
||||||
ChannelVolume = 7,
|
|
||||||
Balance = 8,
|
|
||||||
// CC9 undefined
|
|
||||||
Pan = 10,
|
|
||||||
ExpressionController = 11,
|
|
||||||
EffectControl1 = 12,
|
|
||||||
EffectControl2 = 13,
|
|
||||||
// CC14 undefined
|
|
||||||
// CC15 undefined
|
|
||||||
GeneralPurposeController1 = 16,
|
|
||||||
GeneralPurposeController2 = 17,
|
|
||||||
GeneralPurposeController3 = 18,
|
|
||||||
GeneralPurposeController4 = 19,
|
|
||||||
|
|
||||||
// Switches ----------------------------------------------------------------
|
|
||||||
Sustain = 64,
|
|
||||||
Portamento = 65,
|
|
||||||
Sostenuto = 66,
|
|
||||||
SoftPedal = 67,
|
|
||||||
Legato = 68,
|
|
||||||
Hold2 = 69,
|
|
||||||
|
|
||||||
// Low resolution continuous controllers -----------------------------------
|
|
||||||
SoundController1 = 70, ///< Synth: Sound Variation FX: Exciter On/Off
|
|
||||||
SoundController2 = 71, ///< Synth: Harmonic Content FX: Compressor On/Off
|
|
||||||
SoundController3 = 72, ///< Synth: Release Time FX: Distortion On/Off
|
|
||||||
SoundController4 = 73, ///< Synth: Attack Time FX: EQ On/Off
|
|
||||||
SoundController5 = 74, ///< Synth: Brightness FX: Expander On/Off
|
|
||||||
SoundController6 = 75, ///< Synth: Decay Time FX: Reverb On/Off
|
|
||||||
SoundController7 = 76, ///< Synth: Vibrato Rate FX: Delay On/Off
|
|
||||||
SoundController8 = 77, ///< Synth: Vibrato Depth FX: Pitch Transpose On/Off
|
|
||||||
SoundController9 = 78, ///< Synth: Vibrato Delay FX: Flange/Chorus On/Off
|
|
||||||
SoundController10 = 79, ///< Synth: Undefined FX: Special Effects On/Off
|
|
||||||
GeneralPurposeController5 = 80,
|
|
||||||
GeneralPurposeController6 = 81,
|
|
||||||
GeneralPurposeController7 = 82,
|
|
||||||
GeneralPurposeController8 = 83,
|
|
||||||
PortamentoControl = 84,
|
|
||||||
// CC85 to CC90 undefined
|
|
||||||
Effects1 = 91, ///< Reverb send level
|
|
||||||
Effects2 = 92, ///< Tremolo depth
|
|
||||||
Effects3 = 93, ///< Chorus send level
|
|
||||||
Effects4 = 94, ///< Celeste depth
|
|
||||||
Effects5 = 95, ///< Phaser depth
|
|
||||||
|
|
||||||
// Channel Mode messages ---------------------------------------------------
|
|
||||||
AllSoundOff = 120,
|
|
||||||
ResetAllControllers = 121,
|
|
||||||
LocalControl = 122,
|
|
||||||
AllNotesOff = 123,
|
|
||||||
OmniModeOff = 124,
|
|
||||||
OmniModeOn = 125,
|
|
||||||
MonoModeOn = 126,
|
|
||||||
PolyModeOn = 127
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! The midimsg structure contains decoded data
|
|
||||||
of a MIDI message read from the serial port
|
|
||||||
with read() or thru().
|
|
||||||
*/
|
|
||||||
struct midimsg
|
|
||||||
{
|
|
||||||
|
|
||||||
/*! The MIDI channel on which the message was recieved.
|
|
||||||
\n Value goes from 1 to 16.
|
|
||||||
*/
|
|
||||||
byte channel;
|
|
||||||
|
|
||||||
/*! The type of the message
|
|
||||||
(see the define section for types reference)
|
|
||||||
*/
|
|
||||||
kMIDIType type;
|
|
||||||
|
|
||||||
/*! The first data byte.
|
|
||||||
\n Value goes from 0 to 127.
|
|
||||||
*/
|
|
||||||
byte data1;
|
|
||||||
|
|
||||||
/*! The second data byte.
|
|
||||||
If the message is only 2 bytes long, this one is null.
|
|
||||||
\n Value goes from 0 to 127.
|
|
||||||
*/
|
|
||||||
byte data2;
|
|
||||||
|
|
||||||
/*! System Exclusive dedicated byte array.
|
|
||||||
\n Array length is stocked on 16 bits,
|
|
||||||
in data1 (LSB) and data2 (MSB)
|
|
||||||
*/
|
|
||||||
byte sysex_array[MIDI_SYSEX_ARRAY_SIZE];
|
|
||||||
|
|
||||||
/*! This boolean indicates if the message is valid or not.
|
|
||||||
There is no channel consideration here,
|
|
||||||
validity means the message respects the MIDI norm.
|
|
||||||
*/
|
|
||||||
bool valid;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief The main class for MIDI handling.\n
|
|
||||||
See member descriptions to know how to use it,
|
|
||||||
or check out the examples supplied with the library.
|
|
||||||
*/
|
|
||||||
class MIDI_Class
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
MidiInterface();
|
||||||
|
~MidiInterface();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void begin(byte inChannel = 1);
|
||||||
// =========================================================================
|
|
||||||
// Constructor and Destructor
|
|
||||||
|
|
||||||
MIDI_Class();
|
|
||||||
~MIDI_Class();
|
|
||||||
|
|
||||||
void begin(const byte inChannel = 1);
|
|
||||||
|
|
||||||
|
|
||||||
// =========================================================================
|
// -------------------------------------------------------------------------
|
||||||
// MIDI Output
|
// MIDI Output
|
||||||
|
|
||||||
#if COMPILE_MIDI_OUT // Start compilation block
|
#if MIDI_BUILD_OUTPUT
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void sendNoteOn(byte NoteNumber,byte Velocity,byte Channel);
|
|
||||||
void sendNoteOff(byte NoteNumber,byte Velocity,byte Channel);
|
|
||||||
void sendProgramChange(byte ProgramNumber,byte Channel);
|
|
||||||
void sendControlChange(byte ControlNumber, byte ControlValue,byte Channel);
|
|
||||||
void sendPitchBend(int PitchValue,byte Channel);
|
|
||||||
void sendPitchBend(double PitchValue,byte Channel);
|
|
||||||
void sendPolyPressure(byte NoteNumber,byte Pressure,byte Channel);
|
|
||||||
void sendAfterTouch(byte Pressure,byte Channel);
|
|
||||||
void sendSysEx(int length, const byte *const array,bool ArrayContainsBoundaries = false);
|
|
||||||
void sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble);
|
|
||||||
void sendTimeCodeQuarterFrame(byte data);
|
|
||||||
void sendSongPosition(unsigned int Beats);
|
|
||||||
void sendSongSelect(byte SongNumber);
|
|
||||||
void sendTuneRequest();
|
|
||||||
void sendRealTime(kMIDIType Type);
|
|
||||||
|
|
||||||
void send(kMIDIType type, byte param1, byte param2, byte channel);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
const byte genstatus(const kMIDIType inType,const byte inChannel) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
#if USE_RUNNING_STATUS
|
|
||||||
byte mRunningStatus_TX;
|
|
||||||
#endif // USE_RUNNING_STATUS
|
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_OUT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// MIDI Input
|
|
||||||
|
|
||||||
#if COMPILE_MIDI_IN // Start compilation block
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void sendNoteOn(byte inNoteNumber,
|
||||||
|
byte inVelocity,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
void sendNoteOff(byte inNoteNumber,
|
||||||
|
byte inVelocity,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
void sendProgramChange(byte inProgramNumber,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
void sendControlChange(byte inControlNumber,
|
||||||
|
byte inControlValue,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
void sendPitchBend(int inPitchValue, Channel inChannel);
|
||||||
|
void sendPitchBend(double inPitchValue, Channel inChannel);
|
||||||
|
|
||||||
|
void sendPolyPressure(byte inNoteNumber,
|
||||||
|
byte inPressure,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
void sendAfterTouch(byte inPressure,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
void sendSysEx(unsigned int inLength,
|
||||||
|
const byte* inArray,
|
||||||
|
bool inArrayContainsBoundaries = false);
|
||||||
|
|
||||||
|
void sendTimeCodeQuarterFrame(byte inTypeNibble,
|
||||||
|
byte inValuesNibble);
|
||||||
|
void sendTimeCodeQuarterFrame(byte inData);
|
||||||
|
|
||||||
|
void sendSongPosition(unsigned int inBeats);
|
||||||
|
void sendSongSelect(byte inSongNumber);
|
||||||
|
void sendTuneRequest();
|
||||||
|
void sendRealTime(MidiType inType);
|
||||||
|
|
||||||
|
void send(MidiType inType,
|
||||||
|
DataByte inData1,
|
||||||
|
DataByte inData2,
|
||||||
|
Channel inChannel);
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline StatusByte getStatus(MidiType inType,
|
||||||
|
Channel inChannel) const;
|
||||||
|
|
||||||
|
#endif // MIDI_BUILD_OUTPUT
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// MIDI Input
|
||||||
|
|
||||||
|
#if MIDI_BUILD_INPUT
|
||||||
|
|
||||||
|
public:
|
||||||
bool read();
|
bool read();
|
||||||
bool read(const byte Channel);
|
bool read(Channel inChannel);
|
||||||
|
|
||||||
// Getters
|
public:
|
||||||
kMIDIType getType() const;
|
inline MidiType getType() const;
|
||||||
byte getChannel() const;
|
inline Channel getChannel() const;
|
||||||
byte getData1() const;
|
inline DataByte getData1() const;
|
||||||
byte getData2() const;
|
inline DataByte getData2() const;
|
||||||
const byte * getSysExArray() const;
|
inline const byte* getSysExArray() const;
|
||||||
unsigned int getSysExArrayLength() const;
|
inline unsigned int getSysExArrayLength() const;
|
||||||
bool check() const;
|
inline bool check() const;
|
||||||
|
|
||||||
byte getInputChannel() const
|
public:
|
||||||
{
|
inline Channel getInputChannel() const;
|
||||||
return mInputChannel;
|
inline void setInputChannel(Channel inChannel);
|
||||||
}
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
void setInputChannel(const byte Channel);
|
|
||||||
|
|
||||||
/*! \brief Extract an enumerated MIDI type from a status byte.
|
|
||||||
|
|
||||||
This is a utility static method, used internally, made public so you can handle kMIDITypes more easily.
|
|
||||||
*/
|
|
||||||
static inline const kMIDIType getTypeFromStatusByte(const byte inStatus)
|
|
||||||
{
|
|
||||||
if ((inStatus < 0x80) ||
|
|
||||||
(inStatus == 0xF4) ||
|
|
||||||
(inStatus == 0xF5) ||
|
|
||||||
(inStatus == 0xF9) ||
|
|
||||||
(inStatus == 0xFD)) return InvalidType; // data bytes and undefined.
|
|
||||||
if (inStatus < 0xF0) return (kMIDIType)(inStatus & 0xF0); // Channel message, remove channel nibble.
|
|
||||||
else return (kMIDIType)inStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
static inline MidiType getTypeFromStatusByte(const byte inStatus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -366,7 +154,7 @@ public:
|
||||||
void setHandleActiveSensing(void (*fptr)(void));
|
void setHandleActiveSensing(void (*fptr)(void));
|
||||||
void setHandleSystemReset(void (*fptr)(void));
|
void setHandleSystemReset(void (*fptr)(void));
|
||||||
|
|
||||||
void disconnectCallbackFromType(kMIDIType Type);
|
void disconnectCallbackFromType(MidiType Type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -393,39 +181,46 @@ private:
|
||||||
|
|
||||||
#endif // USE_CALLBACKS
|
#endif // USE_CALLBACKS
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_IN
|
#endif // MIDI_BUILD_INPUT
|
||||||
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// MIDI Soft Thru
|
// MIDI Soft Thru
|
||||||
|
|
||||||
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU)
|
#if (MIDI_BUILD_INPUT && MIDI_BUILD_OUTPUT && MIDI_BUILD_THRU)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
inline MidiFilterMode getFilterMode() const;
|
||||||
|
inline bool getThruState() const;
|
||||||
|
|
||||||
// Getters
|
inline void turnThruOn(MidiFilterMode inThruFilterMode = Full);
|
||||||
kThruFilterMode getFilterMode() const { return mThruFilterMode; }
|
inline void turnThruOff();
|
||||||
bool getThruState() const { return mThruActivated; }
|
inline void setThruFilterMode(MidiFilterMode inThruFilterMode);
|
||||||
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
void turnThruOn(kThruFilterMode inThruFilterMode = Full);
|
|
||||||
void turnThruOff();
|
|
||||||
|
|
||||||
void setThruFilterMode(const kThruFilterMode inThruFilterMode);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void thru_filter(byte inChannel);
|
void thru_filter(byte inChannel);
|
||||||
|
|
||||||
bool mThruActivated;
|
bool mThruActivated : 1;
|
||||||
kThruFilterMode mThruFilterMode;
|
MidiFilterMode mThruFilterMode : 7;
|
||||||
|
|
||||||
#endif // Thru
|
#endif // Thru
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
#if MIDI_USE_RUNNING_STATUS
|
||||||
|
StatusByte mRunningStatus_TX;
|
||||||
|
#endif // MIDI_USE_RUNNING_STATUS
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MIDI_Class MIDI;
|
END_MIDI_NAMESPACE
|
||||||
|
|
||||||
#endif // LIB_MIDI_H_
|
#if MIDI_AUTO_INSTANCIATE
|
||||||
|
extern midi::MidiInterface MIDI;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "midi_Inline.hpp"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* @file midi_Defs.h
|
* @file midi_Defs.h
|
||||||
* Project Arduino MIDI Library
|
* Project Arduino MIDI Library
|
||||||
* @brief MIDI Library for the Arduino - Definitions
|
* @brief MIDI Library for the Arduino - Definitions
|
||||||
* @version 3.5
|
* @version 4.0
|
||||||
* @author Francois Best
|
* @author Francois Best
|
||||||
* @date 24/02/11
|
* @date 24/02/11
|
||||||
* license GPL Forty Seven Effects - 2011
|
* license GPL Forty Seven Effects - 2011
|
||||||
|
|
@ -15,23 +15,31 @@
|
||||||
|
|
||||||
BEGIN_MIDI_NAMESPACE
|
BEGIN_MIDI_NAMESPACE
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#define MIDI_CHANNEL_OMNI 0
|
#define MIDI_CHANNEL_OMNI 0
|
||||||
#define MIDI_CHANNEL_OFF 17 // and over
|
#define MIDI_CHANNEL_OFF 17 // and over
|
||||||
|
|
||||||
#define MIDI_PITCHBEND_MIN -8192
|
#define MIDI_PITCHBEND_MIN -8192
|
||||||
#define MIDI_PITCHBEND_MAX 8191
|
#define MIDI_PITCHBEND_MAX 8191
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Type definitions
|
||||||
|
|
||||||
/*! Type definition for practical use
|
|
||||||
(because "unsigned char" is a bit long to write.. )
|
|
||||||
*/
|
|
||||||
typedef uint8_t byte;
|
typedef uint8_t byte;
|
||||||
typedef uint16_t word;
|
typedef uint16_t word;
|
||||||
|
|
||||||
|
typedef byte StatusByte;
|
||||||
|
typedef byte DataByte;
|
||||||
|
typedef byte Channel;
|
||||||
|
typedef byte FilterMode;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*! Enumeration of MIDI types */
|
/*! Enumeration of MIDI types */
|
||||||
enum kMIDIType
|
enum MidiType
|
||||||
{
|
{
|
||||||
|
InvalidType = 0x00, ///< For notifying errors
|
||||||
NoteOff = 0x80, ///< Note Off
|
NoteOff = 0x80, ///< Note Off
|
||||||
NoteOn = 0x90, ///< Note On
|
NoteOn = 0x90, ///< Note On
|
||||||
AfterTouchPoly = 0xA0, ///< Polyphonic AfterTouch
|
AfterTouchPoly = 0xA0, ///< Polyphonic AfterTouch
|
||||||
|
|
@ -50,19 +58,22 @@ enum kMIDIType
|
||||||
Stop = 0xFC, ///< System Real Time - Stop
|
Stop = 0xFC, ///< System Real Time - Stop
|
||||||
ActiveSensing = 0xFE, ///< System Real Time - Active Sensing
|
ActiveSensing = 0xFE, ///< System Real Time - Active Sensing
|
||||||
SystemReset = 0xFF, ///< System Real Time - System Reset
|
SystemReset = 0xFF, ///< System Real Time - System Reset
|
||||||
InvalidType = 0x00 ///< For notifying errors
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*! Enumeration of Thru filter modes */
|
/*! Enumeration of Thru filter modes */
|
||||||
enum kThruFilterMode {
|
enum MidiFilterMode
|
||||||
|
{
|
||||||
Off = 0, ///< Thru disabled (nothing passes through).
|
Off = 0, ///< Thru disabled (nothing passes through).
|
||||||
Full = 1, ///< Fully enabled Thru (every incoming message is sent back).
|
Full = 1, ///< Fully enabled Thru (every incoming message is sent back).
|
||||||
SameChannel = 2, ///< Only the messages on the Input Channel will be sent back.
|
SameChannel = 2, ///< Only the messages on the Input Channel will be sent back.
|
||||||
DifferentChannel = 3 ///< All the messages but the ones on the Input Channel will be sent back.
|
DifferentChannel = 3, ///< All the messages but the ones on the Input Channel will be sent back.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
enum eMIDICCNumber
|
enum MidiControlChangeNumber
|
||||||
{
|
{
|
||||||
// High resolution Continuous Controllers MSB (+32 for LSB) ----------------
|
// High resolution Continuous Controllers MSB (+32 for LSB) ----------------
|
||||||
BankSelect = 0,
|
BankSelect = 0,
|
||||||
|
|
@ -92,7 +103,7 @@ enum eMIDICCNumber
|
||||||
Sostenuto = 66,
|
Sostenuto = 66,
|
||||||
SoftPedal = 67,
|
SoftPedal = 67,
|
||||||
Legato = 68,
|
Legato = 68,
|
||||||
Hold2 = 69,
|
Hold = 69,
|
||||||
|
|
||||||
// Low resolution continuous controllers -----------------------------------
|
// Low resolution continuous controllers -----------------------------------
|
||||||
SoundController1 = 70, ///< Synth: Sound Variation FX: Exciter On/Off
|
SoundController1 = 70, ///< Synth: Sound Variation FX: Exciter On/Off
|
||||||
|
|
@ -129,40 +140,41 @@ enum eMIDICCNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*! The midimsg structure contains decoded data
|
/*! The midimsg structure contains decoded data
|
||||||
of a MIDI message read from the serial port
|
of a MIDI message read from the serial port
|
||||||
with read() or thru().
|
with read() or thru().
|
||||||
*/
|
*/
|
||||||
struct midimsg
|
struct Message
|
||||||
{
|
{
|
||||||
|
|
||||||
/*! The MIDI channel on which the message was recieved.
|
/*! The MIDI channel on which the message was recieved.
|
||||||
\n Value goes from 1 to 16.
|
\n Value goes from 1 to 16.
|
||||||
*/
|
*/
|
||||||
byte channel;
|
Channel channel;
|
||||||
|
|
||||||
/*! The type of the message
|
/*! The type of the message
|
||||||
(see the define section for types reference)
|
(see the MidiType enum for types reference)
|
||||||
*/
|
*/
|
||||||
kMIDIType type;
|
MidiType type;
|
||||||
|
|
||||||
/*! The first data byte.
|
/*! The first data byte.
|
||||||
\n Value goes from 0 to 127.
|
\n Value goes from 0 to 127.
|
||||||
*/
|
*/
|
||||||
byte data1;
|
DataByte data1;
|
||||||
|
|
||||||
/*! The second data byte.
|
/*! The second data byte.
|
||||||
If the message is only 2 bytes long, this one is null.
|
If the message is only 2 bytes long, this one is null.
|
||||||
\n Value goes from 0 to 127.
|
\n Value goes from 0 to 127.
|
||||||
*/
|
*/
|
||||||
byte data2;
|
DataByte data2;
|
||||||
|
|
||||||
/*! System Exclusive dedicated byte array.
|
/*! System Exclusive dedicated byte array.
|
||||||
\n Array length is stocked on 16 bits,
|
\n Array length is stocked on 16 bits,
|
||||||
in data1 (LSB) and data2 (MSB)
|
in data1 (LSB) and data2 (MSB)
|
||||||
*/
|
*/
|
||||||
byte sysex_array[MIDI_SYSEX_ARRAY_SIZE];
|
DataByte sysex_array[MIDI_SYSEX_ARRAY_SIZE];
|
||||||
|
|
||||||
/*! This boolean indicates if the message is valid or not.
|
/*! This boolean indicates if the message is valid or not.
|
||||||
There is no channel consideration here,
|
There is no channel consideration here,
|
||||||
|
|
@ -172,5 +184,4 @@ struct midimsg
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
END_MIDI_NAMESPACE
|
END_MIDI_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*!
|
||||||
|
* @file midi_Inline.hpp
|
||||||
|
* Project Arduino MIDI Library
|
||||||
|
* @brief MIDI Library for the Arduino - Inline implementations
|
||||||
|
* @version 4.0
|
||||||
|
* @author Francois Best
|
||||||
|
* @date 24/02/11
|
||||||
|
* license GPL Forty Seven Effects - 2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
BEGIN_MIDI_NAMESPACE
|
||||||
|
|
||||||
|
#if MIDI_BUILD_OUTPUT
|
||||||
|
|
||||||
|
StatusByte MidiInterface::getStatus(kMIDIType inType,
|
||||||
|
Channel inChannel) const
|
||||||
|
{
|
||||||
|
return ((byte)inType | ((inChannel - 1) & 0x0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MIDI_BUILD_OUTPUT
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if MIDI_BUILD_INPUT
|
||||||
|
|
||||||
|
/*! \brief Get the last received message's type
|
||||||
|
|
||||||
|
Returns an enumerated type. @see MidiType
|
||||||
|
*/
|
||||||
|
MidiType MidiInterface::getType() const
|
||||||
|
{
|
||||||
|
return mMessage.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Get the channel of the message stored in the structure.
|
||||||
|
|
||||||
|
\return Channel range is 1 to 16.
|
||||||
|
For non-channel messages, this will return 0.
|
||||||
|
*/
|
||||||
|
Channel MidiInterface::getChannel() const
|
||||||
|
{
|
||||||
|
return mMessage.channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Get the first data byte of the last received message. */
|
||||||
|
DataByte MidiInterface::getData1() const
|
||||||
|
{
|
||||||
|
return mMessage.data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Get the second data byte of the last received message. */
|
||||||
|
DataByte MidiInterface::getData2() const
|
||||||
|
{
|
||||||
|
return mMessage.data2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Get the System Exclusive byte array.
|
||||||
|
|
||||||
|
@see getSysExArrayLength to get the array's length in bytes.
|
||||||
|
*/
|
||||||
|
const byte* MidiInterface::getSysExArray() const
|
||||||
|
{
|
||||||
|
return mMessage.sysex_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Get the lenght of the System Exclusive array.
|
||||||
|
|
||||||
|
It is coded using data1 as LSB and data2 as MSB.
|
||||||
|
\return The array's length, in bytes.
|
||||||
|
*/
|
||||||
|
unsigned int MidiInterface::getSysExArrayLength() const
|
||||||
|
{
|
||||||
|
const unsigned int size = ((unsigned)(mMessage.data2) << 8) | mMessage.data1;
|
||||||
|
return (size > MIDI_SYSEX_ARRAY_SIZE) ? MIDI_SYSEX_ARRAY_SIZE : size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Check if a valid message is stored in the structure. */
|
||||||
|
bool MidiInterface::check() const
|
||||||
|
{
|
||||||
|
return mMessage.valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Channel MidiInterface::getInputChannel() const
|
||||||
|
{
|
||||||
|
return mInputChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Set the value for the input MIDI channel
|
||||||
|
\param Channel the channel value. Valid values are 1 to 16, MIDI_CHANNEL_OMNI
|
||||||
|
if you want to listen to all channels, and MIDI_CHANNEL_OFF to disable input.
|
||||||
|
*/
|
||||||
|
void MidiInterface::setInputChannel(Channel inChannel)
|
||||||
|
{
|
||||||
|
mInputChannel = inChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Extract an enumerated MIDI type from a status byte.
|
||||||
|
|
||||||
|
This is a utility static method, used internally,
|
||||||
|
made public so you can handle MidiTypes more easily.
|
||||||
|
*/
|
||||||
|
MidiType MidiInterface::getTypeFromStatusByte(const byte inStatus)
|
||||||
|
{
|
||||||
|
if ((inStatus < 0x80) ||
|
||||||
|
(inStatus == 0xF4) ||
|
||||||
|
(inStatus == 0xF5) ||
|
||||||
|
(inStatus == 0xF9) ||
|
||||||
|
(inStatus == 0xFD)) return InvalidType; // data bytes and undefined.
|
||||||
|
if (inStatus < 0xF0) return (MidiType)(inStatus & 0xF0); // Channel message, remove channel nibble.
|
||||||
|
else return (MidiType)inStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MIDI_BUILD_INPUT
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if (MIDI_BUILD_INPUT && MIDI_BUILD_OUTPUT && MIDI_BUILD_THRU)
|
||||||
|
|
||||||
|
MidiFilterMode MidiInterface::getFilterMode() const
|
||||||
|
{
|
||||||
|
return mThruFilterMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MidiInterface::getThruState() const
|
||||||
|
{
|
||||||
|
return mThruActivated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Setter method: turn message mirroring on. */
|
||||||
|
void MidiInterface::turnThruOn(MidiFilterMode inThruFilterMode)
|
||||||
|
{
|
||||||
|
mThruActivated = true;
|
||||||
|
mThruFilterMode = inThruFilterMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Setter method: turn message mirroring off. */
|
||||||
|
void MidiInterface::turnThruOff()
|
||||||
|
{
|
||||||
|
mThruActivated = false;
|
||||||
|
mThruFilterMode = Off;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Set the filter for thru mirroring
|
||||||
|
\param inThruFilterMode a filter mode
|
||||||
|
|
||||||
|
@see MidiFilterMode
|
||||||
|
*/
|
||||||
|
void MidiInterface::setThruFilterMode(MidiFilterMode inThruFilterMode)
|
||||||
|
{
|
||||||
|
mThruFilterMode = inThruFilterMode;
|
||||||
|
if (mThruFilterMode != Off)
|
||||||
|
mThruActivated = true;
|
||||||
|
else
|
||||||
|
mThruActivated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MIDI_BUILD_THRU
|
||||||
|
|
||||||
|
END_MIDI_NAMESPACE
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* @file midi_Namespace.h
|
* @file midi_Namespace.h
|
||||||
* Project Arduino MIDI Library
|
* Project Arduino MIDI Library
|
||||||
* @brief MIDI Library for the Arduino - Namespace declaration
|
* @brief MIDI Library for the Arduino - Namespace declaration
|
||||||
* @version 3.5
|
* @version 4.0
|
||||||
* @author Francois Best
|
* @author Francois Best
|
||||||
* @date 24/02/11
|
* @date 24/02/11
|
||||||
* license GPL Forty Seven Effects - 2011
|
* license GPL Forty Seven Effects - 2011
|
||||||
|
|
|
||||||
|
|
@ -27,23 +27,25 @@ BEGIN_MIDI_NAMESPACE
|
||||||
// (MIDI in, out, thru), or to 0 to disable the feature and save space.
|
// (MIDI in, out, thru), or to 0 to disable the feature and save space.
|
||||||
// Note that the Thru can only work if in and out are enabled.
|
// Note that the Thru can only work if in and out are enabled.
|
||||||
|
|
||||||
#define MIDI_BUILD_INPUT 1
|
#define MIDI_BUILD_INPUT 1
|
||||||
#define MIDI_BUILD_OUTPUT 1
|
#define MIDI_BUILD_OUTPUT 1
|
||||||
#define MIDI_BUILD_THRU 1
|
#define MIDI_BUILD_THRU 1
|
||||||
|
|
||||||
|
// Create a MIDI object automatically on the port defined with MIDI_SERIAL_PORT.
|
||||||
|
#define MIDI_AUTO_INSTANCIATE 1
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Serial port configuration
|
// Serial port configuration
|
||||||
|
|
||||||
// Change the number (to Serial1 for example)
|
// Set the default port to use for MIDI.
|
||||||
// if you want to use a different serial port for MIDI I/O.
|
#define MIDI_SERIAL_PORT Serial
|
||||||
#define MIDI_SERIAL_PORT Serial
|
|
||||||
|
|
||||||
// Software serial options
|
// Software serial options
|
||||||
#define MIDI_USE_SOFTWARE_SERIAL 0
|
#define MIDI_USE_SOFTWARE_SERIAL 0
|
||||||
|
|
||||||
#if MIDI_USE_SOFTWARE_SERIAL
|
#if MIDI_USE_SOFTWARE_SERIAL
|
||||||
#define MIDI_SOFTSERIAL_RX_PIN 1 // Pin number to use for MIDI Input
|
#define MIDI_SOFTSERIAL_RX_PIN 1 // Pin number to use for MIDI Input
|
||||||
#define MIDI_SOFTSERIAL_TX_PIN 2 // Pin number to use for MIDI Output.
|
#define MIDI_SOFTSERIAL_TX_PIN 2 // Pin number to use for MIDI Output
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
@ -52,11 +54,10 @@ BEGIN_MIDI_NAMESPACE
|
||||||
// Running status enables short messages when sending multiple values
|
// Running status enables short messages when sending multiple values
|
||||||
// of the same type and channel.
|
// of the same type and channel.
|
||||||
// Set to 0 if you have troubles controlling your hardware.
|
// Set to 0 if you have troubles controlling your hardware.
|
||||||
#define MIDI_USE_RUNNING_STATUS 1
|
#define MIDI_USE_RUNNING_STATUS 1
|
||||||
#define MIDI_USE_1BYTE_PARSING 1
|
#define MIDI_USE_1BYTE_PARSING 1
|
||||||
|
|
||||||
|
#define MIDI_BAUDRATE 31250
|
||||||
#define MIDI_BAUDRATE 31250
|
#define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes.
|
||||||
#define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes.
|
|
||||||
|
|
||||||
END_MIDI_NAMESPACE
|
END_MIDI_NAMESPACE
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue