assert (!AudioEngine::instance()->process_lock().trylock());
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
- assert(lm.locked());
+ if (!lm.locked()) {
+ bufs.silence (nframes, 0);
+ return;
+ }
/* figure out if we're going to use gain automation */
if (gain_automation_ok) {
node->add_child_nocopy (_mute_control->get_state ());
node->add_child_nocopy (_mute_master->get_state ());
+ if (full_state) {
+ node->add_child_nocopy (Automatable::get_automation_xml_state ());
+ }
+
XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
snprintf (buf, sizeof (buf), "%d", _remote_control_id);
remote_control_node->add_property (X_("id"), buf);
} else if (child->name() == X_("MuteMaster")) {
_mute_master->set_state (*child, version);
+
+ } else if (child->name() == Automatable::xml_node_name) {
+ set_automation_xml_state (*child, Evoral::Parameter(NullAutomation));
}
}
, _route (r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
+ gl->set_interpolation(Evoral::ControlList::Discrete);
set_list (gl);
}
void
Route::SoloControllable::set_value (double val)
{
- bool bval = ((val >= 0.5f) ? true: false);
+ const bool bval = ((val >= 0.5) ? true : false);
boost::shared_ptr<RouteList> rl (new RouteList);
, _route (r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
+ gl->set_interpolation(Evoral::ControlList::Discrete);
set_list (gl);
}
void
-Route::MuteControllable::set_value (double val)
+Route::MuteControllable::set_superficial_value(bool muted)
{
- bool bval = ((val >= 0.5f) ? true: false);
+ /* Note we can not use AutomationControl::set_value here since it will emit
+ Changed(), but the value will not be correct to the observer. */
- boost::shared_ptr<RouteList> rl (new RouteList);
+ bool to_list = _list && ((AutomationList*)_list.get())->automation_write();
+
+ Control::set_double (muted, _session.transport_frame(), to_list);
+}
+
+void
+Route::MuteControllable::set_value (double val)
+{
+ const bool bval = ((val >= 0.5) ? true : false);
boost::shared_ptr<Route> r = _route.lock ();
if (!r) {
return;
}
- rl->push_back (r);
- _session.set_mute (rl, bval);
+ if (_list && ((AutomationList*)_list.get())->automation_playback()) {
+ // Playing back automation, set route mute directly
+ r->set_mute (bval, this);
+ } else {
+ // Set from user, queue mute event
+ boost::shared_ptr<RouteList> rl (new RouteList);
+ rl->push_back (r);
+ _session.set_mute (rl, bval, Session::rt_cleanup);
+ }
+
+ // Set superficial/automation value to drive controller (and possibly record)
+ set_superficial_value(bval);
}
double
Route::MuteControllable::get_value () const
{
- boost::shared_ptr<Route> r = _route.lock ();
- if (!r) {
- return 0;
+ if (_list && ((AutomationList*)_list.get())->automation_playback()) {
+ // Playing back automation, get the value from the list
+ return AutomationControl::get_value();
}
- return r->muted() ? 1.0f : 0.0f;
+ // Not playing back automation, get the actual route mute value
+ boost::shared_ptr<Route> r = _route.lock ();
+ return (r && r->muted()) ? 1.0 : 0.0;
}
void
void
Route::meter ()
{
- Glib::Threads::RWLock::ReaderLock rm (_processor_lock, Glib::Threads::TRY_LOCK);
+ Glib::Threads::RWLock::ReaderLock rm (_processor_lock);
assert (_meter);
/* maybe one of our processors does or ... */
- Glib::Threads::RWLock::ReaderLock rm (_processor_lock, Glib::Threads::TRY_LOCK);
+ Glib::Threads::RWLock::ReaderLock rm (_processor_lock);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if ((c = boost::dynamic_pointer_cast<AutomationControl>((*i)->control (param))) != 0) {
break;