diff --git a/.github/workflows/platformio.yml b/.github/workflows/platformio.yml index 64331444..5f1c4998 100644 --- a/.github/workflows/platformio.yml +++ b/.github/workflows/platformio.yml @@ -17,6 +17,7 @@ jobs: - Basic_IO - Bench - Callbacks + - Chaining - DualMerger - ErrorCallback - Input diff --git a/examples/Chaining/Chaining.ino b/examples/Chaining/Chaining.ino new file mode 100644 index 00000000..be36ee97 --- /dev/null +++ b/examples/Chaining/Chaining.ino @@ -0,0 +1,37 @@ +#include + +MIDI_CREATE_DEFAULT_INSTANCE(); + +void setup() +{ + pinMode(2, INPUT); + + MIDI // chaining MIDI commands - order is from top to bottom (turnThruOff,... begin) + .turnThruOff() + // using a lamdba function for this callbacks + .setHandleNoteOn([](byte channel, byte note, byte velocity) + { + // Do whatever you want when a note is pressed. + + // Try to keep your callbacks short (no delays ect) + // otherwise it would slow down the loop() and have a bad impact + // on real-time performance. + }) + .setHandleNoteOff([](byte channel, byte note, byte velocity) + { + // Do something when the note is released. + // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs. + }) + .begin(MIDI_CHANNEL_OMNI); // Initiate MIDI communications, listen to all channels +} + +void loop() +{ + // Call MIDI.read the fastest you can for real-time performance. + MIDI.read(); + + if (digitalRead(2)) + MIDI // chained sendNoteOn commands + .sendNoteOn(42, 127, 1) + .sendNoteOn(40, 54, 1); +} diff --git a/src/MIDI.h b/src/MIDI.h index 0e927cea..f1e49f06 100644 --- a/src/MIDI.h +++ b/src/MIDI.h @@ -62,94 +62,94 @@ class MidiInterface inline ~MidiInterface(); public: - void begin(Channel inChannel = 1); + MidiInterface& begin(Channel inChannel = 1); // ------------------------------------------------------------------------- // MIDI Output public: - inline void sendNoteOn(DataByte inNoteNumber, + inline MidiInterface& sendNoteOn(DataByte inNoteNumber, DataByte inVelocity, Channel inChannel); - inline void sendNoteOff(DataByte inNoteNumber, + inline MidiInterface& sendNoteOff(DataByte inNoteNumber, DataByte inVelocity, Channel inChannel); - inline void sendProgramChange(DataByte inProgramNumber, + inline MidiInterface& sendProgramChange(DataByte inProgramNumber, Channel inChannel); - inline void sendControlChange(DataByte inControlNumber, + inline MidiInterface& sendControlChange(DataByte inControlNumber, DataByte inControlValue, Channel inChannel); - inline void sendPitchBend(int inPitchValue, Channel inChannel); - inline void sendPitchBend(double inPitchValue, Channel inChannel); + inline MidiInterface& sendPitchBend(int inPitchValue, Channel inChannel); + inline MidiInterface& sendPitchBend(double inPitchValue, Channel inChannel); - inline void sendPolyPressure(DataByte inNoteNumber, + inline MidiInterface& sendPolyPressure(DataByte inNoteNumber, DataByte inPressure, Channel inChannel) __attribute__ ((deprecated)); - inline void sendAfterTouch(DataByte inPressure, + inline MidiInterface& sendAfterTouch(DataByte inPressure, Channel inChannel); - inline void sendAfterTouch(DataByte inNoteNumber, + inline MidiInterface& sendAfterTouch(DataByte inNoteNumber, DataByte inPressure, Channel inChannel); - inline void sendSysEx(unsigned inLength, + inline MidiInterface& sendSysEx(unsigned inLength, const byte* inArray, bool inArrayContainsBoundaries = false); - inline void sendTimeCodeQuarterFrame(DataByte inTypeNibble, + inline MidiInterface& sendTimeCodeQuarterFrame(DataByte inTypeNibble, DataByte inValuesNibble); - inline void sendTimeCodeQuarterFrame(DataByte inData); + inline MidiInterface& sendTimeCodeQuarterFrame(DataByte inData); - inline void sendSongPosition(unsigned inBeats); - inline void sendSongSelect(DataByte inSongNumber); - inline void sendTuneRequest(); + inline MidiInterface& sendSongPosition(unsigned inBeats); + inline MidiInterface& sendSongSelect(DataByte inSongNumber); + inline MidiInterface& sendTuneRequest(); - inline void sendCommon(MidiType inType, unsigned = 0); + inline MidiInterface& sendCommon(MidiType inType, unsigned = 0); - inline void sendClock() { sendRealTime(Clock); }; - inline void sendStart() { sendRealTime(Start); }; - inline void sendStop() { sendRealTime(Stop); }; - inline void sendTick() { sendRealTime(Tick); }; - inline void sendContinue() { sendRealTime(Continue); }; - inline void sendActiveSensing() { sendRealTime(ActiveSensing); }; - inline void sendSystemReset() { sendRealTime(SystemReset); }; + inline MidiInterface& sendClock() { sendRealTime(Clock); }; + inline MidiInterface& sendStart() { sendRealTime(Start); }; + inline MidiInterface& sendStop() { sendRealTime(Stop); }; + inline MidiInterface& sendTick() { sendRealTime(Tick); }; + inline MidiInterface& sendContinue() { sendRealTime(Continue); }; + inline MidiInterface& sendActiveSensing() { sendRealTime(ActiveSensing); }; + inline MidiInterface& sendSystemReset() { sendRealTime(SystemReset); }; - inline void sendRealTime(MidiType inType); + inline MidiInterface& sendRealTime(MidiType inType); - inline void beginRpn(unsigned inNumber, + inline MidiInterface& beginRpn(unsigned inNumber, Channel inChannel); - inline void sendRpnValue(unsigned inValue, + inline MidiInterface& sendRpnValue(unsigned inValue, Channel inChannel); - inline void sendRpnValue(byte inMsb, + inline MidiInterface& sendRpnValue(byte inMsb, byte inLsb, Channel inChannel); - inline void sendRpnIncrement(byte inAmount, + inline MidiInterface& sendRpnIncrement(byte inAmount, Channel inChannel); - inline void sendRpnDecrement(byte inAmount, + inline MidiInterface& sendRpnDecrement(byte inAmount, Channel inChannel); - inline void endRpn(Channel inChannel); + inline MidiInterface& endRpn(Channel inChannel); - inline void beginNrpn(unsigned inNumber, + inline MidiInterface& beginNrpn(unsigned inNumber, Channel inChannel); - inline void sendNrpnValue(unsigned inValue, + inline MidiInterface& sendNrpnValue(unsigned inValue, Channel inChannel); - inline void sendNrpnValue(byte inMsb, + inline MidiInterface& sendNrpnValue(byte inMsb, byte inLsb, Channel inChannel); - inline void sendNrpnIncrement(byte inAmount, + inline MidiInterface& sendNrpnIncrement(byte inAmount, Channel inChannel); - inline void sendNrpnDecrement(byte inAmount, + inline MidiInterface& sendNrpnDecrement(byte inAmount, Channel inChannel); - inline void endNrpn(Channel inChannel); + inline MidiInterface& endNrpn(Channel inChannel); - inline void send(const MidiMessage&); + inline MidiInterface& send(const MidiMessage&); public: - void send(MidiType inType, + MidiInterface& send(MidiType inType, DataByte inData1, DataByte inData2, Channel inChannel); @@ -172,7 +172,7 @@ class MidiInterface public: inline Channel getInputChannel() const; - inline void setInputChannel(Channel inChannel); + inline MidiInterface& setInputChannel(Channel inChannel); public: static inline MidiType getTypeFromStatusByte(byte inStatus); @@ -183,29 +183,29 @@ class MidiInterface // Input Callbacks public: - inline void setHandleMessage(void (*fptr)(const MidiMessage&)) { mMessageCallback = fptr; }; - inline void setHandleError(ErrorCallback fptr) { mErrorCallback = fptr; } - inline void setHandleNoteOff(NoteOffCallback fptr) { mNoteOffCallback = fptr; } - inline void setHandleNoteOn(NoteOnCallback fptr) { mNoteOnCallback = fptr; } - inline void setHandleAfterTouchPoly(AfterTouchPolyCallback fptr) { mAfterTouchPolyCallback = fptr; } - inline void setHandleControlChange(ControlChangeCallback fptr) { mControlChangeCallback = fptr; } - inline void setHandleProgramChange(ProgramChangeCallback fptr) { mProgramChangeCallback = fptr; } - inline void setHandleAfterTouchChannel(AfterTouchChannelCallback fptr) { mAfterTouchChannelCallback = fptr; } - inline void setHandlePitchBend(PitchBendCallback fptr) { mPitchBendCallback = fptr; } - inline void setHandleSystemExclusive(SystemExclusiveCallback fptr) { mSystemExclusiveCallback = fptr; } - inline void setHandleTimeCodeQuarterFrame(TimeCodeQuarterFrameCallback fptr) { mTimeCodeQuarterFrameCallback = fptr; } - inline void setHandleSongPosition(SongPositionCallback fptr) { mSongPositionCallback = fptr; } - inline void setHandleSongSelect(SongSelectCallback fptr) { mSongSelectCallback = fptr; } - inline void setHandleTuneRequest(TuneRequestCallback fptr) { mTuneRequestCallback = fptr; } - inline void setHandleClock(ClockCallback fptr) { mClockCallback = fptr; } - inline void setHandleStart(StartCallback fptr) { mStartCallback = fptr; } - inline void setHandleTick(TickCallback fptr) { mTickCallback = fptr; } - inline void setHandleContinue(ContinueCallback fptr) { mContinueCallback = fptr; } - inline void setHandleStop(StopCallback fptr) { mStopCallback = fptr; } - inline void setHandleActiveSensing(ActiveSensingCallback fptr) { mActiveSensingCallback = fptr; } - inline void setHandleSystemReset(SystemResetCallback fptr) { mSystemResetCallback = fptr; } - - inline void disconnectCallbackFromType(MidiType inType); + inline MidiInterface& setHandleMessage(void (*fptr)(const MidiMessage&)) { mMessageCallback = fptr; return *this; }; + inline MidiInterface& setHandleError(ErrorCallback fptr) { mErrorCallback = fptr; return *this; }; + inline MidiInterface& setHandleNoteOff(NoteOffCallback fptr) { mNoteOffCallback = fptr; return *this; }; + inline MidiInterface& setHandleNoteOn(NoteOnCallback fptr) { mNoteOnCallback = fptr; return *this; }; + inline MidiInterface& setHandleAfterTouchPoly(AfterTouchPolyCallback fptr) { mAfterTouchPolyCallback = fptr; return *this; }; + inline MidiInterface& setHandleControlChange(ControlChangeCallback fptr) { mControlChangeCallback = fptr; return *this; }; + inline MidiInterface& setHandleProgramChange(ProgramChangeCallback fptr) { mProgramChangeCallback = fptr; return *this; }; + inline MidiInterface& setHandleAfterTouchChannel(AfterTouchChannelCallback fptr) { mAfterTouchChannelCallback = fptr; return *this; }; + inline MidiInterface& setHandlePitchBend(PitchBendCallback fptr) { mPitchBendCallback = fptr; return *this; }; + inline MidiInterface& setHandleSystemExclusive(SystemExclusiveCallback fptr) { mSystemExclusiveCallback = fptr; return *this; }; + inline MidiInterface& setHandleTimeCodeQuarterFrame(TimeCodeQuarterFrameCallback fptr) { mTimeCodeQuarterFrameCallback = fptr; return *this; }; + inline MidiInterface& setHandleSongPosition(SongPositionCallback fptr) { mSongPositionCallback = fptr; return *this; }; + inline MidiInterface& setHandleSongSelect(SongSelectCallback fptr) { mSongSelectCallback = fptr; return *this; }; + inline MidiInterface& setHandleTuneRequest(TuneRequestCallback fptr) { mTuneRequestCallback = fptr; return *this; }; + inline MidiInterface& setHandleClock(ClockCallback fptr) { mClockCallback = fptr; return *this; }; + inline MidiInterface& setHandleStart(StartCallback fptr) { mStartCallback = fptr; return *this; }; + inline MidiInterface& setHandleTick(TickCallback fptr) { mTickCallback = fptr; return *this; }; + inline MidiInterface& setHandleContinue(ContinueCallback fptr) { mContinueCallback = fptr; return *this; }; + inline MidiInterface& setHandleStop(StopCallback fptr) { mStopCallback = fptr; return *this; }; + inline MidiInterface& setHandleActiveSensing(ActiveSensingCallback fptr) { mActiveSensingCallback = fptr; return *this; }; + inline MidiInterface& setHandleSystemReset(SystemResetCallback fptr) { mSystemResetCallback = fptr; return *this; }; + + inline MidiInterface& disconnectCallbackFromType(MidiType inType); private: void launchCallback(); @@ -239,9 +239,9 @@ class MidiInterface inline Thru::Mode getFilterMode() const; inline bool getThruState() const; - inline void turnThruOn(Thru::Mode inThruFilterMode = Thru::Full); - inline void turnThruOff(); - inline void setThruFilterMode(Thru::Mode inThruFilterMode); + inline MidiInterface& turnThruOn(Thru::Mode inThruFilterMode = Thru::Full); + inline MidiInterface& turnThruOff(); + inline MidiInterface& setThruFilterMode(Thru::Mode inThruFilterMode); private: void thruFilter(byte inChannel); diff --git a/src/MIDI.hpp b/src/MIDI.hpp index e071178b..bb9ffc1c 100644 --- a/src/MIDI.hpp +++ b/src/MIDI.hpp @@ -69,7 +69,7 @@ inline MidiInterface::~MidiInterface() - Full thru mirroring */ template -void MidiInterface::begin(Channel inChannel) +MidiInterface& MidiInterface::begin(Channel inChannel) { // Initialise the Transport layer mTransport.begin(); @@ -95,6 +95,8 @@ void MidiInterface::begin(Channel inChannel) mThruFilterMode = Thru::Full; mThruActivated = mTransport.thruActivated; + + return *this; } // ----------------------------------------------------------------------------- @@ -115,10 +117,10 @@ void MidiInterface::begin(Channel inChannel) them thru. */ template -void MidiInterface::send(const MidiMessage& inMessage) +MidiInterface& MidiInterface::send(const MidiMessage& inMessage) { if (!inMessage.valid) - return; + return *this; if (mTransport.beginTransmission(inMessage.type)) { @@ -142,6 +144,8 @@ void MidiInterface::send(const MidiMessage& inMes } mTransport.endTransmission(); updateLastSentTime(); + + return *this; } @@ -157,7 +161,7 @@ void MidiInterface::send(const MidiMessage& inMes from your code, at your own risks. */ template -void MidiInterface::send(MidiType inType, +MidiInterface& MidiInterface::send(MidiType inType, DataByte inData1, DataByte inData2, Channel inChannel) @@ -169,7 +173,7 @@ void MidiInterface::send(MidiType inType, inChannel == MIDI_CHANNEL_OMNI || inType < 0x80) { - return; // Don't send anything + return *this; // Don't send anything } // Protection: remove MSBs on data inData1 &= 0x7f; @@ -209,6 +213,8 @@ void MidiInterface::send(MidiType inType, { sendRealTime(inType); // System Real-time and 1 byte. } + + return *this; } // ----------------------------------------------------------------------------- @@ -223,11 +229,11 @@ void MidiInterface::send(MidiType inType, http://www.phys.unsw.edu.au/jw/notes.html */ template -void MidiInterface::sendNoteOn(DataByte inNoteNumber, +MidiInterface& MidiInterface::sendNoteOn(DataByte inNoteNumber, DataByte inVelocity, Channel inChannel) { - send(NoteOn, inNoteNumber, inVelocity, inChannel); + return send(NoteOn, inNoteNumber, inVelocity, inChannel); } /*! \brief Send a Note Off message @@ -242,11 +248,11 @@ void MidiInterface::sendNoteOn(DataByte inNoteNum http://www.phys.unsw.edu.au/jw/notes.html */ template -void MidiInterface::sendNoteOff(DataByte inNoteNumber, +MidiInterface& MidiInterface::sendNoteOff(DataByte inNoteNumber, DataByte inVelocity, Channel inChannel) { - send(NoteOff, inNoteNumber, inVelocity, inChannel); + return send(NoteOff, inNoteNumber, inVelocity, inChannel); } /*! \brief Send a Program Change message @@ -254,10 +260,10 @@ void MidiInterface::sendNoteOff(DataByte inNoteNu \param inChannel The channel on which the message will be sent (1 to 16). */ template -void MidiInterface::sendProgramChange(DataByte inProgramNumber, +MidiInterface& MidiInterface::sendProgramChange(DataByte inProgramNumber, Channel inChannel) { - send(ProgramChange, inProgramNumber, 0, inChannel); + return send(ProgramChange, inProgramNumber, 0, inChannel); } /*! \brief Send a Control Change message @@ -267,11 +273,11 @@ void MidiInterface::sendProgramChange(DataByte in @see MidiControlChangeNumber */ template -void MidiInterface::sendControlChange(DataByte inControlNumber, +MidiInterface& MidiInterface::sendControlChange(DataByte inControlNumber, DataByte inControlValue, Channel inChannel) { - send(ControlChange, inControlNumber, inControlValue, inChannel); + return send(ControlChange, inControlNumber, inControlValue, inChannel); } /*! \brief Send a Polyphonic AfterTouch message (applies to a specified note) @@ -282,11 +288,11 @@ void MidiInterface::sendControlChange(DataByte in library, @see sendAfterTouch to send polyphonic and monophonic AfterTouch messages. */ template -void MidiInterface::sendPolyPressure(DataByte inNoteNumber, +MidiInterface& MidiInterface::sendPolyPressure(DataByte inNoteNumber, DataByte inPressure, Channel inChannel) { - send(AfterTouchPoly, inNoteNumber, inPressure, inChannel); + return send(AfterTouchPoly, inNoteNumber, inPressure, inChannel); } /*! \brief Send a MonoPhonic AfterTouch message (applies to all notes) @@ -294,10 +300,10 @@ void MidiInterface::sendPolyPressure(DataByte inN \param inChannel The channel on which the message will be sent (1 to 16). */ template -void MidiInterface::sendAfterTouch(DataByte inPressure, +MidiInterface& MidiInterface::sendAfterTouch(DataByte inPressure, Channel inChannel) { - send(AfterTouchChannel, inPressure, 0, inChannel); + return send(AfterTouchChannel, inPressure, 0, inChannel); } /*! \brief Send a Polyphonic AfterTouch message (applies to a specified note) @@ -307,11 +313,11 @@ void MidiInterface::sendAfterTouch(DataByte inPre @see Replaces sendPolyPressure (which is now deprecated). */ template -void MidiInterface::sendAfterTouch(DataByte inNoteNumber, +MidiInterface& MidiInterface::sendAfterTouch(DataByte inNoteNumber, DataByte inPressure, Channel inChannel) { - send(AfterTouchPoly, inNoteNumber, inPressure, inChannel); + return send(AfterTouchPoly, inNoteNumber, inPressure, inChannel); } /*! \brief Send a Pitch Bend message using a signed integer value. @@ -321,11 +327,11 @@ void MidiInterface::sendAfterTouch(DataByte inNot \param inChannel The channel on which the message will be sent (1 to 16). */ template -void MidiInterface::sendPitchBend(int inPitchValue, +MidiInterface& MidiInterface::sendPitchBend(int inPitchValue, Channel inChannel) { const unsigned bend = unsigned(inPitchValue - int(MIDI_PITCHBEND_MIN)); - send(PitchBend, (bend & 0x7f), (bend >> 7) & 0x7f, inChannel); + return send(PitchBend, (bend & 0x7f), (bend >> 7) & 0x7f, inChannel); } @@ -336,12 +342,12 @@ void MidiInterface::sendPitchBend(int inPitchValu \param inChannel The channel on which the message will be sent (1 to 16). */ template -void MidiInterface::sendPitchBend(double inPitchValue, +MidiInterface& MidiInterface::sendPitchBend(double inPitchValue, Channel inChannel) { const int scale = inPitchValue > 0.0 ? MIDI_PITCHBEND_MAX : - MIDI_PITCHBEND_MIN; const int value = int(inPitchValue * double(scale)); - sendPitchBend(value, inChannel); + return sendPitchBend(value, inChannel); } /*! \brief Generate and send a System Exclusive frame. @@ -354,7 +360,7 @@ void MidiInterface::sendPitchBend(double inPitchV with previous versions of the library. */ template -void MidiInterface::sendSysEx(unsigned inLength, +MidiInterface& MidiInterface::sendSysEx(unsigned inLength, const byte* inArray, bool inArrayContainsBoundaries) { @@ -377,6 +383,8 @@ void MidiInterface::sendSysEx(unsigned inLength, if (Settings::UseRunningStatus) mRunningStatus_TX = InvalidType; + + return *this; } /*! \brief Send a Tune Request message. @@ -385,9 +393,9 @@ void MidiInterface::sendSysEx(unsigned inLength, it should tune its oscillators (if equipped with any). */ template -void MidiInterface::sendTuneRequest() +MidiInterface& MidiInterface::sendTuneRequest() { - sendCommon(TuneRequest); + return sendCommon(TuneRequest); } /*! \brief Send a MIDI Time Code Quarter Frame. @@ -397,11 +405,11 @@ void MidiInterface::sendTuneRequest() See MIDI Specification for more information. */ template -void MidiInterface::sendTimeCodeQuarterFrame(DataByte inTypeNibble, +MidiInterface& MidiInterface::sendTimeCodeQuarterFrame(DataByte inTypeNibble, DataByte inValuesNibble) { const byte data = byte((((inTypeNibble & 0x07) << 4) | (inValuesNibble & 0x0f))); - sendTimeCodeQuarterFrame(data); + return sendTimeCodeQuarterFrame(data); } /*! \brief Send a MIDI Time Code Quarter Frame. @@ -411,25 +419,25 @@ void MidiInterface::sendTimeCodeQuarterFrame(Data you can send the byte here. */ template -void MidiInterface::sendTimeCodeQuarterFrame(DataByte inData) +MidiInterface& MidiInterface::sendTimeCodeQuarterFrame(DataByte inData) { - sendCommon(TimeCodeQuarterFrame, inData); + return sendCommon(TimeCodeQuarterFrame, inData); } /*! \brief Send a Song Position Pointer message. \param inBeats The number of beats since the start of the song. */ template -void MidiInterface::sendSongPosition(unsigned inBeats) +MidiInterface& MidiInterface::sendSongPosition(unsigned inBeats) { - sendCommon(SongPosition, inBeats); + return sendCommon(SongPosition, inBeats); } /*! \brief Send a Song Select message */ template -void MidiInterface::sendSongSelect(DataByte inSongNumber) +MidiInterface& MidiInterface::sendSongSelect(DataByte inSongNumber) { - sendCommon(SongSelect, inSongNumber); + return sendCommon(SongSelect, inSongNumber); } /*! \brief Send a Common message. Common messages reset the running status. @@ -440,7 +448,7 @@ void MidiInterface::sendSongSelect(DataByte inSon \param inData1 The byte that goes with the common message. */ template -void MidiInterface::sendCommon(MidiType inType, unsigned inData1) +MidiInterface& MidiInterface::sendCommon(MidiType inType, unsigned inData1) { switch (inType) { @@ -451,7 +459,7 @@ void MidiInterface::sendCommon(MidiType inType, u break; default: // Invalid Common marker - return; + return *this; } if (mTransport.beginTransmission(inType)) @@ -482,6 +490,8 @@ void MidiInterface::sendCommon(MidiType inType, u if (Settings::UseRunningStatus) mRunningStatus_TX = InvalidType; + + return *this; } /*! \brief Send a Real Time (one byte) message. @@ -491,7 +501,7 @@ void MidiInterface::sendCommon(MidiType inType, u @see MidiType */ template -void MidiInterface::sendRealTime(MidiType inType) +MidiInterface& MidiInterface::sendRealTime(MidiType inType) { // Do not invalidate Running Status for real-time messages // as they can be interleaved within any message. @@ -515,6 +525,8 @@ void MidiInterface::sendRealTime(MidiType inType) // Invalid Real Time marker break; } + + return *this; } /*! \brief Start a Registered Parameter Number frame. @@ -522,7 +534,7 @@ void MidiInterface::sendRealTime(MidiType inType) \param inChannel The channel on which the message will be sent (1 to 16). */ template -inline void MidiInterface::beginRpn(unsigned inNumber, +inline MidiInterface& MidiInterface::beginRpn(unsigned inNumber, Channel inChannel) { if (mCurrentRpnNumber != inNumber) @@ -533,6 +545,8 @@ inline void MidiInterface::beginRpn(unsigned inNu sendControlChange(RPNMSB, numMsb, inChannel); mCurrentRpnNumber = inNumber; } + + return *this; } /*! \brief Send a 14-bit value for the currently selected RPN number. @@ -540,13 +554,15 @@ inline void MidiInterface::beginRpn(unsigned inNu \param inChannel The channel on which the message will be sent (1 to 16). */ template -inline void MidiInterface::sendRpnValue(unsigned inValue, +inline MidiInterface& MidiInterface::sendRpnValue(unsigned inValue, Channel inChannel) {; const byte valMsb = 0x7f & (inValue >> 7); const byte valLsb = 0x7f & inValue; sendControlChange(DataEntryMSB, valMsb, inChannel); sendControlChange(DataEntryLSB, valLsb, inChannel); + + return *this; } /*! \brief Send separate MSB/LSB values for the currently selected RPN number. @@ -555,32 +571,38 @@ inline void MidiInterface::sendRpnValue(unsigned \param inChannel The channel on which the message will be sent (1 to 16). */ template -inline void MidiInterface::sendRpnValue(byte inMsb, +inline MidiInterface& MidiInterface::sendRpnValue(byte inMsb, byte inLsb, Channel inChannel) { sendControlChange(DataEntryMSB, inMsb, inChannel); sendControlChange(DataEntryLSB, inLsb, inChannel); + + return *this; } /* \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, +inline MidiInterface& MidiInterface::sendRpnIncrement(byte inAmount, Channel inChannel) { sendControlChange(DataIncrement, inAmount, inChannel); + + return *this; } /* \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, +inline MidiInterface& MidiInterface::sendRpnDecrement(byte inAmount, Channel inChannel) { sendControlChange(DataDecrement, inAmount, inChannel); + + return *this; } /*! \brief Terminate an RPN frame. @@ -588,11 +610,13 @@ 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) +inline MidiInterface& MidiInterface::endRpn(Channel inChannel) { sendControlChange(RPNLSB, 0x7f, inChannel); sendControlChange(RPNMSB, 0x7f, inChannel); mCurrentRpnNumber = 0xffff; + + return *this; } @@ -602,7 +626,7 @@ inline void MidiInterface::endRpn(Channel inChann \param inChannel The channel on which the message will be sent (1 to 16). */ template -inline void MidiInterface::beginNrpn(unsigned inNumber, +inline MidiInterface& MidiInterface::beginNrpn(unsigned inNumber, Channel inChannel) { if (mCurrentNrpnNumber != inNumber) @@ -613,6 +637,8 @@ inline void MidiInterface::beginNrpn(unsigned inN sendControlChange(NRPNMSB, numMsb, inChannel); mCurrentNrpnNumber = inNumber; } + + return *this; } /*! \brief Send a 14-bit value for the currently selected NRPN number. @@ -620,13 +646,15 @@ inline void MidiInterface::beginNrpn(unsigned inN \param inChannel The channel on which the message will be sent (1 to 16). */ template -inline void MidiInterface::sendNrpnValue(unsigned inValue, +inline MidiInterface& MidiInterface::sendNrpnValue(unsigned inValue, Channel inChannel) -{; +{ const byte valMsb = 0x7f & (inValue >> 7); const byte valLsb = 0x7f & inValue; sendControlChange(DataEntryMSB, valMsb, inChannel); sendControlChange(DataEntryLSB, valLsb, inChannel); + + return *this; } /*! \brief Send separate MSB/LSB values for the currently selected NRPN number. @@ -635,32 +663,38 @@ inline void MidiInterface::sendNrpnValue(unsigned \param inChannel The channel on which the message will be sent (1 to 16). */ template -inline void MidiInterface::sendNrpnValue(byte inMsb, +inline MidiInterface& MidiInterface::sendNrpnValue(byte inMsb, byte inLsb, Channel inChannel) { sendControlChange(DataEntryMSB, inMsb, inChannel); sendControlChange(DataEntryLSB, inLsb, inChannel); + + return *this; } /* \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, +inline MidiInterface& MidiInterface::sendNrpnIncrement(byte inAmount, Channel inChannel) { sendControlChange(DataIncrement, inAmount, inChannel); + + return *this; } /* \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, +inline MidiInterface& MidiInterface::sendNrpnDecrement(byte inAmount, Channel inChannel) { sendControlChange(DataDecrement, inAmount, inChannel); + + return *this; } /*! \brief Terminate an NRPN frame. @@ -668,11 +702,13 @@ 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) +inline MidiInterface& MidiInterface::endNrpn(Channel inChannel) { sendControlChange(NRPNLSB, 0x7f, inChannel); sendControlChange(NRPNMSB, 0x7f, inChannel); mCurrentNrpnNumber = 0xffff; + + return *this; } template @@ -1212,9 +1248,11 @@ inline Channel MidiInterface::getInputChannel() c if you want to listen to all channels, and MIDI_CHANNEL_OFF to disable input. */ template -inline void MidiInterface::setInputChannel(Channel inChannel) +inline MidiInterface& MidiInterface::setInputChannel(Channel inChannel) { mInputChannel = inChannel; + + return *this; } // ----------------------------------------------------------------------------- @@ -1269,7 +1307,7 @@ bool MidiInterface::isChannelMessage(MidiType inT When a message of this type is received, no function will be called. */ template -void MidiInterface::disconnectCallbackFromType(MidiType inType) +MidiInterface& MidiInterface::disconnectCallbackFromType(MidiType inType) { switch (inType) { @@ -1295,6 +1333,8 @@ void MidiInterface::disconnectCallbackFromType(Mi default: break; } + + return *this; } /*! @} */ // End of doc group MIDI Callbacks @@ -1361,10 +1401,12 @@ void MidiInterface::launchCallback() @see Thru::Mode */ template -inline void MidiInterface::setThruFilterMode(Thru::Mode inThruFilterMode) +inline MidiInterface& MidiInterface::setThruFilterMode(Thru::Mode inThruFilterMode) { mThruFilterMode = inThruFilterMode; mThruActivated = mThruFilterMode != Thru::Off; + + return *this; } template @@ -1380,17 +1422,21 @@ inline bool MidiInterface::getThruState() const } template -inline void MidiInterface::turnThruOn(Thru::Mode inThruFilterMode) +inline MidiInterface& MidiInterface::turnThruOn(Thru::Mode inThruFilterMode) { mThruActivated = true; mThruFilterMode = inThruFilterMode; + + return *this; } template -inline void MidiInterface::turnThruOff() +inline MidiInterface& MidiInterface::turnThruOff() { mThruActivated = false; mThruFilterMode = Thru::Off; + + return *this; }