- 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;
+void
+MidiModel::DeltaCommand::undo()
+{
+ // This could be made much faster by using a priority_queue for added and
+ // removed notes (or sort here), and doing a single iteration over _model
+
+ MidiModel::WriteLock lock(_model->edit_lock());;
+
+ for (NoteList::iterator i = _added_notes.begin(); i != _added_notes.end(); ++i) {
+ _model->remove_note_unlocked(*i);