48 pendingSysExData.clear();
49 pendingSysExTime = 0.0;
60 template <
typename MessageCallback>
65 if (! pendingSysExData.empty() && shouldPacketTerminateSysExEarly (
firstWord))
66 pendingSysExData.clear();
73 if (Utils::getMessageType (
firstWord) != 0x00)
84 if (Utils::getMessageType (
firstWord) == 0x3)
109 const auto word = m.front();
112 const std::array<uint8_t, 3> bytes { {
uint8_t ((
word >> 0x10) & 0xff),
120 template <
typename MessageCallback>
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;