summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorHans Baier <hansfbaier@googlemail.com>2008-04-15 23:00:06 +0000
committerHans Baier <hansfbaier@googlemail.com>2008-04-15 23:00:06 +0000
commitc4bdcb82afa95555a036cb1418bf6c74b4d4a2c1 (patch)
treee562fed34d3945934dcc1d4a62a6f53e2929829a /libs
parent8b3d298f6b16fbe819a9b9911e018c811b4914e3 (diff)
* 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
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/midi_model.h5
-rw-r--r--libs/ardour/midi_model.cc27
-rw-r--r--libs/midi++2/midi++/event.h8
3 files changed, 30 insertions, 10 deletions
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<Note> > Notes;
inline static bool note_time_comparator (const boost::shared_ptr<const Note> 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<const Note> 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]); }