fix ever increasing MIDI event IDs
[ardour.git] / libs / evoral / src / Sequence.cpp
index 1d52a12e4f239db9ada40e5eb5756453bc02900b..526256bf5e274be9b197329420b3f0454a802fcf 100644 (file)
@@ -72,7 +72,11 @@ Sequence<Time>::const_iterator::const_iterator()
 
 /** @param force_discrete true to force ControlLists to use discrete evaluation, otherwise false to get them to use their configured mode */
 template<typename Time>
-Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t, bool force_discrete, std::set<Evoral::Parameter> const & filtered)
+Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>&              seq,
+                                               Time                               t,
+                                               bool                               force_discrete,
+                                               const std::set<Evoral::Parameter>& filtered,
+                                               const std::set<WeakNotePtr>*       active_notes)
        : _seq(&seq)
        , _active_patch_change_message (0)
        , _type(NIL)
@@ -91,6 +95,17 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
 
        _lock = seq.read_lock();
 
+       // Add currently active notes, if given
+       if (active_notes) {
+               for (typename std::set<WeakNotePtr>::const_iterator i = active_notes->begin();
+                    i != active_notes->end(); ++i) {
+                       NotePtr note = i->lock();
+                       if (note && note->time() <= t && note->end_time() > t) {
+                               _active_notes.push(note);
+                       }
+               }
+       }
+
        // Find first note which begins at or after t
        _note_iter = seq.note_lower_bound(t);
 
@@ -192,16 +207,14 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
        }
 }
 
-template<typename Time>
-Sequence<Time>::const_iterator::~const_iterator()
-{
-}
-
 template<typename Time>
 void
-Sequence<Time>::const_iterator::invalidate()
+Sequence<Time>::const_iterator::invalidate(std::set< boost::weak_ptr< Note<Time> > >* notes)
 {
        while (!_active_notes.empty()) {
+               if (notes) {
+                       notes->insert(_active_notes.top());
+               }
                _active_notes.pop();
        }
        _type = NIL;
@@ -231,7 +244,7 @@ Sequence<Time>::const_iterator::choose_next(Time earliest_t)
 
        // Use the next note off iff it's earlier or the same time as the note on
        if ((!_active_notes.empty())) {
-               if (_type == NIL || _active_notes.top()->end_time() <= earliest_t) {
+               if (_type == NIL || _active_notes.top()->end_time().to_double() <= earliest_t.to_double()) {
                        _type      = NOTE_OFF;
                        earliest_t = _active_notes.top()->end_time();
                }
@@ -271,18 +284,18 @@ Sequence<Time>::const_iterator::set_event()
        switch (_type) {
        case NOTE_ON:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = note on\n");
-               *_event = (*_note_iter)->on_event();
+               _event->assign ((*_note_iter)->on_event());
                _active_notes.push(*_note_iter);
                break;
        case NOTE_OFF:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = note off\n");
                assert(!_active_notes.empty());
-               *_event = _active_notes.top()->off_event();
-               _active_notes.pop();
+               _event->assign (_active_notes.top()->off_event());
+               // We don't pop the active note until we increment past it
                break;
        case SYSEX:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = sysex\n");
-               *_event = *(*_sysex_iter);
+               _event->assign (*(*_sysex_iter));
                break;
        case CONTROL:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = control\n");
@@ -290,7 +303,7 @@ Sequence<Time>::const_iterator::set_event()
                break;
        case PATCH_CHANGE:
                DEBUG_TRACE(DEBUG::Sequence, "iterator = program change\n");
-               *_event = (*_patch_change_iter)->message (_active_patch_change_message);
+               _event->assign ((*_patch_change_iter)->message (_active_patch_change_message));
                break;
        default:
                _is_end = true;
@@ -338,6 +351,7 @@ Sequence<Time>::const_iterator::operator++()
                ++_note_iter;
                break;
        case NOTE_OFF:
+               _active_notes.pop();
                break;
        case CONTROL:
                // Increment current controller iterator