13
0

Replace thinning static state with parameter.

This commit is contained in:
David Robillard 2014-11-30 22:18:18 -05:00
parent b68fd1cc25
commit 7eb4e5d22b
4 changed files with 47 additions and 57 deletions

View File

@ -365,32 +365,34 @@ void
Automatable::transport_stopped (framepos_t now) Automatable::transport_stopped (framepos_t now)
{ {
for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) { for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
boost::shared_ptr<AutomationControl> c =
boost::dynamic_pointer_cast<AutomationControl>(li->second);
if (!c) {
continue;
}
boost::shared_ptr<AutomationControl> c boost::shared_ptr<AutomationList> l =
= boost::dynamic_pointer_cast<AutomationControl>(li->second); boost::dynamic_pointer_cast<AutomationList>(c->list());
if (c) { if (!l) {
boost::shared_ptr<AutomationList> l continue;
= boost::dynamic_pointer_cast<AutomationList>(c->list()); }
if (l) { /* Stop any active touch gesture just before we mark the write pass
/* Stop any active touch gesture just before we mark the write pass as finished. If we don't do this, the transport can end up stopped with
as finished. If we don't do this, the transport can end up stopped with an AutomationList thinking that a touch is still in progress and,
an AutomationList thinking that a touch is still in progress and, when the transport is re-started, a touch will magically
when the transport is re-started, a touch will magically be happening without it ever have being started in the usual way.
be happening without it ever have being started in the usual way. */
*/ l->stop_touch (true, now);
l->stop_touch (true, now); l->write_pass_finished (now, Config->get_automation_thinning_factor());
l->write_pass_finished (now);
if (l->automation_playback()) { if (l->automation_playback()) {
c->set_value(c->list()->eval(now)); c->set_value(c->list()->eval(now));
} }
if (l->automation_state() == Write) { if (l->automation_state() == Write) {
l->set_automation_state (Touch); l->set_automation_state (Touch);
} }
}
}
} }
} }

View File

@ -3503,8 +3503,6 @@ Session::config_changed (std::string p, bool ours)
last_timecode_valid = false; last_timecode_valid = false;
} else if (p == "playback-buffer-seconds") { } else if (p == "playback-buffer-seconds") {
AudioSource::allocate_working_buffers (frame_rate()); AudioSource::allocate_working_buffers (frame_rate());
} else if (p == "automation-thinning-factor") {
Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
} else if (p == "ltc-source-port") { } else if (p == "ltc-source-port") {
reconnect_ltc_input (); reconnect_ltc_input ();
} else if (p == "ltc-sink-port") { } else if (p == "ltc-sink-port") {

View File

@ -131,7 +131,20 @@ public:
bool move_ranges (std::list< RangeMove<double> > const &); bool move_ranges (std::list< RangeMove<double> > const &);
void modify (iterator, double, double); void modify (iterator, double, double);
void thin (); /** Thin the number of events in this list.
*
* The thinning factor has no units but corresponds to the area of a
* triangle computed between three points in the list. If the area is
* large, it indicates significant non-linearity between the points.
*
* During automation recording we thin the recorded points using this
* value. If a point is sufficiently co-linear with its neighbours (as
* defined by the area of the triangle formed by three of them), we will
* not include it in the list. The larger the value, the more points are
* excluded, so this effectively measures the amount of thinning to be
* done.
*/
void thin (double thinning_factor);
boost::shared_ptr<ControlList> cut (double, double); boost::shared_ptr<ControlList> cut (double, double);
boost::shared_ptr<ControlList> copy (double, double); boost::shared_ptr<ControlList> copy (double, double);
@ -245,7 +258,7 @@ public:
virtual bool writing() const { return false; } virtual bool writing() const { return false; }
virtual bool touch_enabled() const { return false; } virtual bool touch_enabled() const { return false; }
void start_write_pass (double time); void start_write_pass (double time);
void write_pass_finished (double when); void write_pass_finished (double when, double thinning_factor=0.0);
void set_in_write_pass (bool, bool add_point = false, double when = 0.0); void set_in_write_pass (bool, bool add_point = false, double when = 0.0);
bool in_write_pass () const; bool in_write_pass () const;
@ -254,9 +267,6 @@ public:
/** Emitted when our interpolation style changes */ /** Emitted when our interpolation style changes */
PBD::Signal1<void, InterpolationStyle> InterpolationChanged; PBD::Signal1<void, InterpolationStyle> InterpolationChanged;
static void set_thinning_factor (double d);
static double thinning_factor() { return _thinning_factor; }
bool operator!= (ControlList const &) const; bool operator!= (ControlList const &) const;
void invalidate_insert_iterator (); void invalidate_insert_iterator ();
@ -291,8 +301,6 @@ protected:
Curve* _curve; Curve* _curve;
static double _thinning_factor;
private: private:
iterator most_recent_insert_iterator; iterator most_recent_insert_iterator;
double insert_position; double insert_position;

View File

@ -36,22 +36,6 @@ inline bool event_time_less_than (ControlEvent* a, ControlEvent* b)
return a->when < b->when; return a->when < b->when;
} }
/* this has no units but corresponds to the area of a rectangle
computed between three points in the list. If the area is
large, it indicates significant non-linearity between the
points.
during automation recording we thin the recorded points
using this value. if a point is sufficiently co-linear
with its neighbours (as defined by the area of the rectangle
formed by three of them), we will not include it in the
ControlList. a smaller value will exclude less points,
a larger value will exclude more points, so it effectively
measures the amount of thinning to be done.
*/
double ControlList::_thinning_factor = 20.0;
ControlList::ControlList (const Parameter& id) ControlList::ControlList (const Parameter& id)
: _parameter(id) : _parameter(id)
, _interpolation(id.toggled() ? Discrete : Linear) , _interpolation(id.toggled() ? Discrete : Linear)
@ -258,8 +242,12 @@ struct ControlEventTimeComparator {
}; };
void void
ControlList::thin () ControlList::thin (double thinning_factor)
{ {
if (thinning_factor == 0.0) {
return;
}
bool changed = false; bool changed = false;
{ {
@ -287,7 +275,7 @@ ControlList::thin ()
(prev->when * (cur->value - prevprev->value)) + (prev->when * (cur->value - prevprev->value)) +
(cur->when * (prevprev->value - prev->value))); (cur->when * (prevprev->value - prev->value)));
if (area < _thinning_factor) { if (area < thinning_factor) {
iterator tmp = pprev; iterator tmp = pprev;
/* pprev will change to current /* pprev will change to current
@ -364,12 +352,12 @@ ControlList::start_write_pass (double when)
} }
void void
ControlList::write_pass_finished (double /*when*/) ControlList::write_pass_finished (double /*when*/, double thinning_factor)
{ {
DEBUG_TRACE (DEBUG::ControlList, "write pass finished\n"); DEBUG_TRACE (DEBUG::ControlList, "write pass finished\n");
if (did_write_during_pass) { if (did_write_during_pass) {
thin (); thin (thinning_factor);
did_write_during_pass = false; did_write_during_pass = false;
} }
new_write_pass = true; new_write_pass = true;
@ -1738,12 +1726,6 @@ ControlList::set_interpolation (InterpolationStyle s)
InterpolationChanged (s); /* EMIT SIGNAL */ InterpolationChanged (s); /* EMIT SIGNAL */
} }
void
ControlList::set_thinning_factor (double v)
{
_thinning_factor = v;
}
bool bool
ControlList::operator!= (ControlList const & other) const ControlList::operator!= (ControlList const & other) const
{ {