mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 08:14:58 +01:00
Add support for Latch Automation
This commit is contained in:
parent
1545c426d9
commit
1d587592ca
9 changed files with 31 additions and 15 deletions
|
|
@ -89,10 +89,10 @@ public:
|
||||||
PBD::Signal1<void, AutoState> automation_state_changed;
|
PBD::Signal1<void, AutoState> automation_state_changed;
|
||||||
|
|
||||||
bool automation_playback() const {
|
bool automation_playback() const {
|
||||||
return (_state & Play) || ((_state & Touch) && !touching());
|
return (_state & Play) || ((_state & (Touch | Latch)) && !touching());
|
||||||
}
|
}
|
||||||
bool automation_write () const {
|
bool automation_write () const {
|
||||||
return ((_state & Write) || ((_state & Touch) && touching()));
|
return ((_state & Write) || ((_state & (Touch | Latch)) && touching()));
|
||||||
}
|
}
|
||||||
|
|
||||||
PBD::Signal0<void> StateChanged;
|
PBD::Signal0<void> StateChanged;
|
||||||
|
|
@ -106,7 +106,7 @@ public:
|
||||||
void stop_touch (double when);
|
void stop_touch (double when);
|
||||||
bool touching() const { return g_atomic_int_get (const_cast<gint*>(&_touching)); }
|
bool touching() const { return g_atomic_int_get (const_cast<gint*>(&_touching)); }
|
||||||
bool writing() const { return _state == Write; }
|
bool writing() const { return _state == Write; }
|
||||||
bool touch_enabled() const { return _state == Touch; }
|
bool touch_enabled() const { return _state & (Touch | Latch); }
|
||||||
|
|
||||||
XMLNode& get_state ();
|
XMLNode& get_state ();
|
||||||
int set_state (const XMLNode &, int version);
|
int set_state (const XMLNode &, int version);
|
||||||
|
|
|
||||||
|
|
@ -58,19 +58,19 @@ class LIBARDOUR_API Pannable : public PBD::Stateful, public Automatable, public
|
||||||
PBD::Signal1<void, AutoState> automation_state_changed;
|
PBD::Signal1<void, AutoState> automation_state_changed;
|
||||||
|
|
||||||
bool automation_playback() const {
|
bool automation_playback() const {
|
||||||
return (_auto_state & Play) || ((_auto_state & Touch) && !touching());
|
return (_auto_state & Play) || ((_auto_state & (Touch | Latch)) && !touching());
|
||||||
}
|
}
|
||||||
bool automation_write () const {
|
bool automation_write () const {
|
||||||
return ((_auto_state & Write) || ((_auto_state & Touch) && touching()));
|
return ((_auto_state & Write) || ((_auto_state & (Touch | Latch)) && touching()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string value_as_string (boost::shared_ptr<const AutomationControl>) const;
|
std::string value_as_string (boost::shared_ptr<const AutomationControl>) const;
|
||||||
|
|
||||||
void start_touch (double when);
|
void start_touch (double when);
|
||||||
void stop_touch (double when);
|
void stop_touch (double when);
|
||||||
bool touching() const { return g_atomic_int_get (const_cast<gint*>(&_touching)); }
|
bool touching() const { return g_atomic_int_get (const_cast<gint*>(&_touching)); }
|
||||||
bool writing() const { return _auto_state == Write; }
|
bool writing() const { return _auto_state == Write; }
|
||||||
bool touch_enabled() const { return _auto_state == Touch; }
|
bool touch_enabled() const { return _auto_state & (Touch | Latch); }
|
||||||
|
|
||||||
XMLNode& get_state ();
|
XMLNode& get_state ();
|
||||||
XMLNode& state (bool full_state);
|
XMLNode& state (bool full_state);
|
||||||
|
|
|
||||||
|
|
@ -163,10 +163,11 @@ namespace ARDOUR {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AutoState {
|
enum AutoState {
|
||||||
Off = 0x0,
|
Off = 0x00,
|
||||||
Write = 0x1,
|
Write = 0x01,
|
||||||
Touch = 0x2,
|
Touch = 0x02,
|
||||||
Play = 0x4
|
Play = 0x04,
|
||||||
|
Latch = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string auto_state_to_string (AutoState);
|
std::string auto_state_to_string (AutoState);
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,8 @@ Automatable::protect_automation ()
|
||||||
case Write:
|
case Write:
|
||||||
l->set_automation_state (Off);
|
l->set_automation_state (Off);
|
||||||
break;
|
break;
|
||||||
|
case Latch:
|
||||||
|
// no break
|
||||||
case Touch:
|
case Touch:
|
||||||
l->set_automation_state (Play);
|
l->set_automation_state (Play);
|
||||||
break;
|
break;
|
||||||
|
|
@ -408,6 +410,7 @@ Automatable::non_realtime_transport_stop (framepos_t now, bool /*flush_processor
|
||||||
*/
|
*/
|
||||||
const bool list_did_write = !l->in_new_write_pass ();
|
const bool list_did_write = !l->in_new_write_pass ();
|
||||||
|
|
||||||
|
c->stop_touch (now);
|
||||||
l->stop_touch (now);
|
l->stop_touch (now);
|
||||||
|
|
||||||
c->commit_transaction (list_did_write);
|
c->commit_transaction (list_did_write);
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ AutomationControl::set_automation_state (AutoState as)
|
||||||
|
|
||||||
if (as == Write) {
|
if (as == Write) {
|
||||||
AutomationWatch::instance().add_automation_watch (shared_from_this());
|
AutomationWatch::instance().add_automation_watch (shared_from_this());
|
||||||
} else if (as == Touch) {
|
} else if (as & (Touch | Latch)) {
|
||||||
if (alist()->empty()) {
|
if (alist()->empty()) {
|
||||||
Control::set_double (val, _session.current_start_frame (), true);
|
Control::set_double (val, _session.current_start_frame (), true);
|
||||||
Control::set_double (val, _session.current_end_frame (), true);
|
Control::set_double (val, _session.current_end_frame (), true);
|
||||||
|
|
@ -283,7 +283,7 @@ AutomationControl::start_touch (double when)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alist()->automation_state() == Touch) {
|
if (alist()->automation_state() & (Touch | Latch)) {
|
||||||
/* subtle. aligns the user value with the playback and
|
/* subtle. aligns the user value with the playback and
|
||||||
* use take actual value (incl masters).
|
* use take actual value (incl masters).
|
||||||
*
|
*
|
||||||
|
|
@ -306,9 +306,13 @@ AutomationControl::stop_touch (double when)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alist()->automation_state() == Latch && _session.transport_rolling ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
set_touching (false);
|
set_touching (false);
|
||||||
|
|
||||||
if (alist()->automation_state() == Touch) {
|
if (alist()->automation_state() & (Touch | Latch)) {
|
||||||
alist()->stop_touch (when);
|
alist()->stop_touch (when);
|
||||||
if (!_desc.toggled) {
|
if (!_desc.toggled) {
|
||||||
AutomationWatch::instance().remove_automation_watch (shared_from_this());
|
AutomationWatch::instance().remove_automation_watch (shared_from_this());
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,7 @@ setup_enum_writer ()
|
||||||
REGISTER_ENUM (Write);
|
REGISTER_ENUM (Write);
|
||||||
REGISTER_ENUM (Touch);
|
REGISTER_ENUM (Touch);
|
||||||
REGISTER_ENUM (Play);
|
REGISTER_ENUM (Play);
|
||||||
|
REGISTER_ENUM (Latch);
|
||||||
REGISTER_BITS (_AutoState);
|
REGISTER_BITS (_AutoState);
|
||||||
|
|
||||||
REGISTER_ENUM (CaptureTime);
|
REGISTER_ENUM (CaptureTime);
|
||||||
|
|
|
||||||
|
|
@ -1704,6 +1704,7 @@ LuaBindings::common (lua_State* L)
|
||||||
.addConst ("Write", ARDOUR::AutoState(Write))
|
.addConst ("Write", ARDOUR::AutoState(Write))
|
||||||
.addConst ("Touch", ARDOUR::AutoState(Touch))
|
.addConst ("Touch", ARDOUR::AutoState(Touch))
|
||||||
.addConst ("Play", ARDOUR::AutoState(Play))
|
.addConst ("Play", ARDOUR::AutoState(Play))
|
||||||
|
.addConst ("Latch", ARDOUR::AutoState(Latch))
|
||||||
.endNamespace ()
|
.endNamespace ()
|
||||||
|
|
||||||
.beginNamespace ("AutomationType")
|
.beginNamespace ("AutomationType")
|
||||||
|
|
|
||||||
|
|
@ -382,7 +382,7 @@ PannerShell::run (BufferSet& inbufs, BufferSet& outbufs, framepos_t start_frame,
|
||||||
|
|
||||||
// If we shouldn't play automation defer to distribute_no_automation
|
// If we shouldn't play automation defer to distribute_no_automation
|
||||||
|
|
||||||
if (!(as & Play || ((as & Touch) && !_panner->touching()))) {
|
if (!((as & Play) || ((as & (Touch | Latch)) && !_panner->touching()))) {
|
||||||
|
|
||||||
distribute_no_automation (inbufs, outbufs, nframes, 1.0);
|
distribute_no_automation (inbufs, outbufs, nframes, 1.0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -561,6 +561,8 @@ ARDOUR::string_to_auto_state (std::string str)
|
||||||
return Write;
|
return Write;
|
||||||
} else if (str == X_("Touch")) {
|
} else if (str == X_("Touch")) {
|
||||||
return Touch;
|
return Touch;
|
||||||
|
} else if (str == X_("Latch")) {
|
||||||
|
return Latch;
|
||||||
}
|
}
|
||||||
|
|
||||||
fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState string: ", str) << endmsg;
|
fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState string: ", str) << endmsg;
|
||||||
|
|
@ -585,6 +587,10 @@ ARDOUR::auto_state_to_string (AutoState as)
|
||||||
break;
|
break;
|
||||||
case Touch:
|
case Touch:
|
||||||
return X_("Touch");
|
return X_("Touch");
|
||||||
|
break;
|
||||||
|
case Latch:
|
||||||
|
return X_("Latch");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState type: ", as) << endmsg;
|
fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState type: ", as) << endmsg;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue