+ if (!mr) {
+ continue;
+ }
+
+ /* Get the existing note tracker for this region, or create a new one. */
+ NoteTrackers::iterator t = _note_trackers.find (mr.get());
+ bool new_tracker = false;
+ boost::shared_ptr<RegionTracker> tracker;
+ if (t == _note_trackers.end()) {
+ tracker = boost::shared_ptr<RegionTracker>(new RegionTracker);
+ new_tracker = true;
+ DEBUG_TRACE (DEBUG::MidiPlaylistIO,
+ string_compose ("\tPre-read %1 (%2 .. %3): new tracker\n",
+ mr->name(), mr->position(), mr->last_frame()));
+ } else {
+ tracker = t->second;
+ DEBUG_TRACE (DEBUG::MidiPlaylistIO,
+ string_compose ("\tPre-read %1 (%2 .. %3): %4 active notes\n",
+ mr->name(), mr->position(), mr->last_frame(), tracker->tracker.on()));
+ }
+
+ /* Read from region into target. */
+ mr->read_at (tgt, start, dur, chan_n, _note_mode, &tracker->tracker, filter);
+ DEBUG_TRACE (DEBUG::MidiPlaylistIO,
+ string_compose ("\tPost-read: %1 active notes\n", tracker->tracker.on()));
+
+ if (find (ended.begin(), ended.end(), *i) != ended.end()) {
+ /* Region ended within the read range, so resolve any active notes
+ (either stuck notes in the data, or notes that end after the end
+ of the region). */
+ DEBUG_TRACE (DEBUG::MidiPlaylistIO,
+ string_compose ("\t%1 ended, resolve notes and delete (%2) tracker\n",
+ mr->name(), ((new_tracker) ? "new" : "old")));
+
+ tracker->tracker.resolve_notes (tgt, (*i)->last_frame());
+ if (!new_tracker) {
+ _note_trackers.erase (t);
+ }
+
+ } else {
+
+ if (new_tracker) {
+ _note_trackers.insert (make_pair (mr.get(), tracker));
+ DEBUG_TRACE (DEBUG::MidiPlaylistIO, "\tadded tracker to trackers\n");
+ }
+ }
+ }
+
+ if (!direct_read && !evlist.empty()) {
+ /* We've read from multiple regions, sort the event list by time. */
+ EventsSortByTimeAndType<framepos_t> cmp;
+ evlist.sort (cmp);
+
+ /* Copy ordered events from event list to dst. */
+ for (Evoral::EventList<framepos_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) {
+ Evoral::Event<framepos_t>* ev (*e);
+ dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
+ delete ev;