summaryrefslogtreecommitdiff
path: root/libs/ardour/smf_source.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-01-23 13:41:20 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2014-01-23 13:41:20 -0500
commit7000afdc66c9e0ae8dcf9ec080517dabba1e7f34 (patch)
tree19574ed8a1fbafa6bed222d8cf817ee1c8098314 /libs/ardour/smf_source.cc
parent065e1e63342633f72725a5309926f71c87804293 (diff)
parent40d8c5ae01f25e02457c554170a53d537246a7d4 (diff)
fix merge conflict with master
Diffstat (limited to 'libs/ardour/smf_source.cc')
-rw-r--r--libs/ardour/smf_source.cc101
1 files changed, 65 insertions, 36 deletions
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index d915bba845..dfaa51481d 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -67,6 +67,15 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
}
/* file is not opened until write */
+
+ if (flags & Writable) {
+ return;
+ }
+
+ if (open(_path)) {
+ throw failed_constructor ();
+ }
+ _open = true;
}
/** Constructor used for existing internal-to-session files. */
@@ -468,6 +477,12 @@ SMFSource::safe_midi_file_extension (const string& file)
return true;
}
+static bool compare_eventlist (
+ const std::pair< Evoral::Event<double>*, gint >& a,
+ const std::pair< Evoral::Event<double>*, gint >& b) {
+ return ( a.first->time() < b.first->time() );
+}
+
void
SMFSource::load_model (bool lock, bool force_reload)
{
@@ -506,60 +521,74 @@ SMFSource::load_model (bool lock, bool force_reload)
uint8_t* buf = NULL;
int ret;
gint event_id;
- bool have_event_id = false;
+ bool have_event_id;
- while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
+ // TODO simplify event allocation
+ std::list< std::pair< Evoral::Event<double>*, gint > > eventlist;
- time += delta_t;
+ for (unsigned i = 1; i <= num_tracks(); ++i) {
+ if (seek_to_track(i)) continue;
- if (ret == 0) {
-
- /* meta-event : did we get an event ID ?
- */
-
- if (event_id >= 0) {
- have_event_id = true;
- }
+ time = 0;
+ have_event_id = false;
- continue;
- }
+ while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
- if (ret > 0) {
+ time += delta_t;
- /* not a meta-event */
+ if (ret == 0) {
+ /* meta-event : did we get an event ID ? */
+ if (event_id >= 0) {
+ have_event_id = true;
+ }
+ continue;
+ }
- ev.set (buf, size, time / (double)ppqn());
- ev.set_event_type(EventTypeMap::instance().midi_event_type(buf[0]));
+ if (ret > 0) {
+ /* not a meta-event */
- if (!have_event_id) {
- event_id = Evoral::next_event_id();
- }
+ if (!have_event_id) {
+ event_id = Evoral::next_event_id();
+ }
+ uint32_t event_type = EventTypeMap::instance().midi_event_type(buf[0]);
+ double event_time = time / (double) ppqn();
#ifndef NDEBUG
- std::string ss;
+ std::string ss;
- for (uint32_t xx = 0; xx < size; ++xx) {
- char b[8];
- snprintf (b, sizeof (b), "0x%x ", buf[xx]);
- ss += b;
- }
+ 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 %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
- delta_t, time, size, ss , ev.event_type(), name()));
+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
+ delta_t, time, size, ss , event_type, name()));
#endif
- _model->append (ev, event_id);
+ eventlist.push_back(make_pair (
+ new Evoral::Event<double> (
+ 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;
- // 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);
+ }
- _length_beats = max(_length_beats, ev.time());
+ /* event ID's must immediately precede the event they are for */
+ have_event_id = false;
}
+ }
- /* event ID's must immediately precede the event they are for
- */
+ eventlist.sort(compare_eventlist);
- have_event_id = false;
+ std::list< std::pair< Evoral::Event<double>*, gint > >::iterator it;
+ for (it=eventlist.begin(); it!=eventlist.end(); ++it) {
+ _model->append (*it->first, it->second);
+ delete it->first;
}
_model->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);