- if (_is_end)
- throw std::logic_error("Attempt to iterate past end of MidiModel");
-
- assert(_event.is_note() || _event.is_cc());
-
- // Increment past current control event
- if (_control_iter != _control_iters.end() && _control_iter->first && _event.is_cc()) {
- double x, y;
- const bool ret = _control_iter->first->rt_safe_earliest_event_unlocked(
- _control_iter->second.first, DBL_MAX, x, y, false);
-
- if (ret) {
- //cerr << "Incremented " << _control_iter->first->parameter().id() << " to " << x << endl;
- _control_iter->second.first = x;
- _control_iter->second.second = y;
- } else {
- //cerr << "Hit end of " << _control_iter->first->parameter().id() << endl;
- _control_iter->first.reset();
- _control_iter->second.first = DBL_MAX;
- }
- }
-
- // Now find and point at the earliest event
-
- _control_iter = _control_iters.begin();
-
- for (std::vector<MidiControlIterator>::iterator i = _control_iters.begin();
- i != _control_iters.end(); ++i) {
- if (i->second.first < _control_iter->second.first) {
- _control_iter = i;
- }
- }
-
- enum Type { NIL, NOTE_ON, NOTE_OFF, CC };
-
- Type type = NIL;
- double t = 0;
-
- // Next earliest note on
- if (_note_iter != _model->notes().end()) {
- type = NOTE_ON;
- t = (*_note_iter)->time();
- }
-
- // Use the next earliest note off iff it's earlier than the note on
- if (_model->note_mode() == Sustained && (! _active_notes.empty())) {
- if (type == NIL || _active_notes.top()->end_time() <= (*_note_iter)->time()) {
- type = NOTE_OFF;
- t = _active_notes.top()->end_time();
- }
- }
-
- // Use the next earliest controller iff it's earlier than the note event
- if (_control_iter != _control_iters.end() && _control_iter->second.first != DBL_MAX)
- if (type == NIL || _control_iter->second.first < t)
- type = CC;
-
- if (type == NOTE_ON) {
- //cerr << "********** MIDI Iterator = note on" << endl;
- _event = MidiEvent((*_note_iter)->on_event(), false);
- _active_notes.push(*_note_iter);
- ++_note_iter;
- } else if (type == NOTE_OFF) {
- //cerr << "********** MIDI Iterator = note off" << endl;
- _event = MidiEvent(_active_notes.top()->off_event(), false);
- _active_notes.pop();
- } else if (type == CC) {
- //cerr << "********** MIDI Iterator = CC" << endl;
- _model->control_to_midi_event(_event, *_control_iter);
- } else {
- //cerr << "********** MIDI Iterator = END" << endl;
- _is_end = true;
- _model->read_unlock();
- _locked = false;
- }
-
- assert(_is_end || _event.size() > 0);
-
- return *this;