/** @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)
_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);
}
}
-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;
// 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();
}
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");
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;
++_note_iter;
break;
case NOTE_OFF:
+ _active_notes.pop();
break;
case CONTROL:
// Increment current controller iterator