From 7f9934b1aaace166de6d49f71de1ef0a183db8fa Mon Sep 17 00:00:00 2001 From: lathoub Date: Sun, 26 Jan 2020 11:05:10 +0100 Subject: [PATCH] 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. --- .gitignore | 1 + src/MIDI.h | 5 ++++- src/MIDI.hpp | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7491451..87dcd22 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ build/ .vscode/.cmaketools.json src/.DS_Store examples/.DS_Store +.DS_Store diff --git a/src/MIDI.h b/src/MIDI.h index e00bf98..78ba06c 100644 --- a/src/MIDI.h +++ b/src/MIDI.h @@ -86,6 +86,8 @@ public: DataByte inPressure, Channel inChannel); + inline void sendActiveSensing(); + inline void sendSysEx(unsigned inLength, const byte* inArray, bool inArrayContainsBoundaries = false); @@ -241,7 +243,8 @@ private: bool mThruActivated : 1; Thru::Mode mThruFilterMode : 7; MidiMessage mMessage; - + unsigned long mLastSendMessageTime; + bool mActiveSensingActivated; private: inline StatusByte getStatus(MidiType inType, diff --git a/src/MIDI.hpp b/src/MIDI.hpp index 7df1afb..0f1aea1 100644 --- a/src/MIDI.hpp +++ b/src/MIDI.hpp @@ -40,6 +40,8 @@ inline MidiInterface::MidiInterface(SerialPort& inSerial) , mPendingMessageIndex(0) , mCurrentRpnNumber(0xffff) , mCurrentNrpnNumber(0xffff) + , mActiveSensingActivated(false) + , mLastSendMessageTime(0) , mThruActivated(true) , mThruFilterMode(Thru::Full) { @@ -100,6 +102,9 @@ void MidiInterface::begin(Channel inChannel) mCurrentRpnNumber = 0xffff; mCurrentNrpnNumber = 0xffff; + mActiveSensingActivated = false; + mLastSendMessageTime = millis(); + mMessage.valid = false; mMessage.type = InvalidType; mMessage.channel = 0; @@ -177,6 +182,9 @@ void MidiInterface::send(MidiType inType, { sendRealTime(inType); // System Real-time and 1 byte. } + + if (mActiveSensingActivated) + mLastSendMessageTime = millis(); } // ----------------------------------------------------------------------------- @@ -312,6 +320,22 @@ void MidiInterface::sendPitchBend(double inPitchValue, 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 +void MidiInterface::sendActiveSensing() +{ + sendRealTime(ActiveSensing); +} + + /*! \brief Generate and send a System Exclusive frame. \param inLength The size of the array to send \param inArray The byte array containing the data to send @@ -650,6 +674,20 @@ inline bool MidiInterface::read() template inline bool MidiInterface::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) return false; // MIDI Input disabled.