From 94fa9278614557effadb5fea8a2387ea29d1cdb6 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 7 Jun 2014 17:43:12 +0200 Subject: [PATCH] limit automation event density - fixes #5928 Constrain control points to one per tick (1/1920 beats). Prior to this it was possible to set two values to the same time (interpolation and iteration failed). --- gtk2_ardour/automation_line.cc | 22 +++++++++++++++++++--- gtk2_ardour/automation_line.h | 3 ++- libs/evoral/src/ControlList.cpp | 8 +++++++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 7e37c32eb7..b0cc6eeea3 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -39,6 +39,7 @@ #include "ardour/automation_list.h" #include "ardour/dB.h" #include "ardour/debug.h" +#include "ardour/tempo.h" #include "evoral/Curve.hpp" @@ -520,11 +521,12 @@ AutomationLine::ContiguousControlPoints::ContiguousControlPoints (AutomationLine } void -AutomationLine::ContiguousControlPoints::compute_x_bounds () +AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e) { uint32_t sz = size(); if (sz > 0 && sz < line.npoints()) { + const TempoMap& map (e.session()->tempo_map()); /* determine the limits on x-axis motion for this contiguous range of control points @@ -532,14 +534,28 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds () if (front()->view_index() > 0) { before_x = line.nth (front()->view_index() - 1)->get_x(); + + const framepos_t pos = e.pixel_to_sample(before_x); + const Meter& meter = map.meter_at (pos); + const framecnt_t len = ceil(meter.frames_per_bar (map.tempo_at (pos), e.session()->frame_rate()) / 1920.0 / meter.divisions_per_bar()); + const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len); + + before_x += one_tick_in_pixels; } /* if our last point has a point after it in the line, we have an "after" bound */ - if (back()->view_index() < (line.npoints() - 2)) { + if (back()->view_index() < (line.npoints() - 1)) { after_x = line.nth (back()->view_index() + 1)->get_x(); + + const framepos_t pos = e.pixel_to_sample(after_x); + const Meter& meter = map.meter_at (pos); + const framecnt_t len = ceil(meter.frames_per_bar (map.tempo_at (pos), e.session()->frame_rate()) / 1920.0 / meter.divisions_per_bar()); + const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len); + + after_x -= one_tick_in_pixels; } } } @@ -643,7 +659,7 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool } for (vector::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) { - (*ccp)->compute_x_bounds (); + (*ccp)->compute_x_bounds (trackview.editor()); } } diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index dcd81c8b4e..67e8fbc52b 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -47,6 +47,7 @@ class TimeAxisView; class AutomationTimeAxisView; class Selectable; class Selection; +class PublicEditor; /** A GUI representation of an ARDOUR::AutomationList */ @@ -183,7 +184,7 @@ public: ContiguousControlPoints (AutomationLine& al); double clamp_dx (double dx); void move (double dx, double dy); - void compute_x_bounds (); + void compute_x_bounds (PublicEditor& e); private: AutomationLine& line; double before_x; diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 4b7704fff1..e507318214 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -1446,7 +1446,13 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double& x, do assert(inclusive ? x >= start : x > start); return true; } else { - return false; + if (inclusive) { + x = next->when; + } else { + x = start; + } + _search_cache.left = x; + return true; } /* No points in the future, so no steps (towards them) in the future */ -- 2.30.2