Make automation record undo per pass rather than per touch.
This commit is contained in:
parent
877b258c74
commit
9c102fa8d2
@ -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);
|
||||
|
@ -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.
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
@ -199,6 +207,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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user