diff options
-rw-r--r-- | gtk2_ardour/automation_controller.cc | 15 | ||||
-rw-r--r-- | libs/ardour/ardour/automation_control.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/automation_list.h | 6 | ||||
-rw-r--r-- | libs/ardour/automatable.cc | 7 | ||||
-rw-r--r-- | libs/ardour/automation_control.cc | 23 | ||||
-rw-r--r-- | libs/ardour/automation_list.cc | 24 | ||||
-rw-r--r-- | libs/ardour/route.cc | 10 | ||||
-rw-r--r-- | libs/evoral/evoral/ControlList.hpp | 1 |
8 files changed, 70 insertions, 18 deletions
diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index 1bce94dca2..691e0f3b58 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -196,7 +196,22 @@ void AutomationController::toggled () { ArdourButton* but = dynamic_cast<ArdourButton*>(_widget); + const AutoState as = _controllable->automation_state (); + + const bool to_list = _controllable->list () && _controllable->session().transport_rolling () && (as == Touch || as == Write); + if (but) { + if (_controllable->session().transport_rolling()) { + if (_controllable->automation_state() == Touch && _controllable->list()->in_new_write_pass ()) { + _controllable->alist()->start_write_pass ( _controllable->session().audible_frame()); + } + if (_controllable->list()) { + _controllable->list()->set_in_write_pass(true, false, _controllable->session().audible_frame()); + } + } + + _controllable->set_double (!but->get_active (), _controllable->session ().transport_frame (), to_list); + const bool was_active = _controllable->get_value() >= 0.5; if (was_active && but->get_active()) { _adjustment->set_value(0.0); diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index 5d73e4aef9..c634e3474a 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -95,13 +95,13 @@ public: const ParameterDescriptor& desc() const { return _desc; } const ARDOUR::Session& session() const { return _session; } + void commit_transaction (); protected: ARDOUR::Session& _session; const ParameterDescriptor _desc; - XMLNode* _before; //used for undo of touch start/stop pairs. }; diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h index bc47f2fe06..67ee6234bb 100644 --- a/libs/ardour/ardour/automation_list.h +++ b/libs/ardour/ardour/automation_list.h @@ -97,6 +97,9 @@ class LIBARDOUR_API AutomationList : public PBD::StatefulDestructible, public Ev static PBD::Signal1<void,AutomationList*> AutomationListCreated; + void start_write_pass (double when); + void write_pass_finished (double when, double thinning_factor=0.0); + void start_touch (double when); void stop_touch (bool mark, double when); bool touching() const { return g_atomic_int_get (const_cast<gint*>(&_touching)); } @@ -110,6 +113,7 @@ class LIBARDOUR_API AutomationList : public PBD::StatefulDestructible, public Ev bool operator!= (const AutomationList &) const; + XMLNode* before () { return _before; } private: void create_curve_if_necessary (); int deserialize_events (const XMLNode&); @@ -121,6 +125,8 @@ class LIBARDOUR_API AutomationList : public PBD::StatefulDestructible, public Ev gint _touching; bool operator== (const AutomationList&) const { /* not called */ abort(); return false; } + XMLNode* _before; //used for undo of touch start/stop pairs. + }; } // namespace diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 0b316890bc..1c72f202b2 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -365,7 +365,7 @@ Automatable::transport_located (framepos_t now) boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list()); - if (l) { + if (l && l->automation_state () == Write) { l->start_write_pass (now); } } @@ -394,7 +394,12 @@ Automatable::transport_stopped (framepos_t now) when the transport is re-started, a touch will magically be happening without it ever have being started in the usual way. */ + const bool list_did_write = !l->in_new_write_pass (); + l->stop_touch (true, now); + if (list_did_write) { + c->commit_transaction (); + } l->write_pass_finished (now, Config->get_automation_thinning_factor()); if (l->automation_playback()) { diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 26ea53cbd2..0e2355e708 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -88,8 +88,6 @@ AutomationControl::set_automation_state (AutoState as) } if (as == Write) { - /* get state for undo */ - _before = &alist ()->get_state (); AutomationWatch::instance().add_automation_watch (shared_from_this()); } else if (as == Touch) { if (!touching()) { @@ -127,7 +125,6 @@ AutomationControl::start_touch(double when) if (alist()->automation_state() == Touch) { /* subtle. aligns the user value with the playback */ set_value (get_value ()); - _before = &alist ()->get_state (); alist()->start_touch (when); if (!_desc.toggled) { AutomationWatch::instance().add_automation_watch (shared_from_this()); @@ -144,25 +141,25 @@ AutomationControl::stop_touch(bool mark, double when) if (touching()) { set_touching (false); - if (alist()->automation_state() == Write) { - _session.begin_reversible_command (string_compose (_("write %1 automation"), name ())); - _session.add_command (new MementoCommand<AutomationList> (*alist ().get (), _before, &alist ()->get_state ())); - _session.commit_reversible_command (); - } - if (alist()->automation_state() == Touch) { alist()->stop_touch (mark, when); if (!_desc.toggled) { AutomationWatch::instance().remove_automation_watch (shared_from_this()); - } - _session.begin_reversible_command (string_compose (_("touch %1 automation"), name ())); - _session.add_command (new MementoCommand<AutomationList> (*alist ().get (), _before, &alist ()->get_state ())); - _session.commit_reversible_command (); + } } } } +void +AutomationControl::commit_transaction () +{ + if (alist ()->before ()) { + _session.begin_reversible_command (string_compose (_("record %1 automation"), name ())); + _session.commit_reversible_command (new MementoCommand<AutomationList> (*alist ().get (), alist ()->before (), &alist ()->get_state ())); + } +} + double AutomationControl::internal_to_interface (double val) const { diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc index 91609f6acb..afff85c1f8 100644 --- a/libs/ardour/automation_list.cc +++ b/libs/ardour/automation_list.cc @@ -50,6 +50,7 @@ static void dumpit (const AutomationList& al, string prefix = "") #endif AutomationList::AutomationList (const Evoral::Parameter& id, const Evoral::ParameterDescriptor& desc) : ControlList(id, desc) + , _before (0) { _state = Off; _style = Absolute; @@ -63,6 +64,7 @@ AutomationList::AutomationList (const Evoral::Parameter& id, const Evoral::Param AutomationList::AutomationList (const Evoral::Parameter& id) : ControlList(id, ARDOUR::ParameterDescriptor(id)) + , _before (0) { _state = Off; _style = Absolute; @@ -77,6 +79,7 @@ AutomationList::AutomationList (const Evoral::Parameter& id) AutomationList::AutomationList (const AutomationList& other) : StatefulDestructible() , ControlList(other) + , _before (0) { _style = other._style; _state = other._state; @@ -90,6 +93,7 @@ AutomationList::AutomationList (const AutomationList& other) AutomationList::AutomationList (const AutomationList& other, double start, double end) : ControlList(other, start, end) + , _before (0) { _style = other._style; _state = other._state; @@ -106,6 +110,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl */ AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id) : ControlList(id, ARDOUR::ParameterDescriptor(id)) + , _before (0) { g_atomic_int_set (&_touching, 0); _state = Off; @@ -186,6 +191,9 @@ AutomationList::set_automation_state (AutoState s) { if (s != _state) { _state = s; + if (s == Write) { + _before = &get_state (); + } automation_state_changed (s); /* EMIT SIGNAL */ } } @@ -200,6 +208,22 @@ AutomationList::set_automation_style (AutoStyle s) } void +AutomationList::start_write_pass (double when) +{ + if (in_new_write_pass ()) { + _before = &get_state (); + } + ControlList::start_write_pass (when); +} + +void +AutomationList::write_pass_finished (double when, double thinning_factor) +{ + ControlList::write_pass_finished (when, thinning_factor); + _before = 0; +} + +void AutomationList::start_touch (double when) { if (_state == Touch) { diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index cb3f0d48c9..adbfefb829 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -3904,11 +3904,15 @@ Route::MuteControllable::set_superficial_value(bool muted) as currently MuteControllable can't be touching. bool to_list = _list && ((AutomationList*)_list.get())->automation_write(); */ - const AutoState as = ((AutomationList*)_list.get())->automation_state (); - bool to_list = _list && _session.transport_rolling () && (as == Touch || as == Write); + AutomationList* alist = (AutomationList*)_list.get(); + const AutoState as = alist->automation_state (); + const bool to_list = _list && _session.transport_rolling () && (as == Touch || as == Write); if (to_list) { - _list->set_in_write_pass(true, false, _session.audible_frame ()); + if (as == Touch && _list->in_new_write_pass ()) { + alist->start_write_pass (_session.audible_frame ()); + } + _list->set_in_write_pass (true, false, _session.audible_frame ()); } Control::set_double (muted, _session.transport_frame(), to_list); diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index 80096b65a4..f1a4627a1c 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -267,6 +267,7 @@ public: 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); bool in_write_pass () const; + bool in_new_write_pass () { return new_write_pass; } /** Emitted when mark_dirty() is called on this object */ mutable PBD::Signal0<void> Dirty; |