From 94954f852ead97bcda7afa548d543222733228ef Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 14 Nov 2014 21:19:09 -0500 Subject: Fix out of order event errors on save with overlapping notes. Another consequence of fuzzy Sequence timing, but if the difference is less than a tick this should handle things correctly. If the difference is more than a tick, something's wrong, and it might be okay to just bump forward anyway, but I can't reproduce this and it could lead to corruption so I'm leaving that case noisy. --- libs/ardour/smf_source.cc | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'libs/ardour/smf_source.cc') diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index c7cd7160f3..8a865c3957 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -389,10 +389,22 @@ SMFSource::append_event_unlocked_beats (const Evoral::Event& ev) name().c_str(), ev.id(), ev.time(), ev.size()); for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/ - if (ev.time() < _last_ev_time_beats) { - warning << string_compose(_("Skipping event with unordered time %1"), ev.time()) - << endmsg; - return; + double time = ev.time(); + if (time < _last_ev_time_beats) { + const double difference = _last_ev_time_beats - time; + if (difference / (double)ppqn() < 1.0) { + /* Close enough. This problem occurs because Sequence is not + actually ordered due to fuzzy time comparison. I'm pretty sure + this is inherently a bad idea which causes problems all over the + place, but tolerate it here for now anyway. */ + time = _last_ev_time_beats; + } else { + /* Out of order by more than a tick. */ + warning << string_compose(_("Skipping event with unordered beat time %1 < %2 (off by %3 beats, %4 ticks)"), + ev.time(), _last_ev_time_beats, difference, difference / (double)ppqn()) + << endmsg; + return; + } } Evoral::event_id_t event_id; @@ -407,13 +419,13 @@ SMFSource::append_event_unlocked_beats (const Evoral::Event& ev) _model->append (ev, event_id); } - _length_beats = max(_length_beats, ev.time()); + _length_beats = max(_length_beats, time); - const double delta_time_beats = ev.time() - _last_ev_time_beats; + const double delta_time_beats = time - _last_ev_time_beats; const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn()); Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id); - _last_ev_time_beats = ev.time(); + _last_ev_time_beats = time; _flags = Source::Flag (_flags & ~Empty); } @@ -430,7 +442,8 @@ SMFSource::append_event_unlocked_frames (const Evoral::Event& ev, fr // for (size_t i=0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n"); if (ev.time() < _last_ev_time_frames) { - warning << string_compose(_("Skipping event with unordered time %1"), ev.time()) + warning << string_compose(_("Skipping event with unordered frame time %1 < %2"), + ev.time(), _last_ev_time_frames) << endmsg; return; } -- cgit v1.2.3