summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-09-07 13:38:06 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-09-07 13:38:06 +0000
commit79dc191d6bcd61a81765ce2563a9c325b97c4ed8 (patch)
tree3393ee104c69c9e83aaf9e4e9508e6adb4393c14
parent837bfc9af44c5b6c1eeb14e7af8d9ec62c59aac6 (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.cc80
-rw-r--r--gtk2_ardour/midi_region_view.h1
-rw-r--r--libs/ardour/ardour/midi_model.h12
-rw-r--r--libs/ardour/midi_model.cc41
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);