mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 08:14:58 +01:00
fix (?) behaviour when punching into automation write mode while the transport is moving, hopefully without breaking anything else
This commit is contained in:
parent
1d48fb011e
commit
04cba6eca0
3 changed files with 79 additions and 66 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue