13
0

Fix automated controllable display value

::automation_run() evaluates the value, possibly ahead of time
depending on latency-compensation. The actual value is set in
realtime-context via set_value_unchecked() -> actually_set_value()
which emits the Changed signal.

At this point in time Control::user_value is already set correctly.
There is no need to evaluate and interpolate again, at a potentially
incorrect (uncompensated) time: `_session.transport_sample()`.

This fixes an issue with the GUI Automation control showing an
outdated value when there is an "immediate jump" in the signal:
eg. add a latent plugin post-fader, then automate the Fader to jump
from 0dB to -inf dB (snap to grid) and play though that transition.

(Plugin controls were not affected by this bug, the process
cycle is split for those, but Mixbus internal AC were affected).
This commit is contained in:
Robin Gareus 2022-06-29 00:21:25 +02:00
parent 7a01f3cbcd
commit 5cb6e1046b
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 9 additions and 13 deletions

View File

@ -95,12 +95,14 @@ AutomationControl::writable() const
return true; return true;
} }
/** Get the current effective `user' value based on automation state */
double double
AutomationControl::get_value() const AutomationControl::get_value() const
{ {
bool from_list = alist() && alist()->automation_playback(); /* automation_run() will have updated the value
return Control::get_double (from_list, timepos_t (_session.transport_sample())); * (possibly ahead of time, according to latency compensation),
* and actually_set_value() will have set the user-value accordingly.
*/
return Control::user_double();
} }
double double

View File

@ -106,18 +106,12 @@ SlavableAutomationControl::get_value_locked() const
double double
SlavableAutomationControl::get_value() const SlavableAutomationControl::get_value() const
{ {
bool from_list = _list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback();
Glib::Threads::RWLock::ReaderLock lm (master_lock); Glib::Threads::RWLock::ReaderLock lm (master_lock);
if (!from_list) { if (!_masters.empty() && automation_write ()) {
if (!_masters.empty() && automation_write ()) { /* writing automation takes the fader value as-is, factor out the master */
/* writing automation takes the fader value as-is, factor out the master */ return Control::user_double ();
return Control::user_double ();
}
return get_value_locked ();
} else {
return Control::get_double (true, timepos_t (_session.transport_sample())) * get_masters_value_locked();
} }
return get_value_locked ();
} }
bool bool