* fixed bug: crash because of invalidated iterator while removing midi notes from...
authorHans Baier <hansfbaier@googlemail.com>
Tue, 15 Apr 2008 23:00:06 +0000 (23:00 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Tue, 15 Apr 2008 23:00:06 +0000 (23:00 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@3253 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/midi_region_view.cc
libs/ardour/ardour/midi_model.h
libs/ardour/midi_model.cc
libs/midi++2/midi++/event.h

index 100c38758024f7e9a602fb6ad290b0eb4efd072a..115733e8ed1e691b36c87b05b4de38fb75579325 100644 (file)
@@ -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<Note> 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
index b6cdac186497122db898499ab0e84213a2f727f2..af506e1f085af784c5856ce2774500c6c9c4275e 100644 (file)
@@ -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;
index 439be8a48171f70fc1ff358b4640f7076fa56e09..b073d9c67859d6588879a44637de97b34cf8686e 100644 (file)
@@ -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; 
+} 
index cce17b0625a7f5c63f7579dfd9a5e109113867dd..b718267704d7d63d5402fe90b4e2d925d6cbd186 100644 (file)
@@ -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]); }