57 static_assert(Outputs >= 1,
"a sequencer needs an output");
60 static constexpr uint8_t
OUTPUTS = Outputs;
70 using Sink = void (*)(
void* context, uint8_t output,
const MidiEvent& event);
73 for (uint8_t o = 0; o < Outputs; ++o) output_channel_[o] =
KEEP_CHANNEL;
83 if (!loaded_)
return false;
89 track_output_[t] = (t >= 1 && t - 1 < Outputs) ?
static_cast<uint8_t
>(t - 1) :
NO_OUTPUT;
91 for (uint8_t c = 0; c <
CHANNELS; ++c) channel_output_[c] = c < Outputs ? c :
NO_OUTPUT;
101 track_output_[track] = output < Outputs ? output :
NO_OUTPUT;
108 channel_output_[channel] = output < Outputs ? output :
NO_OUTPUT;
114 if (output >= Outputs)
return;
126 if (!loaded_)
return;
128 for (uint8_t i = 0; i < snapshot_count_; ++i) {
129 emit_cc(snapshot_[i].output, snapshot_[i].channel, snapshot_[i].controller, snapshot_[i].value);
132 pass_start_scaled_ = now_scaled_;
140 if (!playing_)
return;
147 if (loaded_ && !finished_) playing_ =
true;
164 const uint64_t step =
static_cast<uint64_t
>(elapsed_samples) * MICROS_PER_SECOND;
165 if (!loaded_ || !playing_) {
166 pass_start_scaled_ += step;
173 uint8_t best = NO_TRACK;
174 uint32_t best_tick = 0;
175 for (uint8_t t = 0; t < track_count_; ++t) {
177 if (ev !=
nullptr && (best == NO_TRACK || ev->
tick < best_tick)) {
179 best_tick = ev->
tick;
183 if (best == NO_TRACK) {
184 if (!loop_ || song_us_ == 0) {
191 pass_start_scaled_ += song_us_ * sample_rate_;
197 const uint64_t numerator =
198 static_cast<uint64_t
>(best_tick - last_tick_) * tempo_us_ + tick_remainder_;
199 const uint64_t event_us = song_us_ + numerator / ticks_per_quarter_;
200 if (pass_start_scaled_ + event_us * sample_rate_ > now_scaled_)
return;
203 tick_remainder_ = numerator % ticks_per_quarter_;
204 last_tick_ = best_tick;
211 route(best, ev.
midi);
217 static constexpr uint64_t MICROS_PER_SECOND = 1000000;
218 static constexpr uint8_t NO_TRACK = 0xFF;
228 for (uint8_t t = 0; t < track_count_; ++t) tracks_[t].rewind();
236 bool destination(uint8_t track,
const MidiEvent& e, uint8_t& output, uint8_t& channel)
const {
237 output = format_ == 0 ? channel_output_[e.channel & (
CHANNELS - 1)] : track_output_[track];
238 if (output >= Outputs)
return false;
239 channel = output_channel_[output] ==
KEEP_CHANNEL ? e.channel : output_channel_[output];
243 void route(uint8_t track, MidiEvent e) {
247 if (!destination(track, e, output, channel))
return;
249 if (sink_ !=
nullptr) sink_(context_, output, e);
252 void emit_cc(uint8_t output, uint8_t channel, uint8_t controller, uint8_t value) {
256 e.data1 = controller;
258 if (sink_ !=
nullptr) sink_(context_, output, e);
261 void all_notes_off() {
262 for (uint8_t o = 0; o < Outputs; ++o) {
263 for (uint8_t c = 0; c <
CHANNELS; ++c) {
264 if (used_channels_[o] & (1u << c)) emit_cc(o, c,
ALL_NOTES_OFF, 0);
271 for (uint8_t o = 0; o < Outputs; ++o) used_channels_[o] = 0;
273 for (uint8_t t = 0; t < track_count_; ++t) {
274 SmfTrack cursor = tracks_[t];
276 while (
const SmfEvent* ev = cursor.peek()) {
280 used_channels_[output] |=
static_cast<uint16_t
>(1u << channel);
288 void remember(uint8_t output, uint8_t channel,
const MidiEvent& e) {
289 for (uint8_t i = 0; i < snapshot_count_; ++i) {
290 const Controller& c = snapshot_[i];
291 if (c.output == output && c.channel == channel && c.controller == e.data1)
return;
294 snapshot_[snapshot_count_++] = Controller{output, channel, e.data1, e.data2};
303 uint8_t channel_output_[
CHANNELS] = {};
304 uint8_t output_channel_[Outputs] = {};
305 uint16_t used_channels_[Outputs] = {};
307 uint8_t snapshot_count_ = 0;
309 uint16_t format_ = 0;
310 uint8_t track_count_ = 0;
311 uint16_t ticks_per_quarter_ = 1;
314 bool loaded_ =
false;
315 bool playing_ =
false;
316 bool finished_ =
false;
320 uint64_t song_us_ = 0;
321 uint32_t last_tick_ = 0;
322 uint64_t tick_remainder_ = 0;
323 uint64_t now_scaled_ = 0;
324 uint64_t pass_start_scaled_ = 0;