diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-09-07 13:38:06 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-09-07 13:38:06 +0000 |
commit | 79dc191d6bcd61a81765ce2563a9c325b97c4ed8 (patch) | |
tree | 3393ee104c69c9e83aaf9e4e9508e6adb4393c14 | |
parent | 837bfc9af44c5b6c1eeb14e7af8d9ec62c59aac6 (diff) |
add anonymous union to DiffCommand to allow uint8t_t and time-based arguments; use DiffCommand for note trimming
git-svn-id: svn://localhost/ardour2/branches/3.0@5638 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 80 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_model.h | 12 | ||||
-rw-r--r-- | libs/ardour/midi_model.cc | 41 |
4 files changed, 100 insertions, 34 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index d0ec389262..f87cc50d4e 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -614,8 +614,18 @@ MidiRegionView::delta_remove_note(ArdourCanvas::CanvasNoteEvent* ev) void MidiRegionView::diff_add_change (ArdourCanvas::CanvasNoteEvent* ev, - MidiModel::DiffCommand::Property property, - uint8_t val) + MidiModel::DiffCommand::Property property, + uint8_t val) +{ + if (_diff_command) { + _diff_command->change (ev->note(), property, val); + } +} + +void +MidiRegionView::diff_add_change (ArdourCanvas::CanvasNoteEvent* ev, + MidiModel::DiffCommand::Property property, + Evoral::MusicalTime val) { if (_diff_command) { _diff_command->change (ev->note(), property, val); @@ -1832,6 +1842,11 @@ MidiRegionView::change_note_note (CanvasNoteEvent* event, int8_t note, bool rela void MidiRegionView::trim_note (CanvasNoteEvent* event, Evoral::MusicalTime front_delta, Evoral::MusicalTime end_delta) { + bool change_start = false; + bool change_length = false; + Evoral::MusicalTime new_start; + Evoral::MusicalTime new_length; + /* NOTE: the semantics of the two delta arguments are slightly subtle: front_delta: if positive - move the start of the note later in time (shortening it) @@ -1841,48 +1856,61 @@ MidiRegionView::trim_note (CanvasNoteEvent* event, Evoral::MusicalTime front_del if negative - move the end of the note earlier in time (shortening it) */ - const boost::shared_ptr<NoteType> copy(new NoteType(*(event->note().get()))); - cerr << "Trim front by " << front_delta << " end by " << end_delta << endl; if (front_delta) { if (front_delta < 0) { - if (copy->time() < -front_delta) { - copy->set_time (0); + + if (event->note()->time() < -front_delta) { + new_start = 0; } else { - copy->set_time (copy->time() + front_delta); // moves earlier + new_start = event->note()->time() + front_delta; // moves earlier } + /* start moved toward zero, so move the end point out to where it used to be. Note that front_delta is negative, so this increases the length. - */ - copy->set_length (copy->length() - front_delta); - } else { - Evoral::MusicalTime new_pos = copy->time() + front_delta; + */ - if (new_pos >= copy->end_time()) { - return; - } + new_length = event->note()->length() - front_delta; + change_start = true; + change_length = true; - copy->set_time (copy->time() + front_delta); + } else { - /* start moved toward the end, so move the end point back to where it used to be */ - copy->set_length (copy->length() - front_delta); + Evoral::MusicalTime new_pos = event->note()->time() + front_delta; + + if (new_pos < event->note()->end_time()) { + new_start = event->note()->time() + front_delta; + /* start moved toward the end, so move the end point back to where it used to be */ + new_length = event->note()->length() - front_delta; + change_start = true; + change_length = true; + } } } if (end_delta) { + bool can_change = true; if (end_delta < 0) { - if (copy->length() < -end_delta) { - return; + if (event->note()->length() < -end_delta) { + can_change = false; } + } + + if (can_change) { + new_length = event->note()->length() + end_delta; + change_length = true; } - - copy->set_length (copy->length() + end_delta); } - delta_remove_note(event); - delta_add_note(copy, event->selected(), false); + if (change_start) { + diff_add_change (event, MidiModel::DiffCommand::StartTime, new_start); + } + + if (change_length) { + diff_add_change (event, MidiModel::DiffCommand::Length, new_length); + } } void @@ -2014,8 +2042,8 @@ MidiRegionView::change_note_lengths (bool fine, bool shorter, bool start, bool e if (shorter) { delta = -delta; } - - start_delta_command (_("change note lengths")); + + start_diff_command (_("change note lengths")); for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) { Selection::iterator next = i; @@ -2027,7 +2055,7 @@ MidiRegionView::change_note_lengths (bool fine, bool shorter, bool start, bool e i = next; } - apply_delta (); + apply_diff (); } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 611ba4c142..c855dfeb0f 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -174,6 +174,7 @@ class MidiRegionView : public RegionView void start_diff_command(std::string name = "midi edit"); void diff_add_change(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::DiffCommand::Property, uint8_t val); + void diff_add_change(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::DiffCommand::Property, Evoral::MusicalTime val); void apply_delta(); void apply_diff(); diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 46d4cf794c..460e790323 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -119,6 +119,8 @@ public: void change (const boost::shared_ptr<Evoral::Note<TimeType> > note, Property prop, uint8_t new_value); + void change (const boost::shared_ptr<Evoral::Note<TimeType> > note, + Property prop, TimeType new_time); private: boost::shared_ptr<MidiModel> _model; @@ -127,8 +129,14 @@ public: struct NotePropertyChange { DiffCommand::Property property; boost::shared_ptr<Evoral::Note<TimeType> > note; - uint8_t old_value; - uint8_t new_value; + union { + uint8_t old_value; + TimeType old_time; + }; + union { + uint8_t new_value; + TimeType new_time; + }; }; typedef std::list<NotePropertyChange> ChangeList; diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 60c8829b61..1dc022f274 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -337,10 +337,12 @@ MidiModel::DiffCommand::change(const boost::shared_ptr< Evoral::Note<TimeType> > change.old_value = note->velocity(); break; case StartTime: - change.old_value = note->time(); + fatal << "MidiModel::DiffCommand::change() with integer argument called for start time" << endmsg; + /*NOTREACHED*/ break; case Length: - change.old_value = note->length(); + fatal << "MidiModel::DiffCommand::change() with integer argument called for length" << endmsg; + /*NOTREACHED*/ break; case Channel: change.old_value = note->channel(); @@ -351,6 +353,33 @@ MidiModel::DiffCommand::change(const boost::shared_ptr< Evoral::Note<TimeType> > } void +MidiModel::DiffCommand::change(const boost::shared_ptr< Evoral::Note<TimeType> > note, Property prop, + TimeType new_time) +{ + NotePropertyChange change; + + change.note = note; + change.property = prop; + change.new_time = new_time; + + switch (prop) { + case NoteNumber: + case Channel: + case Velocity: + fatal << "MidiModel::DiffCommand::change() with time argument called for note, channel or velocity" << endmsg; + break; + case StartTime: + change.old_time = note->time(); + break; + case Length: + change.old_time = note->length(); + break; + } + + _changes.push_back (change); +} + +void MidiModel::DiffCommand::operator()() { Glib::Mutex::Lock lm (_model->_midi_source->mutex()); @@ -367,10 +396,10 @@ MidiModel::DiffCommand::operator()() i->note->set_velocity (i->new_value); break; case StartTime: - i->note->set_time (i->new_value); + i->note->set_time (i->new_time); break; case Length: - i->note->set_length (i->new_value); + i->note->set_length (i->new_time); break; case Channel: i->note->set_channel (i->new_value); @@ -399,10 +428,10 @@ MidiModel::DiffCommand::undo() i->note->set_velocity (i->old_value); break; case StartTime: - i->note->set_time (i->old_value); + i->note->set_time (i->old_time); break; case Length: - i->note->set_length (i->old_value); + i->note->set_length (i->old_time); break; case Channel: i->note->set_channel (i->old_value); |