+ time = 0;
+ have_event_id = false;
+
+ while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
+
+ time += delta_t;
+
+ if (ret == 0) {
+ /* meta-event : did we get an event ID ? */
+ if (event_id >= 0) {
+ have_event_id = true;
+ }
+ continue;
+ }
+
+ if (ret > 0) {
+ /* not a meta-event */
+
+ if (!have_event_id) {
+ event_id = Evoral::next_event_id();
+ }
+ const uint32_t event_type = midi_parameter_type(buf[0]);
+ const Evoral::Beats event_time = Evoral::Beats::ticks_at_rate(time, ppqn());
+#ifndef NDEBUG
+ std::string ss;
+
+ for (uint32_t xx = 0; xx < size; ++xx) {
+ char b[8];
+ snprintf (b, sizeof (b), "0x%x ", buf[xx]);
+ ss += b;
+ }
+
+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %7 load model delta %1, time %2, size %3 buf %4, type %5 id %6\n",
+ delta_t, time, size, ss , event_type, event_id, name()));
+#endif
+
+ eventlist.push_back(make_pair (
+ new Evoral::Event<Evoral::Beats> (
+ event_type, event_time,
+ size, buf, true)
+ , event_id));
+
+ // Set size to max capacity to minimize allocs in read_event
+ scratch_size = std::max(size, scratch_size);
+ size = scratch_size;
+
+ _length_beats = max(_length_beats, event_time);
+ }
+
+ /* event ID's must immediately precede the event they are for */
+ have_event_id = false;
+ }