Cosmetics.
This commit is contained in:
parent
21b1e76e95
commit
698889dd6e
178
src/MIDI.cpp
178
src/MIDI.cpp
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
#include "MIDI.h"
|
#include "MIDI.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "Arduino.h" // If using an old (pre-1.0) version of Arduino, use WConstants.h instead of Arduino.h
|
#include "Arduino.h" // If using an old (pre-1.0) version of Arduino,
|
||||||
|
// use WConstants.h instead of Arduino.h
|
||||||
#include "HardwareSerial.h"
|
#include "HardwareSerial.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,13 +21,12 @@
|
||||||
#include "../SoftwareSerial/SoftwareSerial.h"
|
#include "../SoftwareSerial/SoftwareSerial.h"
|
||||||
SoftwareSerial softSerialClass(SOFTSERIAL_RX_PIN,SOFTSERIAL_TX_PIN);
|
SoftwareSerial softSerialClass(SOFTSERIAL_RX_PIN,SOFTSERIAL_TX_PIN);
|
||||||
|
|
||||||
#undef USE_SERIAL_PORT
|
#undef MIDI_SERIAL_PORT
|
||||||
#define USE_SERIAL_PORT softSerialClass
|
#define MIDI_SERIAL_PORT softSerialClass
|
||||||
|
|
||||||
#endif // USE_SOFTWARE_SERIAL
|
#endif // USE_SOFTWARE_SERIAL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Main instance (the class comes pre-instantiated). */
|
/*! \brief Main instance (the class comes pre-instantiated). */
|
||||||
MIDI_Class MIDI;
|
MIDI_Class MIDI;
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ void MIDI_Class::begin(const byte inChannel)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Initialise the Serial port
|
// Initialise the Serial port
|
||||||
USE_SERIAL_PORT.begin(MIDI_BAUDRATE);
|
MIDI_SERIAL_PORT.begin(MIDI_BAUDRATE);
|
||||||
|
|
||||||
|
|
||||||
#if COMPILE_MIDI_OUT
|
#if COMPILE_MIDI_OUT
|
||||||
|
|
@ -122,6 +122,10 @@ void MIDI_Class::begin(const byte inChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// MIDI Output
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
#if COMPILE_MIDI_OUT
|
#if COMPILE_MIDI_OUT
|
||||||
|
|
||||||
// Private method for generating a status byte from channel and type
|
// Private method for generating a status byte from channel and type
|
||||||
|
|
@ -136,11 +140,14 @@ const byte MIDI_Class::genstatus(const kMIDIType inType,
|
||||||
|
|
||||||
/*! \brief Generate and send a MIDI message from the values given.
|
/*! \brief Generate and send a MIDI message from the values given.
|
||||||
\param type The message type (see type defines for reference)
|
\param type The message type (see type defines for reference)
|
||||||
\param data1 The first data byte.
|
\param data1 The first data byte.
|
||||||
\param data2 The second data byte (if the message contains only 1 data byte, set this one to 0).
|
\param data2 The second data byte (if the message contains only 1 data byte,
|
||||||
\param channel The output channel on which the message will be sent (values from 1 to 16). Note: you cannot send to OMNI.
|
set this one to 0).
|
||||||
|
\param channel The output channel on which the message will be sent
|
||||||
|
(values from 1 to 16). Note: you cannot send to OMNI.
|
||||||
|
|
||||||
This is an internal method, use it only if you need to send raw data from your code, at your own risks.
|
This is an internal method, use it only if you need to send raw data
|
||||||
|
from your code, at your own risks.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::send(kMIDIType type,
|
void MIDI_Class::send(kMIDIType type,
|
||||||
byte data1,
|
byte data1,
|
||||||
|
|
@ -172,17 +179,17 @@ void MIDI_Class::send(kMIDIType type,
|
||||||
if (mRunningStatus_TX != statusbyte) {
|
if (mRunningStatus_TX != statusbyte) {
|
||||||
// New message, memorise and send header
|
// New message, memorise and send header
|
||||||
mRunningStatus_TX = statusbyte;
|
mRunningStatus_TX = statusbyte;
|
||||||
USE_SERIAL_PORT.write(mRunningStatus_TX);
|
MIDI_SERIAL_PORT.write(mRunningStatus_TX);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Don't care about running status, send the Control byte.
|
// Don't care about running status, send the Control byte.
|
||||||
USE_SERIAL_PORT.write(statusbyte);
|
MIDI_SERIAL_PORT.write(statusbyte);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Then send data
|
// Then send data
|
||||||
USE_SERIAL_PORT.write(data1);
|
MIDI_SERIAL_PORT.write(data1);
|
||||||
if (type != ProgramChange && type != AfterTouchChannel) {
|
if (type != ProgramChange && type != AfterTouchChannel) {
|
||||||
USE_SERIAL_PORT.write(data2);
|
MIDI_SERIAL_PORT.write(data2);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -195,9 +202,13 @@ void MIDI_Class::send(kMIDIType type,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Note On message
|
/*! \brief Send a Note On message
|
||||||
\param NoteNumber Pitch value in the MIDI format (0 to 127). Take a look at the values, names and frequencies of notes here: http://www.phys.unsw.edu.au/jw/notes.html\n
|
\param NoteNumber Pitch value in the MIDI format (0 to 127).
|
||||||
\param Velocity Note attack velocity (0 to 127). A NoteOn with 0 velocity is considered as a NoteOff.
|
\param Velocity Note attack velocity (0 to 127). A
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
NoteOn with 0 velocity is considered as a NoteOff.
|
||||||
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
|
|
||||||
|
Take a look at the values, names and frequencies of notes here:
|
||||||
|
http://www.phys.unsw.edu.au/jw/notes.html
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendNoteOn(byte NoteNumber,
|
void MIDI_Class::sendNoteOn(byte NoteNumber,
|
||||||
byte Velocity,
|
byte Velocity,
|
||||||
|
|
@ -210,9 +221,12 @@ void MIDI_Class::sendNoteOn(byte NoteNumber,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Note Off message (a real Note Off, not a Note On with null velocity)
|
/*! \brief Send a Note Off message (a real Note Off, not a Note On with null velocity)
|
||||||
\param NoteNumber Pitch value in the MIDI format (0 to 127). Take a look at the values, names and frequencies of notes here: http://www.phys.unsw.edu.au/jw/notes.html\n
|
\param NoteNumber Pitch value in the MIDI format (0 to 127).
|
||||||
\param Velocity Release velocity (0 to 127).
|
\param Velocity Release velocity (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).
|
||||||
|
|
||||||
|
Take a look at the values, names and frequencies of notes here:
|
||||||
|
http://www.phys.unsw.edu.au/jw/notes.html
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendNoteOff(byte NoteNumber,
|
void MIDI_Class::sendNoteOff(byte NoteNumber,
|
||||||
byte Velocity,
|
byte Velocity,
|
||||||
|
|
@ -225,8 +239,8 @@ void MIDI_Class::sendNoteOff(byte NoteNumber,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Program Change message
|
/*! \brief Send a Program Change message
|
||||||
\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 MIDI_Class::sendProgramChange(byte ProgramNumber,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
|
|
@ -238,9 +252,12 @@ void MIDI_Class::sendProgramChange(byte ProgramNumber,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Control Change message
|
/*! \brief Send a Control Change message
|
||||||
\param ControlNumber The controller number (0 to 127). See the detailed description here: http://www.somascape.org/midi/tech/spec.html#ctrlnums
|
\param ControlNumber The controller number (0 to 127).
|
||||||
\param ControlValue The value for the specified controller (0 to 127).
|
\param ControlValue The value for the specified controller (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).
|
||||||
|
|
||||||
|
See the detailed controllers numbers & description here:
|
||||||
|
http://www.somascape.org/midi/tech/spec.html#ctrlnums
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendControlChange(byte ControlNumber,
|
void MIDI_Class::sendControlChange(byte ControlNumber,
|
||||||
byte ControlValue,
|
byte ControlValue,
|
||||||
|
|
@ -253,9 +270,9 @@ void MIDI_Class::sendControlChange(byte ControlNumber,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Polyphonic AfterTouch message (applies to only one specified note)
|
/*! \brief Send a Polyphonic AfterTouch message (applies to only one specified note)
|
||||||
\param NoteNumber The note to apply AfterTouch to (0 to 127).
|
\param NoteNumber The note to apply AfterTouch to (0 to 127).
|
||||||
\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 MIDI_Class::sendPolyPressure(byte NoteNumber,
|
||||||
byte Pressure,
|
byte Pressure,
|
||||||
|
|
@ -268,8 +285,8 @@ void MIDI_Class::sendPolyPressure(byte NoteNumber,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a MonoPhonic AfterTouch message (applies to all notes)
|
/*! \brief Send a MonoPhonic AfterTouch message (applies to all notes)
|
||||||
\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 MIDI_Class::sendAfterTouch(byte Pressure,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
|
|
@ -281,8 +298,10 @@ void MIDI_Class::sendAfterTouch(byte Pressure,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Pitch Bend message using a signed integer value.
|
/*! \brief Send a Pitch Bend message using a signed integer value.
|
||||||
\param PitchValue The amount of bend to send (in a signed integer format), between -8192 (maximum downwards bend) and 8191 (max upwards bend), center value is 0.
|
\param PitchValue The amount of bend to send (in a signed integer format),
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
between -8192 (maximum downwards bend)
|
||||||
|
and 8191 (max upwards bend), center value is 0.
|
||||||
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendPitchBend(int PitchValue,
|
void MIDI_Class::sendPitchBend(int PitchValue,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
|
|
@ -295,8 +314,10 @@ void MIDI_Class::sendPitchBend(int PitchValue,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Pitch Bend message using an unsigned integer value.
|
/*! \brief Send a Pitch Bend message using an unsigned integer value.
|
||||||
\param PitchValue The amount of bend to send (in a signed integer format), between 0 (maximum downwards bend) and 16383 (max upwards bend), center value is 8192.
|
\param PitchValue The amount of bend to send (in a signed integer format),
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
between 0 (maximum downwards bend)
|
||||||
|
and 16383 (max upwards bend), center value is 8192.
|
||||||
|
\param Channel The channel on which the message will be sent (1 to 16).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendPitchBend(unsigned int PitchValue,
|
void MIDI_Class::sendPitchBend(unsigned int PitchValue,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
|
|
@ -308,8 +329,10 @@ void MIDI_Class::sendPitchBend(unsigned int PitchValue,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send a Pitch Bend message using a floating point value.
|
/*! \brief Send a Pitch Bend message using a floating point value.
|
||||||
\param PitchValue The amount of bend to send (in a floating point format), between -1.0f (maximum downwards bend) and +1.0f (max upwards bend), center value is 0.0f.
|
\param PitchValue The amount of bend to send (in a floating point format),
|
||||||
\param Channel The channel on which the message will be sent (1 to 16).
|
between -1.0f (maximum downwards bend)
|
||||||
|
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).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendPitchBend(double PitchValue,
|
void MIDI_Class::sendPitchBend(double PitchValue,
|
||||||
byte Channel)
|
byte Channel)
|
||||||
|
|
@ -323,10 +346,13 @@ void MIDI_Class::sendPitchBend(double PitchValue,
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Generate and send a System Exclusive frame.
|
/*! \brief Generate and send a System Exclusive frame.
|
||||||
\param length The size of the array to send
|
\param length The size of the array to send
|
||||||
\param array The byte array containing the data to send
|
\param array The byte array containing the data to send
|
||||||
\param ArrayContainsBoundaries When set to 'true', 0xF0 & 0xF7 bytes (start & stop SysEx) will NOT be sent (and therefore must be included in the array).
|
\param ArrayContainsBoundaries When set to 'true', 0xF0 & 0xF7 bytes
|
||||||
default value is set to 'false' for compatibility with previous versions of the library.
|
(start & stop SysEx) will NOT be sent
|
||||||
|
(and therefore must be included in the array).
|
||||||
|
default value for ArrayContainsBoundaries is set to 'false' for compatibility
|
||||||
|
with previous versions of the library.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendSysEx(int length,
|
void MIDI_Class::sendSysEx(int length,
|
||||||
const byte *const array,
|
const byte *const array,
|
||||||
|
|
@ -335,22 +361,22 @@ void MIDI_Class::sendSysEx(int length,
|
||||||
|
|
||||||
if (ArrayContainsBoundaries == false) {
|
if (ArrayContainsBoundaries == false) {
|
||||||
|
|
||||||
USE_SERIAL_PORT.write(0xF0);
|
MIDI_SERIAL_PORT.write(0xF0);
|
||||||
|
|
||||||
for (int i=0;i<length;++i) {
|
for (int i=0;i<length;++i) {
|
||||||
|
|
||||||
USE_SERIAL_PORT.write(array[i]);
|
MIDI_SERIAL_PORT.write(array[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USE_SERIAL_PORT.write(0xF7);
|
MIDI_SERIAL_PORT.write(0xF7);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
for (int i=0;i<length;++i) {
|
for (int i=0;i<length;++i) {
|
||||||
|
|
||||||
USE_SERIAL_PORT.write(array[i]);
|
MIDI_SERIAL_PORT.write(array[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,7 +391,8 @@ void MIDI_Class::sendSysEx(int length,
|
||||||
|
|
||||||
/*! \brief Send a Tune Request message.
|
/*! \brief Send a Tune Request message.
|
||||||
|
|
||||||
When a MIDI unit receives this message, it should tune its oscillators (if equipped with any)
|
When a MIDI unit receives this message,
|
||||||
|
it should tune its oscillators (if equipped with any).
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendTuneRequest()
|
void MIDI_Class::sendTuneRequest()
|
||||||
{
|
{
|
||||||
|
|
@ -377,9 +404,9 @@ void MIDI_Class::sendTuneRequest()
|
||||||
|
|
||||||
/*! \brief Send a MIDI Time Code Quarter Frame.
|
/*! \brief Send a MIDI Time Code Quarter Frame.
|
||||||
|
|
||||||
See MIDI Specification for more information.
|
\param TypeNibble MTC type
|
||||||
\param TypeNibble MTC type
|
|
||||||
\param ValuesNibble MTC data
|
\param ValuesNibble MTC data
|
||||||
|
See MIDI Specification for more information.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble)
|
void MIDI_Class::sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble)
|
||||||
{
|
{
|
||||||
|
|
@ -392,14 +419,15 @@ void MIDI_Class::sendTimeCodeQuarterFrame(byte TypeNibble, byte ValuesNibble)
|
||||||
|
|
||||||
/*! \brief Send a MIDI Time Code Quarter Frame.
|
/*! \brief Send a MIDI Time Code Quarter Frame.
|
||||||
|
|
||||||
|
\param data if you want to encode directly the nibbles in your program,
|
||||||
|
you can send the byte here.
|
||||||
See MIDI Specification for more information.
|
See MIDI Specification for more information.
|
||||||
\param data if you want to encode directly the nibbles in your program, you can send the byte here.
|
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::sendTimeCodeQuarterFrame(byte data)
|
void MIDI_Class::sendTimeCodeQuarterFrame(byte data)
|
||||||
{
|
{
|
||||||
|
|
||||||
USE_SERIAL_PORT.write((byte)TimeCodeQuarterFrame);
|
MIDI_SERIAL_PORT.write((byte)TimeCodeQuarterFrame);
|
||||||
USE_SERIAL_PORT.write(data);
|
MIDI_SERIAL_PORT.write(data);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
|
|
@ -409,14 +437,14 @@ 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 MIDI_Class::sendSongPosition(unsigned int Beats)
|
||||||
{
|
{
|
||||||
|
|
||||||
USE_SERIAL_PORT.write((byte)SongPosition);
|
MIDI_SERIAL_PORT.write((byte)SongPosition);
|
||||||
USE_SERIAL_PORT.write(Beats & 0x7F);
|
MIDI_SERIAL_PORT.write(Beats & 0x7F);
|
||||||
USE_SERIAL_PORT.write((Beats >> 7) & 0x7F);
|
MIDI_SERIAL_PORT.write((Beats >> 7) & 0x7F);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
|
|
@ -429,8 +457,8 @@ void MIDI_Class::sendSongPosition(unsigned int Beats)
|
||||||
void MIDI_Class::sendSongSelect(byte SongNumber)
|
void MIDI_Class::sendSongSelect(byte SongNumber)
|
||||||
{
|
{
|
||||||
|
|
||||||
USE_SERIAL_PORT.write((byte)SongSelect);
|
MIDI_SERIAL_PORT.write((byte)SongSelect);
|
||||||
USE_SERIAL_PORT.write(SongNumber & 0x7F);
|
MIDI_SERIAL_PORT.write(SongNumber & 0x7F);
|
||||||
|
|
||||||
#if USE_RUNNING_STATUS
|
#if USE_RUNNING_STATUS
|
||||||
mRunningStatus_TX = InvalidType;
|
mRunningStatus_TX = InvalidType;
|
||||||
|
|
@ -441,7 +469,8 @@ void MIDI_Class::sendSongSelect(byte SongNumber)
|
||||||
|
|
||||||
/*! \brief Send a Real Time (one byte) message.
|
/*! \brief Send a Real Time (one byte) message.
|
||||||
|
|
||||||
\param Type The available Real Time types are: Start, Stop, Continue, Clock, ActiveSensing and SystemReset.
|
\param Type The available Real Time types are:
|
||||||
|
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 kMIDIType
|
||||||
*/
|
*/
|
||||||
|
|
@ -455,7 +484,7 @@ void MIDI_Class::sendRealTime(kMIDIType Type)
|
||||||
case Continue:
|
case Continue:
|
||||||
case ActiveSensing:
|
case ActiveSensing:
|
||||||
case SystemReset:
|
case SystemReset:
|
||||||
USE_SERIAL_PORT.write((byte)Type);
|
MIDI_SERIAL_PORT.write((byte)Type);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Invalid Real Time marker
|
// Invalid Real Time marker
|
||||||
|
|
@ -473,14 +502,19 @@ void MIDI_Class::sendRealTime(kMIDIType Type)
|
||||||
#endif // COMPILE_MIDI_OUT
|
#endif // COMPILE_MIDI_OUT
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// MIDI Input
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
#if COMPILE_MIDI_IN
|
#if COMPILE_MIDI_IN
|
||||||
|
|
||||||
/*! \brief Read a MIDI message from the serial port using the main input channel (see setInputChannel() for reference).
|
/*! \brief Read a MIDI message from the serial port
|
||||||
|
using the main input channel (see setInputChannel() for reference).
|
||||||
|
|
||||||
Returned value: true if any valid message has been stored in the structure, false if not.
|
\return True if a valid message has been stored in the structure, false if not.
|
||||||
A valid message is a message that matches the input channel. \n\n
|
A valid message is a message that matches the input channel. \n\n
|
||||||
If the Thru is enabled and the messages matches the filter, it is sent back on the MIDI output.
|
If the Thru is enabled and the messages matches the filter,
|
||||||
|
it is sent back on the MIDI output.
|
||||||
*/
|
*/
|
||||||
bool MIDI_Class::read()
|
bool MIDI_Class::read()
|
||||||
{
|
{
|
||||||
|
|
@ -490,7 +524,9 @@ bool MIDI_Class::read()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Reading/thru-ing method, the same as read() with a given input channel to read on. */
|
/*! \brief Reading/thru-ing method, the same as read()
|
||||||
|
with a given input channel to read on.
|
||||||
|
*/
|
||||||
bool MIDI_Class::read(const byte inChannel)
|
bool MIDI_Class::read(const byte inChannel)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -522,7 +558,7 @@ bool MIDI_Class::read(const byte inChannel)
|
||||||
bool MIDI_Class::parse(byte inChannel)
|
bool MIDI_Class::parse(byte inChannel)
|
||||||
{
|
{
|
||||||
|
|
||||||
const int bytes_available = USE_SERIAL_PORT.available();
|
const int bytes_available = MIDI_SERIAL_PORT.available();
|
||||||
|
|
||||||
if (bytes_available <= 0) {
|
if (bytes_available <= 0) {
|
||||||
// No data available.
|
// No data available.
|
||||||
|
|
@ -531,7 +567,7 @@ bool MIDI_Class::parse(byte inChannel)
|
||||||
|
|
||||||
// If the buffer is full -> Don't Panic! Call the Vogons to destroy it.
|
// If the buffer is full -> Don't Panic! Call the Vogons to destroy it.
|
||||||
if (bytes_available == 128) {
|
if (bytes_available == 128) {
|
||||||
USE_SERIAL_PORT.flush();
|
MIDI_SERIAL_PORT.flush();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
|
@ -544,7 +580,7 @@ bool MIDI_Class::parse(byte inChannel)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
const byte extracted = USE_SERIAL_PORT.read();
|
const byte extracted = MIDI_SERIAL_PORT.read();
|
||||||
|
|
||||||
if (mPendingMessageIndex == 0) { // Start a new pending message
|
if (mPendingMessageIndex == 0) { // Start a new pending message
|
||||||
mPendingMessage[0] = extracted;
|
mPendingMessage[0] = extracted;
|
||||||
|
|
@ -856,7 +892,8 @@ kMIDIType MIDI_Class::getType() const
|
||||||
|
|
||||||
/*! \brief Get the channel of the message stored in the structure.
|
/*! \brief Get the channel of the message stored in the structure.
|
||||||
|
|
||||||
Channel range is 1 to 16. For non-channel messages, this will return 0.
|
\return Channel range is 1 to 16.
|
||||||
|
For non-channel messages, this will return 0.
|
||||||
*/
|
*/
|
||||||
byte MIDI_Class::getChannel() const
|
byte MIDI_Class::getChannel() const
|
||||||
{
|
{
|
||||||
|
|
@ -922,7 +959,8 @@ bool MIDI_Class::check() const
|
||||||
// Setters
|
// Setters
|
||||||
/*! \brief Set the value for the input MIDI channel
|
/*! \brief Set the value for the input MIDI channel
|
||||||
\param Channel the channel value. Valid values are 1 to 16,
|
\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.
|
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)
|
void MIDI_Class::setInputChannel(const byte Channel)
|
||||||
{
|
{
|
||||||
|
|
@ -957,7 +995,8 @@ void MIDI_Class::setHandleSystemReset(void (*fptr)(void))
|
||||||
/*! \brief Detach an external function from the given type.
|
/*! \brief Detach an external function from the given type.
|
||||||
|
|
||||||
Use this method to cancel the effects of setHandle********.
|
Use this method to cancel the effects of setHandle********.
|
||||||
\param Type The type of message to unbind. When a message of this type is received, no function will be called.
|
\param Type The type of message to unbind.
|
||||||
|
When a message of this type is received, no function will be called.
|
||||||
*/
|
*/
|
||||||
void MIDI_Class::disconnectCallbackFromType(kMIDIType Type)
|
void MIDI_Class::disconnectCallbackFromType(kMIDIType Type)
|
||||||
{
|
{
|
||||||
|
|
@ -1036,9 +1075,11 @@ void MIDI_Class::launchCallback()
|
||||||
#endif // COMPILE_MIDI_IN
|
#endif // COMPILE_MIDI_IN
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// MIDI Soft Thru
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU)
|
||||||
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU) // Thru
|
|
||||||
|
|
||||||
/*! \brief Set the filter for thru mirroring
|
/*! \brief Set the filter for thru mirroring
|
||||||
\param inThruFilterMode a filter mode
|
\param inThruFilterMode a filter mode
|
||||||
|
|
@ -1075,7 +1116,8 @@ void MIDI_Class::turnThruOff()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This method is called upon reception of a message and takes care of Thru filtering and sending.
|
// This method is called upon reception of a message
|
||||||
|
// and takes care of Thru filtering and sending.
|
||||||
void MIDI_Class::thru_filter(byte inChannel)
|
void MIDI_Class::thru_filter(byte inChannel)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
149
src/MIDI.h
149
src/MIDI.h
|
|
@ -31,24 +31,24 @@
|
||||||
#define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input.
|
#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_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
|
#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.
|
// Please note that the Thru will work only when both COMPILE_MIDI_IN and COMPILE_MIDI_OUT set to 1.
|
||||||
|
|
||||||
|
|
||||||
#define USE_SERIAL_PORT Serial // Change the number (to Serial1 for example) if you want
|
#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.
|
// to use a different serial port for MIDI I/O.
|
||||||
|
|
||||||
#define USE_SOFTWARE_SERIAL 1 // Set to 1 to use SoftwareSerial instead of native serial ports.
|
#define USE_SOFTWARE_SERIAL 0 // Set to 1 to use SoftwareSerial instead of native serial ports.
|
||||||
#define SOFTSERIAL_RX_PIN 1 // This pin number will be used for MIDI Input
|
#define SOFTSERIAL_RX_PIN 1 // This pin number will be used for MIDI Input
|
||||||
#define SOFTSERIAL_TX_PIN 2 // This pin number will be used for MIDI Output.
|
#define 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
|
#define USE_RUNNING_STATUS 1 // 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 with controlling you hardware.
|
// 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).
|
#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
|
// 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).
|
#define USE_1BYTE_PARSING 1 // Each call to MIDI.read will only parse one byte (might be faster).
|
||||||
|
|
||||||
|
|
@ -63,10 +63,14 @@
|
||||||
|
|
||||||
#define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes.
|
#define MIDI_SYSEX_ARRAY_SIZE 255 // Maximum size is 65535 bytes.
|
||||||
|
|
||||||
/*! Type definition for practical use (because "unsigned char" is a bit long to write.. )*/
|
|
||||||
typedef uint8_t byte;
|
/*! Type definition for practical use
|
||||||
|
(because "unsigned char" is a bit long to write.. )
|
||||||
|
*/
|
||||||
|
typedef uint8_t byte;
|
||||||
typedef uint16_t word;
|
typedef uint16_t word;
|
||||||
|
|
||||||
|
|
||||||
/*! Enumeration of MIDI types */
|
/*! Enumeration of MIDI types */
|
||||||
enum kMIDIType {
|
enum kMIDIType {
|
||||||
NoteOff = 0x80, ///< Note Off
|
NoteOff = 0x80, ///< Note Off
|
||||||
|
|
@ -87,9 +91,10 @@ 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
|
InvalidType = 0x00 ///< For notifying errors
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*! Enumeration of Thru filter modes */
|
/*! Enumeration of Thru filter modes */
|
||||||
enum kThruFilterMode {
|
enum kThruFilterMode {
|
||||||
Off = 0, ///< Thru disabled (nothing passes through).
|
Off = 0, ///< Thru disabled (nothing passes through).
|
||||||
|
|
@ -99,20 +104,46 @@ enum kThruFilterMode {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*! The midimsg structure contains decoded data of a MIDI message read from the serial port with read() or thru(). \n */
|
/*! The midimsg structure contains decoded data
|
||||||
struct midimsg {
|
of a MIDI message read from the serial port
|
||||||
/*! The MIDI channel on which the message was recieved. \n Value goes from 1 to 16. */
|
with read() or thru().
|
||||||
|
*/
|
||||||
|
struct midimsg
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! The MIDI channel on which the message was recieved.
|
||||||
|
\n Value goes from 1 to 16.
|
||||||
|
*/
|
||||||
byte channel;
|
byte channel;
|
||||||
/*! The type of the message (see the define section for types reference) */
|
|
||||||
|
/*! The type of the message
|
||||||
|
(see the define section for types reference)
|
||||||
|
*/
|
||||||
kMIDIType type;
|
kMIDIType type;
|
||||||
/*! The first data byte.\n Value goes from 0 to 127.\n */
|
|
||||||
|
/*! The first data byte.
|
||||||
|
\n Value goes from 0 to 127.
|
||||||
|
*/
|
||||||
byte data1;
|
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. */
|
|
||||||
|
/*! 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;
|
byte data2;
|
||||||
/*! System Exclusive dedicated byte array. \n Array length is stocked on 16 bits, in data1 (LSB) and data2 (MSB) */
|
|
||||||
|
/*! 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];
|
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. */
|
|
||||||
|
/*! 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;
|
bool valid;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,22 +153,24 @@ struct midimsg {
|
||||||
See member descriptions to know how to use it,
|
See member descriptions to know how to use it,
|
||||||
or check out the examples supplied with the library.
|
or check out the examples supplied with the library.
|
||||||
*/
|
*/
|
||||||
class MIDI_Class {
|
class MIDI_Class
|
||||||
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
// Constructor and Destructor
|
// Constructor and Destructor
|
||||||
|
|
||||||
MIDI_Class();
|
MIDI_Class();
|
||||||
~MIDI_Class();
|
~MIDI_Class();
|
||||||
|
|
||||||
|
|
||||||
void begin(const byte inChannel = 1);
|
void begin(const byte inChannel = 1);
|
||||||
|
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// MIDI Output
|
||||||
|
|
||||||
|
#if COMPILE_MIDI_OUT // Start compilation block
|
||||||
/* ####### OUTPUT COMPILATION BLOCK ####### */
|
|
||||||
#if COMPILE_MIDI_OUT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -170,12 +203,14 @@ private:
|
||||||
byte mRunningStatus_TX;
|
byte mRunningStatus_TX;
|
||||||
#endif // USE_RUNNING_STATUS
|
#endif // USE_RUNNING_STATUS
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_OUT
|
#endif // COMPILE_MIDI_OUT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ####### INPUT COMPILATION BLOCK ####### */
|
// =========================================================================
|
||||||
#if COMPILE_MIDI_IN
|
// MIDI Input
|
||||||
|
|
||||||
|
#if COMPILE_MIDI_IN // Start compilation block
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -205,18 +240,40 @@ public:
|
||||||
*/
|
*/
|
||||||
static inline const kMIDIType getTypeFromStatusByte(const byte inStatus)
|
static inline const kMIDIType getTypeFromStatusByte(const byte inStatus)
|
||||||
{
|
{
|
||||||
if ((inStatus < 0x80)
|
if ((inStatus < 0x80) ||
|
||||||
|| (inStatus == 0xF4)
|
(inStatus == 0xF4) ||
|
||||||
|| (inStatus == 0xF5)
|
(inStatus == 0xF5) ||
|
||||||
|| (inStatus == 0xF9)
|
(inStatus == 0xF9) ||
|
||||||
|| (inStatus == 0xFD)) return InvalidType; // data bytes and undefined.
|
(inStatus == 0xFD)) return InvalidType; // data bytes and undefined.
|
||||||
if (inStatus < 0xF0) return (kMIDIType)(inStatus & 0xF0); // Channel message, remove channel nibble.
|
if (inStatus < 0xF0) return (kMIDIType)(inStatus & 0xF0); // Channel message, remove channel nibble.
|
||||||
else return (kMIDIType)inStatus;
|
else return (kMIDIType)inStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool input_filter(byte inChannel);
|
||||||
|
bool parse(byte inChannel);
|
||||||
|
void reset_input_attributes();
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
byte mRunningStatus_RX;
|
||||||
|
byte mInputChannel;
|
||||||
|
|
||||||
|
byte mPendingMessage[MIDI_SYSEX_ARRAY_SIZE];
|
||||||
|
unsigned int mPendingMessageExpectedLenght;
|
||||||
|
unsigned int mPendingMessageIndex; // Extended to unsigned int for larger sysex payloads.
|
||||||
|
|
||||||
|
midimsg mMessage;
|
||||||
|
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Input Callbacks
|
||||||
|
|
||||||
#if USE_CALLBACKS
|
#if USE_CALLBACKS
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
void setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity));
|
void setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity));
|
||||||
void setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity));
|
void setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity));
|
||||||
void setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure));
|
void setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure));
|
||||||
|
|
@ -238,27 +295,8 @@ public:
|
||||||
|
|
||||||
void disconnectCallbackFromType(kMIDIType Type);
|
void disconnectCallbackFromType(kMIDIType Type);
|
||||||
|
|
||||||
#endif // USE_CALLBACKS
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool input_filter(byte inChannel);
|
|
||||||
bool parse(byte inChannel);
|
|
||||||
void reset_input_attributes();
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
byte mRunningStatus_RX;
|
|
||||||
byte mInputChannel;
|
|
||||||
|
|
||||||
byte mPendingMessage[MIDI_SYSEX_ARRAY_SIZE];
|
|
||||||
unsigned int mPendingMessageExpectedLenght;
|
|
||||||
unsigned int mPendingMessageIndex; // Extended to unsigned int for larger sysex payloads.
|
|
||||||
|
|
||||||
midimsg mMessage;
|
|
||||||
|
|
||||||
#if USE_CALLBACKS
|
|
||||||
|
|
||||||
void launchCallback();
|
void launchCallback();
|
||||||
|
|
||||||
void (*mNoteOffCallback)(byte channel, byte note, byte velocity);
|
void (*mNoteOffCallback)(byte channel, byte note, byte velocity);
|
||||||
|
|
@ -280,14 +318,15 @@ private:
|
||||||
void (*mActiveSensingCallback)(void);
|
void (*mActiveSensingCallback)(void);
|
||||||
void (*mSystemResetCallback)(void);
|
void (*mSystemResetCallback)(void);
|
||||||
|
|
||||||
#endif // USE_CALLBACKS
|
#endif // USE_CALLBACKS
|
||||||
|
|
||||||
|
|
||||||
#endif // COMPILE_MIDI_IN
|
#endif // COMPILE_MIDI_IN
|
||||||
|
|
||||||
|
|
||||||
/* ####### THRU COMPILATION BLOCK ####### */
|
// =========================================================================
|
||||||
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU) // Thru
|
// MIDI Soft Thru
|
||||||
|
|
||||||
|
#if (COMPILE_MIDI_IN && COMPILE_MIDI_OUT && COMPILE_MIDI_THRU)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue