summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/automation_region_view.cc19
-rw-r--r--gtk2_ardour/automation_time_axis.cc16
-rw-r--r--libs/ardour/ardour/automation_list.h2
-rw-r--r--libs/ardour/automation_list.cc27
-rw-r--r--libs/evoral/evoral/ControlList.hpp2
-rw-r--r--libs/evoral/src/ControlList.cpp2
6 files changed, 60 insertions, 8 deletions
diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc
index e3e41b4428..ce1cd1498d 100644
--- a/gtk2_ardour/automation_region_view.cc
+++ b/gtk2_ardour/automation_region_view.cc
@@ -210,6 +210,8 @@ AutomationRegionView::paste (framepos_t pos
float times,
boost::shared_ptr<const ARDOUR::AutomationList> slist)
{
+ using namespace ARDOUR;
+
AutomationTimeAxisView* const view = automation_view();
boost::shared_ptr<ARDOUR::AutomationList> my_list = _line->the_list();
@@ -218,15 +220,24 @@ AutomationRegionView::paste (framepos_t pos
return false;
}
+ AutomationType src_type = (AutomationType)slist->parameter().type ();
+ double len = slist->length();
+
/* add multi-paste offset if applicable */
- pos += view->editor().get_paste_offset(
- pos, paste_count, _source_relative_time_converter.to(slist->length()));
+ if (parameter_is_midi (src_type)) {
+ // convert length to samples (incl tempo-ramps)
+ len = DoubleBeatsFramesConverter (view->session()->tempo_map(), pos).to (len * paste_count);
+ pos += view->editor ().get_paste_offset (pos, paste_count > 0 ? 1 : 0, len);
+ } else {
+ pos += view->editor ().get_paste_offset (pos, paste_count, len);
+ }
- const double model_pos = _source_relative_time_converter.from(
+ /* convert sample-position to model's unit and position */
+ const double model_pos = _source_relative_time_converter.from (
pos - _source_relative_time_converter.origin_b());
XMLNode& before = my_list->get_state();
- my_list->paste(*slist, model_pos, times);
+ my_list->paste(*slist, model_pos, DoubleBeatsFramesConverter (view->session()->tempo_map(), pos));
view->session()->add_command(
new MementoCommand<ARDOUR::AutomationList>(_line->memento_command_binder(), &before, &my_list->get_state()));
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc
index cb8456e062..0b71e423cd 100644
--- a/gtk2_ardour/automation_time_axis.cc
+++ b/gtk2_ardour/automation_time_axis.cc
@@ -29,6 +29,7 @@
#include "pbd/types_convert.h"
#include "ardour/automation_control.h"
+#include "ardour/beats_frames_converter.h"
#include "ardour/event_type_map.h"
#include "ardour/parameter_types.h"
#include "ardour/profile.h"
@@ -695,12 +696,23 @@ AutomationTimeAxisView::paste_one (framepos_t pos, unsigned paste_count, float t
counts.increase_n_lines(_parameter);
/* add multi-paste offset if applicable */
- pos += _editor.get_paste_offset(pos, paste_count, (*p)->length());
+ AutomationType src_type = (AutomationType)(*p)->parameter().type ();
+ double len = (*p)->length();
+
+ if (parameter_is_midi (src_type)) {
+ // convert length to samples (incl tempo-ramps)
+ len = DoubleBeatsFramesConverter (_session->tempo_map(), pos).to (len * paste_count);
+ pos += _editor.get_paste_offset (pos, paste_count > 0 ? 1 : 0, len);
+ } else {
+ pos += _editor.get_paste_offset (pos, paste_count, len);
+ }
+
+ /* convert sample-position to model's unit and position */
double const model_pos = _line->time_converter().from (pos - _line->time_converter().origin_b ());
XMLNode &before = alist->get_state();
- alist->paste (**p, model_pos, times);
+ alist->paste (**p, model_pos, DoubleBeatsFramesConverter (_session->tempo_map(), pos));
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
return true;
diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h
index ca72f5f01f..3f4d3f2f52 100644
--- a/libs/ardour/ardour/automation_list.h
+++ b/libs/ardour/ardour/automation_list.h
@@ -40,6 +40,7 @@
namespace ARDOUR {
class AutomationList;
+class DoubleBeatsFramesConverter;
/** A SharedStatefulProperty for AutomationLists */
class LIBARDOUR_API AutomationListProperty : public PBD::SharedStatefulProperty<AutomationList>
@@ -81,6 +82,7 @@ class LIBARDOUR_API AutomationList : public Evoral::ControlList, public PBD::Sta
AutomationList& operator= (const AutomationList&);
void thaw ();
+ bool paste (const ControlList&, double, DoubleBeatsFramesConverter const&);
void set_automation_state (AutoState);
AutoState automation_state() const { return _state; }
diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc
index c397323767..0d43298610 100644
--- a/libs/ardour/automation_list.cc
+++ b/libs/ardour/automation_list.cc
@@ -24,8 +24,10 @@
#include <sstream>
#include <algorithm>
#include "ardour/automation_list.h"
+#include "ardour/beats_frames_converter.h"
#include "ardour/event_type_map.h"
#include "ardour/parameter_descriptor.h"
+#include "ardour/parameter_types.h"
#include "ardour/evoral_types_convert.h"
#include "ardour/types_convert.h"
#include "evoral/Curve.hpp"
@@ -289,6 +291,31 @@ AutomationList::thaw ()
}
}
+bool
+AutomationList::paste (const ControlList& alist, double pos, DoubleBeatsFramesConverter const& bfc)
+{
+ AutomationType src_type = (AutomationType)alist.parameter().type();
+ AutomationType dst_type = (AutomationType)_parameter.type();
+
+ if (parameter_is_midi (src_type) == parameter_is_midi (dst_type)) {
+ return ControlList::paste (alist, pos);
+ }
+ bool to_frame = parameter_is_midi (src_type);
+
+ ControlList cl (alist);
+ cl.clear ();
+ for (const_iterator i = alist.begin ();i != alist.end (); ++i) {
+ double when = (*i)->when;
+ if (to_frame) {
+ when = bfc.to ((*i)->when);
+ } else {
+ when = bfc.from ((*i)->when);
+ }
+ cl.fast_simple_add (when, (*i)->value);
+ }
+ return ControlList::paste (cl, pos);
+}
+
Command*
AutomationList::memento_command (XMLNode* before, XMLNode* after)
{
diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp
index 8e72c21c48..b58c186c21 100644
--- a/libs/evoral/evoral/ControlList.hpp
+++ b/libs/evoral/evoral/ControlList.hpp
@@ -172,7 +172,7 @@ public:
*/
void clear (double start, double end);
- bool paste (const ControlList&, double position, float times);
+ bool paste (const ControlList&, double position);
void set_yrange (double min, double max) {
_min_yval = min;
diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp
index 0b2184a972..ce8ea89fc9 100644
--- a/libs/evoral/src/ControlList.cpp
+++ b/libs/evoral/src/ControlList.cpp
@@ -1652,7 +1652,7 @@ ControlList::clear (double start, double end)
/** @param pos Position in model coordinates */
bool
-ControlList::paste (const ControlList& alist, double pos, float /*times*/)
+ControlList::paste (const ControlList& alist, double pos)
{
if (alist._events.empty()) {
return false;