42 pendingSysExData.reserve (
size_t (initialBufferSize));
48 pendingSysExData.clear();
49 pendingSysExTime = 0.0;
60 template <
typename MessageCallback>
61 void dispatch (
const View& packet,
double time, MessageCallback&& callback)
63 const auto firstWord = *packet.
data();
65 if (! pendingSysExData.empty() && shouldPacketTerminateSysExEarly (firstWord))
66 pendingSysExData.clear();
68 switch (packet.
size())
73 if (Utils::getMessageType (firstWord) != 0x00)
84 if (Utils::getMessageType (firstWord) == 0x3)
85 processSysEx (
PacketX2 { packet[0], packet[1] }, time, callback);
109 const auto word = m.front();
112 const std::array<uint8_t, 3> bytes { { uint8_t ((word >> 0x10) & 0xff),
113 uint8_t ((word >> 0x08) & 0xff),
114 uint8_t ((word >> 0x00) & 0xff) } };
120 template <
typename MessageCallback>
121 void processSysEx (
const PacketX2& packet,
123 MessageCallback&& callback)
125 switch (getSysEx7Kind (packet[0]))
128 startSysExMessage (time);
130 terminateSysExMessage (callback);
134 startSysExMessage (time);
139 if (pendingSysExData.empty())
146 if (pendingSysExData.empty())
150 terminateSysExMessage (callback);
155 void pushBytes (
const PacketX2& packet)
158 pendingSysExData.insert (pendingSysExData.end(),
160 bytes.data.begin() + bytes.size);
163 void startSysExMessage (
double time)
165 pendingSysExTime = time;
166 pendingSysExData.push_back (std::byte { 0xf0 });
169 template <
typename MessageCallback>
170 void terminateSysExMessage (MessageCallback&& callback)
172 pendingSysExData.push_back (std::byte { 0xf7 });
173 callback (BytestreamMidiView (pendingSysExData, pendingSysExTime));
174 pendingSysExData.clear();
177 static bool shouldPacketTerminateSysExEarly (uint32_t firstWord)
179 return ! (isSysExContinuation (firstWord)
180 || isSystemRealTime (firstWord)
181 || isJROrNOP (firstWord));
189 static bool isJROrNOP (uint32_t word)
191 return Utils::getMessageType (word) == 0x0;
194 static bool isSysExContinuation (uint32_t word)
196 if (Utils::getMessageType (word) != 0x3)
199 const auto kind = getSysEx7Kind (word);
203 static bool isSystemRealTime (uint32_t word)
205 return Utils::getMessageType (word) == 0x1 && ((word >> 0x10) & 0xff) >= 0xf8;
208 std::vector<std::byte> pendingSysExData;
210 double pendingSysExTime = 0.0;