LCOV - code coverage report
Current view: top level - src/Def - MIDICNChannelAddress.hpp (source / functions) Hit Total Coverage
Test: 90a1b9beff85a60dc6ebcea034a947a845e56960 Lines: 57 57 100.0 %
Date: 2019-11-30 15:53:32 Functions: 22 22 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* ✔ */
       2             : 
       3             : #pragma once
       4             : 
       5             : #include <Def/Def.hpp>
       6             : 
       7             : BEGIN_CS_NAMESPACE
       8             : 
       9             : /// A struct for saving a MIDI address consisting of a 7-bit address, a 4-bit
      10             : /// channel, and a 4-bit cable number.
      11             : struct __attribute__((packed)) RawMIDICNChannelAddress {
      12             :     bool valid : 1;
      13             :     uint8_t address : 7;
      14             :     uint8_t channel : 4;
      15             :     uint8_t cableNumber : 4;
      16             : };
      17             : 
      18             : /// A class for saving a MIDI channel and cable number.
      19             : class MIDICNChannel {
      20             :     friend class MIDICNChannelAddress;
      21             : 
      22             :   public:
      23           2 :     constexpr MIDICNChannel() : addresses{0, 0, 0, 0} {}
      24          40 :     constexpr MIDICNChannel(Channel channel, int cableNumber = 0)
      25         120 :         : addresses{
      26             :               1,
      27             :               0,
      28          40 :               (uint8_t)channel.getRaw(),
      29          40 :               (uint8_t)cableNumber,
      30          40 :           } {}
      31             : 
      32             :     /// Get the channel [1, 16].
      33             :     constexpr Channel getChannel() const {
      34             :         return Channel{int8_t(addresses.channel)};
      35             :     }
      36             : 
      37             :     /// Get the channel as an integer [0, 15].
      38          43 :     constexpr uint8_t getRawChannel() const { return addresses.channel; }
      39             : 
      40             :     /// Get the cable number [0, 15].
      41          43 :     constexpr uint8_t getCableNumber() const { return addresses.cableNumber; }
      42             : 
      43             :     /// Check if the MIDI address is valid.
      44          16 :     constexpr bool isValid() const { return addresses.valid; }
      45             : 
      46             :     /// Check if the MIDI address is valid.
      47             :     /// @see    isValid
      48          16 :     constexpr explicit operator bool() const { return isValid(); }
      49             : 
      50             :     constexpr static MIDICNChannel invalid() { return {}; }
      51             : 
      52             :   private:
      53             :     RawMIDICNChannelAddress addresses;
      54             : };
      55             : 
      56             : /// A class for saving an offset to a MIDI address.
      57             : /// It can be added to a MIDICNChannelAddress.
      58             : class RelativeMIDICNChannelAddress {
      59             :     friend class MIDICNChannelAddress;
      60             : 
      61             :   public:
      62           3 :     constexpr RelativeMIDICNChannelAddress() : addresses{0, 0, 0, 0} {}
      63          48 :     constexpr RelativeMIDICNChannelAddress(int deltaAddress,
      64             :                                            int deltaChannel = 0,
      65             :                                            int deltaCableNumber = 0)
      66         192 :         : addresses{
      67             :               1,
      68          48 :               (uint8_t)deltaAddress,
      69          48 :               (uint8_t)deltaChannel,
      70          48 :               (uint8_t)deltaCableNumber,
      71          48 :           } {}
      72          91 :     constexpr bool isValid() const { return addresses.valid; }
      73             : 
      74             :   private:
      75             :     RawMIDICNChannelAddress addresses;
      76             :     static_assert(((-1) & 0x7F) == 0x7F,
      77             :                   "Negative numbers must be two's complement");
      78             : };
      79             : 
      80             : /// A type-safe utility class for saving a MIDI address consisting of a 7-bit
      81             : /// address, a 4-bit channel, and a 4-bit cable number.
      82             : class MIDICNChannelAddress {
      83             :   public:
      84           9 :     constexpr MIDICNChannelAddress()
      85           9 :         : addresses{
      86             :               0,
      87             :               0,
      88             :               0,
      89             :               0,
      90           9 :           } {}
      91          27 :     constexpr MIDICNChannelAddress(int address, MIDICNChannel channelCN)
      92         108 :         : addresses{
      93             :               1,
      94          27 :               (uint8_t)address,
      95          27 :               channelCN.getRawChannel(),
      96          27 :               channelCN.getCableNumber(),
      97          27 :           } {}
      98         209 :     constexpr MIDICNChannelAddress(int address, Channel channel = CHANNEL_1,
      99             :                                    int cableNumber = 0x0)
     100         836 :         : addresses{
     101             :               1,
     102         209 :               (uint8_t)address,
     103         209 :               (uint8_t)channel.getRaw(),
     104         209 :               (uint8_t)cableNumber,
     105         209 :           } {} // Deliberate overflow for negative numbers
     106          12 :     constexpr MIDICNChannelAddress(Channel channel, int cableNumber = 0x0)
     107          36 :         : addresses{
     108             :               1,
     109             :               0,
     110          12 :               (uint8_t)channel.getRaw(),
     111          12 :               (uint8_t)cableNumber,
     112          12 :           } {} // Deliberate overflow for negative numbers
     113          11 :     constexpr MIDICNChannelAddress(const MIDICNChannel &address)
     114          11 :         : addresses(address.addresses) {}
     115             : 
     116             :     MIDICNChannelAddress &operator+=(const RelativeMIDICNChannelAddress &rhs);
     117             : 
     118             :     MIDICNChannelAddress &operator-=(const RelativeMIDICNChannelAddress &rhs);
     119             : 
     120             :     MIDICNChannelAddress
     121             :     operator+(const RelativeMIDICNChannelAddress &rhs) const;
     122             : 
     123             :     MIDICNChannelAddress
     124             :     operator-(const RelativeMIDICNChannelAddress &rhs) const;
     125             : 
     126          18 :     constexpr bool operator==(const MIDICNChannelAddress &rhs) const {
     127          35 :         return this->addresses.valid && rhs.addresses.valid &&
     128          17 :                this->addresses.address == rhs.addresses.address &&
     129          16 :                this->addresses.channel == rhs.addresses.channel &&
     130          15 :                this->addresses.cableNumber == rhs.addresses.cableNumber;
     131             :     }
     132             : 
     133           8 :     constexpr bool operator!=(const MIDICNChannelAddress &rhs) const {
     134          15 :         return this->addresses.valid && rhs.addresses.valid &&
     135          12 :                !(this->addresses.address == rhs.addresses.address &&
     136           5 :                  this->addresses.channel == rhs.addresses.channel &&
     137           3 :                  this->addresses.cableNumber == rhs.addresses.cableNumber);
     138             :     }
     139             : 
     140             :     /// Get the address [0, 127].
     141         378 :     constexpr uint8_t getAddress() const { return addresses.address; }
     142             : 
     143             :     /// Get the channel [CHANNEL_1, CHANNEL_16]
     144          69 :     constexpr Channel getChannel() const {
     145          69 :         return Channel{int8_t(addresses.channel)};
     146             :     }
     147             :     /// Get the channel [0, 15]
     148         128 :     constexpr uint8_t getRawChannel() const { return addresses.channel; }
     149             : 
     150             :     /// Get the cable number [0, 15]
     151         187 :     constexpr uint8_t getCableNumber() const { return addresses.cableNumber; }
     152             : 
     153             :     /// Check if the MIDI address is valid.
     154         280 :     constexpr bool isValid() const { return addresses.valid; }
     155             : 
     156             :     /// Check if the MIDI address is valid.
     157             :     /// @see    isValid
     158          96 :     constexpr explicit operator bool() const { return isValid(); }
     159             : 
     160             :     /// Check if two addresses match.
     161             :     static bool matchSingle(const MIDICNChannelAddress &toMatch,
     162             :                             const MIDICNChannelAddress &base);
     163             : 
     164             :     /// Check if an address falls within a range of addresses, starting with
     165             :     /// address `base`, with a given length.
     166             :     static bool matchAddressInRange(const MIDICNChannelAddress &toMatch,
     167             :                                     const MIDICNChannelAddress &base,
     168             :                                     uint8_t length);
     169             : 
     170             :     constexpr static MIDICNChannelAddress invalid() { return {}; }
     171             : 
     172             :   private:
     173             :     RawMIDICNChannelAddress addresses;
     174             : };
     175             : 
     176             : END_CS_NAMESPACE

Generated by: LCOV version 1.14-5-g4ff2ed6