Make MidiModel::write_section_to able to offset event times
authorJulien "_FrnchFrgg_" RIVAUD <frnchfrgg@free.fr>
Tue, 19 Jul 2016 23:17:58 +0000 (01:17 +0200)
committerJulien "_FrnchFrgg_" RIVAUD <frnchfrgg@free.fr>
Wed, 20 Jul 2016 00:01:40 +0000 (02:01 +0200)
MidiModel::write_section_to() only wrote events to the given source if
those events had a time in the given range. Make it able to optionally
offset event times so that the start of the written range corresponds to
time 0 in the source.

libs/ardour/ardour/midi_model.h
libs/ardour/midi_model.cc

index 254d6100770a25ee05e2087f1cf668e524543a49..ea4f178bf310d7143539fe2d34aafb4e2a188930 100644 (file)
@@ -265,7 +265,8 @@ public:
        bool write_section_to(boost::shared_ptr<MidiSource>     source,
                              const Glib::Threads::Mutex::Lock& source_lock,
                              Evoral::Beats                     begin = Evoral::MinBeats,
-                             Evoral::Beats                     end   = Evoral::MaxBeats);
+                             Evoral::Beats                     end   = Evoral::MaxBeats,
+                             bool                              offset_events = false);
 
        // MidiModel doesn't use the normal AutomationList serialisation code
        // since controller data is stored in the .mid
index 17b5b8a1cb8f6d9f79e9956ceeaa13dbebd14d83..4e895c5a925a9f898767d6d98366133e9abb0927 100644 (file)
@@ -1483,7 +1483,8 @@ bool
 MidiModel::write_section_to (boost::shared_ptr<MidiSource>     source,
                              const Glib::Threads::Mutex::Lock& source_lock,
                              TimeType                          begin_time,
-                             TimeType                          end_time)
+                             TimeType                          end_time,
+                             bool                              offset_events)
 {
        ReadLock lock(read_lock());
        MidiStateTracker mst;
@@ -1495,21 +1496,17 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource>     source,
        source->mark_streaming_midi_write_started (source_lock, note_mode());
 
        for (Evoral::Sequence<TimeType>::const_iterator i = begin(TimeType(), true); i != end(); ++i) {
-               const Evoral::Event<TimeType>& ev (*i);
+               if (i->time() >= begin_time && i->time() < end_time) {
 
-               if (ev.time() >= begin_time && ev.time() < end_time) {
+                       Evoral::MIDIEvent<TimeType> mev (*i, true); /* copy the event */
 
-                       const Evoral::MIDIEvent<TimeType>* mev =
-                               static_cast<const Evoral::MIDIEvent<TimeType>* > (&ev);
-
-                       if (!mev) {
-                               continue;
+                       if (offset_events) {
+                               mev.set_time(mev.time() - begin_time);
                        }
 
+                       if (mev.is_note_off()) {
 
-                       if (mev->is_note_off()) {
-
-                               if (!mst.active (mev->note(), mev->channel())) {
+                               if (!mst.active (mev.note(), mev.channel())) {
                                        /* the matching note-on was outside the
                                           time range we were given, so just
                                           ignore this note-off.
@@ -1517,18 +1514,21 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource>     source,
                                        continue;
                                }
 
-                               source->append_event_beats (source_lock, *i);
-                               mst.remove (mev->note(), mev->channel());
+                               source->append_event_beats (source_lock, mev);
+                               mst.remove (mev.note(), mev.channel());
 
-                       } else if (mev->is_note_on()) {
-                               mst.add (mev->note(), mev->channel());
-                               source->append_event_beats(source_lock, *i);
+                       } else if (mev.is_note_on()) {
+                               mst.add (mev.note(), mev.channel());
+                               source->append_event_beats(source_lock, mev);
                        } else {
-                               source->append_event_beats(source_lock, *i);
+                               source->append_event_beats(source_lock, mev);
                        }
                }
        }
 
+       if (offset_events) {
+               end_time -= begin_time;
+       }
        mst.resolve_notes (*source, source_lock, end_time);
 
        set_percussive(old_percussive);