Add automatable click-free bypass/enable feature to a-eq
[ardour.git] / libs / ardour / midi_model.cc
index d9f6e802cfa4609a5c9b55636c21c75b1ad3953c..4e895c5a925a9f898767d6d98366133e9abb0927 100644 (file)
@@ -40,7 +40,7 @@
 #include "ardour/session.h"
 #include "ardour/types.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
@@ -491,7 +491,7 @@ Evoral::Sequence<MidiModel::TimeType>::NotePtr
 MidiModel::NoteDiffCommand::unmarshal_note (XMLNode *xml_note)
 {
        unsigned int note;
-       XMLProperty* prop;
+       XMLProperty const * prop;
        unsigned int channel;
        MidiModel::TimeType time;
        MidiModel::TimeType length;
@@ -599,7 +599,7 @@ MidiModel::NoteDiffCommand::marshal_change (const NoteChange& change)
 MidiModel::NoteDiffCommand::NoteChange
 MidiModel::NoteDiffCommand::unmarshal_change (XMLNode *xml_change)
 {
-       XMLProperty* prop;
+       XMLProperty const * prop;
        NoteChange change;
        change.note_id = 0;
 
@@ -876,7 +876,7 @@ MidiModel::SysExDiffCommand::marshal_change (const Change& change)
 MidiModel::SysExDiffCommand::Change
 MidiModel::SysExDiffCommand::unmarshal_change (XMLNode *xml_change)
 {
-       XMLProperty* prop;
+       XMLProperty const * prop;
        Change change;
 
        if ((prop = xml_change->property ("property")) != 0) {
@@ -1235,8 +1235,8 @@ MidiModel::PatchChangeDiffCommand::marshal_change (const Change& c)
 MidiModel::PatchChangePtr
 MidiModel::PatchChangeDiffCommand::unmarshal_patch_change (XMLNode* n)
 {
-       XMLProperty* prop;
-       XMLProperty* prop_id;
+       XMLProperty const * prop;
+       XMLProperty const * prop_id;
        Evoral::event_id_t id = 0;
        Evoral::Beats time = Evoral::Beats();
        int channel = 0;
@@ -1277,7 +1277,7 @@ MidiModel::PatchChangeDiffCommand::unmarshal_patch_change (XMLNode* n)
 MidiModel::PatchChangeDiffCommand::Change
 MidiModel::PatchChangeDiffCommand::unmarshal_change (XMLNode* n)
 {
-       XMLProperty* prop;
+       XMLProperty const * prop;
        Change c;
        int an_int;
 
@@ -1482,8 +1482,9 @@ MidiModel::sync_to_source (const Glib::Threads::Mutex::Lock& source_lock)
 bool
 MidiModel::write_section_to (boost::shared_ptr<MidiSource>     source,
                              const Glib::Threads::Mutex::Lock& source_lock,
-                             Evoral::Beats                     begin_time,
-                             Evoral::Beats                     end_time)
+                             TimeType                          begin_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<Evoral::Beats>& 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<Evoral::Beats>* mev =
-                               static_cast<const Evoral::MIDIEvent<Evoral::Beats>* > (&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);
@@ -1665,9 +1665,9 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
 
                if ((sb > sa) && (eb <= ea)) {
                        overlap = OverlapInternal;
-               } else if ((eb >= sa) && (eb <= ea)) {
+               } else if ((eb > sa) && (eb <= ea)) {
                        overlap = OverlapStart;
-               } else if ((sb > sa) && (sb <= ea)) {
+               } else if ((sb > sa) && (sb < ea)) {
                        overlap = OverlapEnd;
                } else if ((sa >= sb) && (sa <= eb) && (ea <= eb)) {
                        overlap = OverlapExternal;