fix (?) behaviour when punching into automation write mode while the transport is moving, hopefully without breaking anything else

This commit is contained in:
Paul Davis 2013-04-02 16:10:51 -04:00
parent 1d48fb011e
commit 04cba6eca0
3 changed files with 79 additions and 66 deletions

View file

@ -72,8 +72,10 @@ AutomationWatch::add_automation_watch (boost::shared_ptr<AutomationControl> ac)
*/ */
if (_session && _session->transport_rolling() && ac->alist()->automation_write()) { if (_session && _session->transport_rolling() && ac->alist()->automation_write()) {
DEBUG_TRACE (DEBUG::Automation, string_compose ("\ttransport is rolling @ %1, so enter write pass\n", _session->transport_speed())); DEBUG_TRACE (DEBUG::Automation, string_compose ("\ttransport is rolling @ %1, audible = %2so enter write pass\n",
ac->list()->set_in_write_pass (true); _session->transport_speed(), _session->audible_frame()));
/* add a guard point since we are already moving */
ac->list()->set_in_write_pass (true, true, _session->audible_frame());
} }
/* we can't store shared_ptr<Destructible> in connections because it /* we can't store shared_ptr<Destructible> in connections because it

View file

@ -83,6 +83,8 @@ public:
virtual boost::shared_ptr<ControlList> create(Parameter id); virtual boost::shared_ptr<ControlList> create(Parameter id);
void dump (std::ostream&);
ControlList& operator= (const ControlList&); ControlList& operator= (const ControlList&);
bool operator== (const ControlList&); bool operator== (const ControlList&);
void copy_events (const ControlList&); void copy_events (const ControlList&);
@ -238,7 +240,7 @@ public:
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);
void set_in_write_pass (bool); void set_in_write_pass (bool, bool add_point = false, double when = 0.0);
bool in_write_pass () const; bool in_write_pass () const;
/** Emitted when mark_dirty() is called on this object */ /** Emitted when mark_dirty() is called on this object */
@ -292,6 +294,7 @@ protected:
bool did_write_during_pass; bool did_write_during_pass;
bool _in_write_pass; bool _in_write_pass;
void unlocked_invalidate_insert_iterator (); void unlocked_invalidate_insert_iterator ();
void add_guard_point (double when);
}; };
} // namespace Evoral } // namespace Evoral

View file

@ -366,9 +366,68 @@ ControlList::write_pass_finished (double /*when*/)
} }
void void
ControlList::set_in_write_pass (bool yn) ControlList::set_in_write_pass (bool yn, bool add_point, double when)
{ {
_in_write_pass = yn; _in_write_pass = yn;
if (yn && add_point) {
add_guard_point (when);
}
}
void
ControlList::add_guard_point (double when)
{
ControlEvent cp (when, 0.0);
most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 ADD GUARD POINT @ %2looked up insert iterator for new write pass\n", this, when));
double eval_value = unlocked_eval (insert_position);
if (most_recent_insert_iterator == _events.end()) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at end, adding eval-value there %2\n", this, eval_value));
_events.push_back (new ControlEvent (when, eval_value));
/* leave insert iterator at the end */
} else if ((*most_recent_insert_iterator)->when == when) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at existing point, setting eval-value there %2\n", this, eval_value));
/* most_recent_insert_iterator points to a control event
already at the insert position, so there is
nothing to do.
... except ...
advance most_recent_insert_iterator so that the "real"
insert occurs in the right place, since it
points to the control event just inserted.
*/
++most_recent_insert_iterator;
} else {
/* insert a new control event at the right spot
*/
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert eval-value %2 just before iterator @ %3\n",
this, eval_value, (*most_recent_insert_iterator)->when));
most_recent_insert_iterator = _events.insert (most_recent_insert_iterator, new ControlEvent (when, eval_value));
/* advance most_recent_insert_iterator so that the "real"
* insert occurs in the right place, since it
* points to the control event just inserted.
*/
++most_recent_insert_iterator;
}
/* don't do this again till the next write pass */
new_write_pass = false;
} }
bool bool
@ -409,68 +468,7 @@ ControlList::add (double when, double value)
if (_in_write_pass && new_write_pass) { if (_in_write_pass && new_write_pass) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 new write pass, insert pos = %2\n", this, insert_position)); add_guard_point (insert_position);
/* The first addition of a new control event during a
* write pass.
*
* We need to add a new point at insert_position
* corresponding to the (existing, implicit) value there.
*/
/* the insert_iterator is not set, figure out where
* it needs to be.
*/
ControlEvent cp (insert_position, 0.0);
most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 looked up insert iterator for new write pass\n", this));
double eval_value = unlocked_eval (insert_position);
if (most_recent_insert_iterator == _events.end()) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at end, adding eval-value there %2\n", this, eval_value));
_events.push_back (new ControlEvent (insert_position, eval_value));
/* leave insert iterator at the end */
} else if ((*most_recent_insert_iterator)->when == when) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at existing point, setting eval-value there %2\n", this, eval_value));
/* most_recent_insert_iterator points to a control event
already at the insert position, so there is
nothing to do.
... except ...
advance most_recent_insert_iterator so that the "real"
insert occurs in the right place, since it
points to the control event just inserted.
*/
++most_recent_insert_iterator;
} else {
/* insert a new control event at the right spot
*/
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert eval-value %2 just before iterator @ %3\n",
this, eval_value, (*most_recent_insert_iterator)->when));
most_recent_insert_iterator = _events.insert (most_recent_insert_iterator, new ControlEvent (insert_position, eval_value));
/* advance most_recent_insert_iterator so that the "real"
* insert occurs in the right place, since it
* points to the control event just inserted.
*/
++most_recent_insert_iterator;
}
/* don't do this again till the next write pass */
new_write_pass = false;
did_write_during_pass = true; did_write_during_pass = true;
} else if (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when) { } else if (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when) {
@ -1725,5 +1723,15 @@ ControlList::operator!= (ControlList const & other) const
); );
} }
void
ControlList::dump (ostream& o)
{
/* NOT LOCKED ... for debugging only */
for (EventList::iterator x = _events.begin(); x != _events.end(); ++x) {
o << (*x)->value << " @ " << (*x)->when << endl;
}
}
} // namespace Evoral } // namespace Evoral