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,14 +365,18 @@ 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,
@ -380,7 +384,7 @@ Automatable::transport_stopped (framepos_t now)
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); l->write_pass_finished (now, Config->get_automation_thinning_factor());
if (l->automation_playback()) { if (l->automation_playback()) {
c->set_value(c->list()->eval(now)); c->set_value(c->list()->eval(now));
@ -391,8 +395,6 @@ Automatable::transport_stopped (framepos_t now)
} }
} }
} }
}
}
boost::shared_ptr<Evoral::Control> boost::shared_ptr<Evoral::Control>
Automatable::control_factory(const Evoral::Parameter& param) Automatable::control_factory(const Evoral::Parameter& param)

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
{ {