added support for ActiveSensing

From: https://www.midi.org/specifications/item/table-1-summary-of-midi-message

Active Sensing. This message is intended to be sent repeatedly to tell the receiver that a connection is alive. Use of this message is optional. When initially received, the receiver will expect to receive another Active Sensing message each 300ms (max), and if it does not then it will assume that the connection has been terminated. At termination, the receiver will turn off all voices and return to normal (non- active sensing) operation.
This commit is contained in:
lathoub 2020-01-26 11:05:10 +01:00
parent a1bff07a1e
commit 7f9934b1aa
3 changed files with 43 additions and 1 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ build/
.vscode/.cmaketools.json .vscode/.cmaketools.json
src/.DS_Store src/.DS_Store
examples/.DS_Store examples/.DS_Store
.DS_Store

View File

@ -86,6 +86,8 @@ public:
DataByte inPressure, DataByte inPressure,
Channel inChannel); Channel inChannel);
inline void sendActiveSensing();
inline void sendSysEx(unsigned inLength, inline void sendSysEx(unsigned inLength,
const byte* inArray, const byte* inArray,
bool inArrayContainsBoundaries = false); bool inArrayContainsBoundaries = false);
@ -241,7 +243,8 @@ private:
bool mThruActivated : 1; bool mThruActivated : 1;
Thru::Mode mThruFilterMode : 7; Thru::Mode mThruFilterMode : 7;
MidiMessage mMessage; MidiMessage mMessage;
unsigned long mLastSendMessageTime;
bool mActiveSensingActivated;
private: private:
inline StatusByte getStatus(MidiType inType, inline StatusByte getStatus(MidiType inType,

View File

@ -40,6 +40,8 @@ inline MidiInterface<SerialPort, Settings>::MidiInterface(SerialPort& inSerial)
, mPendingMessageIndex(0) , mPendingMessageIndex(0)
, mCurrentRpnNumber(0xffff) , mCurrentRpnNumber(0xffff)
, mCurrentNrpnNumber(0xffff) , mCurrentNrpnNumber(0xffff)
, mActiveSensingActivated(false)
, mLastSendMessageTime(0)
, mThruActivated(true) , mThruActivated(true)
, mThruFilterMode(Thru::Full) , mThruFilterMode(Thru::Full)
{ {
@ -100,6 +102,9 @@ void MidiInterface<SerialPort, Settings>::begin(Channel inChannel)
mCurrentRpnNumber = 0xffff; mCurrentRpnNumber = 0xffff;
mCurrentNrpnNumber = 0xffff; mCurrentNrpnNumber = 0xffff;
mActiveSensingActivated = false;
mLastSendMessageTime = millis();
mMessage.valid = false; mMessage.valid = false;
mMessage.type = InvalidType; mMessage.type = InvalidType;
mMessage.channel = 0; mMessage.channel = 0;
@ -177,6 +182,9 @@ void MidiInterface<SerialPort, Settings>::send(MidiType inType,
{ {
sendRealTime(inType); // System Real-time and 1 byte. sendRealTime(inType); // System Real-time and 1 byte.
} }
if (mActiveSensingActivated)
mLastSendMessageTime = millis();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -312,6 +320,22 @@ void MidiInterface<SerialPort, Settings>::sendPitchBend(double inPitchValue,
sendPitchBend(value, inChannel); sendPitchBend(value, inChannel);
} }
/*! \brief Send an Active Sensing message.
This message is intended to be sent
repeatedly to tell the receiver that a connection is alive. Use
of this message is optional. When initially received, the
receiver will expect to receive another Active Sensing
message each 300ms (max), and if it does not then it will
assume that the connection has been terminated.
*/
template<class Encoder, class Settings>
void MidiInterface<Encoder, Settings>::sendActiveSensing()
{
sendRealTime(ActiveSensing);
}
/*! \brief Generate and send a System Exclusive frame. /*! \brief Generate and send a System Exclusive frame.
\param inLength The size of the array to send \param inLength The size of the array to send
\param inArray The byte array containing the data to send \param inArray The byte array containing the data to send
@ -650,6 +674,20 @@ inline bool MidiInterface<SerialPort, Settings>::read()
template<class SerialPort, class Settings> template<class SerialPort, class Settings>
inline bool MidiInterface<SerialPort, Settings>::read(Channel inChannel) inline bool MidiInterface<SerialPort, Settings>::read(Channel inChannel)
{ {
// Active Sensing. This message is intended to be sent
// repeatedly to tell the receiver that a connection is alive. Use
// of this message is optional. When initially received, the
// receiver will expect to receive another Active Sensing
// message each 300ms (max), and if it does not then it will
// assume that the connection has been terminated. At
// termination, the receiver will turn off all voices and return to
// normal (non- active sensing) operation.
if (mActiveSensingActivated && (millis() - mLastSendMessageTime) > 250)
{
sendActiveSensing();
mLastSendMessageTime = millis();
}
if (inChannel >= MIDI_CHANNEL_OFF) if (inChannel >= MIDI_CHANNEL_OFF)
return false; // MIDI Input disabled. return false; // MIDI Input disabled.