/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2015 - ROLI Ltd. Permission is granted to use this software under the terms of either: a) the GPL v2 (or any later version) b) the Affero GPL v3 Details of these licenses can be found at: www.gnu.org/licenses JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.juce.com for more information. ============================================================================== */ #ifndef JUCE_MIDIRPNDETECTOR_H_INCLUDED #define JUCE_MIDIRPNDETECTOR_H_INCLUDED //============================================================================== /** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered parameter number) message. */ struct MidiRPNMessage { /** Midi channel of the message, in the range 1 to 16. */ int channel; /** The 14-bit parameter index, in the range 0 to 16383 (0x3fff). */ int parameterNumber; /** The parameter value, in the range 0 to 16383 (0x3fff). If the message contains no value LSB, the value will be in the range 0 to 127 (0x7f). */ int value; /** True if this message is an NRPN; false if it is an RPN. */ bool isNRPN; /** True if the value uses 14-bit resolution (LSB + MSB); false if the value is 7-bit (MSB only). */ bool is14BitValue; }; //============================================================================== /** Parses a stream of MIDI data to assemble RPN and NRPN messages from their constituent MIDI CC messages. The detector uses the following parsing rules: the parameter number LSB/MSB can be sent/received in either order and must both come before the parameter value; for the parameter value, LSB always has to be sent/received before the value MSB, otherwise it will be treated as 7-bit (MSB only). */ class JUCE_API MidiRPNDetector { public: /** Constructor. */ MidiRPNDetector() noexcept; /** Destructor. */ ~MidiRPNDetector() noexcept; /** Resets the RPN detector's internal state, so that it forgets about previously received MIDI CC messages. */ void reset() noexcept; //============================================================================== /** Takes the next in a stream of incoming MIDI CC messages and returns true if it forms the last of a sequence that makes an RPN or NPRN. If this returns true, then the RPNMessage object supplied will be filled-out with the message's details. (If it returns false then the RPNMessage object will be unchanged). */ bool parseControllerMessage (int midiChannel, int controllerNumber, int controllerValue, MidiRPNMessage& result) noexcept; private: //============================================================================== struct ChannelState { ChannelState() noexcept; bool handleController (int channel, int controllerNumber, int value, MidiRPNMessage&) noexcept; void resetValue() noexcept; bool sendIfReady (int channel, MidiRPNMessage&) noexcept; uint8 parameterMSB, parameterLSB, valueMSB, valueLSB; bool isNRPN; }; //============================================================================== ChannelState states[16]; JUCE_LEAK_DETECTOR (MidiRPNDetector) }; //============================================================================== /** Generates an appropriate sequence of MIDI CC messages to represent an RPN or NRPN message. This sequence (as a MidiBuffer) can then be directly sent to a MidiOutput. */ class JUCE_API MidiRPNGenerator { public: //============================================================================== /** Generates a MIDI sequence representing the given RPN or NRPN message. */ static MidiBuffer generate (MidiRPNMessage message); //============================================================================== /** Generates a MIDI sequence representing an RPN or NRPN message with the given parameters. @param channel The MIDI channel of the RPN/NRPN message. @param parameterNumber The parameter number, in the range 0 to 16383. @param value The parameter value, in the range 0 to 16383, or in the range 0 to 127 if sendAs14BitValue is false. @param isNRPN Whether you need a MIDI RPN or NRPN sequence (RPN is default). @param use14BitValue If true (default), the value will have 14-bit precision (two MIDI bytes). If false, instead the value will have 7-bit presision (a single MIDI byte). */ static MidiBuffer generate (int channel, int parameterNumber, int value, bool isNRPN = false, bool use14BitValue = true); }; #endif // JUCE_MIDIRPNDETECTOR_H_INCLUDED