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
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
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,
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;
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;
}
{
//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. */
return *node;
}
+const MidiSource *
+MidiModel::midi_source() const
+{
+ return _midi_source;
+}
+
+void
+MidiModel::set_midi_source(MidiSource *source)
+{
+ _midi_source = source;
+}
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]); }