diff --git a/examples/3. MIDI Interfaces/MIDI-Input-Fine-Grained-All-Callbacks/MIDI-Input-Fine-Grained-All-Callbacks.ino b/examples/3. MIDI Interfaces/MIDI-Input-Fine-Grained-All-Callbacks/MIDI-Input-Fine-Grained-All-Callbacks.ino index 4a4db0dc01..bbe115d084 100644 --- a/examples/3. MIDI Interfaces/MIDI-Input-Fine-Grained-All-Callbacks/MIDI-Input-Fine-Grained-All-Callbacks.ino +++ b/examples/3. MIDI Interfaces/MIDI-Input-Fine-Grained-All-Callbacks/MIDI-Input-Fine-Grained-All-Callbacks.ino @@ -90,7 +90,9 @@ struct MyMIDI_Callbacks : FineGrainedMIDI_Callbacks { void onActiveSensing(Cable cable) { Serial << "Active Sensing: " << cable << endl; } - void onReset(Cable cable) { Serial << "Reset: " << cable << endl; } + void onSystemReset(Cable cable) { + Serial << "System Reset: " << cable << endl; + } } callback; diff --git a/keywords.txt b/keywords.txt index 9f7e7ac828..0db046dd53 100644 --- a/keywords.txt +++ b/keywords.txt @@ -860,19 +860,35 @@ USBDebugMIDI_Interface KEYWORD1 SoftwareSerialDebugMIDI_Interface KEYWORD1 HairlessMIDI_Interface KEYWORD1 MIDI_Callbacks KEYWORD1 +FineGrainedMIDI_Callbacks KEYWORD1 SysExMessage KEYWORD1 FortySevenEffectsMIDI_Interface KEYWORD1 begin KEYWORD2 update KEYWORD2 send KEYWORD2 +sendChannelMessage KEYWORD2 sendNoteOn KEYWORD2 sendNoteOff KEYWORD2 -sendKP KEYWORD2 -sendCC KEYWORD2 -sendPC KEYWORD2 -sendCP KEYWORD2 -sendPB KEYWORD2 +sendKeyPressure KEYWORD2 +sendControlChange KEYWORD2 +sendProgramChange KEYWORD2 +sendChannelPressure KEYWORD2 +sendPitchBend KEYWORD2 +sendSysCommon KEYWORD2 +sendMTCQuarterFrame KEYWORD2 +sendSongPositionPointer KEYWORD2 +sendSongSelect KEYWORD2 +sendTuneRequest KEYWORD2 +sendSysEx KEYWORD2 +sendRealTime KEYWORD2 +sendTimingClock KEYWORD2 +sendStart KEYWORD2 +sendContinue KEYWORD2 +sendStop KEYWORD2 +sendActiveSensing KEYWORD2 +sendSystemReset KEYWORD2 +sendNow KEYWORD2 getDefault KEYWORD2 setAsDefault KEYWORD2 setCallbacks KEYWORD2 @@ -882,6 +898,24 @@ getSysExMessage KEYWORD2 onChannelMessage KEYWORD2 onSysExMessage KEYWORD2 onRealTimeMessage KEYWORD2 +onNoteOff KEYWORD2 +onNoteOn KEYWORD2 +onKeyPressure KEYWORD2 +onControlChange KEYWORD2 +onProgramChange KEYWORD2 +onChannelPressure KEYWORD2 +onPitchBend KEYWORD2 +onSystemExclusive KEYWORD2 +onTimeCodeQuarterFrame KEYWORD2 +onSongPosition KEYWORD2 +onSongSelect KEYWORD2 +onTuneRequest KEYWORD2 +onClock KEYWORD2 +onStart KEYWORD2 +onContinue KEYWORD2 +onStop KEYWORD2 +onActiveSensing KEYWORD2 +onSystemReset KEYWORD2 MIDIChannelCable KEYWORD1 MIDIAddress KEYWORD1 \ No newline at end of file diff --git a/src/Control_Surface/Control_Surface_Class.cpp b/src/Control_Surface/Control_Surface_Class.cpp index 371b212ed8..46c7f8b8b8 100644 --- a/src/Control_Surface/Control_Surface_Class.cpp +++ b/src/Control_Surface/Control_Surface_Class.cpp @@ -171,7 +171,7 @@ void Control_Surface_::sinkMIDIfromPipe(ChannelMessage midimsg) { case MIDIMessageType::STOP: break; case MIDIMessageType::UNDEFINED_REALTIME_2: break; case MIDIMessageType::ACTIVE_SENSING: break; - case MIDIMessageType::RESET: break; + case MIDIMessageType::SYSTEM_RESET: break; default: break; // LCOV_EXCL_STOP diff --git a/src/MIDI_Interfaces/MIDI_Callbacks.hpp b/src/MIDI_Interfaces/MIDI_Callbacks.hpp index d9bb64db17..93b3f29700 100644 --- a/src/MIDI_Interfaces/MIDI_Callbacks.hpp +++ b/src/MIDI_Interfaces/MIDI_Callbacks.hpp @@ -54,7 +54,7 @@ class FineGrainedMIDI_Callbacks : public MIDI_Callbacks { void onContinue(Cable cable); void onStop(Cable cable); void onActiveSensing(Cable cable); - void onReset(Cable cable); + void onSystemReset(Cable cable); // clang-format on /// @} @@ -105,7 +105,7 @@ class FineGrainedMIDI_Callbacks : public MIDI_Callbacks { case MMT::STOP: case MMT::UNDEFINED_REALTIME_2: case MMT::ACTIVE_SENSING: - case MMT::RESET: + case MMT::SYSTEM_RESET: default: break; } } @@ -150,7 +150,7 @@ class FineGrainedMIDI_Callbacks : public MIDI_Callbacks { case MMT::STOP: case MMT::UNDEFINED_REALTIME_2: case MMT::ACTIVE_SENSING: - case MMT::RESET: + case MMT::SYSTEM_RESET: default: break; } } @@ -185,7 +185,7 @@ class FineGrainedMIDI_Callbacks : public MIDI_Callbacks { case MMT::ACTIVE_SENSING: CRTP(Derived).onActiveSensing(msg.getCable()); break; - case MMT::RESET: CRTP(Derived).onReset(msg.getCable()); break; + case MMT::SYSTEM_RESET: CRTP(Derived).onSystemReset(msg.getCable()); break; default: break; } } @@ -223,7 +223,7 @@ class FineGrainedMIDI_Callbacks : public MIDI_Callbacks { static_assert(same_return_type_and_arguments(&Derived::onContinue, &FineGrainedMIDI_Callbacks::onContinue), "Incorrect signature for onContinue"); static_assert(same_return_type_and_arguments(&Derived::onStop, &FineGrainedMIDI_Callbacks::onStop), "Incorrect signature for onStop"); static_assert(same_return_type_and_arguments(&Derived::onActiveSensing, &FineGrainedMIDI_Callbacks::onActiveSensing), "Incorrect signature for onActiveSensing"); - static_assert(same_return_type_and_arguments(&Derived::onReset, &FineGrainedMIDI_Callbacks::onReset), "Incorrect signature for onReset"); + static_assert(same_return_type_and_arguments(&Derived::onSystemReset, &FineGrainedMIDI_Callbacks::onSystemReset), "Incorrect signature for onSystemReset"); // clang-format on } @@ -248,7 +248,7 @@ template inline void FineGrainedMIDI_Callbacks::onStart template inline void FineGrainedMIDI_Callbacks::onContinue(Cable) {} template inline void FineGrainedMIDI_Callbacks::onStop(Cable) {} template inline void FineGrainedMIDI_Callbacks::onActiveSensing(Cable) {} -template inline void FineGrainedMIDI_Callbacks::onReset(Cable) {} +template inline void FineGrainedMIDI_Callbacks::onSystemReset(Cable) {} // clang-format on END_CS_NAMESPACE diff --git a/src/MIDI_Interfaces/MIDI_Sender.hpp b/src/MIDI_Interfaces/MIDI_Sender.hpp index 956b707588..23084faf6e 100644 --- a/src/MIDI_Interfaces/MIDI_Sender.hpp +++ b/src/MIDI_Interfaces/MIDI_Sender.hpp @@ -10,11 +10,14 @@ BEGIN_CS_NAMESPACE template class MIDI_Sender { public: - /// @name Sending MIDI + /// @name Sending MIDI Channel Voice messages /// @{ + /// Send a MIDI %Channel Voice message. + void send(ChannelMessage message); + /** - * @brief Send a 3-byte MIDI Channel Voice message. + * @brief Send a 3-byte MIDI %Channel Voice message. * * @param m * MIDI message type. [0x80, 0xE0] @@ -25,13 +28,13 @@ class MIDI_Sender { * @param d2 * The second data byte. [0, 127] * @param cable - * The MIDI Cable Number. [1, 16] + * The MIDI Cable Number. [CABLE_1, CABLE_16] */ - void send(MIDIMessageType m, Channel c, uint8_t d1, uint8_t d2, - Cable cable = CABLE_1); + void sendChannelMessage(MIDIMessageType m, Channel c, uint8_t d1, + uint8_t d2, Cable cable = CABLE_1); /** - * @brief Send a 2-byte MIDI Channel Voice message. + * @brief Send a 2-byte MIDI %Channel Voice message. * * @param m * MIDI message type. [0x80, 0xE0] @@ -42,28 +45,58 @@ class MIDI_Sender { * @param cable * The MIDI Cable Number. [1, 16] */ - void send(MIDIMessageType m, Channel c, uint8_t d1, Cable cable = CABLE_1); + void sendChannelMessage(MIDIMessageType m, Channel c, uint8_t d1, + Cable cable = CABLE_1); /// Send a MIDI Note On event. void sendNoteOn(MIDIAddress address, uint8_t velocity); /// Send a MIDI Note Off event. void sendNoteOff(MIDIAddress address, uint8_t velocity); /// Send a MIDI Key Pressure event. - void sendKP(MIDIAddress address, uint8_t pressure); + void sendKeyPressure(MIDIAddress address, uint8_t pressure); /// Send a MIDI Control Change event. - void sendCC(MIDIAddress address, uint8_t value); + void sendControlChange(MIDIAddress address, uint8_t value); /// Send a MIDI Program Change event. - void sendPC(MIDIAddress address); + void sendProgramChange(MIDIAddress address); /// Send a MIDI Program Change event. - void sendPC(MIDIChannelCable address, uint8_t value); - /// Send a MIDI Channel Pressure event. - void sendCP(MIDIChannelCable address, uint8_t pressure); + void sendProgramChange(MIDIChannelCable address, uint8_t value); + /// Send a MIDI %Channel Pressure event. + void sendChannelPressure(MIDIChannelCable address, uint8_t pressure); /// Send a MIDI Pitch Bend event. - void sendPB(MIDIChannelCable address, uint16_t value); - /// Send a MIDI Channel Voice message. - void send(ChannelMessage message); + void sendPitchBend(MIDIChannelCable address, uint16_t value); + + /// @} + + /// @name Sending MIDI System Common messages + /// @{ + /// Send a MIDI System Common message. void send(SysCommonMessage message); + /// Send a MIDI System Common message. + void sendSysCommon(MIDIMessageType m, Cable cable = CABLE_1); + /// Send a MIDI System Common message. + void sendSysCommon(MIDIMessageType m, uint8_t data1, Cable cable = CABLE_1); + /// Send a MIDI System Common message. + void sendSysCommon(MIDIMessageType m, uint8_t data1, uint8_t data2, + Cable cable = CABLE_1); + + /// Send a MIDI Time Code Quarter Frame. + void sendMTCQuarterFrame(uint8_t data, Cable cable = CABLE_1); + /// Send a MIDI Time Code Quarter Frame. + void sendMTCQuarterFrame(uint8_t messageType, uint8_t values, + Cable cable = CABLE_1); + /// Send a MIDI Song Position Pointer message. + void sendSongPositionPointer(uint16_t spp, Cable cable = CABLE_1); + /// Send a MIDI Song Select message. + void sendSongSelect(uint8_t song, Cable cable = CABLE_1); + /// Send a MIDI Tune Request. + void sendTuneRequest(Cable cable = CABLE_1); + + /// @} + + /// @name Sending MIDI System Exclusive messages + /// @{ + /// Send a MIDI System Exclusive message. void send(SysExMessage message); /// Send a MIDI System Exclusive message. @@ -71,6 +104,12 @@ class MIDI_Sender { void sendSysEx(const uint8_t (&sysexdata)[N], Cable cable = CABLE_1); /// Send a MIDI System Exclusive message. void sendSysEx(const uint8_t *data, uint16_t length, Cable cable = CABLE_1); + + /// @} + + /// @name Sending MIDI Real-Time messages + /// @{ + /// Send a MIDI Real-Time message. void send(RealTimeMessage message); /// Send a MIDI Real-Time message. @@ -78,13 +117,61 @@ class MIDI_Sender { /// Send a MIDI Real-Time message. void sendRealTime(uint8_t rt, Cable cable = CABLE_1); + /// Send a MIDI Timing Clock message. + void sendTimingClock(Cable cable = CABLE_1); + /// Send a MIDI Start message. + void sendStart(Cable cable = CABLE_1); + /// Send a MIDI Continue message. + void sendContinue(Cable cable = CABLE_1); + /// Send a MIDI Stop message. + void sendStop(Cable cable = CABLE_1); + /// Send a MIDI Active Sensing message. + void sendActiveSensing(Cable cable = CABLE_1); + /// Send a MIDI System Reset message. + void sendSystemReset(Cable cable = CABLE_1); + + /// @} + + /// @name Flusing the MIDI send buffer + /// @{ + /// Causes all buffered messages to be sent immediately. - /// @note Doesn't necessarily wait until all data has been sent, it just - /// triggers the transmission, so everything will be transmitted as + /// @note Doesn't necessarily wait until all data has been sent, it just + /// triggers the transmission, so everything will be transmitted as /// soon as possible. void sendNow(); /// @} + + /// @name Deprecated + /// @{ + + /// Send a MIDI Key Pressure event. + /// @deprecated Use @ref sendKeyPressure(MIDIAddress,uint8_t) instead + [[deprecated("Use sendKeyPressure() instead")]] void + sendKP(MIDIAddress address, uint8_t pressure); + /// Send a MIDI Control Change event. + /// @deprecated Use @ref sendControlChange(MIDIAddress,uint8_t) instead + [[deprecated("Use sendControlChange() instead")]] void + sendCC(MIDIAddress address, uint8_t value); + /// Send a MIDI Program Change event. + /// @deprecated Use @ref sendProgramChange(MIDIAddress) instead + [[deprecated("Use sendProgramChange() instead")]] void + sendPC(MIDIAddress address); + /// Send a MIDI Program Change event. + /// @deprecated Use @ref sendProgramChange(MIDIChannelCable,uint8_t) instead + [[deprecated("Use sendProgramChange() instead")]] void + sendPC(MIDIChannelCable address, uint8_t value); + /// Send a MIDI %Channel Pressure event. + /// @deprecated Use @ref sendChannelPressure(MIDIChannelCable,uint8_t) instead + [[deprecated("Use sendChannelPressure() instead")]] void + sendCP(MIDIChannelCable address, uint8_t pressure); + /// Send a MIDI Pitch Bend event. + /// @deprecated Use @ref sendPitchBend(MIDIChannelCable,uint16_t) instead + [[deprecated("Use sendPitchBend() instead")]] void + sendPB(MIDIChannelCable address, uint16_t value); + + /// @} }; END_CS_NAMESPACE diff --git a/src/MIDI_Interfaces/MIDI_Sender.ipp b/src/MIDI_Interfaces/MIDI_Sender.ipp index ce402db45a..01a9dd1835 100644 --- a/src/MIDI_Interfaces/MIDI_Sender.ipp +++ b/src/MIDI_Interfaces/MIDI_Sender.ipp @@ -4,14 +4,15 @@ BEGIN_CS_NAMESPACE template -void MIDI_Sender::send(MIDIMessageType m, Channel c, uint8_t d1, - uint8_t d2, Cable cable) { +void MIDI_Sender::sendChannelMessage(MIDIMessageType m, Channel c, + uint8_t d1, uint8_t d2, + Cable cable) { send(ChannelMessage(m, c, d1, d2, cable)); } template -void MIDI_Sender::send(MIDIMessageType m, Channel c, uint8_t d1, - Cable cable) { +void MIDI_Sender::sendChannelMessage(MIDIMessageType m, Channel c, + uint8_t d1, Cable cable) { send(ChannelMessage(m, c, d1, 0, cable)); } @@ -38,7 +39,8 @@ void MIDI_Sender::sendNoteOff(MIDIAddress address, uint8_t velocity) { }); } template -void MIDI_Sender::sendKP(MIDIAddress address, uint8_t pressure) { +void MIDI_Sender::sendKeyPressure(MIDIAddress address, + uint8_t pressure) { if (address) CRTP(Derived).sendChannelMessageImpl({ MIDIMessageType::KEY_PRESSURE, @@ -49,7 +51,8 @@ void MIDI_Sender::sendKP(MIDIAddress address, uint8_t pressure) { }); } template -void MIDI_Sender::sendCC(MIDIAddress address, uint8_t value) { +void MIDI_Sender::sendControlChange(MIDIAddress address, + uint8_t value) { if (address) CRTP(Derived).sendChannelMessageImpl({ MIDIMessageType::CONTROL_CHANGE, @@ -60,7 +63,8 @@ void MIDI_Sender::sendCC(MIDIAddress address, uint8_t value) { }); } template -void MIDI_Sender::sendPC(MIDIChannelCable address, uint8_t value) { +void MIDI_Sender::sendProgramChange(MIDIChannelCable address, + uint8_t value) { if (address) CRTP(Derived).sendChannelMessageImpl({ MIDIMessageType::PROGRAM_CHANGE, @@ -71,7 +75,7 @@ void MIDI_Sender::sendPC(MIDIChannelCable address, uint8_t value) { }); } template -void MIDI_Sender::sendPC(MIDIAddress address) { +void MIDI_Sender::sendProgramChange(MIDIAddress address) { if (address) CRTP(Derived).sendChannelMessageImpl({ MIDIMessageType::PROGRAM_CHANGE, @@ -82,7 +86,8 @@ void MIDI_Sender::sendPC(MIDIAddress address) { }); } template -void MIDI_Sender::sendCP(MIDIChannelCable address, uint8_t pressure) { +void MIDI_Sender::sendChannelPressure(MIDIChannelCable address, + uint8_t pressure) { if (address) CRTP(Derived).sendChannelMessageImpl({ MIDIMessageType::CHANNEL_PRESSURE, @@ -93,7 +98,8 @@ void MIDI_Sender::sendCP(MIDIChannelCable address, uint8_t pressure) { }); } template -void MIDI_Sender::sendPB(MIDIChannelCable address, uint16_t value) { +void MIDI_Sender::sendPitchBend(MIDIChannelCable address, + uint16_t value) { if (address) CRTP(Derived).sendChannelMessageImpl({ MIDIMessageType::PITCH_BEND, @@ -143,6 +149,45 @@ void MIDI_Sender::sendSysEx(const uint8_t *data, uint16_t length, send(SysExMessage(data, length, cable)); } +template +void MIDI_Sender::sendSysCommon(MIDIMessageType m, Cable cable) { + send(SysCommonMessage(m, cable)); +} +template +void MIDI_Sender::sendSysCommon(MIDIMessageType m, uint8_t data1, + Cable cable) { + send(SysCommonMessage(m, data1, cable)); +} +template +void MIDI_Sender::sendSysCommon(MIDIMessageType m, uint8_t data1, + uint8_t data2, Cable cable) { + send(SysCommonMessage(m, data1, data2, cable)); +} + +template +void MIDI_Sender::sendMTCQuarterFrame(uint8_t data, Cable cable) { + send(SysCommonMessage(MIDIMessageType::MTC_QUARTER_FRAME, data, cable)); +} +template +void MIDI_Sender::sendMTCQuarterFrame(uint8_t messageType, + uint8_t values, Cable cable) { + sendMTCQuarterFrame((messageType << 4) | values, cable); +} +template +void MIDI_Sender::sendSongPositionPointer(uint16_t spp, Cable cable) { + SysCommonMessage msg(MIDIMessageType::SONG_POSITION_POINTER, cable); + msg.setData14bit(spp); + send(msg); +} +template +void MIDI_Sender::sendSongSelect(uint8_t song, Cable cable) { + send(SysCommonMessage(MIDIMessageType::SONG_SELECT, song, cable)); +} +template +void MIDI_Sender::sendTuneRequest(Cable cable) { + send(SysCommonMessage(MIDIMessageType::TUNE_REQUEST, cable)); +} + template void MIDI_Sender::sendRealTime(MIDIMessageType rt, Cable cable) { send(RealTimeMessage(rt, cable)); @@ -152,9 +197,59 @@ void MIDI_Sender::sendRealTime(uint8_t rt, Cable cable) { send(RealTimeMessage(rt, cable)); } +template +void MIDI_Sender::sendTimingClock(Cable cable) { + sendRealTime(MIDIMessageType::TIMING_CLOCK, cable); +} +template +void MIDI_Sender::sendStart(Cable cable) { + sendRealTime(MIDIMessageType::START, cable); +} +template +void MIDI_Sender::sendContinue(Cable cable) { + sendRealTime(MIDIMessageType::CONTINUE, cable); +} +template +void MIDI_Sender::sendStop(Cable cable) { + sendRealTime(MIDIMessageType::STOP, cable); +} +template +void MIDI_Sender::sendActiveSensing(Cable cable) { + sendRealTime(MIDIMessageType::ACTIVE_SENSING, cable); +} +template +void MIDI_Sender::sendSystemReset(Cable cable) { + sendRealTime(MIDIMessageType::SYSTEM_RESET, cable); +} + template void MIDI_Sender::sendNow() { CRTP(Derived).sendNowImpl(); } +template +void MIDI_Sender::sendKP(MIDIAddress address, uint8_t pressure) { + sendKeyPressure(address, pressure); +} +template +void MIDI_Sender::sendCC(MIDIAddress address, uint8_t value) { + sendControlChange(address, value); +} +template +void MIDI_Sender::sendPC(MIDIAddress address) { + sendProgramChange(address); +} +template +void MIDI_Sender::sendPC(MIDIChannelCable address, uint8_t value) { + sendProgramChange(address, value); +} +template +void MIDI_Sender::sendCP(MIDIChannelCable address, uint8_t pressure) { + sendChannelPressure(address, pressure); +} +template +void MIDI_Sender::sendPB(MIDIChannelCable address, uint16_t value) { + sendPitchBend(address, value); +} + END_CS_NAMESPACE \ No newline at end of file diff --git a/src/MIDI_Interfaces/keywords.yml b/src/MIDI_Interfaces/keywords.yml index 1ba8a30904..e4945091a6 100644 --- a/src/MIDI_Interfaces/keywords.yml +++ b/src/MIDI_Interfaces/keywords.yml @@ -13,6 +13,7 @@ keyword1: - SoftwareSerialDebugMIDI_Interface - HairlessMIDI_Interface - MIDI_Callbacks + - FineGrainedMIDI_Callbacks - SysExMessage - FortySevenEffectsMIDI_Interface @@ -20,15 +21,28 @@ keyword2: - begin - update - send + - sendChannelMessage - sendNoteOn - sendNoteOff - - sendKP - - sendCC - - sendPC - - sendCP - - sendPB - - sendRealTime + - sendKeyPressure + - sendControlChange + - sendProgramChange + - sendChannelPressure + - sendPitchBend + - sendSysCommon + - sendMTCQuarterFrame + - sendSongPositionPointer + - sendSongSelect + - sendTuneRequest - sendSysEx + - sendRealTime + - sendTimingClock + - sendStart + - sendContinue + - sendStop + - sendActiveSensing + - sendSystemReset + - sendNow - getDefault - setAsDefault - setCallbacks @@ -37,4 +51,22 @@ keyword2: - getSysExMessage - onChannelMessage - onSysExMessage - - onRealTimeMessage \ No newline at end of file + - onRealTimeMessage + - onNoteOff + - onNoteOn + - onKeyPressure + - onControlChange + - onProgramChange + - onChannelPressure + - onPitchBend + - onSystemExclusive + - onTimeCodeQuarterFrame + - onSongPosition + - onSongSelect + - onTuneRequest + - onClock + - onStart + - onContinue + - onStop + - onActiveSensing + - onSystemReset \ No newline at end of file diff --git a/src/MIDI_Parsers/MIDI_MessageTypes.cpp b/src/MIDI_Parsers/MIDI_MessageTypes.cpp index 89dd034a8c..1dfc0025ea 100644 --- a/src/MIDI_Parsers/MIDI_MessageTypes.cpp +++ b/src/MIDI_Parsers/MIDI_MessageTypes.cpp @@ -29,7 +29,7 @@ FlashString_t enum_to_string(MIDIMessageType m) { case M::STOP: return F("STOP"); case M::UNDEFINED_REALTIME_2: return F("UNDEFINED_REALTIME_2"); case M::ACTIVE_SENSING: return F("ACTIVE_SENSING"); - case M::RESET: return F("RESET"); + case M::SYSTEM_RESET: return F("SYSTEM_RESET"); default: return F(""); } } diff --git a/src/MIDI_Parsers/MIDI_MessageTypes.hpp b/src/MIDI_Parsers/MIDI_MessageTypes.hpp index 7dfa216746..b4008daf0f 100644 --- a/src/MIDI_Parsers/MIDI_MessageTypes.hpp +++ b/src/MIDI_Parsers/MIDI_MessageTypes.hpp @@ -1,7 +1,7 @@ #pragma once #include // Print -#include // size_t +#include // size_t #include #include #include @@ -52,7 +52,7 @@ enum class MIDIMessageType : uint8_t { STOP = 0xFC, UNDEFINED_REALTIME_2 = 0xFD, ACTIVE_SENSING = 0xFE, - RESET = 0xFF, + SYSTEM_RESET = 0xFF, }; /// MIDI USB Code Index Numbers. @@ -156,6 +156,12 @@ struct MIDIMessage { uint16_t getData14bit() const { return data1 | (uint16_t(data2) << uint16_t(7)); } + /// If Data 1 and Data 2 represent a single 14-bit number, you can use this + /// method to set that number. + void setData14bit(uint16_t data) { + data1 = (data >> 0) & 0x7F; + data2 = (data >> 7) & 0x7F; + } /// Make sure that the status byte has the most significant bit set and /// the data bytes have the most significant bits cleared. @@ -256,11 +262,15 @@ struct SysCommonMessage : MIDIMessage { return 0; } - constexpr static auto MTC_QUARTER_FRAME = MIDIMessageType::MTC_QUARTER_FRAME; - constexpr static auto SONG_POSITION_POINTER = MIDIMessageType::SONG_POSITION_POINTER; + constexpr static auto MTC_QUARTER_FRAME = + MIDIMessageType::MTC_QUARTER_FRAME; + constexpr static auto SONG_POSITION_POINTER = + MIDIMessageType::SONG_POSITION_POINTER; constexpr static auto SONG_SELECT = MIDIMessageType::SONG_SELECT; - constexpr static auto UNDEFINED_SYSCOMMON_1 = MIDIMessageType::UNDEFINED_SYSCOMMON_1; - constexpr static auto UNDEFINED_SYSCOMMON_2 = MIDIMessageType::UNDEFINED_SYSCOMMON_2; + constexpr static auto UNDEFINED_SYSCOMMON_1 = + MIDIMessageType::UNDEFINED_SYSCOMMON_1; + constexpr static auto UNDEFINED_SYSCOMMON_2 = + MIDIMessageType::UNDEFINED_SYSCOMMON_2; constexpr static auto TUNE_REQUEST = MIDIMessageType::TUNE_REQUEST; }; @@ -348,13 +358,15 @@ struct RealTimeMessage { bool isValid() const { return message >= 0xF8; } constexpr static auto TIMING_CLOCK = MIDIMessageType::TIMING_CLOCK; - constexpr static auto UNDEFINED_REALTIME_1 = MIDIMessageType::UNDEFINED_REALTIME_1; + constexpr static auto UNDEFINED_REALTIME_1 = + MIDIMessageType::UNDEFINED_REALTIME_1; constexpr static auto START = MIDIMessageType::START; constexpr static auto CONTINUE = MIDIMessageType::CONTINUE; constexpr static auto STOP = MIDIMessageType::STOP; - constexpr static auto UNDEFINED_REALTIME_2 = MIDIMessageType::UNDEFINED_REALTIME_2; + constexpr static auto UNDEFINED_REALTIME_2 = + MIDIMessageType::UNDEFINED_REALTIME_2; constexpr static auto ACTIVE_SENSING = MIDIMessageType::ACTIVE_SENSING; - constexpr static auto RESET = MIDIMessageType::RESET; + constexpr static auto RESET = MIDIMessageType::SYSTEM_RESET; }; #ifndef ARDUINO diff --git a/src/MIDI_Senders/ContinuousCCSender.hpp b/src/MIDI_Senders/ContinuousCCSender.hpp index 4597759fe7..e62913615c 100644 --- a/src/MIDI_Senders/ContinuousCCSender.hpp +++ b/src/MIDI_Senders/ContinuousCCSender.hpp @@ -15,7 +15,7 @@ class ContinuousCCSender { public: /// Send a 7-bit CC message to the given address. void send(uint8_t value, MIDIAddress address) { - Control_Surface.sendCC(address, value); + Control_Surface.sendControlChange(address, value); } /// Get the resolution of the sender in bits (always returns 7). @@ -37,12 +37,12 @@ template class ContinuousCCSender14 { public: /// Send a 14-bit CC message to the given address. - /// Sends two 7-bit CC packets, one for @p address (MSB), and one for + /// Sends two 7-bit CC packets, one for @p address (MSB), and one for /// @p address + 0x20 (LSB). void send(uint16_t value, MIDIAddress address) { value = AH::increaseBitDepth<14, precision(), uint16_t>(value); - Control_Surface.sendCC(address + 0x00, (value >> 7) & 0x7f); - Control_Surface.sendCC(address + 0x20, (value >> 0) & 0x7F); + Control_Surface.sendControlChange(address + 0x00, (value >> 7) & 0x7f); + Control_Surface.sendControlChange(address + 0x20, (value >> 0) & 0x7F); } /// Get this sender's precision. diff --git a/src/MIDI_Senders/DigitalCCSender.hpp b/src/MIDI_Senders/DigitalCCSender.hpp index 61b313bb6d..eb1eab44ba 100644 --- a/src/MIDI_Senders/DigitalCCSender.hpp +++ b/src/MIDI_Senders/DigitalCCSender.hpp @@ -18,12 +18,12 @@ class DigitalCCSender { /// Send a control change message to the given address, with @p onValue as /// value. void sendOn(MIDIAddress address) { - Control_Surface.sendCC(address, onValue); + Control_Surface.sendControlChange(address, onValue); } /// Send a control change message to the given address, with @p offValue as /// value. void sendOff(MIDIAddress address) { - Control_Surface.sendCC(address, offValue); + Control_Surface.sendControlChange(address, offValue); } uint8_t getOnValue() const { return this->onValue; } diff --git a/src/MIDI_Senders/PitchBendSender.hpp b/src/MIDI_Senders/PitchBendSender.hpp index c52db290b7..1e09fd21c0 100644 --- a/src/MIDI_Senders/PitchBendSender.hpp +++ b/src/MIDI_Senders/PitchBendSender.hpp @@ -26,8 +26,8 @@ class PitchBendSender { value = AH::increaseBitDepth<14, precision(), uint16_t>(value); // ignore address byte, just use channel and cable numbers MIDIChannelCable channelCN = {address.getChannel(), - address.getCableNumber()}; - Control_Surface.sendPB(channelCN, value); + address.getCableNumber()}; + Control_Surface.sendPitchBend(channelCN, value); } /// Get this sender's precision. diff --git a/src/MIDI_Senders/ProgramChangeSender.hpp b/src/MIDI_Senders/ProgramChangeSender.hpp index 0d7c8e5175..8e540eaae8 100644 --- a/src/MIDI_Senders/ProgramChangeSender.hpp +++ b/src/MIDI_Senders/ProgramChangeSender.hpp @@ -13,12 +13,10 @@ class ProgramChangeSender { public: /// Sends a MIDI program change message for the given program. void sendOn(MIDIAddress address) { - Control_Surface.sendPC(address); + Control_Surface.sendProgramChange(address); } /// Doesn't do anything (you cannot "un-select" a program). - void sendOff(MIDIAddress address) { - (void) address; - } + void sendOff(MIDIAddress address) { (void)address; } }; END_CS_NAMESPACE \ No newline at end of file diff --git a/src/MIDI_Senders/RelativeCCSender.hpp b/src/MIDI_Senders/RelativeCCSender.hpp index 55f5858fb1..38d45d3a4f 100644 --- a/src/MIDI_Senders/RelativeCCSender.hpp +++ b/src/MIDI_Senders/RelativeCCSender.hpp @@ -124,7 +124,7 @@ class RelativeCCSender { long thisDelta = constrain(delta, -15, 15); uint8_t msgVal = mapRelativeCC(thisDelta); // send a Control Change MIDI event - Control_Surface.sendCC(address, msgVal); + Control_Surface.sendControlChange(address, msgVal); delta -= thisDelta; } } diff --git a/src/Selectors/ProgramChanger.hpp b/src/Selectors/ProgramChanger.hpp index 92fe6efbf0..1c4cac7ec7 100644 --- a/src/Selectors/ProgramChanger.hpp +++ b/src/Selectors/ProgramChanger.hpp @@ -10,12 +10,13 @@ BEGIN_CS_NAMESPACE template class ProgramChanger : public Selectable { public: - ProgramChanger(const Array &programs, MIDIChannelCable channelCN) + ProgramChanger(const Array &programs, + MIDIChannelCable channelCN) : programs(programs), channelCN(channelCN) {} void select(setting_t setting) override { setting = this->validateSetting(setting); - Control_Surface.sendPC(channelCN, programs[setting]); + Control_Surface.sendProgramChange(channelCN, programs[setting]); } private: diff --git a/test/MIDI_Interfaces/test-BluetoothMIDI_Interface.cpp b/test/MIDI_Interfaces/test-BluetoothMIDI_Interface.cpp index 22a75f30f8..585764ed3d 100644 --- a/test/MIDI_Interfaces/test-BluetoothMIDI_Interface.cpp +++ b/test/MIDI_Interfaces/test-BluetoothMIDI_Interface.cpp @@ -366,7 +366,7 @@ TEST(BluetoothMIDIInterface, sendOneProgramChangeMessage) { .WillRepeatedly(Return(timestamp(0x01, 0x02))); EXPECT_CALL(midi, notifyMIDIBLE(expected)); - midi.sendPC(CHANNEL_6, 0x78); + midi.sendProgramChange(CHANNEL_6, 0x78); midi.flush(); Mock::VerifyAndClear(&ArduinoMock::getInstance()); @@ -387,8 +387,8 @@ TEST(BluetoothMIDIInterface, sendProgramChangeMessageBufferFull) { EXPECT_CALL(midi, notifyMIDIBLE(expected1)).InSequence(s); EXPECT_CALL(midi, notifyMIDIBLE(expected2)).InSequence(s); - midi.sendPC(CHANNEL_6, 0x78); - midi.sendPC(CHANNEL_7, 0x79); + midi.sendProgramChange(CHANNEL_6, 0x78); + midi.sendProgramChange(CHANNEL_7, 0x79); midi.flush(); Mock::VerifyAndClear(&ArduinoMock::getInstance()); diff --git a/test/MIDI_Interfaces/test-DebugStreamMIDI_Interface.cpp b/test/MIDI_Interfaces/test-DebugStreamMIDI_Interface.cpp index 2efaffc9dc..b3ae5c8758 100644 --- a/test/MIDI_Interfaces/test-DebugStreamMIDI_Interface.cpp +++ b/test/MIDI_Interfaces/test-DebugStreamMIDI_Interface.cpp @@ -14,12 +14,12 @@ using u8vec = std::vector; TEST(StreamDebugMIDI_Interface, send3B) { TestStream stream; StreamDebugMIDI_Interface midi = stream; - midi.send(MIDIMessageType::NOTE_ON, CHANNEL_4, 0x55, 0x66); + midi.sendChannelMessage(MIDIMessageType::NOTE_ON, CHANNEL_4, 0x55, 0x66); midi.sendNoteOn({0x55, CHANNEL_4, CABLE_9}, 0x66); midi.sendNoteOff({0x55, CHANNEL_4, CABLE_9}, 0x66); - midi.sendCC({0x55, CHANNEL_4, CABLE_9}, 0x66); - midi.sendKP({0x55, CHANNEL_4, CABLE_9}, 0x66); - midi.sendPB({CHANNEL_4, CABLE_9}, 0x3355); + midi.sendControlChange({0x55, CHANNEL_4, CABLE_9}, 0x66); + midi.sendKeyPressure({0x55, CHANNEL_4, CABLE_9}, 0x66); + midi.sendPitchBend({CHANNEL_4, CABLE_9}, 0x3355); std::string expected = "Note On Channel: 4\tData 1: 0x55\tData " "2: 0x66\tCable: 1\r\n" "Note On Channel: 4\tData 1: 0x55\tData " @@ -40,10 +40,10 @@ TEST(StreamDebugMIDI_Interface, send3B) { TEST(StreamDebugMIDI_Interface, send2B) { TestStream stream; StreamDebugMIDI_Interface midi = stream; - midi.send(MIDIMessageType::PROGRAM_CHANGE, CHANNEL_4, 0x66); - midi.sendPC({CHANNEL_4, CABLE_9}, 0x66); - midi.sendPC({0x66, CHANNEL_4, CABLE_9}); - midi.sendCP({CHANNEL_4, CABLE_9}, 0x66); + midi.sendChannelMessage(MIDIMessageType::PROGRAM_CHANGE, CHANNEL_4, 0x66); + midi.sendProgramChange({CHANNEL_4, CABLE_9}, 0x66); + midi.sendProgramChange({0x66, CHANNEL_4, CABLE_9}); + midi.sendChannelPressure({CHANNEL_4, CABLE_9}, 0x66); std::string expected = "Program Change Channel: 4\tData 1: 0x66\tCable: 1\r\n" "Program Change Channel: 4\tData 1: 0x66\tCable: 9\r\n" diff --git a/test/MIDI_Interfaces/test-StreamMIDI_Interface.cpp b/test/MIDI_Interfaces/test-StreamMIDI_Interface.cpp index 1bd40bf898..e7f2193d01 100644 --- a/test/MIDI_Interfaces/test-StreamMIDI_Interface.cpp +++ b/test/MIDI_Interfaces/test-StreamMIDI_Interface.cpp @@ -1,8 +1,8 @@ #include #include +#include #include #include -#include USING_CS_NAMESPACE; using ::testing::Return; @@ -15,12 +15,12 @@ using u8vec = std::vector; TEST(StreamMIDI_Interface, send3B) { TestStream stream; StreamMIDI_Interface midi = stream; - midi.send(MIDIMessageType::NOTE_ON, CHANNEL_4, 0x55, 0x66); + midi.sendChannelMessage(MIDIMessageType::NOTE_ON, CHANNEL_4, 0x55, 0x66); midi.sendNoteOn({0x55, CHANNEL_4}, 0x66); midi.sendNoteOff({0x55, CHANNEL_4}, 0x66); - midi.sendCC({0x55, CHANNEL_4}, 0x66); - midi.sendKP({0x55, CHANNEL_4}, 0x66); - midi.sendPB(CHANNEL_4, 0x3355); + midi.sendControlChange({0x55, CHANNEL_4}, 0x66); + midi.sendKeyPressure({0x55, CHANNEL_4}, 0x66); + midi.sendPitchBend(CHANNEL_4, 0x3355); u8vec expected = { 0x93, 0x55, 0x66, // 0x93, 0x55, 0x66, // @@ -35,10 +35,10 @@ TEST(StreamMIDI_Interface, send3B) { TEST(StreamMIDI_Interface, send2B) { TestStream stream; StreamMIDI_Interface midi = stream; - midi.send(MIDIMessageType::PROGRAM_CHANGE, CHANNEL_4, 0x66); - midi.sendPC({CHANNEL_4}, 0x66); - midi.sendPC({0x66, CHANNEL_4}); - midi.sendCP(CHANNEL_4, 0x66); + midi.sendChannelMessage(MIDIMessageType::PROGRAM_CHANGE, CHANNEL_4, 0x66); + midi.sendProgramChange({CHANNEL_4}, 0x66); + midi.sendProgramChange({0x66, CHANNEL_4}); + midi.sendChannelPressure(CHANNEL_4, 0x66); u8vec expected = { 0xC3, 0x66, // 0xC3, 0x66, // diff --git a/test/MIDI_Interfaces/test-USBMIDI_Interface.cpp b/test/MIDI_Interfaces/test-USBMIDI_Interface.cpp index 23e9a5ea18..1b79d9d3eb 100644 --- a/test/MIDI_Interfaces/test-USBMIDI_Interface.cpp +++ b/test/MIDI_Interfaces/test-USBMIDI_Interface.cpp @@ -18,22 +18,20 @@ TEST(USBMIDI_Interface, send3B) { TEST(USBMIDI_Interface, send2B) { StrictMock midi; EXPECT_CALL(midi.backend, write(0x8C, 0xC3, 0x66, 0x00)); - midi.sendPC({CHANNEL_4, CABLE_9}, 0x66); + midi.sendProgramChange({CHANNEL_4, CABLE_9}, 0x66); } TEST(USBMIDI_Interface, RealTime) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x8F, 0xF8, 0x00, 0x00)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x8F, 0xF8, 0x00, 0x00)).InSequence(seq); midi.sendRealTime(MIDIMessageType::TIMING_CLOCK, CABLE_9); } TEST(USBMIDI_Interface, SysExSend3B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x87, 0xF0, 0x55, 0xF7)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x87, 0xF0, 0x55, 0xF7)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0xF7}; midi.sendSysEx(sysex, CABLE_9); } @@ -41,10 +39,8 @@ TEST(USBMIDI_Interface, SysExSend3B) { TEST(USBMIDI_Interface, SysExSend4B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x95, 0xF7, 0x00, 0x00)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x95, 0xF7, 0x00, 0x00)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0x66, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -52,10 +48,8 @@ TEST(USBMIDI_Interface, SysExSend4B) { TEST(USBMIDI_Interface, SysExSend5B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x96, 0x77, 0xF7, 0x00)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x96, 0x77, 0xF7, 0x00)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0x66, 0x77, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -63,10 +57,8 @@ TEST(USBMIDI_Interface, SysExSend5B) { TEST(USBMIDI_Interface, SysExSend6B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x97, 0x77, 0x11, 0xF7)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x97, 0x77, 0x11, 0xF7)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0x66, 0x77, 0x11, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -74,12 +66,9 @@ TEST(USBMIDI_Interface, SysExSend6B) { TEST(USBMIDI_Interface, SysExSend7B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x95, 0xF7, 0x00, 0x00)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x95, 0xF7, 0x00, 0x00)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0x66, 0x77, 0x11, 0x22, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -87,12 +76,9 @@ TEST(USBMIDI_Interface, SysExSend7B) { TEST(USBMIDI_Interface, SysExSend8B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x96, 0x33, 0xF7, 0x00)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x96, 0x33, 0xF7, 0x00)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0x66, 0x77, 0x11, 0x22, 0x33, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -100,12 +86,9 @@ TEST(USBMIDI_Interface, SysExSend8B) { TEST(USBMIDI_Interface, SysExSend9B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x97, 0x33, 0x44, 0xF7)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x97, 0x33, 0x44, 0xF7)).InSequence(seq); uint8_t sysex[] = {0xF0, 0x55, 0x66, 0x77, 0x11, 0x22, 0x33, 0x44, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -124,8 +107,7 @@ TEST(USBMIDI_Interface, SysExSend1B) { TEST(USBMIDI_Interface, SysExSend2B) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x96, 0xF0, 0xF7, 0x00)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x96, 0xF0, 0xF7, 0x00)).InSequence(seq); uint8_t sysex[] = {0xF0, 0xF7}; midi.sendSysEx(sysex, CABLE_10); } @@ -133,20 +115,13 @@ TEST(USBMIDI_Interface, SysExSend2B) { TEST(USBMIDI_Interface, SysExSendChunks) { StrictMock midi; Sequence seq; - EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x23, 0x24, 0x25)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x26, 0x27, 0x28)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x29, 0x2A, 0x2B)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x94, 0x2C, 0x2D, 0x2E)) - .InSequence(seq); - EXPECT_CALL(midi.backend, write(0x97, 0x33, 0x44, 0xF7)) - .InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0xF0, 0x55, 0x66)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x77, 0x11, 0x22)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x23, 0x24, 0x25)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x26, 0x27, 0x28)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x29, 0x2A, 0x2B)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x94, 0x2C, 0x2D, 0x2E)).InSequence(seq); + EXPECT_CALL(midi.backend, write(0x97, 0x33, 0x44, 0xF7)).InSequence(seq); std::vector chunks[] = { {0xF0, 0x55, 0x66}, {0x77, 0x11},