mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
* 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
This commit is contained in:
parent
8b3d298f6b
commit
c4bdcb82af
4 changed files with 31 additions and 12 deletions
|
|
@ -914,7 +914,6 @@ MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote)
|
||||||
Selection::iterator next = i;
|
Selection::iterator next = i;
|
||||||
++next;
|
++next;
|
||||||
|
|
||||||
command_remove_note(*i);
|
|
||||||
const boost::shared_ptr<Note> copy(new Note(*(*i)->note().get()));
|
const boost::shared_ptr<Note> copy(new Note(*(*i)->note().get()));
|
||||||
|
|
||||||
// we need to snap here again in nframes_t in order to be sample accurate
|
// 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);
|
copy->set_note(new_pitch);
|
||||||
|
|
||||||
|
command_remove_note(*i);
|
||||||
command_add_note(copy);
|
command_add_note(copy);
|
||||||
|
|
||||||
_marked_for_selection.insert(copy);
|
_marked_for_selection.insert(copy);
|
||||||
i = next;
|
i = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_command();
|
apply_command();
|
||||||
|
|
||||||
// care about notes being moved beyond the upper/lower bounds on the canvas
|
// care about notes being moved beyond the upper/lower bounds on the canvas
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@ public:
|
||||||
inline size_t n_notes() const { return _notes.size(); }
|
inline size_t n_notes() const { return _notes.size(); }
|
||||||
inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; }
|
inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; }
|
||||||
|
|
||||||
/* FIXME: use better data structure */
|
|
||||||
typedef std::vector< boost::shared_ptr<Note> > Notes;
|
typedef std::vector< boost::shared_ptr<Note> > Notes;
|
||||||
|
|
||||||
inline static bool note_time_comparator (const boost::shared_ptr<const Note> a,
|
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_iterator begin() const { return const_iterator(*this, 0); }
|
||||||
const const_iterator& end() const { return _end_iter; }
|
const const_iterator& end() const { return _end_iter; }
|
||||||
|
|
||||||
const MidiSource *midi_source() const { return _midi_source; }
|
const MidiSource *midi_source() const;
|
||||||
void set_midi_source(MidiSource *source) { _midi_source = source; }
|
void set_midi_source(MidiSource *source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class DeltaCommand;
|
friend class DeltaCommand;
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,8 @@ MidiModel::end_write(bool delete_stuck)
|
||||||
if ((*n)->duration() == 0) {
|
if ((*n)->duration() == 0) {
|
||||||
cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl;
|
cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl;
|
||||||
n = _notes.erase(n);
|
n = _notes.erase(n);
|
||||||
|
// we have to break here because erase invalidates the iterator
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
++n;
|
++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;
|
//cerr << "MidiModel " << this << " remove note " << (int)note.note() << " @ " << note.time() << endl;
|
||||||
for(Notes::iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
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);
|
_notes.erase(n);
|
||||||
}
|
// we have to break here, because erase invalidates all iterators, ie. n itself
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Slow! for debugging only. */
|
/** Slow! for debugging only. */
|
||||||
|
|
@ -840,3 +850,14 @@ MidiModel::get_state()
|
||||||
return *node;
|
return *node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MidiSource *
|
||||||
|
MidiModel::midi_source() const
|
||||||
|
{
|
||||||
|
return _midi_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiModel::set_midi_source(MidiSource *source)
|
||||||
|
{
|
||||||
|
_midi_source = source;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,10 +167,10 @@ struct Event {
|
||||||
inline uint32_t& size() { return _size; }
|
inline uint32_t& size() { return _size; }
|
||||||
inline uint8_t type() const { return (_buffer[0] & 0xF0); }
|
inline uint8_t type() const { return (_buffer[0] & 0xF0); }
|
||||||
inline uint8_t channel() const { return (_buffer[0] & 0x0F); }
|
inline uint8_t channel() const { return (_buffer[0] & 0x0F); }
|
||||||
inline void set_channel(uint8_t channel) { _buffer[0] = (0xF0 & _buffer[0]) | channel; }
|
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_on() const { return (type() == MIDI_CMD_NOTE_ON); }
|
||||||
inline bool is_note_off() const { return (type() == MIDI_CMD_NOTE_OFF); }
|
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_cc() const { return (type() == MIDI_CMD_CONTROL); }
|
||||||
inline bool is_note() const { return (is_note_on() || is_note_off()); }
|
inline bool is_note() const { return (is_note_on() || is_note_off()); }
|
||||||
inline uint8_t note() const { return (_buffer[1]); }
|
inline uint8_t note() const { return (_buffer[1]); }
|
||||||
inline uint8_t velocity() const { return (_buffer[2]); }
|
inline uint8_t velocity() const { return (_buffer[2]); }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue