summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-12-06 13:37:08 -0500
committerDavid Robillard <d@drobilla.net>2014-12-06 13:40:35 -0500
commit4650912ae36ef79fd342a6e183e0bc205d3326c2 (patch)
tree3af63c1b0dc9dfdbb16441e35b7c0a966c254d3f
parent96a9292a407dd90b85ed6bebae932c096b357ce8 (diff)
Adapt range when copying between automation types.
For things like copying from pitch bender to a CC. Also things like fader to pan, but that seems a bit funny. The conversion probably needs to be a bit smarter here, perhaps taking the normal into consideration...
-rw-r--r--gtk2_ardour/editor_ops.cc27
-rw-r--r--libs/evoral/evoral/Parameter.hpp4
-rw-r--r--libs/evoral/src/ControlList.cpp11
3 files changed, 27 insertions, 15 deletions
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index c84bae6ad4..69fcf67d16 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -4440,26 +4440,25 @@ Editor::paste_internal (framepos_t position, float times)
R1.A1, R1.A2, R2, R2.A1, ... */
}
- if (internal_editing ()) {
+ if (ts.size() == 1 && cut_buffer->lines.size() == 1 &&
+ dynamic_cast<AutomationTimeAxisView*>(ts.front())) {
+ /* Only one line copied, and one automation track selected. Do a
+ "greedy" paste from one automation type to another. */
+
+ begin_reversible_command (Operations::paste);
+
+ PasteContext ctx(paste_count, times, ItemCounts(), true);
+ ts.front()->paste (position, *cut_buffer, ctx);
+
+ commit_reversible_command ();
+
+ } else if (internal_editing ()) {
/* undo/redo is handled by individual tracks/regions */
RegionSelection rs;
get_regions_at (rs, position, ts);
- if (ts.size() == 1 && cut_buffer->lines.size() == 1) {
- AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(ts.front());
- if (atv) {
- /* Only one line, and one automation track selected. Do a
- "greedy" paste from one automation type to another. */
- PasteContext ctx(paste_count, times, ItemCounts(), true);
- begin_reversible_command (Operations::paste);
- atv->paste (position, *cut_buffer, ctx);
- commit_reversible_command ();
- return;
- }
- }
-
PasteContext ctx(paste_count, times, ItemCounts(), false);
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*r);
diff --git a/libs/evoral/evoral/Parameter.hpp b/libs/evoral/evoral/Parameter.hpp
index c870fa8e99..1412699b4d 100644
--- a/libs/evoral/evoral/Parameter.hpp
+++ b/libs/evoral/evoral/Parameter.hpp
@@ -57,6 +57,10 @@ public:
return (_type == id._type && _channel == id._channel && _id == id._id );
}
+ inline bool operator!=(const Parameter& id) const {
+ return !operator==(id);
+ }
+
/** Strict weak ordering
* See: http://www.sgi.com/tech/stl/StrictWeakOrdering.html
* Sort Parameters first according to type then to channel and lastly to ID.
diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp
index 61bac6148e..70500ba8de 100644
--- a/libs/evoral/src/ControlList.cpp
+++ b/libs/evoral/src/ControlList.cpp
@@ -1599,7 +1599,16 @@ ControlList::paste (const ControlList& alist, double pos, float /*times*/)
where = upper_bound (_events.begin(), _events.end(), &cp, time_comparator);
for (const_iterator i = alist.begin();i != alist.end(); ++i) {
- _events.insert (where, new ControlEvent( (*i)->when+pos,( *i)->value));
+ double value = (*i)->value;
+ if (alist.parameter() != parameter()) {
+ const ParameterDescriptor& src_desc = alist.descriptor();
+
+ value -= src_desc.lower; // translate to 0-relative
+ value /= (src_desc.upper - src_desc.lower); // normalize range
+ value *= (_desc.upper - _desc.lower); // scale to our range
+ value += _desc.lower; // translate to our offset
+ }
+ _events.insert (where, new ControlEvent((*i)->when + pos, value));
end = (*i)->when + pos;
}