LCOV - code coverage report
Current view: top level - src/MIDI_Inputs - MIDIInputElementMatchers.hpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 95.3 % 43 41
Test Date: 2026-06-06 17:44:35 Functions: 100.0 % 15 15
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include "BankableMIDIMatcherHelpers.hpp"
       4              : #include "MIDIInputElement.hpp"
       5              : 
       6              : BEGIN_CS_NAMESPACE
       7              : 
       8              : /// @addtogroup MIDIInputMatchers
       9              : /// @{
      10              : 
      11              : // -------------------------------------------------------------------------- //
      12              : 
      13              : /// Matcher for MIDI messages with 1 data byte, such as Channel Pressure
      14              : /// and Program Change.
      15              : struct OneByteMIDIMatcher {
      16            3 :     OneByteMIDIMatcher(MIDIChannelCable address) : address(address) {}
      17              : 
      18              :     struct Result {
      19              :         bool match;
      20              :         uint8_t value;
      21              :     };
      22              : 
      23            4 :     Result operator()(ChannelMessage m) {
      24            4 :         if (!MIDIChannelCable::matchSingle(m.getChannelCable(), address))
      25            2 :             return {false, 0};
      26            2 :         uint8_t value = m.data1;
      27            2 :         return {true, value};
      28              :     }
      29              : 
      30              :     MIDIChannelCable address;
      31              : };
      32              : 
      33              : // -------------------------------------------------------------------------- //
      34              : 
      35              : /// Matcher for MIDI messages with 2 data bytes, such as Note On/Off, Control
      36              : /// Change, Key Pressure (but not Pitch Bend). Matches a single address.
      37              : struct TwoByteMIDIMatcher {
      38            7 :     TwoByteMIDIMatcher(MIDIAddress address) : address(address) {}
      39              : 
      40              :     struct Result {
      41              :         bool match;
      42              :         uint8_t value;
      43              :     };
      44              : 
      45           16 :     Result operator()(ChannelMessage m) {
      46           16 :         if (!MIDIAddress::matchSingle(m.getAddress(), address))
      47            0 :             return {false, 0};
      48              :         uint8_t value =
      49           16 :             m.getMessageType() == MIDIMessageType::NoteOff ? 0 : m.getData2();
      50           16 :         return {true, value};
      51              :     }
      52              : 
      53              :     MIDIAddress address;
      54              : };
      55              : 
      56              : // -------------------------------------------------------------------------- //
      57              : 
      58              : /// Matcher for MIDI Pitch Bend messages. Matches a single address.
      59              : struct PitchBendMIDIMatcher {
      60              :     PitchBendMIDIMatcher(MIDIChannelCable address) : address(address) {}
      61              : 
      62              :     struct Result {
      63              :         bool match;
      64              :         uint16_t value;
      65              :     };
      66              : 
      67              :     Result operator()(ChannelMessage m) {
      68              :         if (!MIDIChannelCable::matchSingle(m.getChannelCable(), address))
      69              :             return {false, 0};
      70              :         uint16_t value = (m.data2 << 7) | m.data1;
      71              :         return {true, value};
      72              :     }
      73              : 
      74              :     MIDIChannelCable address;
      75              : };
      76              : 
      77              : // -------------------------------------------------------------------------- //
      78              : 
      79              : /// Matcher for MIDI messages with 2 data bytes, such as Note On/Off, Control
      80              : /// Change, Key Pressure (but not Pitch Bend). Matches ranges of addresses on a
      81              : /// single channel and cable.
      82              : struct TwoByteRangeMIDIMatcher {
      83           17 :     TwoByteRangeMIDIMatcher(MIDIAddress address, uint8_t length)
      84           17 :         : address(address), length(length) {}
      85              : 
      86              :     struct Result {
      87              :         bool match;
      88              :         uint8_t value;
      89              :         uint8_t index;
      90              :     };
      91              : 
      92           96 :     Result operator()(ChannelMessage m) {
      93           96 :         if (!MIDIAddress::matchAddressInRange(m.getAddress(), address, length))
      94            2 :             return {false, 0, 0};
      95              :         uint8_t value =
      96           94 :             m.getMessageType() == MIDIMessageType::NoteOff ? 0 : m.getData2();
      97           94 :         uint8_t index = m.getData1() - address.getAddress();
      98           94 :         return {true, value, index};
      99              :     }
     100              : 
     101              :     MIDIAddress address;
     102              :     uint8_t length;
     103              : };
     104              : 
     105              : // -------------------------------------------------------------------------- //
     106              : 
     107              : /// Matcher for MIDI messages with 1 data byte, such as Channel Pressure
     108              : /// and Program Change. Matches a single address over multiple banks.
     109              : template <uint8_t BankSize>
     110              : struct BankableOneByteMIDIMatcher {
     111              :     BankableOneByteMIDIMatcher(
     112              :         BankConfig<BankSize, BankType::ChangeChannel> config,
     113              :         MIDIChannelCable address)
     114              :         : config(config), address(address) {}
     115              : 
     116              :     struct Result {
     117              :         bool match;
     118              :         uint8_t value;
     119              :         uint8_t bankIndex;
     120              :     };
     121              : 
     122              :     Result operator()(ChannelMessage m) {
     123              :         using BankableMIDIMatcherHelpers::getBankIndex;
     124              :         using BankableMIDIMatcherHelpers::matchBankable;
     125              :         if (!matchBankable(m.getChannelCable(), address, config))
     126              :             return {false, 0, 0};
     127              :         uint8_t value = m.data1;
     128              :         uint8_t bankIndex = getBankIndex(m.getChannelCable(), address, config);
     129              :         return {true, value, bankIndex};
     130              :     }
     131              : 
     132              :     Bank<BankSize> &getBank() { return config.bank; }
     133              :     const Bank<BankSize> &getBank() const { return config.bank; }
     134              :     BankType getBankType() const { return config.type; }
     135              :     static constexpr setting_t getBankSize() { return BankSize; }
     136              : 
     137              :     /// Get the current bank setting.
     138              :     /// @see    @ref Bank<N>::getSelection()
     139              :     setting_t getSelection() const { return getBank().getSelection(); }
     140              : 
     141              :     BaseBankConfig<BankSize> config;
     142              :     MIDIChannelCable address;
     143              : };
     144              : 
     145              : // -------------------------------------------------------------------------- //
     146              : 
     147              : /// Matcher for MIDI messages with 2 data bytes, such as Note On/Off, Control
     148              : /// Change, Key Pressure. Matches a single address over multiple banks.
     149              : template <uint8_t BankSize>
     150              : struct BankableTwoByteMIDIMatcher {
     151            6 :     BankableTwoByteMIDIMatcher(BankConfig<BankSize> config, MIDIAddress address)
     152            6 :         : config(config), address(address) {}
     153              : 
     154              :     struct Result {
     155              :         bool match;
     156              :         uint8_t value;
     157              :         uint8_t bankIndex;
     158              :     };
     159              : 
     160           11 :     Result operator()(ChannelMessage m) {
     161              :         using BankableMIDIMatcherHelpers::getBankIndex;
     162              :         using BankableMIDIMatcherHelpers::matchBankable;
     163           11 :         if (!matchBankable(m.getAddress(), address, config))
     164            0 :             return {false, 0, 0};
     165           11 :         uint8_t value =
     166           20 :             m.getMessageType() == MIDIMessageType::NoteOff ? 0 : m.getData2();
     167           11 :         uint8_t bankIndex = getBankIndex(m.getAddress(), address, config);
     168           11 :         return {true, value, bankIndex};
     169              :     }
     170              : 
     171           12 :     Bank<BankSize> &getBank() { return config.bank; }
     172           55 :     const Bank<BankSize> &getBank() const { return config.bank; }
     173              :     BankType getBankType() const { return config.type; }
     174              :     static constexpr setting_t getBankSize() { return BankSize; }
     175              : 
     176              :     /// Get the current bank setting.
     177              :     /// @see    @ref Bank<N>::getSelection()
     178           55 :     setting_t getSelection() const { return getBank().getSelection(); }
     179              : 
     180              :     BaseBankConfig<BankSize> config;
     181              :     MIDIAddress address;
     182              : };
     183              : 
     184              : // -------------------------------------------------------------------------- //
     185              : 
     186              : /// Matcher for MIDI Pitch Bend messages. Matches a single address over multiple
     187              : /// banks.
     188              : template <uint8_t BankSize>
     189              : struct BankablePitchBendMIDIMatcher {
     190              :     BankablePitchBendMIDIMatcher(
     191              :         BankConfig<BankSize, BankType::ChangeChannel> config,
     192              :         MIDIChannelCable address)
     193              :         : config(config), address(address) {}
     194              : 
     195              :     struct Result {
     196              :         bool match;
     197              :         uint16_t value;
     198              :         uint8_t bankIndex;
     199              :     };
     200              : 
     201              :     Result operator()(ChannelMessage m) {
     202              :         using BankableMIDIMatcherHelpers::getBankIndex;
     203              :         using BankableMIDIMatcherHelpers::matchBankable;
     204              :         if (!matchBankable(m.getChannelCable(), address, config))
     205              :             return {false, 0, 0};
     206              :         uint16_t value = (m.data2 << 7) | m.data1;
     207              :         uint8_t bankIndex = getBankIndex(m.getChannelCable(), address, config);
     208              :         return {true, value, bankIndex};
     209              :     }
     210              : 
     211              :     Bank<BankSize> &getBank() { return config.bank; }
     212              :     const Bank<BankSize> &getBank() const { return config.bank; }
     213              :     BankType getBankType() const { return config.type; }
     214              :     static constexpr setting_t getBankSize() { return BankSize; }
     215              : 
     216              :     /// Get the current bank setting.
     217              :     /// @see    @ref Bank<N>::getSelection()
     218              :     setting_t getSelection() const { return getBank().getSelection(); }
     219              : 
     220              :     BaseBankConfig<BankSize> config;
     221              :     MIDIChannelCable address;
     222              : };
     223              : 
     224              : // -------------------------------------------------------------------------- //
     225              : 
     226              : /// Matcher for MIDI messages with 2 data bytes, such as Note On/Off, Control
     227              : /// Change, Key Pressure. Matches a range of addresses over multiple banks.
     228              : template <uint8_t BankSize>
     229              : struct BankableTwoByteRangeMIDIMatcher {
     230              :     /// Constructor.
     231            6 :     BankableTwoByteRangeMIDIMatcher(BankConfig<BankSize> config,
     232              :                                     MIDIAddress address, uint8_t length)
     233            6 :         : config(config), address(address), length(length) {}
     234              : 
     235              :     struct Result {
     236              :         bool match;
     237              :         uint8_t value;
     238              :         uint8_t bankIndex;
     239              :         uint8_t index;
     240              :     };
     241              : 
     242           30 :     Result operator()(ChannelMessage m) {
     243              :         using BankableMIDIMatcherHelpers::getBankIndex;
     244              :         using BankableMIDIMatcherHelpers::getRangeIndex;
     245              :         using BankableMIDIMatcherHelpers::matchBankableInRange;
     246           30 :         if (!matchBankableInRange(m.getAddress(), address, config, length))
     247           18 :             return {false, 0, 0, 0};
     248           12 :         uint8_t value = m.getMessageType() == m.NoteOff ? 0 : m.getData2();
     249           12 :         uint8_t bankIndex = getBankIndex(m.getAddress(), address, config);
     250           12 :         uint8_t rangeIndex = getRangeIndex(m.getAddress(), address, config);
     251           12 :         return {true, value, bankIndex, rangeIndex};
     252              :     }
     253              : 
     254           12 :     Bank<BankSize> &getBank() { return config.bank; }
     255              :     const Bank<BankSize> &getBank() const { return config.bank; }
     256              :     static constexpr setting_t getBankSize() { return BankSize; }
     257              : 
     258              :     /// Get the current bank setting.
     259              :     /// @see    @ref Bank<N>::getSelection()
     260          180 :     setting_t getSelection() const { return config.bank.getSelection(); }
     261              : 
     262              :     BaseBankConfig<BankSize> config;
     263              :     MIDIAddress address;
     264              :     uint8_t length;
     265              : };
     266              : 
     267              : // -------------------------------------------------------------------------- //
     268              : 
     269              : /// @}
     270              : 
     271              : END_CS_NAMESPACE
        

Generated by: LCOV version 2.4-beta