From 86de0386c9aea09e1efef604c695afec7cd7845c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 1 Dec 2014 19:37:05 -0500 Subject: [PATCH] Fix automation write/touch. --- gtk2_ardour/automation_controller.cc | 14 +++-- libs/ardour/automation_control.cc | 11 +++- libs/evoral/src/Control.cpp | 2 +- libs/evoral/src/ControlList.cpp | 77 +++++++++++++--------------- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index a7922d2f00..f4a0d7d2f1 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -208,16 +208,22 @@ AutomationController::toggled () { ArdourButton* but = dynamic_cast(_widget); if (but) { - start_touch(); + if (_controllable->session().transport_rolling()) { + if (_controllable->automation_state() == Touch) { + _controllable->set_automation_state(Write); + } + if (_controllable->list()) { + _controllable->list()->set_in_write_pass(true, false, _controllable->session().audible_frame()); + } + } const bool was_active = _controllable->get_value() >= 0.5; - if (was_active) { + if (was_active && but->get_active()) { _adjustment->set_value(0.0); but->set_active(false); - } else { + } else if (!was_active && !but->get_active()) { _adjustment->set_value(1.0); but->set_active(true); } - end_touch(); } } diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 773fd3f40c..72548f0b1f 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -80,6 +80,9 @@ AutomationControl::set_automation_state (AutoState as) if (_list && as != alist()->automation_state()) { alist()->set_automation_state (as); + if (_desc.toggled) { + return; // No watch for boolean automation + } if (as == Write) { AutomationWatch::instance().add_automation_watch (shared_from_this()); @@ -113,7 +116,9 @@ AutomationControl::start_touch(double when) if (!touching()) { if (alist()->automation_state() == Touch) { alist()->start_touch (when); - AutomationWatch::instance().add_automation_watch (shared_from_this()); + if (!_desc.toggled) { + AutomationWatch::instance().add_automation_watch (shared_from_this()); + } } set_touching (true); } @@ -127,7 +132,9 @@ AutomationControl::stop_touch(bool mark, double when) set_touching (false); if (alist()->automation_state() == Touch) { alist()->stop_touch (mark, when); - AutomationWatch::instance().remove_automation_watch (shared_from_this()); + if (!_desc.toggled) { + AutomationWatch::instance().remove_automation_watch (shared_from_this()); + } } } } diff --git a/libs/evoral/src/Control.cpp b/libs/evoral/src/Control.cpp index b7537c57ed..68858cd145 100644 --- a/libs/evoral/src/Control.cpp +++ b/libs/evoral/src/Control.cpp @@ -59,7 +59,7 @@ Control::set_double (double value, double frame, bool to_list) values and add them to the list, so we we don't need to bother. */ - if (to_list && !_list->in_write_pass()) { + if (to_list && (!_list->in_write_pass() || _list->descriptor().toggled)) { _list->add (frame, value, false); } } diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 27f7bae838..61bac6148e 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -261,7 +261,7 @@ struct ControlEventTimeComparator { void ControlList::thin (double thinning_factor) { - if (thinning_factor == 0.0) { + if (thinning_factor == 0.0 || _desc.toggled) { return; } @@ -485,9 +485,6 @@ void ControlList::maybe_add_insert_guard (double when) { if (most_recent_insert_iterator != _events.end()) { - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase from existing iterator (@end ? %3)\n", - this, (most_recent_insert_iterator == _events.end()))); - if ((*most_recent_insert_iterator)->when - when > 64) { /* Next control point is some distance from where our new point is going to go, so add a new point to avoid changing the shape of @@ -537,7 +534,7 @@ ControlList::erase_from_iterator_to (iterator iter, double when) { while (iter != _events.end()) { if ((*iter)->when < when) { - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase existing @ %2\n", this, (*iter))); + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase existing @ %2\n", this, (*iter)->when)); delete *iter; iter = _events.erase (iter); continue; @@ -556,8 +553,10 @@ ControlList::add (double when, double value, bool with_guards, bool with_default control surface (GUI, MIDI, OSC etc) */ - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 add %2 at %3 w/erase = %4 (new ? %6) at end ? %5\n", - this, value, when, _in_write_pass, (most_recent_insert_iterator == _events.end()), new_write_pass)); + DEBUG_TRACE (DEBUG::ControlList, + string_compose ("@%1 add %2 at %3 guards = %4 write pass = %5 (new? %6) at end? %7\n", + this, value, when, with_guards, _in_write_pass, new_write_pass, + (most_recent_insert_iterator == _events.end()))); { Glib::Threads::Mutex::Lock lm (_lock); ControlEvent cp (when, 0.0f); @@ -565,9 +564,7 @@ ControlList::add (double when, double value, bool with_guards, bool with_default if (_events.empty() && with_default) { - /* as long as the point we're adding is not at zero, - * add an "anchor" point there. - */ + /* empty: add an "anchor" point if the point we're adding past time 0 */ if (when >= 1) { _events.insert (_events.end(), new ControlEvent (0, _default_value)); @@ -577,42 +574,43 @@ ControlList::add (double when, double value, bool with_guards, bool with_default if (_in_write_pass && new_write_pass) { + /* first write in a write pass: add guard point if requested */ + if (with_guards) { add_guard_point (insert_position); did_write_during_pass = true; - } - - } else if (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when) { - - if (_in_write_pass) { - most_recent_insert_iterator = erase_from_iterator_to(most_recent_insert_iterator, when); - if (with_guards) { - maybe_add_insert_guard (when); - } - } else { - - /* not in a write pass: figure out the iterator we should insert in front of */ - - DEBUG_TRACE (DEBUG::ControlList, string_compose ("compute MRI for position %1\n", when)); - ControlEvent cp (when, 0.0f); + /* not adding a guard, but we need to set iterator appropriately */ + const ControlEvent cp (when, 0.0); most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); } + new_write_pass = false; - } else { + } else if (_in_write_pass && + (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when)) { + + /* in write pass: erase from most recent insert to now */ + + if (most_recent_insert_iterator != _events.end()) { + /* advance to avoid deleting the last inserted point itself. */ + ++most_recent_insert_iterator; + } + + most_recent_insert_iterator = erase_from_iterator_to(most_recent_insert_iterator, when); + if (with_guards) { + maybe_add_insert_guard (when); + } + + } else if (!_in_write_pass) { + + /* not in a write pass: figure out the iterator we should insert in front of */ - /* not in a write pass, adding a point within existing - * data: figure out the iterator we should insert in - * front of - */ - DEBUG_TRACE (DEBUG::ControlList, string_compose ("compute(b) MRI for position %1\n", when)); ControlEvent cp (when, 0.0f); most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); } - /* OK, now we're really ready to add a new point - */ + /* OK, now we're really ready to add a new point */ if (most_recent_insert_iterator == _events.end()) { DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 appending new point at end\n", this)); @@ -623,10 +621,8 @@ ControlList::add (double when, double value, bool with_guards, bool with_default DEBUG_TRACE (DEBUG::ControlList, string_compose ("\tactually appended, size now %1\n", _events.size())); } - if (!_in_write_pass) { - most_recent_insert_iterator = _events.end(); - --most_recent_insert_iterator; - } + most_recent_insert_iterator = _events.end(); + --most_recent_insert_iterator; } else if ((*most_recent_insert_iterator)->when == when) { @@ -644,7 +640,7 @@ ControlList::add (double when, double value, bool with_guards, bool with_default * next addition, so make sure we know that. */ - if (_in_write_pass && _events.back()->when == when) { + if (_events.back()->when == when) { most_recent_insert_iterator = _events.end(); } @@ -663,10 +659,7 @@ ControlList::add (double when, double value, bool with_guards, bool with_default if (!done) { EventList::iterator x = _events.insert (most_recent_insert_iterator, new ControlEvent (when, value)); DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 inserted new value before MRI, size now %2\n", this, _events.size())); - - if (!_in_write_pass) { - most_recent_insert_iterator = x; - } + most_recent_insert_iterator = x; } }