67 SmfTrack(
const uint8_t* data, uint32_t length) : data_(data), length_(length) {
rewind(); }
75 done_ = (data_ ==
nullptr);
80 if (!has_pending_ && !done_) has_pending_ = decode(pending_);
81 return has_pending_ ? &pending_ :
nullptr;
84 void pop() { has_pending_ =
false; }
86 bool done()
const {
return done_ && !has_pending_; }
87 bool error()
const {
return error_; }
90 static constexpr uint8_t STATUS_BIT = 0x80;
91 static constexpr uint8_t META = 0xFF;
92 static constexpr uint8_t SYSEX = 0xF0;
93 static constexpr uint8_t SYSEX_ESCAPE = 0xF7;
94 static constexpr uint8_t SYSTEM_FIRST = 0xF0;
95 static constexpr uint8_t META_TRACK_NAME = 0x03;
96 static constexpr uint8_t META_END_OF_TRACK = 0x2F;
97 static constexpr uint8_t META_TEMPO = 0x51;
98 static constexpr uint8_t META_TIME_SIGNATURE = 0x58;
99 static constexpr uint32_t TEMPO_LENGTH = 3;
100 static constexpr uint32_t TIME_SIGNATURE_LENGTH = 2;
101 static constexpr uint8_t VLQ_MAX_BYTES = 4;
102 static constexpr uint8_t VLQ_MORE = 0x80;
103 static constexpr uint8_t VLQ_BITS = 0x7F;
104 static constexpr uint8_t VLQ_SHIFT = 7;
105 static constexpr uint8_t STATUS_KIND_MASK = 0xF0;
106 static constexpr uint8_t CHANNEL_MASK = 0x0F;
107 static constexpr uint8_t PROGRAM_CHANGE = 0xC0;
108 static constexpr uint8_t CHANNEL_PRESSURE = 0xD0;
116 bool read_vlq(uint32_t& out) {
118 for (uint8_t i = 0; i < VLQ_MAX_BYTES; ++i) {
119 if (pos_ >= length_)
return false;
120 const uint8_t b = data_[pos_++];
121 out = (out << VLQ_SHIFT) | (b & VLQ_BITS);
122 if ((b & VLQ_MORE) == 0)
return true;
128 bool decode(SmfEvent& ev) {
129 while (pos_ < length_) {
131 if (!read_vlq(delta))
return fail();
133 if (pos_ >= length_)
return fail();
134 const uint8_t lead = data_[pos_];
137 if (pos_ + 2 > length_)
return fail();
138 const uint8_t type = data_[pos_ + 1];
141 if (!read_vlq(len) || pos_ + len > length_)
return fail();
142 const uint32_t body = pos_;
149 case META_END_OF_TRACK:
154 if (len < TEMPO_LENGTH)
return fail();
156 ev.tempo_us = (
static_cast<uint32_t
>(data_[body]) << 16) |
157 (
static_cast<uint32_t
>(data_[body + 1]) << 8) |
160 case META_TIME_SIGNATURE:
161 if (len < TIME_SIGNATURE_LENGTH)
return fail();
163 ev.numerator = data_[body];
164 ev.denominator_power = data_[body + 1];
166 case META_TRACK_NAME:
168 ev.text = data_ + body;
169 ev.text_length = len;
176 if (lead == SYSEX || lead == SYSEX_ESCAPE) {
179 if (!read_vlq(len) || pos_ + len > length_)
return fail();
185 uint8_t status = running_status_;
186 if (lead & STATUS_BIT) {
187 if (lead >= SYSTEM_FIRST)
return fail();
189 running_status_ = lead;
191 }
else if (status == 0) {
195 const uint8_t kind = status & STATUS_KIND_MASK;
196 const uint8_t data_bytes = (kind == PROGRAM_CHANGE || kind == CHANNEL_PRESSURE) ? 1 : 2;
197 if (pos_ + data_bytes > length_)
return fail();
203 ev.midi.channel = status & CHANNEL_MASK;
204 ev.midi.data1 = data_[pos_];
205 ev.midi.data2 = data_bytes == 2 ? data_[pos_ + 1] : 0;
213 const uint8_t* data_ =
nullptr;
214 uint32_t length_ = 0;
217 uint8_t running_status_ = 0;
218 bool has_pending_ =
false;