diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2019-10-14 19:00:32 -0600 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2019-11-02 16:32:18 -0600 |
commit | 22da779322e742775eb8d1e22bdf8c16f20c16b2 (patch) | |
tree | 61327a4f3df2ff393600f78b4573a35d833dbea1 /libs/ardour/midi_playlist.cc | |
parent | cc949232fe39c4c0a8a0775ab9fc9284df3fb39a (diff) |
introduce new all-in-RAM MIDI datastructure and use it for MIDI playback
Diffstat (limited to 'libs/ardour/midi_playlist.cc')
-rw-r--r-- | libs/ardour/midi_playlist.cc | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index 1522f17184..2231791de6 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -202,7 +202,7 @@ MidiPlaylist::read (Evoral::EventSink<samplepos_t>& dst, /* Read from region into target. */ DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("read from %1 at %2 for %3 LR %4 .. %5\n", - mr->name(), start, dur, + mr->name(), start, dur, (loop_range ? loop_range->from : -1), (loop_range ? loop_range->to : -1))); mr->read_at (tgt, start, dur, loop_range, tracker->cursor, chan_n, _note_mode, &tracker->tracker, filter); @@ -489,3 +489,62 @@ MidiPlaylist::contained_automation() return ret; } + +void +MidiPlaylist::dump (Evoral::EventSink<samplepos_t>& dst, MidiChannelFilter* filter) +{ + typedef pair<MidiStateTracker*,samplepos_t> TrackerInfo; + + Playlist::RegionReadLock rl (this); + + DEBUG_TRACE (DEBUG::MidiPlaylistIO, "---- MidiPlaylist::dump-----\n"); + + std::vector< boost::shared_ptr<Region> > regs; + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + + /* check for the case of solo_selection */ + + if (_session.solo_selection_active() && SoloSelectedActive() && !SoloSelectedListIncludes ((const Region*) &(**i))) { + continue; + } + + regs.push_back (*i); + } + + /* If we are reading from a single region, we can read directly into dst. Otherwise, + we read into a temporarily list, sort it, then write that to dst. + */ + Evoral::EventList<samplepos_t> evlist; + Evoral::EventSink<samplepos_t>& tgt = (regs.size() == 1) ? dst : evlist; + + DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1 regions to read, direct: %2\n", regs.size(), (regs.size() == 1))); + + for (vector<boost::shared_ptr<Region> >::iterator i = regs.begin(); i != regs.end(); ++i) { + + boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*i); + + if (!mr) { + continue; + } + + DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("dump from %1 at %2\n", mr->name())); + mr->dump_to (tgt, 0, _note_mode, filter); + } + + if (!evlist.empty()) { + /* We've read from multiple regions into evlist, sort the event list by time. */ + EventsSortByTimeAndType<samplepos_t> cmp; + evlist.sort (cmp); + + /* Copy ordered events from event list to dst. */ + for (Evoral::EventList<samplepos_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) { + Evoral::Event<samplepos_t>* ev (*e); + dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer()); + delete ev; + } + } + + DEBUG_TRACE (DEBUG::MidiPlaylistIO, "---- End MidiPlaylist::dump ----\n"); + +} |