Adapt range when copying between automation types.
authorDavid Robillard <d@drobilla.net>
Sat, 6 Dec 2014 18:37:08 +0000 (13:37 -0500)
committerDavid Robillard <d@drobilla.net>
Sat, 6 Dec 2014 18:40:35 +0000 (13:40 -0500)
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...

gtk2_ardour/editor_ops.cc
libs/evoral/evoral/Parameter.hpp
libs/evoral/src/ControlList.cpp

index c84bae6ad44e41e0cdf776499af6c1902d1a469d..69fcf67d16e2526e38a79211fbd5a792c1dab18f 100644 (file)
@@ -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);
index c870fa8e99f6e49ae295cd99b3a8a62c2f421173..1412699b4d2fab28c4b92b53f03d021d6a918b5e 100644 (file)
@@ -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.
index 61bac6148ebcc35fb57bfbe415c45d979ea00467..70500ba8de0319e0e56b40574dcc9000dd04f7eb 100644 (file)
@@ -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;
                }