diff --git a/src/MIDI.h b/src/MIDI.h index 773ebb9..09961a2 100644 --- a/src/MIDI.h +++ b/src/MIDI.h @@ -97,6 +97,33 @@ public: inline void sendTuneRequest(); inline void sendRealTime(MidiType inType); + inline void beginRpn(unsigned inNumber, + Channel inChannel); + inline void sendRpnValue(unsigned inValue, + Channel inChannel); + inline void sendRpnValue(byte inMsb, + byte inLsb, + Channel inChannel); + inline void sendRpnIncrement(byte inAmount, + Channel inChannel); + inline void sendRpnDecrement(byte inAmount, + Channel inChannel); + inline void endRpn(Channel inChannel); + + inline void beginNrpn(unsigned inNumber, + Channel inChannel); + inline void sendNrpnValue(unsigned inValue, + Channel inChannel); + inline void sendNrpnValue(byte inMsb, + byte inLsb, + Channel inChannel); + inline void sendNrpnIncrement(byte inAmount, + Channel inChannel); + inline void sendNrpnDecrement(byte inAmount, + Channel inChannel); + inline void endNrpn(Channel inChannel); + + public: void send(MidiType inType, DataByte inData1, @@ -210,6 +237,8 @@ private: byte mPendingMessage[3]; unsigned mPendingMessageExpectedLenght; unsigned mPendingMessageIndex; + unsigned mCurrentRpnNumber; + unsigned mCurrentNrpnNumber; MidiMessage mMessage; private: diff --git a/src/MIDI.hpp b/src/MIDI.hpp index c1ca93d..28e672e 100644 --- a/src/MIDI.hpp +++ b/src/MIDI.hpp @@ -438,6 +438,164 @@ void MidiInterface::sendRealTime(MidiType inType) } } +/*! \brief Start a Registered Parameter Number frame. + \param inNumber The 14-bit number of the RPN you want to select. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::beginRpn(unsigned inNumber, + Channel inChannel) +{ + if (mCurrentRpnNumber != inNumber) + { + const byte numMsb = 0x7f & (inNumber >> 7); + const byte numLsb = 0x7f & inNumber; + sendControlChange(RPNLSB, numLsb, inChannel); + sendControlChange(RPNMSB, numMsb, inChannel); + mCurrentRpnNumber = inNumber; + } +} + +/*! \brief Send a 14-bit value for the currently selected RPN number. + \param inValue The 14-bit value of the selected RPN. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::sendRpnValue(unsigned inValue, + Channel inChannel) +{; + const byte valMsb = 0x7f & (inValue >> 7); + const byte valLsb = 0x7f & inValue; + sendControlChange(DataEntryLSB, valLsb, inChannel); + sendControlChange(DataEntryMSB, valMsb, inChannel); +} + +/*! \brief Send separate MSB/LSB values for the currently selected RPN number. + \param inMsb The MSB part of the value to send. Meaning depends on RPN number. + \param inLsb The LSB part of the value to send. Meaning depends on RPN number. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::sendRpnValue(byte inMsb, + byte inLsb, + Channel inChannel) +{ + sendControlChange(DataEntryLSB, inLsb, inChannel); + sendControlChange(DataEntryMSB, inMsb, inChannel); +} + +/* \brief Increment the value of the currently selected RPN number by the specified amount. + \param inAmount The amount to add to the currently selected RPN value. +*/ +template +inline void MidiInterface::sendRpnIncrement(byte inAmount, + Channel inChannel) +{ + sendControlChange(DataIncrement, inAmount, inChannel); +} + +/* \brief Decrement the value of the currently selected RPN number by the specified amount. + \param inAmount The amount to subtract to the currently selected RPN value. +*/ +template +inline void MidiInterface::sendRpnDecrement(byte inAmount, + Channel inChannel) +{ + sendControlChange(DataDecrement, inAmount, inChannel); +} + +/*! \brief Terminate an RPN frame. +This will send a Null Function to deselect the currently selected RPN. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::endRpn(Channel inChannel) +{ + sendControlChange(RPNLSB, 0x7f, inChannel); + sendControlChange(RPNMSB, 0x7f, inChannel); + mCurrentRpnNumber = 0xffff; +} + + + +/*! \brief Start a Non-Registered Parameter Number frame. + \param inNumber The 14-bit number of the NRPN you want to select. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::beginNrpn(unsigned inNumber, + Channel inChannel) +{ + if (mCurrentNrpnNumber != inNumber) + { + const byte numMsb = 0x7f & (inNumber >> 7); + const byte numLsb = 0x7f & inNumber; + sendControlChange(NRPNLSB, numLsb, inChannel); + sendControlChange(NRPNMSB, numMsb, inChannel); + mCurrentNrpnNumber = inNumber; + } +} + +/*! \brief Send a 14-bit value for the currently selected NRPN number. + \param inValue The 14-bit value of the selected NRPN. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::sendNrpnValue(unsigned inValue, + Channel inChannel) +{; + const byte valMsb = 0x7f & (inValue >> 7); + const byte valLsb = 0x7f & inValue; + sendControlChange(DataEntryLSB, valLsb, inChannel); + sendControlChange(DataEntryMSB, valMsb, inChannel); +} + +/*! \brief Send separate MSB/LSB values for the currently selected NRPN number. + \param inMsb The MSB part of the value to send. Meaning depends on NRPN number. + \param inLsb The LSB part of the value to send. Meaning depends on NRPN number. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::sendNrpnValue(byte inMsb, + byte inLsb, + Channel inChannel) +{ + sendControlChange(DataEntryLSB, inLsb, inChannel); + sendControlChange(DataEntryMSB, inMsb, inChannel); +} + +/* \brief Increment the value of the currently selected NRPN number by the specified amount. + \param inAmount The amount to add to the currently selected NRPN value. +*/ +template +inline void MidiInterface::sendNrpnIncrement(byte inAmount, + Channel inChannel) +{ + sendControlChange(DataIncrement, inAmount, inChannel); +} + +/* \brief Decrement the value of the currently selected NRPN number by the specified amount. + \param inAmount The amount to subtract to the currently selected NRPN value. +*/ +template +inline void MidiInterface::sendNrpnDecrement(byte inAmount, + Channel inChannel) +{ + sendControlChange(DataDecrement, inAmount, inChannel); +} + +/*! \brief Terminate an NRPN frame. +This will send a Null Function to deselect the currently selected NRPN. + \param inChannel The channel on which the message will be sent (1 to 16). +*/ +template +inline void MidiInterface::endNrpn(Channel inChannel) +{ + sendControlChange(NRPNLSB, 0x7f, inChannel); + sendControlChange(NRPNMSB, 0x7f, inChannel); + mCurrentNrpnNumber = 0xffff; +} + /*! @} */ // End of doc group MIDI Output // ----------------------------------------------------------------------------- diff --git a/src/midi_Defs.h b/src/midi_Defs.h index b8f2985..6ddb326 100644 --- a/src/midi_Defs.h +++ b/src/midi_Defs.h @@ -107,7 +107,7 @@ enum MidiControlChangeNumber // CC3 undefined FootController = 4, PortamentoTime = 5, - DataEntry = 6, + DataEntryMSB = 6, ChannelVolume = 7, Balance = 8, // CC9 undefined @@ -156,9 +156,9 @@ enum MidiControlChangeNumber Effects5 = 95, ///< Phaser depth DataIncrement = 96, DataDecrement = 97, - NRPN = 98, ///< Non-Registered Parameter Number (LSB) + NRPNLSB = 98, ///< Non-Registered Parameter Number (LSB) NRPNMSB = 99, ///< Non-Registered Parameter Number (MSB) - RPN = 100, ///< Registered Parameter Number (LSB) + RPNLSB = 100, ///< Registered Parameter Number (LSB) RPNMSB = 101, ///< Registered Parameter Number (MSB) // Channel Mode messages ---------------------------------------------------