OpenShot Audio Library | OpenShotAudio  0.6.0
juce_UMPacket.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 #ifndef DOXYGEN
24 
25 namespace juce::universal_midi_packets
26 {
27 
33 template <size_t numWords>
34 class Packet
35 {
36 public:
37  Packet() = default;
38 
39  template <size_t w = numWords, std::enable_if_t<w == 1, int> = 0>
40  Packet (uint32_t a)
41  : contents { { a } }
42  {
43  jassert (Utils::getNumWordsForMessageType (a) == 1);
44  }
45 
46  template <size_t w = numWords, std::enable_if_t<w == 2, int> = 0>
47  Packet (uint32_t a, uint32_t b)
48  : contents { { a, b } }
49  {
50  jassert (Utils::getNumWordsForMessageType (a) == 2);
51  }
52 
53  template <size_t w = numWords, std::enable_if_t<w == 3, int> = 0>
54  Packet (uint32_t a, uint32_t b, uint32_t c)
55  : contents { { a, b, c } }
56  {
57  jassert (Utils::getNumWordsForMessageType (a) == 3);
58  }
59 
60  template <size_t w = numWords, std::enable_if_t<w == 4, int> = 0>
61  Packet (uint32_t a, uint32_t b, uint32_t c, uint32_t d)
62  : contents { { a, b, c, d } }
63  {
64  jassert (Utils::getNumWordsForMessageType (a) == 4);
65  }
66 
67  template <size_t w, std::enable_if_t<w == numWords, int> = 0>
68  explicit Packet (const std::array<uint32_t, w>& fullPacket)
69  : contents (fullPacket)
70  {
71  jassert (Utils::getNumWordsForMessageType (fullPacket.front()) == numWords);
72  }
73 
74  Packet withMessageType (uint8_t type) const noexcept
75  {
76  return withU4<0> (type);
77  }
78 
79  Packet withGroup (uint8_t group) const noexcept
80  {
81  return withU4<1> (group);
82  }
83 
84  Packet withStatus (uint8_t status) const noexcept
85  {
86  return withU4<2> (status);
87  }
88 
89  Packet withChannel (uint8_t channel) const noexcept
90  {
91  return withU4<3> (channel);
92  }
93 
94  uint8_t getMessageType() const noexcept { return getU4<0>(); }
95 
96  uint8_t getGroup() const noexcept { return getU4<1>(); }
97 
98  uint8_t getStatus() const noexcept { return getU4<2>(); }
99 
100  uint8_t getChannel() const noexcept { return getU4<3>(); }
101 
102  template <size_t index>
103  Packet withU4 (uint8_t value) const noexcept
104  {
105  constexpr auto word = index / 8;
106  auto copy = *this;
107  std::get<word> (copy.contents) = Utils::U4<index % 8>::set (copy.template getU32<word>(), value);
108  return copy;
109  }
110 
111  template <size_t index>
112  Packet withU8 (uint8_t value) const noexcept
113  {
114  constexpr auto word = index / 4;
115  auto copy = *this;
116  std::get<word> (copy.contents) = Utils::U8<index % 4>::set (copy.template getU32<word>(), value);
117  return copy;
118  }
119 
120  template <size_t index>
121  Packet withU16 (uint16_t value) const noexcept
122  {
123  constexpr auto word = index / 2;
124  auto copy = *this;
125  std::get<word> (copy.contents) = Utils::U16<index % 2>::set (copy.template getU32<word>(), value);
126  return copy;
127  }
128 
129  template <size_t index>
130  Packet withU32 (uint32_t value) const noexcept
131  {
132  auto copy = *this;
133  std::get<index> (copy.contents) = value;
134  return copy;
135  }
136 
137  template <size_t index>
138  uint8_t getU4() const noexcept
139  {
140  return Utils::U4<index % 8>::get (this->template getU32<index / 8>());
141  }
142 
143  template <size_t index>
144  uint8_t getU8() const noexcept
145  {
146  return Utils::U8<index % 4>::get (this->template getU32<index / 4>());
147  }
148 
149  template <size_t index>
150  uint16_t getU16() const noexcept
151  {
152  return Utils::U16<index % 2>::get (this->template getU32<index / 2>());
153  }
154 
155  template <size_t index>
156  uint32_t getU32() const noexcept
157  {
158  return std::get<index> (contents);
159  }
160 
161  //==============================================================================
162  using Contents = std::array<uint32_t, numWords>;
163 
164  using const_iterator = typename Contents::const_iterator;
165 
166  const_iterator begin() const noexcept { return contents.begin(); }
167  const_iterator cbegin() const noexcept { return contents.begin(); }
168 
169  const_iterator end() const noexcept { return contents.end(); }
170  const_iterator cend() const noexcept { return contents.end(); }
171 
172  const uint32_t* data() const noexcept { return contents.data(); }
173 
174  const uint32_t& front() const noexcept { return contents.front(); }
175  const uint32_t& back() const noexcept { return contents.back(); }
176 
177  const uint32_t& operator[] (size_t index) const noexcept { return contents[index]; }
178 
179 private:
180  Contents contents { {} };
181 };
182 
183 using PacketX1 = Packet<1>;
184 using PacketX2 = Packet<2>;
185 using PacketX3 = Packet<3>;
186 using PacketX4 = Packet<4>;
187 
188 } // namespace juce::universal_midi_packets
189 
190 #endif
static uint32_t getNumWordsForMessageType(uint32_t)