From: Hans Baier Date: Tue, 15 Apr 2008 23:00:06 +0000 (+0000) Subject: * fixed bug: crash because of invalidated iterator while removing midi notes from... X-Git-Tag: 3.0-alpha5~4285 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=c4bdcb82afa95555a036cb1418bf6c74b4d4a2c1;p=ardour.git * fixed bug: crash because of invalidated iterator while removing midi notes from model git-svn-id: svn://localhost/ardour2/branches/3.0@3253 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 100c387580..115733e8ed 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -914,7 +914,6 @@ MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote) Selection::iterator next = i; ++next; - command_remove_note(*i); const boost::shared_ptr copy(new Note(*(*i)->note().get())); // we need to snap here again in nframes_t in order to be sample accurate @@ -948,12 +947,12 @@ MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote) copy->set_note(new_pitch); + command_remove_note(*i); command_add_note(copy); _marked_for_selection.insert(copy); i = next; } - apply_command(); // care about notes being moved beyond the upper/lower bounds on the canvas diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index b6cdac1864..af506e1f08 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -83,7 +83,6 @@ public: inline size_t n_notes() const { return _notes.size(); } inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; } - /* FIXME: use better data structure */ typedef std::vector< boost::shared_ptr > Notes; inline static bool note_time_comparator (const boost::shared_ptr a, @@ -188,8 +187,8 @@ public: const_iterator begin() const { return const_iterator(*this, 0); } const const_iterator& end() const { return _end_iter; } - const MidiSource *midi_source() const { return _midi_source; } - void set_midi_source(MidiSource *source) { _midi_source = source; } + const MidiSource *midi_source() const; + void set_midi_source(MidiSource *source); private: friend class DeltaCommand; diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 439be8a481..b073d9c678 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -386,6 +386,8 @@ MidiModel::end_write(bool delete_stuck) if ((*n)->duration() == 0) { cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl; n = _notes.erase(n); + // we have to break here because erase invalidates the iterator + break; } else { ++n; } @@ -521,11 +523,19 @@ MidiModel::remove_note_unlocked(const boost::shared_ptr note) { //cerr << "MidiModel " << this << " remove note " << (int)note.note() << " @ " << note.time() << endl; for(Notes::iterator n = _notes.begin(); n != _notes.end(); ++n) { - if(**n == *note) { + Note _n = *(*n); + Note _note =*note; + cerr << "======================================= " << endl; + cerr << int(_n.note()) << "@" << int(_n.time()) << "[" << int(_n.channel()) << "] --" << int(_n.duration()) << "-- #" << int(_n.velocity()) << endl; + cerr << int(_note.note()) << "@" << int(_note.time()) << "[" << int(_note.channel()) << "] --" << int(_note.duration()) << "-- #" << int(_note.velocity()) << endl; + cerr << "Equal: " << bool(_n == _note) << endl; + cerr << endl << endl; + if(_n == _note) { _notes.erase(n); - } + // we have to break here, because erase invalidates all iterators, ie. n itself + break; + } } - } /** Slow! for debugging only. */ @@ -840,3 +850,14 @@ MidiModel::get_state() return *node; } +const MidiSource * +MidiModel::midi_source() const +{ + return _midi_source; +} + +void +MidiModel::set_midi_source(MidiSource *source) +{ + _midi_source = source; +} diff --git a/libs/midi++2/midi++/event.h b/libs/midi++2/midi++/event.h index cce17b0625..b718267704 100644 --- a/libs/midi++2/midi++/event.h +++ b/libs/midi++2/midi++/event.h @@ -167,10 +167,10 @@ struct Event { inline uint32_t& size() { return _size; } inline uint8_t type() const { return (_buffer[0] & 0xF0); } inline uint8_t channel() const { return (_buffer[0] & 0x0F); } - inline void set_channel(uint8_t channel) { _buffer[0] = (0xF0 & _buffer[0]) | channel; } - inline bool is_note_on() const { return (type() == MIDI_CMD_NOTE_ON); } - inline bool is_note_off() const { return (type() == MIDI_CMD_NOTE_OFF); } - inline bool is_cc() const { return (type() == MIDI_CMD_CONTROL); } + inline void set_channel(uint8_t channel) { _buffer[0] = (0xF0 & _buffer[0]) | (0x0F & channel); } + inline bool is_note_on() const { return (type() == MIDI_CMD_NOTE_ON); } + inline bool is_note_off() const { return (type() == MIDI_CMD_NOTE_OFF); } + inline bool is_cc() const { return (type() == MIDI_CMD_CONTROL); } inline bool is_note() const { return (is_note_on() || is_note_off()); } inline uint8_t note() const { return (_buffer[1]); } inline uint8_t velocity() const { return (_buffer[2]); }