88 std::function<void(uint8_t status, uint8_t d1, uint8_t d2)>;
93 std::function<void(
const std::vector<uint8_t>& buf)>;
104 auto clear_pending = [&
state] {
105 state.pending_status = 0;
106 state.pending_data[0] = 0;
107 state.pending_data[1] = 0;
108 state.pending_count = 0;
109 state.pending_expected = 0;
112 auto short_data_len = [](uint8_t status) -> std::size_t {
113 if ((status & 0xF0) >= 0x80 && (status & 0xF0) <= 0xE0) {
114 return ((status & 0xF0) == 0xC0 || (status & 0xF0) == 0xD0) ? 1u : 2u;
116 if (status == 0xF1 || status == 0xF3)
return 1;
117 if (status == 0xF2)
return 2;
118 if (status == 0xF6 || status == 0xF7)
return 0;
119 return static_cast<std::size_t
>(-1);
122 auto is_channel_status = [](uint8_t status) {
123 return (status & 0xF0) >= 0x80 && (status & 0xF0) <= 0xE0;
126 auto emit_pending = [&] {
128 on_short(
state.pending_status,
129 state.pending_expected > 0 ?
state.pending_data[0] : 0,
130 state.pending_expected > 1 ?
state.pending_data[1] : 0);
132 const uint8_t completed_status =
state.pending_status;
134 if (is_channel_status(completed_status))
state.running_status = completed_status;
137 auto start_pending = [&](uint8_t status) {
139 const auto data_len = short_data_len(status);
140 if (data_len ==
static_cast<std::size_t
>(-1)) {
141 state.running_status = 0;
144 if (is_channel_status(status)) {
145 state.running_status = status;
147 state.running_status = 0;
150 if (on_short) on_short(status, 0, 0);
153 state.pending_status = status;
154 state.pending_expected = data_len;
157 auto consume_data = [&](uint8_t data) {
158 if (
state.pending_status == 0) {
159 if (
state.running_status == 0)
return;
160 start_pending(
state.running_status);
162 if (
state.pending_status == 0 ||
state.pending_count >= 2)
return;
163 state.pending_data[
state.pending_count++] = data;
164 if (
state.pending_count >=
state.pending_expected) emit_pending();
167 for (std::size_t i = 0; i < n; ++i) {
168 const uint8_t b = buf[i];
173 if (on_short) on_short(b, 0, 0);
177 if (
state.sysex_in_progress) {
179 if (
state.sysex_buffer.size() >=
state.maximum_sysex_bytes) {
180 state.sysex_buffer.clear();
181 state.sysex_in_progress =
false;
185 state.sysex_buffer.push_back(b);
186 if (on_sysex) on_sysex(
state.sysex_buffer);
187 state.sysex_buffer.clear();
188 state.sysex_in_progress =
false;
195 if ((b & 0x80) != 0) {
196 state.sysex_buffer.clear();
197 state.sysex_in_progress =
false;
201 if (
state.sysex_buffer.size() >=
state.maximum_sysex_bytes) {
202 state.sysex_buffer.clear();
203 state.sysex_in_progress =
false;
207 state.sysex_buffer.push_back(b);
213 state.sysex_buffer.clear();
214 state.running_status = 0;
216 if (
state.maximum_sysex_bytes == 0) {
217 state.sysex_in_progress =
false;
221 state.sysex_buffer.push_back(b);
222 state.sysex_in_progress =
true;
227 if ((b & 0x80) != 0) {
Definition custom_node_events.hpp:26
constexpr std::size_t kRawMidiSysexLimit
Definition raw_midi_parser.hpp:50
void parse_raw_midi_bytes(const uint8_t *buf, std::size_t n, RawMidiParserState &state, const RawMidiShortCallback &on_short, const RawMidiSysexCallback &on_sysex)
Definition raw_midi_parser.hpp:99
std::function< void(const std::vector< uint8_t > &buf)> RawMidiSysexCallback
Definition raw_midi_parser.hpp:92
std::function< void(uint8_t status, uint8_t d1, uint8_t d2)> RawMidiShortCallback
Definition raw_midi_parser.hpp:87
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
Definition raw_midi_parser.hpp:52
std::size_t pending_count
Definition raw_midi_parser.hpp:78
DropReason last_drop_reason
Definition raw_midi_parser.hpp:82
std::size_t maximum_sysex_bytes
Definition raw_midi_parser.hpp:81
std::size_t pending_expected
Definition raw_midi_parser.hpp:79
bool sysex_in_progress
Definition raw_midi_parser.hpp:74
uint8_t pending_data[2]
Definition raw_midi_parser.hpp:77
void reset_sysex() noexcept
Discard an incomplete message while retaining prepared capacity.
Definition raw_midi_parser.hpp:67
uint8_t running_status
Definition raw_midi_parser.hpp:75
uint8_t pending_status
Definition raw_midi_parser.hpp:76
std::vector< uint8_t > sysex_buffer
Definition raw_midi_parser.hpp:73
DropReason
Definition raw_midi_parser.hpp:53
@ overflow
Definition raw_midi_parser.hpp:53
@ none
Definition raw_midi_parser.hpp:53
@ reset
Definition raw_midi_parser.hpp:53
@ aborted
Definition raw_midi_parser.hpp:53
void reserve_sysex(std::size_t worst_case_bytes)
Prepare internal SysEx storage for realtime use.
Definition raw_midi_parser.hpp:60